Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
14 / 14
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
ThemeManager
100.00% covered (success)
100.00%
13 / 13
100.00% covered (success)
100.00%
5 / 5
7
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 getActiveTheme
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 setActiveTheme
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
2
 isSupportedTheme
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 resolveLayoutPath
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Core\Theme;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use InvalidArgumentException;
12
13/**
14 * Core Theme Manager Implementation.
15 *
16 * Manages active application theme resolution, validation,
17 * and layout path resolution for Twig template engine.
18 *
19 * @package App\Core\Theme
20 */
21final class ThemeManager implements ThemeManagerInterface
22{
23    /**
24     * Currently active theme name.
25     */
26    private string $activeTheme;
27
28    /**
29     * ThemeManager constructor.
30     *
31     * @param string $defaultTheme Initial active theme name.
32     */
33    public function __construct(string $defaultTheme = self::DEFAULT_THEME)
34    {
35        $this->setActiveTheme($defaultTheme);
36    }
37
38    /**
39     * Gets the currently active theme name.
40     *
41     * @return string Active theme name ('tabler').
42     */
43    public function getActiveTheme(): string
44    {
45        return $this->activeTheme;
46    }
47
48    /**
49     * Sets the active theme name.
50     *
51     * @param string $theme Theme name to set.
52     * @throws InvalidArgumentException When provided theme is unsupported.
53     */
54    public function setActiveTheme(string $theme): void
55    {
56        if (!$this->isSupportedTheme($theme)) {
57            $supported = implode(', ', self::SUPPORTED_THEMES);
58            throw new InvalidArgumentException(
59                sprintf('Unsupported theme name "%s". Supported: %s.', $theme, $supported)
60            );
61        }
62
63        $this->activeTheme = $theme;
64    }
65
66    /**
67     * Checks if a theme name is supported by the system.
68     *
69     * @param string $theme Theme name to validate.
70     * @return bool True if supported, false otherwise.
71     */
72    public function isSupportedTheme(string $theme): bool
73    {
74        return in_array($theme, self::SUPPORTED_THEMES, true);
75    }
76
77    /**
78     * Resolves the full layout template path for a given layout name.
79     *
80     * @param string $layoutName Layout file name (e.g. 'admin_main', 'guest_auth').
81     * @return string Relative Twig template path.
82     */
83    public function resolveLayoutPath(string $layoutName): string
84    {
85        $cleanLayout = ltrim($layoutName, '/');
86        if (!str_ends_with($cleanLayout, '.twig')) {
87            $cleanLayout .= '.twig';
88        }
89
90        return sprintf('@theme/%s/layouts/%s', $this->activeTheme, $cleanLayout);
91    }
92}