Skip to content

Commit c1b7710

Browse files
Merge pull request #2056 from magento-tango/2.1.13-PR-0.1
Bugs - MAGETWO-69496 Impossible specify Bundle option title on store view level with changes to more than one store view - MAGETWO-66793 [Backport] Merchant can't unsubscribe Customer from Newsletter in Admin - MAGETWO-80643 Cannot create orders in the admin for stores other than the default when using Paypal Payflow Pro - MAGETWO-65534 RED BUILD [2.1-develop] [L4] Unstable Tests in L4 Functional Tests EE build on mainline develop: AddToCartCrossSellTest, NavigateUpSellProductsTest, NavigateRelatedProductsTest
2 parents 7fa17f3 + c91d6f1 commit c1b7710

File tree

14 files changed

+433
-50
lines changed

14 files changed

+433
-50
lines changed

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

Lines changed: 8 additions & 5 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');
@@ -127,13 +132,11 @@ protected function processBundleOptionsData(\Magento\Catalog\Model\Product $prod
127132
}
128133
$options = [];
129134
foreach ($bundleOptionsData as $key => $optionData) {
130-
if ((bool)$optionData['delete']) {
131-
continue;
132-
}
133-
134135
$option = $this->optionFactory->create(['data' => $optionData]);
135136
$option->setSku($product->getSku());
136-
$option->setOptionId(null);
137+
if (!$option->getOptionId()) {
138+
$option->setOptionId(null);
139+
}
137140

138141
$links = [];
139142
$bundleLinks = $product->getBundleSelectionsData();

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,10 +246,11 @@ protected function updateOptionSelection(
246246
* @param string $sku
247247
* @return \Magento\Catalog\Api\Data\ProductInterface
248248
* @throws \Magento\Framework\Exception\InputException
249+
* @throws \Magento\Framework\Exception\NoSuchEntityException
249250
*/
250251
private function getProduct($sku)
251252
{
252-
$product = $this->productRepository->get($sku, true);
253+
$product = $this->productRepository->get($sku, true, null, true);
253254
if ($product->getTypeId() != \Magento\Catalog\Model\Product\Type::TYPE_BUNDLE) {
254255
throw new InputException(__('Only implemented for bundle product'));
255256
}

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

Lines changed: 107 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Magento\Bundle\Api\ProductOptionRepositoryInterface as OptionRepository;
99
use Magento\Bundle\Api\ProductLinkManagementInterface;
1010
use Magento\Framework\EntityManager\Operation\ExtensionInterface;
11+
use Magento\Catalog\Api\Data\ProductInterface;
1112

1213
/**
1314
* Class SaveHandler
@@ -37,44 +38,51 @@ public function __construct(
3738
}
3839

3940
/**
40-
* @param object $entity
41+
* @param object|ProductInterface $entity
4142
* @param array $arguments
42-
* @return \Magento\Catalog\Api\Data\ProductInterface|object
43+
* @return object|ProductInterface
44+
* @throws \Magento\Framework\Exception\NoSuchEntityException
45+
* @throws \Magento\Framework\Exception\InputException
46+
* @throws \Magento\Framework\Exception\CouldNotSaveException
4347
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
4448
*/
4549
public function execute($entity, $arguments = [])
4650
{
4751
$bundleProductOptions = $entity->getExtensionAttributes()->getBundleProductOptions();
48-
if ($entity->getTypeId() !== 'bundle' || empty($bundleProductOptions)) {
52+
if ($entity->getTypeId() !== Type::TYPE_CODE || empty($bundleProductOptions)) {
4953
return $entity;
5054
}
5155

56+
$existingBundleProductOptions = $this->optionRepository->getList($entity->getSku());
57+
58+
$existingOptionsIds = !empty($existingBundleProductOptions)
59+
? $this->getOptionIds($existingBundleProductOptions)
60+
: [];
61+
$optionIds = !empty($bundleProductOptions)
62+
? $this->getOptionIds($bundleProductOptions)
63+
: [];
64+
65+
$options = $bundleProductOptions ?: [];
66+
5267
if (!$entity->getCopyFromView()) {
53-
/** @var \Magento\Catalog\Api\Data\ProductInterface $entity */
54-
foreach ($this->optionRepository->getList($entity->getSku()) as $option) {
55-
$this->removeOptionLinks($entity->getSku(), $option);
56-
$this->optionRepository->delete($option);
57-
}
68+
$this->processRemovedOptions($entity->getSku(), $existingOptionsIds, $optionIds);
69+
$this->processExistingOptions($entity->getSku(), $existingOptionsIds, $optionIds);
5870

59-
$options = $bundleProductOptions ?: [];
60-
foreach ($options as $option) {
61-
$option->setOptionId(null);
62-
$this->optionRepository->save($entity, $option);
63-
}
71+
$newOptionsIds = array_diff($optionIds, $existingOptionsIds);
72+
$this->saveOptions($entity, $options, $newOptionsIds);
6473
} else {
6574
//save only labels and not selections + product links
66-
$options = $bundleProductOptions ?: [];
67-
foreach ($options as $option) {
68-
$this->optionRepository->save($entity, $option);
69-
$entity->setCopyFromView(false);
70-
}
75+
$this->saveOptions($entity, $options);
76+
$entity->setCopyFromView(false);
7177
}
7278
return $entity;
7379
}
7480

7581
/**
7682
* @param string $entitySku
7783
* @param \Magento\Bundle\Api\Data\OptionInterface $option
84+
* @throws \Magento\Framework\Exception\NoSuchEntityException
85+
* @throws \Magento\Framework\Exception\InputException
7886
* @return void
7987
*/
8088
protected function removeOptionLinks($entitySku, $option)
@@ -86,4 +94,85 @@ protected function removeOptionLinks($entitySku, $option)
8694
}
8795
}
8896
}
97+
98+
/**
99+
* Perform save for all options entities
100+
*
101+
* @param ProductInterface $entity
102+
* @param array $options
103+
* @param array $newOptionsIds
104+
* @throws \Magento\Framework\Exception\CouldNotSaveException
105+
* @throws \Magento\Framework\Exception\InputException
106+
* @return void
107+
*/
108+
private function saveOptions(ProductInterface $entity, array $options, array $newOptionsIds = [])
109+
{
110+
foreach ($options as $option) {
111+
if (in_array($option->getOptionId(), $newOptionsIds, true)) {
112+
$option->setOptionId(null);
113+
}
114+
$this->optionRepository->save($entity, $option);
115+
}
116+
}
117+
118+
/**
119+
* Get options ids from array of the options entities
120+
*
121+
* @param array $options
122+
* @return array
123+
*/
124+
private function getOptionIds(array $options)
125+
{
126+
$optionIds = [];
127+
128+
if (empty($options)) {
129+
return $optionIds;
130+
}
131+
132+
/** @var \Magento\Bundle\Api\Data\OptionInterface $option */
133+
foreach ($options as $option) {
134+
if ($option->getOptionId()) {
135+
$optionIds[] = $option->getOptionId();
136+
}
137+
}
138+
return $optionIds;
139+
}
140+
141+
/**
142+
* Removes old options that no longer exists
143+
*
144+
* @param string $entitySku
145+
* @param array $existingOptionsIds
146+
* @param array $optionIds
147+
* @throws \Magento\Framework\Exception\NoSuchEntityException
148+
* @throws \Magento\Framework\Exception\InputException
149+
* @throws \Magento\Framework\Exception\CouldNotSaveException
150+
* @return void
151+
*/
152+
private function processRemovedOptions($entitySku, array $existingOptionsIds, array $optionIds)
153+
{
154+
foreach (array_diff($existingOptionsIds, $optionIds) as $optionId) {
155+
$option = $this->optionRepository->get($entitySku, $optionId);
156+
$this->removeOptionLinks($entitySku, $option);
157+
$this->optionRepository->delete($option);
158+
}
159+
}
160+
161+
/**
162+
* Removes option links for existing options
163+
*
164+
* @param string $entitySku
165+
* @param array $existingOptionsIds
166+
* @param array $optionIds
167+
* @throws \Magento\Framework\Exception\NoSuchEntityException
168+
* @throws \Magento\Framework\Exception\InputException
169+
* @return void
170+
*/
171+
private function processExistingOptions($entitySku, array $existingOptionsIds, array $optionIds)
172+
{
173+
foreach (array_intersect($optionIds, $existingOptionsIds) as $optionId) {
174+
$option = $this->optionRepository->get($entitySku, $optionId);
175+
$this->removeOptionLinks($entitySku, $option);
176+
}
177+
}
89178
}

app/code/Magento/Customer/Controller/Adminhtml/Index/Save.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ public function execute()
210210
$this->dataObjectHelper->populateWithArray(
211211
$customer,
212212
$customerData,
213-
'\Magento\Customer\Api\Data\CustomerInterface'
213+
\Magento\Customer\Api\Data\CustomerInterface::class
214214
);
215215
$addresses = [];
216216
foreach ($addressesData as $addressData) {
@@ -224,7 +224,7 @@ public function execute()
224224
$this->dataObjectHelper->populateWithArray(
225225
$addressDataObject,
226226
$addressData,
227-
'\Magento\Customer\Api\Data\AddressInterface'
227+
\Magento\Customer\Api\Data\AddressInterface::class
228228
);
229229
$addresses[] = $addressDataObject;
230230
}
@@ -253,7 +253,7 @@ public function execute()
253253
$isSubscribed = $this->getRequest()->getPost('subscription');
254254
}
255255
if ($isSubscribed !== null) {
256-
if ($isSubscribed !== 'false') {
256+
if ($isSubscribed !== '0') {
257257
$this->_subscriberFactory->create()->subscribeCustomerById($customerId);
258258
} else {
259259
$this->_subscriberFactory->create()->unsubscribeCustomerById($customerId);

app/code/Magento/Customer/Test/Unit/Controller/Adminhtml/Index/SaveTest.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,7 @@ public function testExecuteWithExistentCustomer()
280280
{
281281
$customerId = 22;
282282
$addressId = 11;
283-
$subscription = 'true';
283+
$subscription = '1';
284284
$postValue = [
285285
'customer' => [
286286
'entity_id' => $customerId,
@@ -610,7 +610,7 @@ public function testExecuteWithNewCustomer()
610610
{
611611
$customerId = 22;
612612
$addressId = 11;
613-
$subscription = 'false';
613+
$subscription = '0';
614614
$postValue = [
615615
'customer' => [
616616
'coolness' => false,
@@ -879,7 +879,7 @@ public function testExecuteWithNewCustomer()
879879
*/
880880
public function testExecuteWithNewCustomerAndValidationException()
881881
{
882-
$subscription = 'false';
882+
$subscription = '0';
883883
$postValue = [
884884
'customer' => [
885885
'coolness' => false,
@@ -1022,7 +1022,7 @@ public function testExecuteWithNewCustomerAndValidationException()
10221022
*/
10231023
public function testExecuteWithNewCustomerAndLocalizedException()
10241024
{
1025-
$subscription = 'false';
1025+
$subscription = '0';
10261026
$postValue = [
10271027
'customer' => [
10281028
'coolness' => false,
@@ -1165,7 +1165,7 @@ public function testExecuteWithNewCustomerAndLocalizedException()
11651165
*/
11661166
public function testExecuteWithNewCustomerAndException()
11671167
{
1168-
$subscription = 'false';
1168+
$subscription = '0';
11691169
$postValue = [
11701170
'customer' => [
11711171
'coolness' => false,

0 commit comments

Comments
 (0)