Skip to content

Commit 00cb786

Browse files
author
Vadim Zubovich
committed
Merge branch 'develop' into pr2
# Conflicts: # dev/tests/functional/tests/app/Magento/Checkout/Test/TestCase/OnePageCheckoutTest.xml
2 parents 71b965e + 1f4f104 commit 00cb786

File tree

45 files changed

+618
-354
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+618
-354
lines changed

app/code/Magento/Catalog/Model/ResourceModel/Product/StatusBaseSelectProcessor.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
use Magento\Eav\Model\Config;
1212
use Magento\Framework\DB\Select;
1313
use Magento\Framework\EntityManager\MetadataPool;
14+
use Magento\Store\Api\StoreResolverInterface;
15+
use Magento\Store\Model\Store;
1416

1517
/**
1618
* Class StatusBaseSelectProcessor
@@ -27,16 +29,24 @@ class StatusBaseSelectProcessor implements BaseSelectProcessorInterface
2729
*/
2830
private $metadataPool;
2931

32+
/**
33+
* @var StoreResolverInterface
34+
*/
35+
private $storeResolver;
36+
3037
/**
3138
* @param Config $eavConfig
3239
* @param MetadataPool $metadataPool
40+
* @param StoreResolverInterface $storeResolver
3341
*/
3442
public function __construct(
3543
Config $eavConfig,
36-
MetadataPool $metadataPool
44+
MetadataPool $metadataPool,
45+
StoreResolverInterface $storeResolver
3746
) {
3847
$this->eavConfig = $eavConfig;
3948
$this->metadataPool = $metadataPool;
49+
$this->storeResolver = $storeResolver;
4050
}
4151

4252
/**
@@ -48,13 +58,23 @@ public function process(Select $select)
4858
$linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
4959
$statusAttribute = $this->eavConfig->getAttribute(Product::ENTITY, ProductInterface::STATUS);
5060

51-
$select->join(
61+
$select->joinLeft(
62+
['status_global_attr' => $statusAttribute->getBackendTable()],
63+
"status_global_attr.{$linkField} = " . self::PRODUCT_TABLE_ALIAS . ".{$linkField}"
64+
. ' AND status_global_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
65+
. ' AND status_global_attr.store_id = ' . Store::DEFAULT_STORE_ID,
66+
[]
67+
);
68+
69+
$select->joinLeft(
5270
['status_attr' => $statusAttribute->getBackendTable()],
53-
sprintf('status_attr.%s = %s.%1$s', $linkField, self::PRODUCT_TABLE_ALIAS),
71+
"status_attr.{$linkField} = " . self::PRODUCT_TABLE_ALIAS . ".{$linkField}"
72+
. ' AND status_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
73+
. ' AND status_attr.store_id = ' . $this->storeResolver->getCurrentStoreId(),
5474
[]
55-
)
56-
->where('status_attr.attribute_id = ?', $statusAttribute->getAttributeId())
57-
->where('status_attr.value = ?', Status::STATUS_ENABLED);
75+
);
76+
77+
$select->where('IFNULL(status_attr.value, status_global_attr.value) = ?', Status::STATUS_ENABLED);
5878

5979
return $select;
6080
}

app/code/Magento/Catalog/Test/Unit/Model/ResourceModel/Product/StatusBaseSelectProcessorTest.php

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,12 @@
1616
use Magento\Framework\EntityManager\EntityMetadataInterface;
1717
use Magento\Framework\EntityManager\MetadataPool;
1818
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
19+
use Magento\Store\Api\StoreResolverInterface;
20+
use Magento\Store\Model\Store;
1921

22+
/**
23+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
24+
*/
2025
class StatusBaseSelectProcessorTest extends \PHPUnit_Framework_TestCase
2126
{
2227
/**
@@ -29,6 +34,11 @@ class StatusBaseSelectProcessorTest extends \PHPUnit_Framework_TestCase
2934
*/
3035
private $metadataPool;
3136

37+
/**
38+
* @var StoreResolverInterface|\PHPUnit_Framework_MockObject_MockObject
39+
*/
40+
private $storeResolver;
41+
3242
/**
3343
* @var Select|\PHPUnit_Framework_MockObject_MockObject
3444
*/
@@ -43,19 +53,22 @@ protected function setUp()
4353
{
4454
$this->eavConfig = $this->getMockBuilder(Config::class)->disableOriginalConstructor()->getMock();
4555
$this->metadataPool = $this->getMockBuilder(MetadataPool::class)->disableOriginalConstructor()->getMock();
56+
$this->storeResolver = $this->getMockBuilder(StoreResolverInterface::class)->getMock();
4657
$this->select = $this->getMockBuilder(Select::class)->disableOriginalConstructor()->getMock();
4758

4859
$this->statusBaseSelectProcessor = (new ObjectManager($this))->getObject(StatusBaseSelectProcessor::class, [
4960
'eavConfig' => $this->eavConfig,
5061
'metadataPool' => $this->metadataPool,
62+
'storeResolver' => $this->storeResolver,
5163
]);
5264
}
5365

5466
public function testProcess()
5567
{
5668
$linkField = 'link_field';
5769
$backendTable = 'backend_table';
58-
$attributeId = 'attribute_id';
70+
$attributeId = 2;
71+
$currentStoreId = 1;
5972

6073
$metadata = $this->getMock(EntityMetadataInterface::class);
6174
$metadata->expects($this->once())
@@ -66,35 +79,49 @@ public function testProcess()
6679
->with(ProductInterface::class)
6780
->willReturn($metadata);
6881

82+
/** @var AttributeInterface|\PHPUnit_Framework_MockObject_MockObject $statusAttribute */
6983
$statusAttribute = $this->getMockBuilder(AttributeInterface::class)
7084
->setMethods(['getBackendTable', 'getAttributeId'])
7185
->getMock();
72-
$statusAttribute->expects($this->once())
86+
$statusAttribute->expects($this->atLeastOnce())
7387
->method('getBackendTable')
7488
->willReturn($backendTable);
75-
$statusAttribute->expects($this->once())
89+
$statusAttribute->expects($this->atLeastOnce())
7690
->method('getAttributeId')
7791
->willReturn($attributeId);
7892
$this->eavConfig->expects($this->once())
7993
->method('getAttribute')
8094
->with(Product::ENTITY, ProductInterface::STATUS)
8195
->willReturn($statusAttribute);
8296

83-
$this->select->expects($this->once())
84-
->method('join')
97+
$this->storeResolver->expects($this->once())
98+
->method('getCurrentStoreId')
99+
->willReturn($currentStoreId);
100+
101+
$this->select->expects($this->at(0))
102+
->method('joinLeft')
85103
->with(
86-
['status_attr' => $backendTable],
87-
sprintf('status_attr.%s = %s.%1$s', $linkField, BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS),
104+
['status_global_attr' => $backendTable],
105+
"status_global_attr.{$linkField} = "
106+
. BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS . ".{$linkField}"
107+
. " AND status_global_attr.attribute_id = {$attributeId}"
108+
. ' AND status_global_attr.store_id = ' . Store::DEFAULT_STORE_ID,
88109
[]
89110
)
90111
->willReturnSelf();
91112
$this->select->expects($this->at(1))
92-
->method('where')
93-
->with('status_attr.attribute_id = ?', $attributeId)
113+
->method('joinLeft')
114+
->with(
115+
['status_attr' => $backendTable],
116+
"status_attr.{$linkField} = " . BaseSelectProcessorInterface::PRODUCT_TABLE_ALIAS . ".{$linkField}"
117+
. " AND status_attr.attribute_id = {$attributeId}"
118+
. " AND status_attr.store_id = {$currentStoreId}",
119+
[]
120+
)
94121
->willReturnSelf();
95122
$this->select->expects($this->at(2))
96123
->method('where')
97-
->with('status_attr.value = ?', Status::STATUS_ENABLED)
124+
->with('IFNULL(status_attr.value, status_global_attr.value) = ?', Status::STATUS_ENABLED)
98125
->willReturnSelf();
99126

100127
$this->assertEquals($this->select, $this->statusBaseSelectProcessor->process($this->select));

app/code/Magento/Checkout/view/frontend/web/template/summary/cart-items.html

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
* See COPYING.txt for license details.
55
*/
66
-->
7-
<!-- ko ifnot: isItemsBlockExpanded() -->
8-
<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'openedState': 'active'}}">
7+
<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'openedState': 'active', 'active': isItemsBlockExpanded()}}">
98
<div class="title" data-role="title">
109
<strong role="heading"><span data-bind="text: getItemsQty()"></span>
1110
<!-- ko if: getItemsQty() == 1 -->
@@ -32,33 +31,3 @@
3231
</div>
3332
</div>
3433
</div>
35-
<!-- /ko -->
36-
<!-- ko if: isItemsBlockExpanded() -->
37-
<div class="block items-in-cart" data-bind="mageInit: {'collapsible':{'openedState': 'active', 'active': true}}">
38-
<div class="title" data-role="title">
39-
<strong role="heading"><span data-bind="text: getItemsQty()"></span>
40-
<!-- ko if: getItemsQty() == 1 -->
41-
<!-- ko i18n: 'Item in Cart' --><!-- /ko -->
42-
<!-- /ko -->
43-
<!-- ko if: getItemsQty() > 1 -->
44-
<!-- ko i18n: 'Items in Cart' --><!-- /ko -->
45-
<!-- /ko -->
46-
</strong>
47-
</div>
48-
<div class="content minicart-items" data-role="content">
49-
<div class="minicart-items-wrapper overflowed">
50-
<ol class="minicart-items">
51-
<!-- ko foreach: getItems() -->
52-
<li class="product-item">
53-
<div class="product">
54-
<!-- ko foreach: $parent.elems() -->
55-
<!-- ko template: getTemplate() --><!-- /ko -->
56-
<!-- /ko -->
57-
</div>
58-
</li>
59-
<!-- /ko -->
60-
</ol>
61-
</div>
62-
</div>
63-
</div>
64-
<!-- /ko -->

app/code/Magento/ConfigurableProduct/Model/ResourceModel/Product/Indexer/Price/Configurable.php

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,45 @@
99

1010
use Magento\Catalog\Api\Data\ProductInterface;
1111
use Magento\Catalog\Model\Product\Attribute\Source\Status as ProductStatus;
12+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
13+
use Magento\Store\Api\StoreResolverInterface;
14+
use Magento\Store\Model\Store;
1215

16+
/**
17+
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
18+
*/
1319
class Configurable extends \Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\DefaultPrice
1420
{
21+
/**
22+
* @var StoreResolverInterface
23+
*/
24+
private $storeResolver;
25+
26+
/**
27+
* Class constructor
28+
*
29+
* @param \Magento\Framework\Model\ResourceModel\Db\Context $context
30+
* @param \Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy
31+
* @param \Magento\Eav\Model\Config $eavConfig
32+
* @param \Magento\Framework\Event\ManagerInterface $eventManager
33+
* @param \Magento\Framework\Module\Manager $moduleManager
34+
* @param string $connectionName
35+
* @param StoreResolverInterface $storeResolver
36+
*/
37+
public function __construct(
38+
\Magento\Framework\Model\ResourceModel\Db\Context $context,
39+
\Magento\Framework\Indexer\Table\StrategyInterface $tableStrategy,
40+
\Magento\Eav\Model\Config $eavConfig,
41+
\Magento\Framework\Event\ManagerInterface $eventManager,
42+
\Magento\Framework\Module\Manager $moduleManager,
43+
$connectionName = null,
44+
StoreResolverInterface $storeResolver = null
45+
) {
46+
parent::__construct($context, $tableStrategy, $eavConfig, $eventManager, $moduleManager, $connectionName);
47+
$this->storeResolver = $storeResolver ?:
48+
\Magento\Framework\App\ObjectManager::getInstance()->get(StoreResolverInterface::class);
49+
}
50+
1551
/**
1652
* Reindex temporary (price result data) for all products
1753
*
@@ -190,16 +226,21 @@ protected function _applyConfigurableOption()
190226
[]
191227
)->where(
192228
'le.required_options=0'
193-
)->join(
194-
['product_status' => $this->getTable($statusAttribute->getBackend()->getTable())],
195-
sprintf(
196-
'le.%1$s = product_status.%1$s AND product_status.attribute_id = %2$s',
197-
$linkField,
198-
$statusAttribute->getAttributeId()
199-
),
229+
)->joinLeft(
230+
['status_global_attr' => $statusAttribute->getBackendTable()],
231+
"status_global_attr.{$linkField} = le.{$linkField}"
232+
. ' AND status_global_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
233+
. ' AND status_global_attr.store_id = ' . Store::DEFAULT_STORE_ID,
234+
[]
235+
)->joinLeft(
236+
['status_attr' => $statusAttribute->getBackendTable()],
237+
"status_attr.{$linkField} = le.{$linkField}"
238+
. ' AND status_attr.attribute_id = ' . (int)$statusAttribute->getAttributeId()
239+
. ' AND status_attr.store_id = ' . $this->storeResolver->getCurrentStoreId(),
200240
[]
201241
)->where(
202-
'product_status.value=' . ProductStatus::STATUS_ENABLED
242+
'IFNULL(status_attr.value, status_global_attr.value) = ?',
243+
Status::STATUS_ENABLED
203244
)->group(
204245
['e.entity_id', 'i.customer_group_id', 'i.website_id', 'l.product_id']
205246
);

app/code/Magento/Customer/Model/Address/AbstractAddress.php

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,8 @@ public function getDataModel($defaultBillingAddressId = null, $defaultShippingAd
554554
/**
555555
* Validate address attribute values
556556
*
557+
*
558+
*
557559
* @return bool|array
558560
* @SuppressWarnings(PHPMD.CyclomaticComplexity)
559561
* @SuppressWarnings(PHPMD.NPathComplexity)
@@ -562,23 +564,24 @@ public function validate()
562564
{
563565
$errors = [];
564566
if (!\Zend_Validate::is($this->getFirstname(), 'NotEmpty')) {
565-
$errors[] = __('Please enter the first name.');
567+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'firstname']);
566568
}
567569

568570
if (!\Zend_Validate::is($this->getLastname(), 'NotEmpty')) {
569-
$errors[] = __('Please enter the last name.');
571+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'lastname']);
570572
}
571573

572574
if (!\Zend_Validate::is($this->getStreetLine(1), 'NotEmpty')) {
573-
$errors[] = __('Please enter the street.');
575+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'street']);
574576
}
575577

576578
if (!\Zend_Validate::is($this->getCity(), 'NotEmpty')) {
577-
$errors[] = __('Please enter the city.');
579+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'city']);
578580
}
579581

580582
if (!\Zend_Validate::is($this->getTelephone(), 'NotEmpty')) {
581-
$errors[] = __('Please enter the phone number.');
583+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'telephone']);
584+
582585
}
583586

584587
$_havingOptionalZip = $this->_directoryData->getCountriesWithOptionalZip();
@@ -590,11 +593,11 @@ public function validate()
590593
'NotEmpty'
591594
)
592595
) {
593-
$errors[] = __('Please enter the zip/postal code.');
596+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'postcode']);
594597
}
595598

596599
if (!\Zend_Validate::is($this->getCountryId(), 'NotEmpty')) {
597-
$errors[] = __('Please enter the country.');
600+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'countryId']);
598601
}
599602

600603
if ($this->getCountryModel()->getRegionCollection()->getSize() && !\Zend_Validate::is(
@@ -604,7 +607,7 @@ public function validate()
604607
$this->getCountryId()
605608
)
606609
) {
607-
$errors[] = __('Please enter the state/province.');
610+
$errors[] = __('%fieldName is a required field.', ['fieldName' => 'regionId']);
608611
}
609612

610613
if (empty($errors) || $this->getShouldIgnoreValidation()) {

0 commit comments

Comments
 (0)