Skip to content

Commit 47ea318

Browse files
author
Oleksii Korshenko
authored
Merge branch '2.3-develop' into batch-11-forwardport-2.3-develop
2 parents e07d040 + b48ec86 commit 47ea318

File tree

385 files changed

+8405
-9578
lines changed

Some content is hidden

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

385 files changed

+8405
-9578
lines changed

.htaccess.sample

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@
111111
############################################
112112
## enable rewrites
113113

114-
Options +FollowSymLinks
114+
# The following line has better security but add some performance overhead - see https://httpd.apache.org/docs/2.4/en/misc/perf-tuning.html
115+
Options -FollowSymLinks +SymLinksIfOwnerMatch
115116
RewriteEngine on
116117

117118
############################################

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,13 @@
55
Welcome to Magento 2 installation! We're glad you chose to install Magento 2, a cutting edge, feature-rich eCommerce solution that gets results.
66

77
## Magento system requirements
8-
[Magento system requirements](http://devdocs.magento.com/magento-system-requirements.html)
8+
[Magento system requirements](http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements2.html)
99

1010
## Install Magento
1111
To install Magento, see either:
1212

1313
* [Magento DevBox](https://magento.com/tech-resources/download), the easiest way to get started with Magento.
14-
* [Installation guide](http://devdocs.magento.com/guides/v2.0/install-gde/bk-install-guide.html)
14+
* [Installation guide](http://devdocs.magento.com/guides/v2.2/install-gde/bk-install-guide.html)
1515

1616
<h2>Contributing to the Magento 2 code base</h2>
1717
Contributions can take the form of new components or features, changes to existing features, tests, documentation (such as developer guides, user guides, examples, or specifications), bug fixes, optimizations, or just good suggestions.
@@ -22,8 +22,8 @@ To learn about issues, click [here][2]. To open an issue, click [here][3].
2222

2323
To suggest documentation improvements, click [here][4].
2424

25-
[1]: <http://devdocs.magento.com/guides/v2.0/contributor-guide/contributing.html>
26-
[2]: <http://devdocs.magento.com/guides/v2.0/contributor-guide/contributing.html#report>
25+
[1]: <http://devdocs.magento.com/guides/v2.2/contributor-guide/contributing.html>
26+
[2]: <http://devdocs.magento.com/guides/v2.2/contributor-guide/contributing.html#report>
2727
[3]: <https://github.com/magento/magento2/issues>
2828
[4]: <http://devdocs.magento.com>
2929

app/bootstrap.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@
1414
if (!defined('PHP_VERSION_ID') || !(PHP_VERSION_ID === 70002 || PHP_VERSION_ID === 70004 || PHP_VERSION_ID >= 70006)) {
1515
if (PHP_SAPI == 'cli') {
1616
echo 'Magento supports 7.0.2, 7.0.4, and 7.0.6 or later. ' .
17-
'Please read http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html';
17+
'Please read http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements.html';
1818
} else {
1919
echo <<<HTML
2020
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
2121
<p>Magento supports PHP 7.0.2, 7.0.4, and 7.0.6 or later. Please read
22-
<a target="_blank" href="http://devdocs.magento.com/guides/v1.0/install-gde/system-requirements.html">
22+
<a target="_blank" href="http://devdocs.magento.com/guides/v2.2/install-gde/system-requirements.html">
2323
Magento System Requirements</a>.
2424
</div>
2525
HTML;

app/code/Magento/Backend/Controller/Adminhtml/Noroute/Index.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public function execute()
3434
{
3535
/** @var \Magento\Backend\Model\View\Result\Page $resultPage */
3636
$resultPage = $this->resultPageFactory->create();
37-
$resultPage->setStatusHeader(404, '1.1', 'Forbidden');
37+
$resultPage->setStatusHeader(404, '1.1', 'Not Found');
3838
$resultPage->setHeader('Status', '404 File not found');
3939
$resultPage->addHandle('adminhtml_noroute');
4040
return $resultPage;

app/code/Magento/Backend/etc/adminhtml/system.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@
231231
<label>European Union Countries</label>
232232
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
233233
</field>
234-
<field id="destinations" translate="label" type="multiselect" sortOrder="40" showInDefault="1" showInWebsite="0" showInStore="0">
234+
<field id="destinations" translate="label" type="multiselect" sortOrder="40" showInDefault="1" showInWebsite="1" showInStore="1">
235235
<label>Top destinations</label>
236236
<source_model>Magento\Directory\Model\Config\Source\Country</source_model>
237237
</field>

app/code/Magento/Backend/view/adminhtml/web/template/dynamic-rows/grid.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
<div class="messages">
8686
<div class="message message-notice notice">
8787
<span
88-
translate="'Search strings are either normal strings or regular exceptions (PCRE). They are matched in the same order as entered.'"></span>
88+
translate="'Search strings are either normal strings or regular expressions (PCRE). They are matched in the same order as entered.'"></span>
8989
<br>
9090
<span
9191
translate="'Examples'"></span>:

app/code/Magento/Backup/Model/Db.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ public function createBackup(\Magento\Framework\Backup\Db\BackupInterface $backu
154154

155155
if ($tableStatus->getDataLength() > self::BUFFER_LENGTH) {
156156
if ($tableStatus->getAvgRowLength() < self::BUFFER_LENGTH) {
157-
$limit = floor(self::BUFFER_LENGTH / $tableStatus->getAvgRowLength());
157+
$limit = floor(self::BUFFER_LENGTH / max($tableStatus->getAvgRowLength(), 1));
158158
$multiRowsLength = ceil($tableStatus->getRows() / $limit);
159159
} else {
160160
$limit = 1;

app/code/Magento/Braintree/view/frontend/web/js/view/payment/method-renderer/cc-form.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ define(
7979
*/
8080
onError: function (response) {
8181
braintree.showError($t('Payment ' + this.getTitle() + ' can\'t be initialized'));
82+
this.isPlaceOrderActionAllowed(true);
8283
throw response.message;
8384
},
8485

app/code/Magento/Catalog/Helper/Product/View.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,18 +120,18 @@ public function initProductLayout(ResultPage $resultPage, $product, $params = nu
120120
// Load default page handles and page configurations
121121
if ($params && $params->getBeforeHandles()) {
122122
foreach ($params->getBeforeHandles() as $handle) {
123-
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
124123
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], $handle, false);
124+
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
125125
}
126126
}
127-
128-
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku]);
127+
129128
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], null, false);
129+
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku]);
130130

131131
if ($params && $params->getAfterHandles()) {
132132
foreach ($params->getAfterHandles() as $handle) {
133-
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
134133
$resultPage->addPageLayoutHandles(['type' => $product->getTypeId()], $handle, false);
134+
$resultPage->addPageLayoutHandles(['id' => $product->getId(), 'sku' => $urlSafeSku], $handle);
135135
}
136136
}
137137

app/code/Magento/Catalog/Model/Category/Link/SaveHandler.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,9 @@ private function mergeCategoryLinks($newCategoryPositions, $oldCategoryPositions
119119

120120
if ($key === false) {
121121
$result[] = $newCategoryPosition;
122-
} elseif ($oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']) {
122+
} elseif (isset($oldCategoryPositions[$key])
123+
&& $oldCategoryPositions[$key]['position'] != $newCategoryPosition['position']
124+
) {
123125
$result[] = $newCategoryPositions[$key];
124126
unset($oldCategoryPositions[$key]);
125127
}

app/code/Magento/Catalog/Model/Product/Attribute/OptionManagement.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,17 @@ public function getItems($attributeCode)
4040
*/
4141
public function add($attributeCode, $option)
4242
{
43+
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface[] $currentOptions */
44+
$currentOptions = $this->getItems($attributeCode);
45+
if (is_array($currentOptions)) {
46+
array_walk($currentOptions, function (&$attributeOption) {
47+
/** @var \Magento\Eav\Api\Data\AttributeOptionInterface $attributeOption */
48+
$attributeOption = $attributeOption->getLabel();
49+
});
50+
if (in_array($option->getLabel(), $currentOptions)) {
51+
return false;
52+
}
53+
}
4354
return $this->eavOptionManagement->add(
4455
\Magento\Catalog\Api\Data\ProductAttributeInterface::ENTITY_TYPE_CODE,
4556
$attributeCode,

app/code/Magento/Catalog/Model/Product/Gallery/Processor.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ public function addImage(
149149
}
150150

151151
$fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($pathinfo['basename']);
152-
$dispretionPath = \Magento\MediaStorage\Model\File\Uploader::getDispretionPath($fileName);
152+
$dispretionPath = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName);
153153
$fileName = $dispretionPath . '/' . $fileName;
154154

155155
$fileName = $this->getNotDuplicatedFilename($fileName, $dispretionPath);

app/code/Magento/Catalog/Model/Product/Option/Type/File/ValidatorFile.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ public function validate($processingParams, $option)
150150
$extension = pathinfo(strtolower($fileInfo['name']), PATHINFO_EXTENSION);
151151

152152
$fileName = \Magento\MediaStorage\Model\File\Uploader::getCorrectFileName($fileInfo['name']);
153-
$dispersion = \Magento\MediaStorage\Model\File\Uploader::getDispretionPath($fileName);
153+
$dispersion = \Magento\MediaStorage\Model\File\Uploader::getDispersionPath($fileName);
154154

155155
$filePath = $dispersion;
156156

app/code/Magento/Catalog/Model/ResourceModel/Config.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,7 @@ public function getAttributesUsedForSortBy()
149149
['main_table' => $this->getTable('eav_attribute')]
150150
)->join(
151151
['additional_table' => $this->getTable('catalog_eav_attribute')],
152-
'main_table.attribute_id = additional_table.attribute_id',
153-
[]
152+
'main_table.attribute_id = additional_table.attribute_id'
154153
)->joinLeft(
155154
['al' => $this->getTable('eav_attribute_label')],
156155
'al.attribute_id = main_table.attribute_id AND al.store_id = ' . $this->getStoreId(),

app/code/Magento/Catalog/Model/Template/Filter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function viewDirective($construction)
125125
*/
126126
public function mediaDirective($construction)
127127
{
128-
$params = $this->getParameters($construction[2]);
128+
$params = $this->getParameters(html_entity_decode($construction[2], ENT_QUOTES));
129129
return $this->_storeManager->getStore()
130130
->getBaseUrl(\Magento\Framework\UrlInterface::URL_TYPE_MEDIA) . $params['url'];
131131
}

app/code/Magento/Catalog/Setup/InstallSchema.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -674,7 +674,7 @@ public function install(SchemaSetupInterface $setup, ModuleContextInterface $con
674674
\Magento\Framework\DB\Ddl\Table::TYPE_SMALLINT,
675675
null,
676676
['unsigned' => true, 'nullable' => false, 'default' => '0'],
677-
'Attriute Set ID'
677+
'Attribute Set ID'
678678
)
679679
->addColumn(
680680
'parent_id',

app/code/Magento/Catalog/Test/Unit/Model/Category/Link/SaveHandlerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,21 @@ public function getCategoryDataProvider()
197197
],
198198
[], //affected category_ids
199199
],
200+
[
201+
[3], //model category_ids
202+
[
203+
['category_id' => 3, 'position' => 20],
204+
['category_id' => 4, 'position' => 30],
205+
], // dto category links
206+
[
207+
['category_id' => 3, 'position' => 10],
208+
],
209+
[
210+
['category_id' => 3, 'position' => 20],
211+
['category_id' => 4, 'position' => 30],
212+
],
213+
[3, 4], //affected category_ids
214+
],
200215
];
201216
}
202217

Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\Catalog\Test\Unit\Model\ResourceModel;
8+
9+
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
10+
11+
/**
12+
* Test for Magento\Catalog\Model\ResourceModel\Config
13+
*/
14+
class ConfigTest extends \PHPUnit\Framework\TestCase
15+
{
16+
/**
17+
* @var \Magento\Catalog\Model\ResourceModel\Config
18+
*/
19+
private $model;
20+
21+
/**
22+
* @var \PHPUnit_Framework_MockObject_MockObject
23+
*/
24+
private $resource;
25+
26+
/**
27+
* @var \PHPUnit_Framework_MockObject_MockObject
28+
*/
29+
private $storeManager;
30+
31+
/**
32+
* @var \PHPUnit_Framework_MockObject_MockObject
33+
*/
34+
private $eavConfig;
35+
36+
protected function setUp()
37+
{
38+
$objectManager = new ObjectManager($this);
39+
40+
$this->resource = $this->createMock(\Magento\Framework\App\ResourceConnection::class);
41+
$this->storeManager = $this->createMock(\Magento\Store\Model\StoreManagerInterface::class);
42+
$this->eavConfig = $this->createMock(\Magento\Eav\Model\Config::class);
43+
44+
$this->model = $objectManager->getObject(
45+
\Magento\Catalog\Model\ResourceModel\Config::class,
46+
[
47+
'resource' => $this->resource,
48+
'storeManager' => $this->storeManager,
49+
'eavConfig' => $this->eavConfig,
50+
]
51+
);
52+
53+
parent::setUp();
54+
}
55+
56+
public function testGetAttributesUsedForSortBy()
57+
{
58+
$expression = 'someExpression';
59+
$storeId = 1;
60+
$entityTypeId = 4;
61+
62+
$connectionMock = $this->createMock(\Magento\Framework\DB\Adapter\AdapterInterface::class);
63+
$selectMock = $this->createMock(\Magento\Framework\DB\Select::class);
64+
$storeMock = $this->createMock(\Magento\Store\Api\Data\StoreInterface::class);
65+
$entityTypeMock = $this->createMock(\Magento\Eav\Model\Entity\Type::class);
66+
67+
$this->resource->expects($this->atLeastOnce())->method('getConnection')->willReturn($connectionMock);
68+
69+
$connectionMock->expects($this->once())->method('getCheckSql')
70+
->with('al.value IS NULL', 'main_table.frontend_label', 'al.value')
71+
->willReturn($expression);
72+
$connectionMock->expects($this->atLeastOnce())->method('select')->willReturn($selectMock);
73+
74+
$this->resource->expects($this->exactly(3))->method('getTableName')->withConsecutive(
75+
['eav_attribute'],
76+
['catalog_eav_attribute'],
77+
['eav_attribute_label']
78+
)->willReturnOnConsecutiveCalls('eav_attribute', 'catalog_eav_attribute', 'eav_attribute_label');
79+
80+
$this->storeManager->expects($this->once())->method('getStore')->willReturn($storeMock);
81+
$storeMock->expects($this->once())->method('getId')->willReturn($storeId);
82+
83+
$this->eavConfig->expects($this->once())->method('getEntityType')->willReturn($entityTypeMock);
84+
$entityTypeMock->expects($this->once())->method('getId')->willReturn($entityTypeId);
85+
86+
$selectMock->expects($this->once())->method('from')
87+
->with(['main_table' => 'eav_attribute'])->willReturn($selectMock);
88+
$selectMock->expects($this->once())->method('join')->with(
89+
['additional_table' => 'catalog_eav_attribute'],
90+
'main_table.attribute_id = additional_table.attribute_id'
91+
)->willReturn($selectMock);
92+
$selectMock->expects($this->once())->method('joinLeft')
93+
->with(
94+
['al' => 'eav_attribute_label'],
95+
'al.attribute_id = main_table.attribute_id AND al.store_id = ' . $storeId,
96+
['store_label' => $expression]
97+
)->willReturn($selectMock);
98+
$selectMock->expects($this->exactly(2))->method('where')->withConsecutive(
99+
['main_table.entity_type_id = ?', $entityTypeId],
100+
['additional_table.used_for_sort_by = ?', 1]
101+
)->willReturn($selectMock);
102+
103+
$connectionMock->expects($this->once())->method('fetchAll')->with($selectMock);
104+
105+
$this->model->getAttributesUsedForSortBy();
106+
}
107+
}

app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/js.phtml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,11 @@ function switchDefaultValueField()
196196

197197
<?php foreach ($this->helper('Magento\Catalog\Helper\Data')->getAttributeHiddenFields() as $type => $fields): ?>
198198
case '<?= /* @escapeNotVerified */ $type ?>':
199+
var isFrontTabHidden = false;
199200
<?php foreach ($fields as $one): ?>
200201
<?php if ($one == '_front_fieldset'): ?>
201202
getFrontTab().hide();
203+
isFrontTabHidden = true;
202204
<?php elseif ($one == '_default_value'): ?>
203205
defaultValueTextVisibility =
204206
defaultValueTextareaVisibility =
@@ -210,6 +212,10 @@ function switchDefaultValueField()
210212
setRowVisibility('<?= /* @escapeNotVerified */ $one ?>', false);
211213
<?php endif; ?>
212214
<?php endforeach; ?>
215+
216+
if (!isFrontTabHidden){
217+
getFrontTab().show();
218+
}
213219
break;
214220
<?php endforeach; ?>
215221

app/code/Magento/Catalog/view/adminhtml/templates/catalog/product/attribute/options.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ $stores = $block->getStoresSortedBySortOrder();
5757
<input type="hidden" id="option-count-check" value="" />
5858
</div>
5959
<script id="row-template" type="text/x-magento-template">
60-
<tr>
60+
<tr <% if (data.rowClasses) { %>class="<%- data.rowClasses %>"<% } %>>
6161
<td class="col-draggable">
6262
<?php if (!$block->getReadOnly() && !$block->canManageOptionDefaultOnly()): ?>
6363
<div data-role="draggable-handle" class="draggable-handle"

app/code/Magento/Catalog/view/adminhtml/web/js/options.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ define([
2424
totalItems: 0,
2525
rendered: 0,
2626
template: mageTemplate('#row-template'),
27+
newOptionClass: 'new-option',
2728
isReadOnly: config.isReadOnly,
2829
add: function (data, render) {
2930
var isNewOption = false,
@@ -32,7 +33,8 @@ define([
3233
if (typeof data.id == 'undefined') {
3334
data = {
3435
'id': 'option_' + this.itemCount,
35-
'sort_order': this.itemCount + 1
36+
'sort_order': this.itemCount + 1,
37+
'rowClasses': this.newOptionClass
3638
};
3739
isNewOption = true;
3840
}
@@ -84,6 +86,10 @@ define([
8486
this.totalItems--;
8587
this.updateItemsCountField();
8688
}
89+
90+
if (element.hasClassName(this.newOptionClass)) {
91+
element.remove();
92+
}
8793
},
8894
updateItemsCountField: function () {
8995
$('option-count-check').value = this.totalItems > 0 ? '1' : '';

app/code/Magento/Catalog/view/frontend/templates/product/list/items.phtml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ switch ($type = $block->getType()) {
202202
<?= $block->getReviewsSummaryHtml($_item, $templateType) ?>
203203
<?php endif; ?>
204204

205-
<?php if (!$_item->isComposite() && $_item->isSaleable() && $type == 'related'): ?>
205+
<?php if ($canItemsAddToCart && !$_item->isComposite() && $_item->isSaleable() && $type == 'related'): ?>
206206
<?php if (!$_item->getRequiredOptions()): ?>
207207
<div class="field choice related">
208208
<input type="checkbox" class="checkbox related" id="related-checkbox<?= /* @escapeNotVerified */ $_item->getId() ?>" name="related_products[]" value="<?= /* @escapeNotVerified */ $_item->getId() ?>" />

0 commit comments

Comments
 (0)