Passed
Push — master ( 2dc3a7...30a60e )
by Angel Fernando Quiroz
07:18
created

ThemeHelper   A

Complexity

Total Complexity 24

Size/Duplication

Total Lines 147
Duplicated Lines 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 61
dl 0
loc 147
rs 10
c 5
b 0
f 0
wmc 24

7 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
B getVisualTheme() 0 41 8
A getThemeAssetLinkTag() 0 9 2
A getFileLocation() 0 16 3
A getAssetBase64Encoded() 0 14 3
A getAssetContents() 0 17 3
A getThemeAssetUrl() 0 16 4
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\ServiceHelper;
8
9
use Chamilo\CoreBundle\Settings\SettingsManager;
10
use Chamilo\CourseBundle\Settings\SettingsCourseManager;
11
use League\Flysystem\FilesystemException;
12
use League\Flysystem\FilesystemOperator;
13
use League\Flysystem\UnableToReadFile;
14
use League\MimeTypeDetection\ExtensionMimeTypeDetector;
15
use Symfony\Component\DependencyInjection\Attribute\Autowire;
16
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
17
use Symfony\Component\Routing\RouterInterface;
18
19
use const DIRECTORY_SEPARATOR;
20
use const PHP_SAPI;
21
22
final class ThemeHelper
23
{
24
    public const DEFAULT_THEME = 'chamilo';
25
26
    public function __construct(
27
        private readonly AccessUrlHelper $accessUrlHelper,
28
        private readonly SettingsManager $settingsManager,
29
        private readonly UserHelper $userHelper,
30
        private readonly CidReqHelper $cidReqHelper,
31
        private readonly SettingsCourseManager $settingsCourseManager,
32
        private readonly RouterInterface $router,
33
        #[Autowire(service: 'oneup_flysystem.themes_filesystem')]
34
        private readonly FilesystemOperator $filesystem,
35
    ) {}
36
37
    /**
38
     * Returns the name of the color theme configured to be applied on the current page.
39
     * The returned name depends on the platform, course or user settings.
40
     */
41
    public function getVisualTheme(): string
42
    {
43
        if ('cli' === PHP_SAPI) {
44
            return '';
45
        }
46
47
        static $visualTheme;
48
49
        global $lp_theme_css;
50
51
        if (isset($visualTheme)) {
52
            return $visualTheme;
53
        }
54
55
        $accessUrl = $this->accessUrlHelper->getCurrent();
56
57
        $visualTheme = $accessUrl->getActiveColorTheme()?->getColorTheme()->getSlug();
58
59
        if ('true' == $this->settingsManager->getSetting('profile.user_selected_theme')) {
60
            $visualTheme = $this->userHelper->getCurrent()?->getTheme();
61
        }
62
63
        if ('true' == $this->settingsManager->getSetting('course.allow_course_theme')) {
64
            $course = $this->cidReqHelper->getCourseEntity();
65
66
            if ($course) {
67
                $this->settingsCourseManager->setCourse($course);
68
69
                $visualTheme = $this->settingsCourseManager->getCourseSettingValue('course_theme');
70
71
                if (1 === (int) $this->settingsCourseManager->getCourseSettingValue('allow_learning_path_theme')) {
72
                    $visualTheme = $lp_theme_css;
73
                }
74
            }
75
        }
76
77
        if (empty($visualTheme)) {
78
            $visualTheme = self::DEFAULT_THEME;
79
        }
80
81
        return $visualTheme;
82
    }
83
84
    /**
85
     * @throws FilesystemException
86
     * @throws UnableToCheckExistence
87
     */
88
    public function getFileLocation(string $path): ?string
89
    {
90
        $themeName = $this->getVisualTheme();
91
92
        $locations = [
93
            $themeName.DIRECTORY_SEPARATOR.$path,
94
            self::DEFAULT_THEME.DIRECTORY_SEPARATOR.$path,
95
        ];
96
97
        foreach ($locations as $location) {
98
            if ($this->filesystem->fileExists($location)) {
99
                return $location;
100
            }
101
        }
102
103
        return null;
104
    }
105
106
    public function getThemeAssetUrl(string $path, bool $absoluteUrl = false): string
107
    {
108
        try {
109
            if (!$this->getFileLocation($path)) {
110
                return '';
111
            }
112
        } catch (FilesystemException) {
113
            return '';
114
        }
115
116
        $themeName = $this->getVisualTheme();
117
118
        return $this->router->generate(
119
            'theme_asset',
120
            ['name' => $themeName, 'path' => $path],
121
            $absoluteUrl ? UrlGeneratorInterface::ABSOLUTE_URL : UrlGeneratorInterface::ABSOLUTE_PATH
122
        );
123
    }
124
125
    public function getThemeAssetLinkTag(string $path, bool $absoluteUrl = false): string
126
    {
127
        $url = $this->getThemeAssetUrl($path, $absoluteUrl);
128
129
        if (empty($url)) {
130
            return '';
131
        }
132
133
        return \sprintf('<link rel="stylesheet" href="%s">', $url);
134
    }
135
136
    public function getAssetContents(string $path): string
137
    {
138
        try {
139
            if ($fullPath = $this->getFileLocation($path)) {
140
                $stream = $this->filesystem->readStream($fullPath);
141
142
                $contents = stream_get_contents($stream);
143
144
                fclose($stream);
145
146
                return $contents;
147
            }
148
        } catch (FilesystemException|UnableToReadFile) {
149
            return '';
150
        }
151
152
        return '';
153
    }
154
155
    public function getAssetBase64Encoded(string $path): string
156
    {
157
        try {
158
            if ($fullPath = $this->getFileLocation($path)) {
159
                $detector = new ExtensionMimeTypeDetector();
160
                $mimeType = (string) $detector->detectMimeTypeFromFile($fullPath);
161
162
                return 'data:'.$mimeType.';base64,'.base64_encode($this->getAssetContents($path));
163
            }
164
        } catch (FilesystemException) {
165
            return '';
166
        }
167
168
        return '';
169
    }
170
}
171