Skip to content

Commit 391b8bf

Browse files
author
Magento CICD
authored
merge magento/2.2-develop into magento-performance/MAGETWO-90575
2 parents 499586b + 116c2c3 commit 391b8bf

File tree

15 files changed

+415
-89
lines changed

15 files changed

+415
-89
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ The members of this team have been recognized for their outstanding commitment t
3535
</a>
3636

3737
<h3>Top Contributors</h3>
38-
Magento team thanks for any contribution that can improve our code base, documentation or increase test coverage. We always recognize our most active members, your contributions are the foundation of the Magento open source platform.
38+
Magento is thankful for any contribution that can improve our code base, documentation or increase test coverage. We always recognize our most active members, as their contributions are the foundation of the Magento Open Source platform.
3939
<a href="https://magento.com/magento-contributors">
4040
<img src="https://raw.githubusercontent.com/wiki/magento/magento2/images/contributors.png"/>
4141
</a>

app/code/Magento/Bundle/Controller/Adminhtml/Product/Initialization/Helper/Plugin/Bundle.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,13 @@ public function afterInitialize(
105105
if ($result['bundle_options'] && !$compositeReadonly) {
106106
$product->setBundleOptionsData($result['bundle_options']);
107107
}
108+
108109
$this->processBundleOptionsData($product);
109110
$this->processDynamicOptionsData($product);
111+
} elseif (!$compositeReadonly) {
112+
$extension = $product->getExtensionAttributes();
113+
$extension->setBundleProductOptions([]);
114+
$product->setExtensionAttributes($extension);
110115
}
111116

112117
$affectProductSelections = (bool)$this->request->getPost('affect_bundle_product_selections');

app/code/Magento/Bundle/Model/OptionRepository.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,10 +277,11 @@ protected function updateOptionSelection(
277277
* @param string $sku
278278
* @return \Magento\Catalog\Api\Data\ProductInterface
279279
* @throws \Magento\Framework\Exception\InputException
280+
* @throws \Magento\Framework\Exception\NoSuchEntityException
280281
*/
281282
private function getProduct($sku)
282283
{
283-
$product = $this->productRepository->get($sku, true);
284+
$product = $this->productRepository->get($sku, true, null, true);
284285
if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
285286
throw new InputException(__('Only implemented for bundle product'));
286287
}

app/code/Magento/Bundle/Model/Product/SaveHandler.php

Lines changed: 87 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
*/
66
namespace Magento\Bundle\Model\Product;
77

8-
use Magento\Catalog\Api\Data\ProductInterface;
98
use Magento\Bundle\Api\ProductOptionRepositoryInterface as OptionRepository;
109
use Magento\Bundle\Api\ProductLinkManagementInterface;
1110
use Magento\Framework\App\ObjectManager;
@@ -53,50 +52,50 @@ public function __construct(
5352
* @param object $entity
5453
* @param array $arguments
5554
* @return \Magento\Catalog\Api\Data\ProductInterface|object
55+
* @throws \Magento\Framework\Exception\NoSuchEntityException
56+
* @throws \Magento\Framework\Exception\InputException
57+
* @throws \Magento\Framework\Exception\CouldNotSaveException
5658
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
5759
*/
5860
public function execute($entity, $arguments = [])
5961
{
6062
/** @var \Magento\Bundle\Api\Data\OptionInterface[] $options */
61-
$options = $entity->getExtensionAttributes()->getBundleProductOptions() ?: [];
63+
$bundleProductOptions = $entity->getExtensionAttributes()->getBundleProductOptions() ?: [];
6264

63-
if ($entity->getTypeId() !== 'bundle' || empty($options)) {
65+
if ($entity->getTypeId() !== Type::TYPE_CODE || empty($bundleProductOptions)) {
6466
return $entity;
6567
}
6668

67-
if (!$entity->getCopyFromView()) {
68-
$updatedOptions = [];
69-
$oldOptions = $this->optionRepository->getList($entity->getSku());
70-
71-
$metadata = $this->metadataPool->getMetadata(ProductInterface::class);
69+
$existingBundleProductOptions = $this->optionRepository->getList($entity->getSku());
7270

73-
$productId = $entity->getData($metadata->getLinkField());
71+
$existingOptionsIds = !empty($existingBundleProductOptions)
72+
? $this->getOptionIds($existingBundleProductOptions)
73+
: [];
74+
$optionIds = !empty($bundleProductOptions)
75+
? $this->getOptionIds($bundleProductOptions)
76+
: [];
7477

75-
foreach ($options as $option) {
76-
$updatedOptions[$option->getOptionId()][$productId] = (bool)$option->getOptionId();
77-
}
78-
79-
foreach ($oldOptions as $option) {
80-
if (!isset($updatedOptions[$option->getOptionId()][$productId])) {
81-
$option->setParentId($productId);
82-
$this->removeOptionLinks($entity->getSku(), $option);
83-
$this->optionRepository->delete($option);
84-
}
85-
}
86-
}
78+
$options = $bundleProductOptions ?: [];
8779

88-
foreach ($options as $option) {
89-
$this->optionRepository->save($entity, $option);
80+
if (!$entity->getCopyFromView()) {
81+
$this->processRemovedOptions($entity->getSku(), $existingOptionsIds, $optionIds);
82+
83+
$newOptionsIds = array_diff($optionIds, $existingOptionsIds);
84+
$this->saveOptions($entity, $options, $newOptionsIds);
85+
} else {
86+
//save only labels and not selections + product links
87+
$this->saveOptions($entity, $options);
88+
$entity->setCopyFromView(false);
9089
}
9190

92-
$entity->setCopyFromView(false);
93-
9491
return $entity;
9592
}
9693

9794
/**
9895
* @param string $entitySku
9996
* @param \Magento\Bundle\Api\Data\OptionInterface $option
97+
* @throws \Magento\Framework\Exception\NoSuchEntityException
98+
* @throws \Magento\Framework\Exception\InputException
10099
* @return void
101100
*/
102101
protected function removeOptionLinks($entitySku, $option)
@@ -108,4 +107,67 @@ protected function removeOptionLinks($entitySku, $option)
108107
}
109108
}
110109
}
110+
111+
/**
112+
* Perform save for all options entities
113+
*
114+
* @param object $entity
115+
* @param array $options
116+
* @param array $newOptionsIds
117+
* @throws \Magento\Framework\Exception\CouldNotSaveException
118+
* @throws \Magento\Framework\Exception\InputException
119+
* @return void
120+
*/
121+
private function saveOptions($entity, array $options, array $newOptionsIds = [])
122+
{
123+
foreach ($options as $option) {
124+
if (in_array($option->getOptionId(), $newOptionsIds, true)) {
125+
$option->setOptionId(null);
126+
}
127+
$this->optionRepository->save($entity, $option);
128+
}
129+
}
130+
131+
/**
132+
* Get options ids from array of the options entities
133+
*
134+
* @param array $options
135+
* @return array
136+
*/
137+
private function getOptionIds(array $options)
138+
{
139+
$optionIds = [];
140+
141+
if (empty($options)) {
142+
return $optionIds;
143+
}
144+
145+
/** @var \Magento\Bundle\Api\Data\OptionInterface $option */
146+
foreach ($options as $option) {
147+
if ($option->getOptionId()) {
148+
$optionIds[] = $option->getOptionId();
149+
}
150+
}
151+
return $optionIds;
152+
}
153+
154+
/**
155+
* Removes old options that no longer exists
156+
*
157+
* @param string $entitySku
158+
* @param array $existingOptionsIds
159+
* @param array $optionIds
160+
* @throws \Magento\Framework\Exception\NoSuchEntityException
161+
* @throws \Magento\Framework\Exception\InputException
162+
* @throws \Magento\Framework\Exception\CouldNotSaveException
163+
* @return void
164+
*/
165+
private function processRemovedOptions($entitySku, array $existingOptionsIds, array $optionIds)
166+
{
167+
foreach (array_diff($existingOptionsIds, $optionIds) as $optionId) {
168+
$option = $this->optionRepository->get($entitySku, $optionId);
169+
$this->removeOptionLinks($entitySku, $option);
170+
$this->optionRepository->delete($option);
171+
}
172+
}
111173
}

app/code/Magento/Bundle/Model/ResourceModel/Option.php

Lines changed: 14 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -81,39 +81,28 @@ protected function _afterSave(\Magento\Framework\Model\AbstractModel $object)
8181
{
8282
parent::_afterSave($object);
8383

84-
$conditions = [
84+
$condition = [
8585
'option_id = ?' => $object->getId(),
8686
'store_id = ? OR store_id = 0' => $object->getStoreId(),
8787
'parent_product_id = ?' => $object->getParentId()
8888
];
89-
9089
$connection = $this->getConnection();
90+
$connection->delete($this->getTable('catalog_product_bundle_option_value'), $condition);
9191

92-
if ($this->isOptionPresent($conditions)) {
93-
$connection->update(
94-
$this->getTable('catalog_product_bundle_option_value'),
95-
[
96-
'title' => $object->getTitle()
97-
],
98-
$conditions
99-
);
100-
} else {
101-
$data = new \Magento\Framework\DataObject();
102-
$data->setOptionId($object->getId())
103-
->setStoreId($object->getStoreId())
104-
->setParentProductId($object->getParentId())
105-
->setTitle($object->getTitle());
92+
$data = new \Magento\Framework\DataObject();
93+
$data->setOptionId($object->getId())
94+
->setStoreId($object->getStoreId())
95+
->setParentProductId($object->getParentId())
96+
->setTitle($object->getTitle());
10697

107-
$connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData());
98+
$connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData());
10899

109-
/**
110-
* also saving default value if this store view scope
111-
*/
112-
if ($object->getStoreId()) {
113-
$data->setStoreId(0);
114-
$data->setTitle($object->getDefaultTitle());
115-
$connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData());
116-
}
100+
/**
101+
* also saving default fallback value
102+
*/
103+
if (0 !== (int)$object->getStoreId()) {
104+
$data->setStoreId(0)->setTitle($object->getDefaultTitle());
105+
$connection->insert($this->getTable('catalog_product_bundle_option_value'), $data->getData());
117106
}
118107

119108
return $this;
@@ -218,26 +207,4 @@ public function save(\Magento\Framework\Model\AbstractModel $object)
218207

219208
return $this;
220209
}
221-
222-
/**
223-
* Is Bundle option present in the database
224-
*
225-
* @param array $conditions
226-
*
227-
* @return bool
228-
*/
229-
private function isOptionPresent($conditions)
230-
{
231-
$connection = $this->getConnection();
232-
233-
$select = $connection->select()->from($this->getTable('catalog_product_bundle_option_value'));
234-
foreach ($conditions as $condition => $conditionValue) {
235-
$select->where($condition, $conditionValue);
236-
}
237-
$select->limit(1);
238-
239-
$rowSelect = $connection->fetchRow($select);
240-
241-
return (is_array($rowSelect) && !empty($rowSelect));
242-
}
243210
}

app/code/Magento/CheckoutAgreements/Block/Adminhtml/Agreement/Grid.php

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,42 @@
55
*/
66
namespace Magento\CheckoutAgreements\Block\Adminhtml\Agreement;
77

8+
use Magento\Framework\App\ObjectManager;
9+
use Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid\CollectionFactory as GridCollectionFactory;
10+
811
class Grid extends \Magento\Backend\Block\Widget\Grid\Extended
912
{
1013
/**
1114
* @var \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory
15+
* @deprecated
1216
*/
1317
protected $_collectionFactory;
1418

19+
/**
20+
* @param GridCollectionFactory
21+
*/
22+
private $gridCollectionFactory;
23+
1524
/**
1625
* @param \Magento\Backend\Block\Template\Context $context
1726
* @param \Magento\Backend\Helper\Data $backendHelper
1827
* @param \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory $collectionFactory
1928
* @param array $data
29+
* @param GridCollectionFactory $gridColFactory
2030
* @codeCoverageIgnore
2131
*/
2232
public function __construct(
2333
\Magento\Backend\Block\Template\Context $context,
2434
\Magento\Backend\Helper\Data $backendHelper,
2535
\Magento\CheckoutAgreements\Model\ResourceModel\Agreement\CollectionFactory $collectionFactory,
26-
array $data = []
36+
array $data = [],
37+
GridCollectionFactory $gridColFactory = null
2738
) {
39+
2840
$this->_collectionFactory = $collectionFactory;
41+
$this->gridCollectionFactory = $gridColFactory
42+
? : ObjectManager::getInstance()->get(GridCollectionFactory::class);
43+
2944
parent::__construct($context, $backendHelper, $data);
3045
}
3146

@@ -47,7 +62,7 @@ protected function _construct()
4762
*/
4863
protected function _prepareCollection()
4964
{
50-
$this->setCollection($this->_collectionFactory->create());
65+
$this->setCollection($this->gridCollectionFactory->create());
5166
return parent::_prepareCollection();
5267
}
5368

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
namespace Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Grid;
8+
9+
/**
10+
* CheckoutAgreement Grid Collection
11+
*/
12+
class Collection extends \Magento\CheckoutAgreements\Model\ResourceModel\Agreement\Collection
13+
{
14+
15+
/**
16+
* {@inheritdoc}
17+
*/
18+
public function load($printQuery = false, $logQuery = false)
19+
{
20+
if ($this->isLoaded()) {
21+
return $this;
22+
}
23+
24+
parent::load($printQuery, $logQuery);
25+
26+
$this->addStoresToResult();
27+
28+
return $this;
29+
}
30+
31+
/**
32+
* @return void
33+
*/
34+
private function addStoresToResult()
35+
{
36+
$stores = $this->getStoresForAgreements();
37+
38+
if (!empty($stores)) {
39+
$storesByAgreementId = [];
40+
41+
foreach ($stores as $storeData) {
42+
$storesByAgreementId[$storeData['agreement_id']][] = $storeData['store_id'];
43+
}
44+
45+
foreach ($this as $item) {
46+
$agreementId = $item->getData('agreement_id');
47+
48+
if (!isset($storesByAgreementId[$agreementId])) {
49+
continue;
50+
}
51+
52+
$item->setData('stores', $storesByAgreementId[$agreementId]);
53+
}
54+
}
55+
}
56+
57+
/**
58+
* @return array
59+
*/
60+
private function getStoresForAgreements()
61+
{
62+
$agreementId = $this->getColumnValues('agreement_id');
63+
64+
if (!empty($agreementId)) {
65+
$select = $this->getConnection()->select()->from(
66+
['agreement_store' => 'checkout_agreement_store']
67+
)->where(
68+
'agreement_store.agreement_id IN (?)',
69+
$agreementId
70+
);
71+
72+
return $this->getConnection()->fetchAll($select);
73+
}
74+
75+
return [];
76+
}
77+
}

0 commit comments

Comments
 (0)