Skip to content

Commit c284664

Browse files
authored
Merge pull request #5798 from magento-tsg-csl3/2.4-develop-pr30
[TSG-CSL3] For 2.4 (pr30)
2 parents 3a65cdc + 1121b23 commit c284664

File tree

17 files changed

+963
-70
lines changed

17 files changed

+963
-70
lines changed

app/code/Magento/Catalog/Ui/DataProvider/Product/Form/Modifier/Eav.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
use Magento\Eav\Model\ResourceModel\Entity\Attribute\CollectionFactory as AttributeCollectionFactory;
4141

4242
/**
43-
* Data provider for eav attributes on product page
43+
* Class Eav data provider for product editing form
4444
*
4545
* @api
4646
*
@@ -791,7 +791,9 @@ private function getAttributeDefaultValue(ProductAttributeInterface $attribute)
791791
\Magento\Store\Model\ScopeInterface::SCOPE_STORE,
792792
$this->storeManager->getStore()
793793
);
794-
$attribute->setDefaultValue($defaultValue);
794+
if ($defaultValue !== null) {
795+
$attribute->setDefaultValue($defaultValue);
796+
}
795797
}
796798
return $attribute->getDefaultValue();
797799
}

app/code/Magento/Theme/Model/Config/Customization.php

Lines changed: 44 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,34 @@
55
*/
66
namespace Magento\Theme\Model\Config;
77

8+
use Magento\Framework\App\Area;
9+
use Magento\Framework\App\ObjectManager;
10+
use Magento\Framework\View\Design\Theme\ThemeProviderInterface;
11+
use Magento\Framework\View\Design\ThemeInterface;
12+
use Magento\Framework\View\DesignInterface;
13+
use Magento\Store\Model\Store;
14+
use Magento\Store\Model\StoreManagerInterface;
15+
use Magento\Theme\Model\ResourceModel\Theme\Collection;
16+
use Magento\Theme\Model\Theme\StoreThemesResolverInterface;
17+
use Magento\Theme\Model\Theme\StoreUserAgentThemeResolver;
18+
819
/**
920
* Theme customization config model
1021
*/
1122
class Customization
1223
{
1324
/**
14-
* @var \Magento\Store\Model\StoreManagerInterface
25+
* @var StoreManagerInterface
1526
*/
1627
protected $_storeManager;
1728

1829
/**
19-
* @var \Magento\Framework\View\DesignInterface
30+
* @var DesignInterface
2031
*/
2132
protected $_design;
2233

2334
/**
24-
* @var \Magento\Framework\View\Design\Theme\ThemeProviderInterface
35+
* @var ThemeProviderInterface
2536
*/
2637
protected $themeProvider;
2738

@@ -40,20 +51,28 @@ class Customization
4051
* @see self::_prepareThemeCustomizations()
4152
*/
4253
protected $_unassignedTheme;
54+
/**
55+
* @var StoreUserAgentThemeResolver|mixed|null
56+
*/
57+
private $storeThemesResolver;
4358

4459
/**
45-
* @param \Magento\Store\Model\StoreManagerInterface $storeManager
46-
* @param \Magento\Framework\View\DesignInterface $design
47-
* @param \Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider
60+
* @param StoreManagerInterface $storeManager
61+
* @param DesignInterface $design
62+
* @param ThemeProviderInterface $themeProvider
63+
* @param StoreThemesResolverInterface|null $storeThemesResolver
4864
*/
4965
public function __construct(
50-
\Magento\Store\Model\StoreManagerInterface $storeManager,
51-
\Magento\Framework\View\DesignInterface $design,
52-
\Magento\Framework\View\Design\Theme\ThemeProviderInterface $themeProvider
66+
StoreManagerInterface $storeManager,
67+
DesignInterface $design,
68+
ThemeProviderInterface $themeProvider,
69+
?StoreThemesResolverInterface $storeThemesResolver = null
5370
) {
5471
$this->_storeManager = $storeManager;
5572
$this->_design = $design;
5673
$this->themeProvider = $themeProvider;
74+
$this->storeThemesResolver = $storeThemesResolver
75+
?? ObjectManager::getInstance()->get(StoreThemesResolverInterface::class);
5776
}
5877

5978
/**
@@ -93,22 +112,23 @@ public function getStoresByThemes()
93112
{
94113
$storesByThemes = [];
95114
$stores = $this->_storeManager->getStores();
96-
/** @var $store \Magento\Store\Model\Store */
115+
/** @var $store Store */
97116
foreach ($stores as $store) {
98-
$themeId = $this->_getConfigurationThemeId($store);
99-
if (!isset($storesByThemes[$themeId])) {
100-
$storesByThemes[$themeId] = [];
117+
foreach ($this->storeThemesResolver->getThemes($store) as $themeId) {
118+
if (!isset($storesByThemes[$themeId])) {
119+
$storesByThemes[$themeId] = [];
120+
}
121+
$storesByThemes[$themeId][] = $store;
101122
}
102-
$storesByThemes[$themeId][] = $store;
103123
}
104124
return $storesByThemes;
105125
}
106126

107127
/**
108128
* Check if current theme has assigned to any store
109129
*
110-
* @param \Magento\Framework\View\Design\ThemeInterface $theme
111-
* @param null|\Magento\Store\Model\Store $store
130+
* @param ThemeInterface $theme
131+
* @param null|Store $store
112132
* @return bool
113133
*/
114134
public function isThemeAssignedToStore($theme, $store = null)
@@ -133,8 +153,8 @@ public function hasThemeAssigned()
133153
/**
134154
* Is theme assigned to specific store
135155
*
136-
* @param \Magento\Framework\View\Design\ThemeInterface $theme
137-
* @param \Magento\Store\Model\Store $store
156+
* @param ThemeInterface $theme
157+
* @param Store $store
138158
* @return bool
139159
*/
140160
protected function _isThemeAssignedToSpecificStore($theme, $store)
@@ -145,37 +165,37 @@ protected function _isThemeAssignedToSpecificStore($theme, $store)
145165
/**
146166
* Get configuration theme id
147167
*
148-
* @param \Magento\Store\Model\Store $store
168+
* @param Store $store
149169
* @return int
150170
*/
151171
protected function _getConfigurationThemeId($store)
152172
{
153173
return $this->_design->getConfigurationDesignTheme(
154-
\Magento\Framework\App\Area::AREA_FRONTEND,
174+
Area::AREA_FRONTEND,
155175
['store' => $store]
156176
);
157177
}
158178

159179
/**
160180
* Fetch theme customization and sort them out to arrays:
161-
* self::_assignedTheme and self::_unassignedTheme.
162181
*
182+
* Set self::_assignedTheme and self::_unassignedTheme.
163183
* NOTE: To get into "assigned" list theme customization not necessary should be assigned to store-view directly.
164184
* It can be set to website or as default theme and be used by store-view via config fallback mechanism.
165185
*
166186
* @return $this
167187
*/
168188
protected function _prepareThemeCustomizations()
169189
{
170-
/** @var \Magento\Theme\Model\ResourceModel\Theme\Collection $themeCollection */
171-
$themeCollection = $this->themeProvider->getThemeCustomizations(\Magento\Framework\App\Area::AREA_FRONTEND);
190+
/** @var Collection $themeCollection */
191+
$themeCollection = $this->themeProvider->getThemeCustomizations(Area::AREA_FRONTEND);
172192

173193
$assignedThemes = $this->getStoresByThemes();
174194

175195
$this->_assignedTheme = [];
176196
$this->_unassignedTheme = [];
177197

178-
/** @var $theme \Magento\Framework\View\Design\ThemeInterface */
198+
/** @var $theme ThemeInterface */
179199
foreach ($themeCollection as $theme) {
180200
if (isset($assignedThemes[$theme->getId()])) {
181201
$theme->setAssignedStores($assignedThemes[$theme->getId()]);
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
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\Theme\Model\Theme;
9+
10+
use Magento\Framework\App\Area;
11+
use Magento\Framework\View\Design\ThemeInterface;
12+
use Magento\Framework\View\DesignInterface;
13+
use Magento\Store\Api\Data\StoreInterface;
14+
use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory;
15+
16+
/**
17+
* Store default theme resolver.
18+
*
19+
* Use system config fallback mechanism if no theme is directly assigned to the store-view.
20+
*/
21+
class StoreDefaultThemeResolver implements StoreThemesResolverInterface
22+
{
23+
/**
24+
* @var CollectionFactory
25+
*/
26+
private $themeCollectionFactory;
27+
/**
28+
* @var DesignInterface
29+
*/
30+
private $design;
31+
/**
32+
* @var ThemeInterface[]
33+
*/
34+
private $registeredThemes;
35+
36+
/**
37+
* @param CollectionFactory $themeCollectionFactory
38+
* @param DesignInterface $design
39+
*/
40+
public function __construct(
41+
CollectionFactory $themeCollectionFactory,
42+
DesignInterface $design
43+
) {
44+
$this->design = $design;
45+
$this->themeCollectionFactory = $themeCollectionFactory;
46+
}
47+
48+
/**
49+
* @inheritDoc
50+
*/
51+
public function getThemes(StoreInterface $store): array
52+
{
53+
$theme = $this->design->getConfigurationDesignTheme(
54+
Area::AREA_FRONTEND,
55+
['store' => $store]
56+
);
57+
$themes = [];
58+
if ($theme) {
59+
if (!is_numeric($theme)) {
60+
$registeredThemes = $this->getRegisteredThemes();
61+
if (isset($registeredThemes[$theme])) {
62+
$themes[] = $registeredThemes[$theme]->getId();
63+
}
64+
} else {
65+
$themes[] = $theme;
66+
}
67+
}
68+
return $themes;
69+
}
70+
71+
/**
72+
* Get system registered themes.
73+
*
74+
* @return ThemeInterface[]
75+
*/
76+
private function getRegisteredThemes(): array
77+
{
78+
if ($this->registeredThemes === null) {
79+
$this->registeredThemes = [];
80+
/** @var \Magento\Theme\Model\ResourceModel\Theme\Collection $collection */
81+
$collection = $this->themeCollectionFactory->create();
82+
$themes = $collection->loadRegisteredThemes();
83+
/** @var ThemeInterface $theme */
84+
foreach ($themes as $theme) {
85+
$this->registeredThemes[$theme->getCode()] = $theme;
86+
}
87+
}
88+
return $this->registeredThemes;
89+
}
90+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
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\Theme\Model\Theme;
9+
10+
use InvalidArgumentException;
11+
use Magento\Store\Api\Data\StoreInterface;
12+
use Magento\Theme\Model\ResourceModel\Theme\CollectionFactory;
13+
14+
/**
15+
* Store associated themes resolver.
16+
*/
17+
class StoreThemesResolver implements StoreThemesResolverInterface
18+
{
19+
/**
20+
* @var StoreThemesResolverInterface[]
21+
*/
22+
private $resolvers;
23+
24+
/**
25+
* @param StoreThemesResolverInterface[] $resolvers
26+
*/
27+
public function __construct(
28+
array $resolvers
29+
) {
30+
foreach ($resolvers as $resolver) {
31+
if (!$resolver instanceof StoreThemesResolverInterface) {
32+
throw new InvalidArgumentException(
33+
sprintf(
34+
'Instance of %s is expected, got %s instead.',
35+
StoreThemesResolverInterface::class,
36+
get_class($resolver)
37+
)
38+
);
39+
}
40+
}
41+
$this->resolvers = $resolvers;
42+
}
43+
44+
/**
45+
* @inheritDoc
46+
*/
47+
public function getThemes(StoreInterface $store): array
48+
{
49+
$themes = [];
50+
foreach ($this->resolvers as $resolver) {
51+
foreach ($resolver->getThemes($store) as $theme) {
52+
$themes[] = $theme;
53+
}
54+
}
55+
return array_values(array_unique($themes));
56+
}
57+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
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\Theme\Model\Theme;
9+
10+
use Magento\Store\Api\Data\StoreInterface;
11+
12+
/**
13+
* Store associated themes resolver.
14+
*/
15+
interface StoreThemesResolverInterface
16+
{
17+
/**
18+
* Get themes associated with a store view
19+
*
20+
* @param StoreInterface $store
21+
* @return int[]
22+
*/
23+
public function getThemes(StoreInterface $store): array;
24+
}

0 commit comments

Comments
 (0)