diff --git a/app/code/Magento/CatalogInventory/Model/Source/Stock.php b/app/code/Magento/CatalogInventory/Model/Source/Stock.php index f64026cce23a5..9ed891d1dcc0f 100644 --- a/app/code/Magento/CatalogInventory/Model/Source/Stock.php +++ b/app/code/Magento/CatalogInventory/Model/Source/Stock.php @@ -26,4 +26,23 @@ public function getAllOptions() ['value' => \Magento\CatalogInventory\Model\Stock::STOCK_OUT_OF_STOCK, 'label' => __('Out of Stock')] ]; } + + /** + * Add Value Sort To Collection Select. + * + * @param \Magento\Eav\Model\Entity\Collection\AbstractCollection $collection + * @param string $dir + * + * @return $this + */ + public function addValueSortToCollection($collection, $dir = \Magento\Framework\Data\Collection::SORT_ORDER_DESC) + { + $collection->getSelect()->joinLeft( + ['stock_item_table' => 'cataloginventory_stock_item'], + "e.entity_id=stock_item_table.product_id", + [] + ); + $collection->getSelect()->order("stock_item_table.qty $dir"); + return $this; + } } diff --git a/app/code/Magento/CatalogInventory/Test/Unit/Model/Source/StockTest.php b/app/code/Magento/CatalogInventory/Test/Unit/Model/Source/StockTest.php new file mode 100644 index 0000000000000..11f41fcaf6d01 --- /dev/null +++ b/app/code/Magento/CatalogInventory/Test/Unit/Model/Source/StockTest.php @@ -0,0 +1,44 @@ +model = new \Magento\CatalogInventory\Model\Source\Stock(); + } + + public function testAddValueSortToCollection() + { + $selectMock = $this->createMock(\Magento\Framework\DB\Select::class); + $collectionMock = $this->createMock(\Magento\Eav\Model\Entity\Collection\AbstractCollection::class); + $collectionMock->expects($this->atLeastOnce())->method('getSelect')->willReturn($selectMock); + + $selectMock->expects($this->once()) + ->method('joinLeft') + ->with( + ['stock_item_table' => 'cataloginventory_stock_item'], + "e.entity_id=stock_item_table.product_id", + [] + ) + ->willReturnSelf(); + $selectMock->expects($this->once()) + ->method('order') + ->with("stock_item_table.qty DESC") + ->willReturnSelf(); + + $this->model->addValueSortToCollection($collectionMock); + } +} 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 5ac062a12180c..a2f8c8c56ff33 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 @@ -10,7 +10,8 @@ define([ 'ko', 'underscore', 'sidebar', - 'mage/translate' + 'mage/translate', + 'mage/dropdown' ], function (Component, customerData, $, ko, _) { 'use strict'; diff --git a/app/code/Magento/Customer/view/frontend/web/js/action/login.js b/app/code/Magento/Customer/view/frontend/web/js/action/login.js index 8bf96cd76b1a8..d75b8f70c5346 100644 --- a/app/code/Magento/Customer/view/frontend/web/js/action/login.js +++ b/app/code/Magento/Customer/view/frontend/web/js/action/login.js @@ -7,8 +7,9 @@ define([ 'jquery', 'mage/storage', 'Magento_Ui/js/model/messageList', - 'Magento_Customer/js/customer-data' -], function ($, storage, globalMessageList, customerData) { + 'Magento_Customer/js/customer-data', + 'mage/translate' +], function ($, storage, globalMessageList, customerData, $t) { 'use strict'; var callbacks = [], @@ -48,7 +49,7 @@ define([ } }).fail(function () { messageContainer.addErrorMessage({ - 'message': 'Could not authenticate. Please try again later' + 'message': $t('Could not authenticate. Please try again later') }); callbacks.forEach(function (callback) { callback(loginData); diff --git a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php index dc875a7bb37c4..3c26ed9c6faa8 100644 --- a/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php +++ b/app/code/Magento/CustomerGraphQl/Model/Resolver/Customer.php @@ -6,11 +6,12 @@ namespace Magento\CustomerGraphQl\Model\Resolver; +use Magento\Authorization\Model\UserContextInterface; +use Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider; use Magento\Framework\Exception\NoSuchEntityException; use Magento\Framework\GraphQl\Exception\GraphQlAuthorizationException; use Magento\Framework\GraphQl\Exception\GraphQlNoSuchEntityException; use Magento\GraphQl\Model\ResolverInterface; -use Magento\Framework\GraphQl\Exception\GraphQlInputException; use Magento\GraphQl\Model\ResolverContextInterface; /** @@ -24,10 +25,10 @@ class Customer implements ResolverInterface private $customerResolver; /** - * @param \Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider $customerResolver + * @param CustomerDataProvider $customerResolver */ public function __construct( - \Magento\CustomerGraphQl\Model\Resolver\Customer\CustomerDataProvider $customerResolver + CustomerDataProvider $customerResolver ) { $this->customerResolver = $customerResolver; } @@ -37,7 +38,7 @@ public function __construct( */ public function resolve(array $args, ResolverContextInterface $context) { - if ((!$context->getUserId()) || $context->getUserType() == 4) { + if ((!$context->getUserId()) || $context->getUserType() == UserContextInterface::USER_TYPE_GUEST) { throw new GraphQlAuthorizationException( __( 'Current customer does not have access to the resource "%1"', diff --git a/app/code/Magento/CustomerGraphQl/composer.json b/app/code/Magento/CustomerGraphQl/composer.json index 8d8e18fab9388..3138a76fc4b4e 100644 --- a/app/code/Magento/CustomerGraphQl/composer.json +++ b/app/code/Magento/CustomerGraphQl/composer.json @@ -6,6 +6,7 @@ "require": { "php": "7.0.2|7.0.4|~7.0.6|~7.1.0", "magento/module-customer": "100.2.*", + "magento/module-authorization": "100.3.*", "magento/module-graph-ql": "100.0.*", "magento/framework": "100.3.*" }, diff --git a/app/code/Magento/CustomerGraphQl/etc/module.xml b/app/code/Magento/CustomerGraphQl/etc/module.xml index c3149965b0fe0..bde93c6276500 100644 --- a/app/code/Magento/CustomerGraphQl/etc/module.xml +++ b/app/code/Magento/CustomerGraphQl/etc/module.xml @@ -9,6 +9,7 @@ + diff --git a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Option.php b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Option.php index cd2e985e57ee8..79c277dcb6a82 100644 --- a/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Option.php +++ b/app/code/Magento/Eav/Model/ResourceModel/Entity/Attribute/Option.php @@ -44,8 +44,8 @@ public function addOptionValueToCollection($collection, $attribute, $valueExpr) ); $valueExpr = $connection->getCheckSql( "{$optionTable2}.value_id IS NULL", - "{$optionTable1}.value", - "{$optionTable2}.value" + "{$optionTable1}.option_id", + "{$optionTable2}.option_id" ); $collection->getSelect()->joinLeft( 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 e8598f46eb5be..2e9ddf77bf7bd 100644 --- a/app/code/Magento/Search/view/frontend/web/form-mini.js +++ b/app/code/Magento/Search/view/frontend/web/form-mini.js @@ -98,7 +98,9 @@ define([ }, this), 250); }, this)); - this.element.trigger('blur'); + if (this.element.get(0) === document.activeElement) { + this.setActiveState(true); + } this.element.on('focus', this.setActiveState.bind(this, true)); this.element.on('keydown', this._onKeyDown); 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 a24c72c473fe9..a1effcb972204 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 @@ -312,7 +312,7 @@ define([ */ _sortAttributes: function () { this.options.jsonConfig.attributes = _.sortBy(this.options.jsonConfig.attributes, function (attribute) { - return attribute.position; + return parseInt(attribute.position, 10); }); }, diff --git a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml index 58548a0ba268a..4395cab651de1 100644 --- a/app/code/Magento/Theme/view/frontend/templates/html/header.phtml +++ b/app/code/Magento/Theme/view/frontend/templates/html/header.phtml @@ -19,7 +19,7 @@ $welcomeMessage = $block->getWelcome(); - + getBlockHtml('header.additional') ?> diff --git a/app/design/adminhtml/Magento/backend/web/css/source/variables/_spinner.less b/app/design/adminhtml/Magento/backend/web/css/source/variables/_spinner.less index 09baf498cbcf4..60b84b1f467fe 100644 --- a/app/design/adminhtml/Magento/backend/web/css/source/variables/_spinner.less +++ b/app/design/adminhtml/Magento/backend/web/css/source/variables/_spinner.less @@ -26,4 +26,4 @@ @spinner-rotate-step: 45; // One step in degree -@spinner-delay: .9; +@spinner-delay: .9s; diff --git a/lib/internal/Magento/Framework/Encryption/Encryptor.php b/lib/internal/Magento/Framework/Encryption/Encryptor.php index be329fc75a362..881c5843b155e 100644 --- a/lib/internal/Magento/Framework/Encryption/Encryptor.php +++ b/lib/internal/Magento/Framework/Encryption/Encryptor.php @@ -148,7 +148,7 @@ public function validateCipher($version) public function getHash($password, $salt = false, $version = self::HASH_VERSION_LATEST) { if ($salt === false) { - return $this->hash($password); + return $this->hash($password, $version); } if ($salt === true) { $salt = self::DEFAULT_SALT_LENGTH; @@ -160,7 +160,7 @@ public function getHash($password, $salt = false, $version = self::HASH_VERSION_ return implode( self::DELIMITER, [ - $this->hash($salt . $password), + $this->hash($salt . $password, $version), $salt, $version ] diff --git a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php index 685c22f24c303..52a7a98eac312 100644 --- a/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php +++ b/lib/internal/Magento/Framework/Encryption/Test/Unit/EncryptorTest.php @@ -207,4 +207,32 @@ public function testValidateKey() $this->assertEquals($expectedEncryptedData, $actualEncryptedData); $this->assertEquals($crypt->decrypt($expectedEncryptedData), $actual->decrypt($actualEncryptedData)); } + + public function testUseSpecifiedHashingAlgoDataProvider() + { + return [ + ['password', 'salt', Encryptor::HASH_VERSION_MD5, + '67a1e09bb1f83f5007dc119c14d663aa:salt:0'], + ['password', 'salt', Encryptor::HASH_VERSION_SHA256, + '13601bda4ea78e55a07b98866d2be6be0744e3866f13c00c811cab608a28f322:salt:1'], + ['password', false, Encryptor::HASH_VERSION_MD5, + '5f4dcc3b5aa765d61d8327deb882cf99'], + ['password', false, Encryptor::HASH_VERSION_SHA256, + '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'] + ]; + } + + /** + * @dataProvider testUseSpecifiedHashingAlgoDataProvider + * + * @param $password + * @param $salt + * @param $hashAlgo + * @param $expected + */ + public function testGetHashMustUseSpecifiedHashingAlgo($password, $salt, $hashAlgo, $expected) + { + $hash = $this->_model->getHash($password, $salt, $hashAlgo); + $this->assertEquals($expected, $hash); + } }