Skip to content

Commit 52fe4f5

Browse files
committed
MC-40811: Schedule Design Update when edit product in backend seem not set properly
1 parent 55c4ff8 commit 52fe4f5

File tree

4 files changed

+211
-44
lines changed

4 files changed

+211
-44
lines changed

app/code/Magento/Catalog/Model/Design.php

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,20 @@
33
* Copyright © Magento, Inc. All rights reserved.
44
* See COPYING.txt for license details.
55
*/
6+
67
namespace Magento\Catalog\Model;
78

89
use Magento\Catalog\Model\Category\Attribute\LayoutUpdateManager as CategoryLayoutManager;
910
use Magento\Catalog\Model\Product\Attribute\LayoutUpdateManager as ProductLayoutManager;
1011
use Magento\Framework\App\ObjectManager;
11-
use \Magento\Framework\TranslateInterface;
12+
use Magento\Framework\Data\Collection\AbstractDb;
13+
use Magento\Framework\DataObject;
14+
use Magento\Framework\Model\Context;
15+
use Magento\Framework\Model\ResourceModel\AbstractResource;
16+
use Magento\Framework\Registry;
17+
use Magento\Framework\Stdlib\DateTime\TimezoneInterface;
18+
use Magento\Framework\TranslateInterface;
19+
use Magento\Framework\View\DesignInterface;
1220

1321
/**
1422
* Catalog Custom Category design Model
@@ -28,12 +36,12 @@ class Design extends \Magento\Framework\Model\AbstractModel
2836
/**
2937
* Design package instance
3038
*
31-
* @var \Magento\Framework\View\DesignInterface
39+
* @var DesignInterface
3240
*/
3341
protected $_design = null;
3442

3543
/**
36-
* @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface
44+
* @var TimezoneInterface
3745
*/
3846
protected $_localeDate;
3947

@@ -53,25 +61,25 @@ class Design extends \Magento\Framework\Model\AbstractModel
5361
private $productLayoutUpdates;
5462

5563
/**
56-
* @param \Magento\Framework\Model\Context $context
57-
* @param \Magento\Framework\Registry $registry
58-
* @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
59-
* @param \Magento\Framework\View\DesignInterface $design
60-
* @param \Magento\Framework\Model\ResourceModel\AbstractResource|null $resource
61-
* @param \Magento\Framework\Data\Collection\AbstractDb|null $resourceCollection
64+
* @param Context $context
65+
* @param Registry $registry
66+
* @param TimezoneInterface $localeDate
67+
* @param DesignInterface $design
68+
* @param AbstractResource|null $resource
69+
* @param AbstractDb|null $resourceCollection
6270
* @param array $data
6371
* @param TranslateInterface|null $translator
6472
* @param CategoryLayoutManager|null $categoryLayoutManager
6573
* @param ProductLayoutManager|null $productLayoutManager
6674
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
6775
*/
6876
public function __construct(
69-
\Magento\Framework\Model\Context $context,
70-
\Magento\Framework\Registry $registry,
71-
\Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
72-
\Magento\Framework\View\DesignInterface $design,
73-
\Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
74-
\Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
77+
Context $context,
78+
Registry $registry,
79+
TimezoneInterface $localeDate,
80+
DesignInterface $design,
81+
AbstractResource $resource = null,
82+
AbstractDb $resourceCollection = null,
7583
array $data = [],
7684
TranslateInterface $translator = null,
7785
?CategoryLayoutManager $categoryLayoutManager = null,
@@ -104,7 +112,7 @@ public function applyCustomDesign($design)
104112
* Get custom layout settings
105113
*
106114
* @param Category|Product $object
107-
* @return \Magento\Framework\DataObject
115+
* @return DataObject
108116
*/
109117
public function getDesignSettings($object)
110118
{
@@ -134,14 +142,16 @@ public function getDesignSettings($object)
134142
* Extract custom layout settings from category or product object
135143
*
136144
* @param Category|Product $object
137-
* @return \Magento\Framework\DataObject
145+
* @return DataObject
138146
*/
139147
protected function _extractSettings($object)
140148
{
141-
$settings = new \Magento\Framework\DataObject();
149+
$settings = new DataObject();
142150
if (!$object) {
143151
return $settings;
144152
}
153+
$settings->setPageLayout($object->getPageLayout());
154+
145155
$date = $object->getCustomDesignDate();
146156
if (array_key_exists(
147157
'from',
@@ -158,7 +168,7 @@ protected function _extractSettings($object)
158168
$settings->setCustomDesign(
159169
$object->getCustomDesign()
160170
)->setPageLayout(
161-
$object->getPageLayout()
171+
$object->getCustomLayout()
162172
)->setLayoutUpdates(
163173
(array)$object->getCustomLayoutUpdate()
164174
);
@@ -168,15 +178,16 @@ protected function _extractSettings($object)
168178
$this->productLayoutUpdates->extractCustomSettings($object, $settings);
169179
}
170180
}
181+
171182
return $settings;
172183
}
173184

174185
/**
175186
* Merge custom design settings
176187
*
177-
* @param \Magento\Framework\DataObject $categorySettings
178-
* @param \Magento\Framework\DataObject $productSettings
179-
* @return \Magento\Framework\DataObject
188+
* @param DataObject $categorySettings
189+
* @param DataObject $productSettings
190+
* @return DataObject
180191
*/
181192
protected function _mergeSettings($categorySettings, $productSettings)
182193
{
Lines changed: 113 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,130 @@
11
<?php
2+
23
/**
34
* Copyright © Magento, Inc. All rights reserved.
45
* See COPYING.txt for license details.
56
*/
7+
declare(strict_types=1);
8+
9+
namespace Magento\Catalog\Model;
10+
11+
use Magento\Catalog\Api\Data\ProductInterface;
12+
use Magento\Catalog\Api\ProductRepositoryInterface;
13+
use Magento\Framework\TranslateInterface;
14+
use Magento\Framework\View\Design\ThemeInterface;
15+
use Magento\Framework\View\DesignInterface;
16+
use Magento\TestFramework\Helper\Bootstrap;
17+
use Magento\Theme\Model\Theme;
18+
use PHPUnit\Framework\TestCase;
619

720
/**
821
* Test class for \Magento\Catalog\Model\Design.
922
*/
10-
namespace Magento\Catalog\Model;
11-
12-
class DesignTest extends \PHPUnit\Framework\TestCase
23+
class DesignTest extends TestCase
1324
{
1425
/**
15-
* @var \Magento\Catalog\Model\Design
26+
* @var Design
1627
*/
17-
protected $_model;
28+
private $model;
1829

30+
/**
31+
* @var ProductRepositoryInterface
32+
*/
33+
private $productRepository;
34+
35+
/**
36+
* @inheriDoc
37+
*/
1938
protected function setUp(): void
2039
{
21-
$this->_model = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
22-
\Magento\Catalog\Model\Design::class
23-
);
40+
$this->model = Bootstrap::getObjectManager()->create(Design::class);
41+
$this->productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
2442
}
2543

2644
/**
2745
* @dataProvider getThemeModel
46+
* @param Theme $theme
47+
* @return void
2848
*/
29-
public function testApplyCustomDesign($theme)
49+
public function testApplyCustomDesign(Theme $theme): void
3050
{
31-
$this->_model->applyCustomDesign($theme);
32-
$design = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
33-
\Magento\Framework\View\DesignInterface::class
34-
);
35-
$translate = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->get(
36-
\Magento\Framework\TranslateInterface::class
37-
);
51+
$this->model->applyCustomDesign($theme);
52+
$design = Bootstrap::getObjectManager()->get(DesignInterface::class);
53+
$translate = Bootstrap::getObjectManager()->get(TranslateInterface::class);
3854
$this->assertEquals('package', $design->getDesignTheme()->getPackageCode());
3955
$this->assertEquals('theme', $design->getDesignTheme()->getThemeCode());
4056
$this->assertEquals('themepackage/theme', $translate->getTheme());
4157
}
4258

4359
/**
44-
* @return \Magento\Theme\Model\Theme
60+
* Verify design product settings will be generated correctly for PDP.
61+
*
62+
* @magentoDataFixture Magento/Catalog/_files/simple_product_with_custom_design.php
63+
* @param array $designSettings
64+
* @param array $expectedSetting
65+
* @dataProvider getDesignSettingsForProductWithScheduleDesignTest
66+
* @return void
67+
*/
68+
public function testGetDesignSettingsForProductWithScheduleDesign(
69+
array $designSettings,
70+
array $expectedSetting
71+
): void {
72+
$product = $this->productRepository->get('simple_with_custom_design', false, null, true);
73+
$this->applyScheduleDesignUpdate($product, $designSettings);
74+
$settings = $this->model->getDesignSettings($product);
75+
self::assertEquals($expectedSetting['page_layout'], $settings->getData('page_layout'));
76+
self::assertEquals($expectedSetting['custom_design'], $settings->getData('custom_design'));
77+
}
78+
79+
/**
80+
* @return array[]
4581
*/
46-
public function getThemeModel()
82+
public function getDesignSettingsForProductWithScheduleDesignTest(): array
4783
{
48-
$theme = \Magento\TestFramework\Helper\Bootstrap::getObjectManager()->create(
49-
\Magento\Framework\View\Design\ThemeInterface::class
50-
);
84+
$datetime = new \DateTime();
85+
$datetime->modify('-10 day');
86+
$fromApplied = $datetime->format('Y-m-d');
87+
$datetime->modify('+20 day');
88+
$fromNotApplied = $datetime->format('Y-m-d');
89+
$datetime->modify('+30 day');
90+
$to = $datetime->format('Y-m-d');
91+
92+
return [
93+
'schedule_design_applied' => [
94+
'design_settings' => [
95+
'custom_layout' => '2columns-left',
96+
'custom_design' => '2',
97+
'custom_design_from' => $fromApplied,
98+
'custom_design_to' => $to,
99+
],
100+
'expected_settings' => [
101+
'page_layout' => '2columns-left',
102+
'custom_design' => '2',
103+
]
104+
],
105+
'schedule_design_not_applied' => [
106+
'design_settings' => [
107+
'custom_layout' => '2columns-left',
108+
'custom_design' => '2',
109+
'custom_design_from' => $fromNotApplied,
110+
'custom_design_to' => $to,
111+
],
112+
'expected_settings' => [
113+
'page_layout' => '3columns',
114+
'custom_design' => null,
115+
]
116+
],
117+
];
118+
}
119+
120+
/**
121+
* @return array
122+
*/
123+
public function getThemeModel(): array
124+
{
125+
$theme = Bootstrap::getObjectManager()->create(ThemeInterface::class);
51126
$theme->setData($this->_getThemeData());
127+
52128
return [[$theme]];
53129
}
54130

@@ -65,7 +141,22 @@ protected function _getThemeData()
65141
'parent_theme' => null,
66142
'is_featured' => true,
67143
'preview_image' => '',
68-
'theme_directory' => __DIR__ . '_files/design/frontend/default/default'
144+
'theme_directory' => __DIR__ . '_files/design/frontend/default/default',
69145
];
70146
}
147+
148+
/**
149+
* Apply provided setting to product scheduled design update.
150+
*
151+
* @param ProductInterface $product
152+
* @param array $designSettings
153+
* @return void
154+
*/
155+
private function applyScheduleDesignUpdate(ProductInterface $product, array $designSettings): void
156+
{
157+
$product->setCustomLayout($designSettings['custom_layout']);
158+
$product->setCustomDesign($designSettings['custom_design']);
159+
$product->setCustomDesignFrom($designSettings['custom_design_from']);
160+
$product->setCustomDesignTo($designSettings['custom_design_to']);
161+
}
71162
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
/**
3+
* Copyright © Magento, Inc. All rights reserved.
4+
* See COPYING.txt for license details.
5+
*/
6+
7+
use Magento\Catalog\Model\Product;
8+
use Magento\Catalog\Model\Product\Attribute\Source\Status;
9+
use Magento\Catalog\Model\Product\Visibility;
10+
use Magento\Catalog\Model\ProductFactory;
11+
use Magento\TestFramework\Helper\Bootstrap;
12+
13+
$product = Bootstrap::getObjectManager()->create(ProductFactory::class)->create();
14+
$product->setTypeId('simple')
15+
->setPageLayout('3columns')
16+
->setAttributeSetId(4)
17+
->setWebsiteIds([1])
18+
->setName('Simple Product With Custom Design')
19+
->setSku('simple_with_custom_design')
20+
->setPrice(10)
21+
->setVisibility(Visibility::VISIBILITY_BOTH)
22+
->setStatus(Status::STATUS_ENABLED)
23+
->setStockData(['use_config_manage_stock' => 1, 'qty' => 100, 'is_in_stock' => 1])
24+
->save();
25+
26+
$customDesignProduct = Bootstrap::getObjectManager()
27+
->create(Product::class, ['data' => $product->getData()]);
28+
29+
$customDesignProduct->setUrlKey('custom-design-simple-product')
30+
->setId(2)
31+
->setRowId(2)
32+
->setName('Custom Design Simple Product')
33+
->setSku('custom-design-simple-product')
34+
->setCustomDesign('Magento/blank')
35+
->setStockData(['use_config_manage_stock' => 1, 'qty' => 24, 'is_in_stock' => 1])
36+
->setQty(24)
37+
->save();
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
/**
4+
* Copyright © Magento, Inc. All rights reserved.
5+
* See COPYING.txt for license details.
6+
*/
7+
declare(strict_types=1);
8+
9+
use Magento\Catalog\Api\ProductRepositoryInterface;
10+
use Magento\Framework\Exception\NoSuchEntityException;
11+
use Magento\Framework\Registry;
12+
use Magento\TestFramework\Helper\Bootstrap;
13+
14+
$objectManager = Bootstrap::getObjectManager();
15+
$registry = $objectManager->get(Registry::class);
16+
$productRepository = $objectManager->get(ProductRepositoryInterface::class);
17+
18+
$registry->unregister('isSecureArea');
19+
$registry->register('isSecureArea', true);
20+
21+
try {
22+
$productRepository->deleteById('simple_with_custom_design');
23+
} catch (NoSuchEntityException $e) {
24+
//product already deleted.
25+
}
26+
27+
$registry->unregister('isSecureArea');
28+
$registry->register('isSecureArea', false);

0 commit comments

Comments
 (0)