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();
-
+
= $block->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);
+ }
}