Skip to content

Commit fc4e931

Browse files
Gerych1984vjik
andauthored
Add immutable withTheme method (#243)
Co-authored-by: Sergei Predvoditelev <sergei@predvoditelev.ru>
1 parent b44649a commit fc4e931

8 files changed

Lines changed: 79 additions & 27 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## 8.0.1 under development
44

5+
- New #243: Add immutable method `ViewInterface::withTheme()` (@Gerych1984)
56
- Bug #224: Fix signature of `CachedContent::cache()` (@vjik)
67
- Bug #226: Fix `reset` config for referenced definitions (@rustamwin)
78
- Enh #226: Adjust config to make `View` and `WebView` more configurable (@rustamwin)

src/State/StateTrait.php

Lines changed: 0 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
namespace Yiisoft\View\State;
66

77
use InvalidArgumentException;
8-
use Yiisoft\View\Theme;
98

109
use function array_key_exists;
1110
use function func_get_args;
@@ -16,8 +15,6 @@
1615
*/
1716
trait StateTrait
1817
{
19-
private ?Theme $theme = null;
20-
2118
/**
2219
* @var array Parameters that are common for all view templates.
2320
* @psalm-var array<string, mixed>
@@ -30,27 +27,6 @@ trait StateTrait
3027
*/
3128
private array $blocks = [];
3229

33-
/**
34-
* Set the specified theme instance.
35-
*
36-
* @param Theme|null $theme The theme instance or `null` for reset theme.
37-
*/
38-
public function setTheme(?Theme $theme): static
39-
{
40-
$this->theme = $theme;
41-
return $this;
42-
}
43-
44-
/**
45-
* Gets the theme instance, or `null` if no theme has been set.
46-
*
47-
* @return Theme|null The theme instance, or `null` if no theme has been set.
48-
*/
49-
public function getTheme(): ?Theme
50-
{
51-
return $this->theme;
52-
}
53-
5430
/**
5531
* Sets a common parameters that is accessible in all view templates.
5632
*

src/State/ThemeState.php

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\View\State;
6+
7+
use Yiisoft\View\Theme;
8+
9+
/**
10+
* @internal
11+
*/
12+
final class ThemeState
13+
{
14+
public function __construct(
15+
private ?Theme $theme = null
16+
) {
17+
}
18+
19+
/**
20+
* Set the specified view theme.
21+
*
22+
* @param Theme|null $theme $theme The theme instance or `null` for reset theme.
23+
*/
24+
public function setTheme(?Theme $theme): self
25+
{
26+
$this->theme = $theme;
27+
28+
return $this;
29+
}
30+
31+
/**
32+
* Gets the theme instance, or `null` if no theme has been set.
33+
*
34+
* @return Theme|null The theme instance, or `null` if no theme has been set.
35+
*/
36+
public function getTheme(): ?Theme
37+
{
38+
return $this->theme;
39+
}
40+
}

src/View.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Yiisoft\View\Event\View\PageBegin;
1313
use Yiisoft\View\Event\View\PageEnd;
1414
use Yiisoft\View\State\LocaleState;
15+
use Yiisoft\View\State\ThemeState;
1516
use Yiisoft\View\State\ViewState;
1617

1718
use function ob_end_flush;
@@ -29,6 +30,7 @@ final class View implements ViewInterface
2930

3031
private ViewState $state;
3132
private LocaleState $localeState;
33+
private ThemeState $themeState;
3234

3335
/**
3436
* @param string $basePath The full path to the base directory of views.
@@ -39,6 +41,7 @@ public function __construct(string $basePath, EventDispatcherInterface $eventDis
3941
$this->basePath = $basePath;
4042
$this->state = new ViewState();
4143
$this->localeState = new LocaleState();
44+
$this->themeState = new ThemeState();
4245
$this->eventDispatcher = $eventDispatcher;
4346
$this->setPlaceholderSalt(__DIR__);
4447
}

src/ViewInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,13 @@ public function getTheme(): ?Theme;
132132
*/
133133
public function setTheme(?Theme $theme): static;
134134

135+
/**
136+
* Set the specified theme instance immutable.
137+
*
138+
* @param Theme|null $theme The theme instance or `null` for reset theme.
139+
*/
140+
public function withTheme(?Theme $theme): static;
141+
135142
/**
136143
* Sets a common parameters that is accessible in all view templates.
137144
*

src/ViewTrait.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Yiisoft\View\Event\AfterRenderEventInterface;
1313
use Yiisoft\View\Exception\ViewNotFoundException;
1414
use Yiisoft\View\State\LocaleState;
15+
use Yiisoft\View\State\ThemeState;
1516

1617
use function array_merge;
1718
use function array_pop;
@@ -237,7 +238,7 @@ public function getFallbackExtensions(): array
237238
*/
238239
public function getTheme(): ?Theme
239240
{
240-
return $this->state->getTheme();
241+
return $this->themeState->getTheme();
241242
}
242243

243244
/**
@@ -247,10 +248,18 @@ public function getTheme(): ?Theme
247248
*/
248249
public function setTheme(?Theme $theme): static
249250
{
250-
$this->state->setTheme($theme);
251+
$this->themeState->setTheme($theme);
251252
return $this;
252253
}
253254

255+
public function withTheme(?Theme $theme): static
256+
{
257+
$new = clone $this;
258+
$new->themeState = new ThemeState($theme);
259+
260+
return $new;
261+
}
262+
254263
/**
255264
* Sets a common parameters that is accessible in all view templates.
256265
*
@@ -535,6 +544,7 @@ public function clear(): void
535544
$this->viewFiles = [];
536545
$this->state->clear();
537546
$this->localeState = new LocaleState();
547+
$this->themeState = new ThemeState();
538548
}
539549

540550
/**

src/WebView.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use Yiisoft\View\Event\WebView\PageBegin;
2222
use Yiisoft\View\Event\WebView\PageEnd;
2323
use Yiisoft\View\State\LocaleState;
24+
use Yiisoft\View\State\ThemeState;
2425
use Yiisoft\View\State\WebViewState;
2526

2627
use function array_merge;
@@ -42,6 +43,7 @@ final class WebView implements ViewInterface
4243

4344
private WebViewState $state;
4445
private LocaleState $localeState;
46+
private ThemeState $themeState;
4547

4648
/**
4749
* This means the location is in the head section.
@@ -93,6 +95,7 @@ public function __construct(string $basePath, EventDispatcherInterface $eventDis
9395
$this->basePath = $basePath;
9496
$this->state = new WebViewState();
9597
$this->localeState = new LocaleState();
98+
$this->themeState = new ThemeState();
9699
$this->eventDispatcher = $eventDispatcher;
97100
$this->setPlaceholderSalt(__DIR__);
98101
}

tests/ViewTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,6 +584,18 @@ public function testImmutability(): void
584584
$this->assertNotSame($view, $view->withClearedState());
585585
$this->assertNotSame($view, $view->withLocale('es'));
586586
$this->assertNotSame($view, $view->withFallbackExtension('tpl'));
587+
$this->assertNotSame($view, $view->withTheme(null));
588+
}
589+
590+
public function testImmutableTheme(): void
591+
{
592+
$view = TestHelper::createView();
593+
$theme = new Theme([]);
594+
$viewWithTheme = $view->withTheme($theme);
595+
596+
$this->assertNull($view->getTheme());
597+
$this->assertNotNull($viewWithTheme->getTheme());
598+
$this->assertSame($theme, $viewWithTheme->getTheme());
587599
}
588600

589601
public function testGetLocale()
@@ -604,7 +616,7 @@ private function createViewWithBasePath(string $basePath): View
604616

605617
private function createContext(string $viewPath): ViewContextInterface
606618
{
607-
return new class ($viewPath) implements ViewContextInterface {
619+
return new class($viewPath) implements ViewContextInterface {
608620
public function __construct(private string $viewPath)
609621
{
610622
}

0 commit comments

Comments
 (0)