Skip to content

Commit 2eb0fe6

Browse files
ENGCOM-7853: Deploy all used locales #28922
- Merge Pull Request #28922 from AntonEvers/magento2:lang-deploy - Merged commits: 1. da400fb
2 parents 455ca54 + da400fb commit 2eb0fe6

File tree

4 files changed

+461
-11
lines changed

4 files changed

+461
-11
lines changed
Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
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\Deploy\Package;
9+
10+
use InvalidArgumentException;
11+
use Magento\Framework\App\Area;
12+
use Magento\Framework\App\DeploymentConfig;
13+
use Magento\Framework\AppInterface;
14+
use Magento\Framework\Config\ConfigOptionsListConstants;
15+
use Magento\Framework\Exception\LocalizedException;
16+
use Magento\Framework\Validator\Locale;
17+
use Magento\Store\Model\Config\StoreView;
18+
use Magento\User\Api\Data\UserInterface;
19+
use Magento\User\Model\ResourceModel\User\Collection as UserCollection;
20+
use Magento\User\Model\ResourceModel\User\CollectionFactory as UserCollectionFactory;
21+
use Psr\Log\LoggerInterface;
22+
23+
/**
24+
* Deployment Package Locale Resolver class
25+
*/
26+
class LocaleResolver
27+
{
28+
/**
29+
* Parameter to force deploying certain languages for the admin, without any users having configured them yet.
30+
*/
31+
const ADMIN_LOCALES_FOR_DEPLOY = 'admin_locales_for_deploy';
32+
33+
/**
34+
* @var StoreView
35+
*/
36+
private $storeView;
37+
38+
/**
39+
* @var UserCollectionFactory
40+
*/
41+
private $userCollFactory;
42+
43+
/**
44+
* @var DeploymentConfig
45+
*/
46+
private $deploymentConfig;
47+
48+
/**
49+
* @var Locale
50+
*/
51+
private $locale;
52+
53+
/**
54+
* @var LoggerInterface
55+
*/
56+
private $logger;
57+
58+
/**
59+
* @var array|null
60+
*/
61+
private $usedStoreLocales;
62+
63+
/**
64+
* @var array|null
65+
*/
66+
private $usedAdminLocales;
67+
68+
/**
69+
* LocaleResolver constructor.
70+
*
71+
* @param StoreView $storeView
72+
* @param UserCollectionFactory $userCollectionFactory
73+
* @param DeploymentConfig $deploymentConfig
74+
* @param Locale $locale
75+
* @param LoggerInterface $logger
76+
*/
77+
public function __construct(
78+
StoreView $storeView,
79+
UserCollectionFactory $userCollectionFactory,
80+
DeploymentConfig $deploymentConfig,
81+
Locale $locale,
82+
LoggerInterface $logger
83+
) {
84+
$this->storeView = $storeView;
85+
$this->userCollFactory = $userCollectionFactory;
86+
$this->deploymentConfig = $deploymentConfig;
87+
$this->locale = $locale;
88+
$this->logger = $logger;
89+
}
90+
91+
/**
92+
* Get locales that are used for a given theme.
93+
* If it is a frontend theme, return supported frontend languages.
94+
* If it is an adminhtml theme, return languages that admin users have configured together with deployment config.
95+
*
96+
* @param Package $package
97+
*
98+
* @return array
99+
*/
100+
public function getUsedPackageLocales(Package $package): array
101+
{
102+
switch ($package->getArea()) {
103+
case Area::AREA_ADMINHTML:
104+
$locales = $this->getUsedAdminLocales();
105+
break;
106+
case Area::AREA_FRONTEND:
107+
$locales = $this->getUsedStoreLocales();
108+
break;
109+
default:
110+
$locales = array_merge($this->getUsedAdminLocales(), $this->getUsedStoreLocales());
111+
}
112+
return $this->validateLocales($locales);
113+
}
114+
115+
/**
116+
* Get used admin user locales, en_US is always included by default.
117+
*
118+
* @return array
119+
*/
120+
private function getUsedAdminLocales(): array
121+
{
122+
if ($this->usedAdminLocales === null) {
123+
$deploymentConfig = $this->getDeploymentAdminLocales();
124+
$this->usedAdminLocales = array_merge([AppInterface::DISTRO_LOCALE_CODE], $deploymentConfig);
125+
126+
if (!$this->isDbConnectionAvailable()) {
127+
return $this->usedAdminLocales;
128+
}
129+
130+
/** @var UserCollection $userCollection */
131+
$userCollection = $this->userCollFactory->create();
132+
/** @var UserInterface $adminUser */
133+
foreach ($userCollection as $adminUser) {
134+
$this->usedAdminLocales[] = $adminUser->getInterfaceLocale();
135+
}
136+
}
137+
return $this->usedAdminLocales;
138+
}
139+
140+
/**
141+
* Get used store locales.
142+
*
143+
* @return array
144+
*/
145+
private function getUsedStoreLocales(): array
146+
{
147+
if ($this->usedStoreLocales === null) {
148+
$this->usedStoreLocales = $this->isDbConnectionAvailable()
149+
? $this->storeView->retrieveLocales()
150+
: [AppInterface::DISTRO_LOCALE_CODE];
151+
}
152+
return $this->usedStoreLocales;
153+
}
154+
155+
/**
156+
* Strip out duplicates and break on invalid locale codes.
157+
*
158+
* @param array $usedLocales
159+
*
160+
* @return array
161+
* @throws InvalidArgumentException if unknown locale is provided by the store configuration
162+
*/
163+
private function validateLocales(array $usedLocales): array
164+
{
165+
return array_map(
166+
function ($locale) {
167+
if (!$this->locale->isValid($locale)) {
168+
throw new InvalidArgumentException(
169+
$locale . ' argument has invalid value, run info:language:list for list of available locales'
170+
);
171+
}
172+
173+
return $locale;
174+
},
175+
array_unique($usedLocales)
176+
);
177+
}
178+
179+
/**
180+
* Check if a database connection is already set up.
181+
*
182+
* @return bool
183+
*/
184+
private function isDbConnectionAvailable(): bool
185+
{
186+
try {
187+
$connections = $this->deploymentConfig->get(ConfigOptionsListConstants::CONFIG_PATH_DB_CONNECTIONS, []);
188+
} catch (LocalizedException $exception) {
189+
$this->logger->critical($exception);
190+
}
191+
return !empty($connections);
192+
}
193+
194+
/**
195+
* Retrieve deployment configuration for admin locales that have to be deployed.
196+
*
197+
* @return array|mixed|string|null
198+
*/
199+
private function getDeploymentAdminLocales(): array
200+
{
201+
try {
202+
return $this->deploymentConfig
203+
->get(self::ADMIN_LOCALES_FOR_DEPLOY, []);
204+
} catch (LocalizedException $exception) {
205+
return [];
206+
}
207+
}
208+
}

app/code/Magento/Deploy/Package/PackagePool.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
use Magento\Deploy\Collector\Collector;
99
use Magento\Deploy\Console\DeployStaticOptions as Options;
10-
use Magento\Framework\AppInterface;
10+
use Magento\Framework\App\ObjectManager;
1111
use Magento\Framework\View\Design\ThemeInterface;
1212
use Magento\Framework\View\Design\Theme\ListInterface;
1313

@@ -41,22 +41,30 @@ class PackagePool
4141
*/
4242
private $collected = false;
4343

44+
/**
45+
* @var LocaleResolver|null
46+
*/
47+
private $localeResolver;
48+
4449
/**
4550
* PackagePool constructor
4651
*
4752
* @param Collector $collector
4853
* @param ListInterface $themeCollection
4954
* @param PackageFactory $packageFactory
55+
* @param LocaleResolver|null $localeResolver
5056
*/
5157
public function __construct(
5258
Collector $collector,
5359
ListInterface $themeCollection,
54-
PackageFactory $packageFactory
60+
PackageFactory $packageFactory,
61+
?LocaleResolver $localeResolver = null
5562
) {
5663
$this->collector = $collector;
5764
$themeCollection->clear()->resetConstraints();
5865
$this->themes = $themeCollection->getItems();
5966
$this->packageFactory = $packageFactory;
67+
$this->localeResolver = $localeResolver ?: ObjectManager::getInstance()->get(LocaleResolver::class);
6068
}
6169

6270
/**
@@ -221,17 +229,18 @@ private function ensurePackagesForRequiredLocales(array $options)
221229
private function ensureRequiredLocales(array $options)
222230
{
223231
if (empty($options[Options::LANGUAGE]) || $options[Options::LANGUAGE][0] === 'all') {
224-
$forcedLocales = [AppInterface::DISTRO_LOCALE_CODE];
232+
$forcedLocales = [];
225233
} else {
226234
$forcedLocales = $options[Options::LANGUAGE];
227235
}
228236

229-
$resultPackages = $this->packages;
230-
foreach ($resultPackages as $package) {
237+
foreach ($this->packages as $package) {
231238
if ($package->getTheme() === Package::BASE_THEME) {
232239
continue;
233240
}
234-
foreach ($forcedLocales as $locale) {
241+
242+
$locales = $forcedLocales ?: $this->localeResolver->getUsedPackageLocales($package);
243+
foreach ($locales as $locale) {
235244
$this->ensurePackage([
236245
'area' => $package->getArea(),
237246
'theme' => $package->getTheme(),

0 commit comments

Comments
 (0)