Skip to content

Commit 83f03d9

Browse files
authored
Merge pull request #2441 from elcreator/fix-manager-language
fix(manager): language set by admin for manager should be used.
2 parents 8478750 + 71eeda6 commit 83f03d9

4 files changed

Lines changed: 122 additions & 31 deletions

File tree

‎core/src/Core.php‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Illuminate\Http\Request;
2020
use Illuminate\Support\Arr;
2121
use Illuminate\Support\Facades\Cache;
22+
use Illuminate\Support\Facades\Facade;
2223
use Illuminate\Support\Facades\Log;
2324
use Illuminate\Support\Facades\Route;
2425
use Illuminate\Support\Str;
@@ -6572,6 +6573,44 @@ public function getSettings()
65726573
$this->getUserSettings();
65736574
$this->setConfig('site_timezone', $siteTimezone);
65746575
$this->invokeEvent('OnLoadSettings', ['config' => &$this->config]);
6576+
6577+
// The factory defaults read the manager lexicon (core/factory/settings.php), so
6578+
// ManagerTheme is already built from the system theme and language by the time the
6579+
// user settings above are merged. Realign it so a per-user manager_theme /
6580+
// manager_language (and anything OnLoadSettings changed) reaches the manager UI.
6581+
$this->syncManagerTheme();
6582+
}
6583+
6584+
/**
6585+
* Realign the already resolved ManagerTheme with the current manager_theme and
6586+
* manager_language. A different theme needs a new instance (the theme name drives the
6587+
* view namespaces, the style and the theme snippets/chunks); a different language only
6588+
* needs the lexicon read again.
6589+
*/
6590+
protected function syncManagerTheme(): void
6591+
{
6592+
if (!$this->isBackend() || !$this->resolved('ManagerTheme')) {
6593+
return;
6594+
}
6595+
6596+
$managerTheme = $this['ManagerTheme'];
6597+
if (!$managerTheme instanceof ManagerTheme) {
6598+
return;
6599+
}
6600+
6601+
$theme = (string) $this->getConfig('manager_theme', 'default');
6602+
if ($theme !== '' && $theme !== $managerTheme->getTheme()) {
6603+
// Dropped, not rebuilt: the next call resolves it again from the merged config.
6604+
$this->forgetInstance('ManagerTheme');
6605+
Facade::clearResolvedInstance('ManagerTheme');
6606+
6607+
return;
6608+
}
6609+
6610+
$language = (string) $this->getConfig('manager_language');
6611+
if ($language !== '' && $language !== $managerTheme->getLangName()) {
6612+
$managerTheme->reloadLang($language);
6613+
}
65756614
}
65766615

65776616
/**

‎core/src/ManagerTheme.php‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,20 @@ public function __construct(CoreInterface $core, string $theme)
205205
}
206206
}
207207

208+
/**
209+
* Re-read the lexicon for another language.
210+
*
211+
* The theme is built while the configuration still only holds the system settings,
212+
* so the core calls this once the per-user manager_language has been merged in.
213+
*
214+
* @param string $lang
215+
* @return string
216+
*/
217+
public function reloadLang(string $lang): string
218+
{
219+
return $this->loadLang($lang);
220+
}
221+
208222
protected function loadLang($lang = 'english')
209223
{
210224
$_lang = [];
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
<?php
2+
3+
namespace Tests\Unit;
4+
5+
use EvolutionCMS\ManagerTheme;
6+
use PHPUnit\Framework\TestCase;
7+
use ReflectionMethod;
8+
9+
/**
10+
* core/factory/settings.php reads the manager lexicon, so the ManagerTheme singleton is
11+
* already built - with the system theme and language - by the time Core::getSettings()
12+
* merges the per-user settings. Without an explicit refresh a user-level manager_language
13+
* or manager_theme never reaches the manager UI: the whole backend stays on the site-wide
14+
* value.
15+
*/
16+
final class ManagerPerUserLanguageTest extends TestCase
17+
{
18+
private static string $coreSource = '';
19+
20+
public static function setUpBeforeClass(): void
21+
{
22+
$rootDir = dirname(__DIR__, 3);
23+
require_once $rootDir . '/core/vendor/autoload.php';
24+
25+
self::$coreSource = (string) file_get_contents($rootDir . '/core/src/Core.php');
26+
}
27+
28+
public function testFactorySettingsStillNeedTheManagerLexicon(): void
29+
{
30+
$factorySettings = (string) file_get_contents(dirname(__DIR__, 2) . '/factory/settings.php');
31+
32+
// This is what forces ManagerTheme to be resolved before the user settings are known.
33+
self::assertStringContainsString('ManagerTheme::getLexicon(', $factorySettings);
34+
}
35+
36+
public function testManagerThemeCanReloadItsLexicon(): void
37+
{
38+
$method = new ReflectionMethod(ManagerTheme::class, 'reloadLang');
39+
40+
self::assertTrue($method->isPublic());
41+
self::assertSame(1, $method->getNumberOfRequiredParameters());
42+
}
43+
44+
public function testCoreRefreshesTheManagerThemeAfterMergingUserSettings(): void
45+
{
46+
$mergePosition = mb_strpos(self::$coreSource, '$this->getUserSettings();');
47+
$syncPosition = mb_strpos(self::$coreSource, '$this->syncManagerTheme();');
48+
49+
self::assertIsInt($mergePosition);
50+
self::assertIsInt($syncPosition);
51+
self::assertGreaterThan($mergePosition, $syncPosition);
52+
}
53+
54+
public function testManagerThemeRefreshOnlyTouchesAnAlreadyBuiltBackendTheme(): void
55+
{
56+
$sync = mb_substr(
57+
self::$coreSource,
58+
(int) mb_strpos(self::$coreSource, 'protected function syncManagerTheme')
59+
);
60+
$sync = mb_substr($sync, 0, (int) mb_strpos($sync, "\n }"));
61+
62+
self::assertStringContainsString('$this->isBackend()', $sync);
63+
self::assertStringContainsString("\$this->resolved('ManagerTheme')", $sync);
64+
self::assertStringContainsString('reloadLang(', $sync);
65+
// A different theme cannot be patched in place - the instance has to go.
66+
self::assertStringContainsString("forgetInstance('ManagerTheme')", $sync);
67+
self::assertStringContainsString("Facade::clearResolvedInstance('ManagerTheme')", $sync);
68+
}
69+
}

‎manager/includes/user_settings.inc.php‎

Lines changed: 0 additions & 31 deletions
This file was deleted.

0 commit comments

Comments
 (0)