Skip to content

Commit 3ccf72b

Browse files
author
Serhiy Zhovnir
committed
Merge branch '2.2-develop' of github.com:magento/magento2 into 2.2-develop-PR-port-22787
2 parents d4553a2 + 0175f09 commit 3ccf72b

File tree

34 files changed

+1177
-114
lines changed

34 files changed

+1177
-114
lines changed

app/code/Magento/Backend/Test/Mftf/Section/AdminSlideOutDialogSection.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1010
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
1111
<section name="AdminSlideOutDialogSection">
12-
<element name="closeButton" type="button" selector=".modal-slide._show [data-role='closeBtn']" timeout="30"/>
12+
<element name="closeButton" type="button" selector=".modal-slide._show [data-role=&quot;closeBtn&quot;]" timeout="30"/>
1313
<element name="cancelButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Cancel']" timeout="30"/>
1414
<element name="doneButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Done']" timeout="30"/>
1515
<element name="saveButton" type="button" selector="//*[contains(@class, 'modal-slide') and contains(@class, '_show')]//*[contains(@class, 'page-actions')]//button[normalize-space(.)='Save']" timeout="30"/>

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

Lines changed: 70 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1570,26 +1570,9 @@ public function addAttributeToFilter($attribute, $condition = null, $joinType =
15701570
$this->_allIdsCache = null;
15711571

15721572
if (is_string($attribute) && $attribute == 'is_saleable') {
1573-
$columns = $this->getSelect()->getPart(\Magento\Framework\DB\Select::COLUMNS);
1574-
foreach ($columns as $columnEntry) {
1575-
list($correlationName, $column, $alias) = $columnEntry;
1576-
if ($alias == 'is_saleable') {
1577-
if ($column instanceof \Zend_Db_Expr) {
1578-
$field = $column;
1579-
} else {
1580-
$connection = $this->getSelect()->getConnection();
1581-
if (empty($correlationName)) {
1582-
$field = $connection->quoteColumnAs($column, $alias, true);
1583-
} else {
1584-
$field = $connection->quoteColumnAs([$correlationName, $column], $alias, true);
1585-
}
1586-
}
1587-
$this->getSelect()->where("{$field} = ?", $condition);
1588-
break;
1589-
}
1590-
}
1591-
1592-
return $this;
1573+
$this->addIsSaleableAttributeToFilter($condition);
1574+
} elseif (is_string($attribute) && $attribute == 'tier_price') {
1575+
$this->addTierPriceAttributeToFilter($attribute, $condition);
15931576
} else {
15941577
return parent::addAttributeToFilter($attribute, $condition, $joinType);
15951578
}
@@ -2469,4 +2452,71 @@ public function getPricesCount()
24692452

24702453
return $this->_pricesCount;
24712454
}
2455+
2456+
/**
2457+
* Add is_saleable attribute to filter
2458+
*
2459+
* @param array|null $condition
2460+
* @return $this
2461+
*/
2462+
private function addIsSaleableAttributeToFilter($condition)
2463+
{
2464+
$columns = $this->getSelect()->getPart(Select::COLUMNS);
2465+
foreach ($columns as $columnEntry) {
2466+
list($correlationName, $column, $alias) = $columnEntry;
2467+
if ($alias == 'is_saleable') {
2468+
if ($column instanceof \Zend_Db_Expr) {
2469+
$field = $column;
2470+
} else {
2471+
$connection = $this->getSelect()->getConnection();
2472+
if (empty($correlationName)) {
2473+
$field = $connection->quoteColumnAs($column, $alias, true);
2474+
} else {
2475+
$field = $connection->quoteColumnAs([$correlationName, $column], $alias, true);
2476+
}
2477+
}
2478+
$this->getSelect()->where("{$field} = ?", $condition);
2479+
break;
2480+
}
2481+
}
2482+
2483+
return $this;
2484+
}
2485+
2486+
/**
2487+
* Add tier price attribute to filter
2488+
*
2489+
* @param string $attribute
2490+
* @param array|null $condition
2491+
* @return $this
2492+
*/
2493+
private function addTierPriceAttributeToFilter($attribute, $condition)
2494+
{
2495+
$attrCode = $attribute;
2496+
$connection = $this->getConnection();
2497+
$attrTable = $this->_getAttributeTableAlias($attrCode);
2498+
$entity = $this->getEntity();
2499+
$fKey = 'e.' . $this->getEntityPkName($entity);
2500+
$pKey = $attrTable . '.' . $this->getEntityPkName($entity);
2501+
$attribute = $entity->getAttribute($attrCode);
2502+
$attrFieldName = $attrTable . '.value';
2503+
$fKey = $connection->quoteColumnAs($fKey, null);
2504+
$pKey = $connection->quoteColumnAs($pKey, null);
2505+
2506+
$condArr = ["{$pKey} = {$fKey}"];
2507+
$this->getSelect()->join(
2508+
[$attrTable => $this->getTable('catalog_product_entity_tier_price')],
2509+
'(' . implode(') AND (', $condArr) . ')',
2510+
[$attrCode => $attrFieldName]
2511+
);
2512+
$this->removeAttributeToSelect($attrCode);
2513+
$this->_filterAttributes[$attrCode] = $attribute->getId();
2514+
$this->_joinFields[$attrCode] = ['table' => '', 'field' => $attrFieldName];
2515+
$field = $this->_getAttributeTableAlias($attrCode) . '.value';
2516+
$conditionSql = $this->_getConditionSql($field, $condition);
2517+
$this->getSelect()->where($conditionSql, null, Select::TYPE_CONDITION);
2518+
$this->_totalRecords = null;
2519+
2520+
return $this;
2521+
}
24722522
}

app/code/Magento/Catalog/Test/Unit/Model/Product/ProductList/ToolbarMemorizerTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ public function getMemorizedDataProvider(): array
197197
/**
198198
* Test method isMemorizingAllowed.
199199
*
200-
* @aram bool|null $variableValue
200+
* @param bool|null $variableValue
201201
* @param bool $flag
202202
* @param bool $expected
203203
* @return void
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
11+
<entity name="WysiwygEnabledByDefault">
12+
<data key="path">cms/wysiwyg/enabled</data>
13+
<data key="scope_id">0</data>
14+
<data key="value">enabled</data>
15+
</entity>
16+
<entity name="WysiwygDisabledByDefault">
17+
<data key="path">cms/wysiwyg/enabled</data>
18+
<data key="scope_id">0</data>
19+
<data key="value">hidden</data>
20+
</entity>
21+
</entities>

app/code/Magento/ConfigurableProduct/Test/Unit/Model/Product/Type/ConfigurableTest.php

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,13 @@
1111
use Magento\Catalog\Model\Product\Configuration\Item\Option\OptionInterface;
1212
use Magento\ConfigurableProduct\Model\Product\Type\Collection\SalableProcessor;
1313
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
14+
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
1415
use Magento\ConfigurableProduct\Model\Product\Type\Configurable\AttributeFactory;
1516
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection;
1617
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\CollectionFactory;
1718
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ProductCollection;
19+
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory
20+
as ProductCollectionFactory;
1821
use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\ConfigurableFactory;
1922
use Magento\Customer\Model\Session;
2023
use Magento\Eav\Model\Entity\Attribute\Frontend\AbstractFrontend;
@@ -27,7 +30,6 @@
2730
* @SuppressWarnings(PHPMD.LongVariable)
2831
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
2932
* @SuppressWarnings(PHPMD.TooManyFields)
30-
* @codingStandardsIgnoreFile
3133
*/
3234
class ConfigurableTest extends \PHPUnit\Framework\TestCase
3335
{
@@ -154,8 +156,7 @@ protected function setUp()
154156
->disableOriginalConstructor()
155157
->setMethods(['create'])
156158
->getMock();
157-
$this->productCollectionFactory = $this->getMockBuilder(
158-
\Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory::class)
159+
$this->productCollectionFactory = $this->getMockBuilder(ProductCollectionFactory::class)
159160
->disableOriginalConstructor()
160161
->setMethods(['create'])
161162
->getMock();
@@ -281,8 +282,7 @@ public function testSave()
281282
$product->expects($this->atLeastOnce())
282283
->method('getData')
283284
->willReturnMap($dataMap);
284-
$attribute = $this->getMockBuilder(
285-
\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class)
285+
$attribute = $this->getMockBuilder(Attribute::class)
286286
->disableOriginalConstructor()
287287
->setMethods(['addData', 'setStoreId', 'setProductId', 'save', '__wakeup', '__sleep'])
288288
->getMock();
@@ -464,8 +464,7 @@ public function testGetConfigurableAttributesAsArray($productStore)
464464
$eavAttribute->expects($this->once())->method('getSource')->willReturn($attributeSource);
465465
$eavAttribute->expects($this->atLeastOnce())->method('getStoreLabel')->willReturn('Store Label');
466466

467-
$attribute = $this->getMockBuilder(
468-
\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class)
467+
$attribute = $this->getMockBuilder(Attribute::class)
469468
->disableOriginalConstructor()
470469
->setMethods(['getProductAttribute', '__wakeup', '__sleep'])
471470
->getMock();
@@ -524,7 +523,7 @@ public function testGetConfigurableAttributesNewProduct()
524523
$this->assertEquals([], $this->model->getConfigurableAttributes($product));
525524
}
526525

527-
public function testGetConfigurableAttributes()
526+
public function testGetConfigurableAttributes()
528527
{
529528
$configurableAttributes = '_cache_instance_configurable_attributes';
530529

@@ -591,8 +590,7 @@ public function testHasOptionsConfigurableAttribute()
591590
->setMethods(['__wakeup', 'getAttributeCode', 'getOptions', 'hasData', 'getData'])
592591
->disableOriginalConstructor()
593592
->getMock();
594-
$attributeMock = $this->getMockBuilder(
595-
\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class)
593+
$attributeMock = $this->getMockBuilder(Attribute::class)
596594
->disableOriginalConstructor()
597595
->getMock();
598596

@@ -698,7 +696,7 @@ function ($value) {
698696
->disableOriginalConstructor()
699697
->getMock();
700698
$usedAttributeMock = $this->getMockBuilder(
701-
\Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute::class
699+
Attribute::class
702700
)
703701
->setMethods(['getProductAttribute'])
704702
->disableOriginalConstructor()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontRegisterCustomerFromOrderSuccessPage">
12+
<arguments>
13+
<argument name="customer" />
14+
</arguments>
15+
<click selector="{{CheckoutSuccessRegisterSection.createAccountButton}}" stepKey="clickCreateAccountButton"/>
16+
<fillField selector="{{StorefrontCustomerCreateFormSection.passwordField}}" userInput="{{customer.password}}" stepKey="typePassword"/>
17+
<fillField selector="{{StorefrontCustomerCreateFormSection.confirmPasswordField}}" userInput="{{customer.password}}" stepKey="typeConfirmationPassword"/>
18+
<click selector="{{StorefrontCustomerCreateFormSection.createAccountButton}}" stepKey="clickOnCreateAccount"/>
19+
<waitForElementVisible selector="{{StorefrontMessagesSection.success}}" stepKey="waitForSuccessMessage"/>
20+
<see selector="{{StorefrontMessagesSection.success}}" userInput="Thank you for registering" stepKey="verifyAccountCreated"/>
21+
</actionGroup>
22+
</actionGroups>
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
declare(strict_types=1);
7+
8+
namespace Magento\Downloadable\Observer;
9+
10+
use Magento\Downloadable\Model\ResourceModel\Link\Purchased\Collection as PurchasedCollection;
11+
use Magento\Downloadable\Model\ResourceModel\Link\Purchased\CollectionFactory;
12+
use Magento\Framework\Event\Observer;
13+
use Magento\Framework\Event\ObserverInterface;
14+
15+
/**
16+
* Assign Downloadable links to customer created after issuing guest order.
17+
*/
18+
class UpdateLinkPurchasedObserver implements ObserverInterface
19+
{
20+
/**
21+
* Purchased links collection factory
22+
*
23+
* @var CollectionFactory
24+
*/
25+
private $purchasedCollectionFactory;
26+
27+
/**
28+
* @param CollectionFactory $purchasedCollectionFactory
29+
*/
30+
public function __construct(
31+
CollectionFactory $purchasedCollectionFactory
32+
) {
33+
$this->purchasedCollectionFactory = $purchasedCollectionFactory;
34+
}
35+
36+
/**
37+
* Link customer_id to downloadable link purchased after update order
38+
*
39+
* @param Observer $observer
40+
* @return $this
41+
*/
42+
public function execute(Observer $observer)
43+
{
44+
$order = $observer->getEvent()->getOrder();
45+
$orderId = $order->getId();
46+
$customerId = $order->getCustomerId();
47+
if (!$orderId || !$customerId) {
48+
return $this;
49+
}
50+
$purchasedLinksCollection = $this->getPurchasedCollection((int)$orderId);
51+
foreach ($purchasedLinksCollection as $linkPurchased) {
52+
$linkPurchased->setCustomerId($customerId)->save();
53+
}
54+
55+
return $this;
56+
}
57+
58+
/**
59+
* Get purchased collection by order id
60+
*
61+
* @param int $orderId
62+
* @return PurchasedCollection
63+
*/
64+
private function getPurchasedCollection(int $orderId): PurchasedCollection
65+
{
66+
return $this->purchasedCollectionFactory->create()->addFieldToFilter(
67+
'order_id',
68+
['eq' => $orderId]
69+
);
70+
}
71+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<actionGroups xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Test/etc/actionGroupSchema.xsd">
11+
<actionGroup name="StorefrontAssertDownloadableProductIsPresentInCustomerAccount">
12+
<arguments>
13+
<argument name="product"/>
14+
</arguments>
15+
<amOnPage url="{{StorefrontCustomerDownloadableProductsPage.url}}" stepKey="goToCustomerDownloadableProductsPage"/>
16+
<seeElement selector="{{StorefrontCustomerDownloadableProductsSection.productName(product.name)}}" stepKey="seeStorefontDownloadableProductsProductName" />
17+
</actionGroup>
18+
</actionGroups>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<entities xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:DataGenerator/etc/dataProfileSchema.xsd">
11+
<entity name="EnableGuestCheckoutWithDownloadableItems">
12+
<data key="path">catalog/downloadable/disable_guest_checkout</data>
13+
<data key="scope_id">0</data>
14+
<data key="value">0</data>
15+
</entity>
16+
<entity name="DisableGuestCheckoutWithDownloadableItems">
17+
<data key="path">catalog/downloadable/disable_guest_checkout</data>
18+
<data key="scope_id">0</data>
19+
<data key="value">1</data>
20+
</entity>
21+
</entities>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
<pages xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
9+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/PageObject.xsd">
10+
<page name="StorefrontCustomerDownloadableProductsPage" url="downloadable/customer/products/" area="storefront" module="Magento_Downloadable">
11+
<section name="StorefrontCustomerDownloadableProductsSection"/>
12+
</page>
13+
</pages>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
-->
8+
9+
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
10+
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
11+
<section name="StorefrontCustomerDownloadableProductsSection">
12+
<element name="productName" type="text" selector="//table[@id='my-downloadable-products-table']//strong[contains(@class, 'product-name') and normalize-space(.)='{{productName}}']" parameterized="true"/>
13+
</section>
14+
</sections>

0 commit comments

Comments
 (0)