Passed
Branch master (c87ba8)
by Christian
16:02
created

defineResourcesOfWidgets()   A

Complexity

Conditions 5
Paths 9

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 9
nop 1
dl 0
loc 12
rs 9.6111
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace TYPO3\CMS\Dashboard;
19
20
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
21
use TYPO3\CMS\Core\Utility\GeneralUtility;
22
use TYPO3\CMS\Core\Utility\PathUtility;
23
use TYPO3\CMS\Dashboard\Widgets\AdditionalCssInterface;
24
use TYPO3\CMS\Dashboard\Widgets\AdditionalJavaScriptInterface;
25
use TYPO3\CMS\Dashboard\Widgets\RequireJsModuleInterface;
26
27
/**
28
 * @internal
29
 */
30
class DashboardInitializationService
31
{
32
    protected const MODULE_DATA_CURRENT_DASHBOARD_IDENTIFIER = 'dashboard/current_dashboard/';
33
34
    /**
35
     * @var DashboardRepository
36
     */
37
    private $dashboardRepository;
38
39
    /**
40
     * @var DashboardPresetRegistry
41
     */
42
    private $dashboardPresetRegistry;
43
44
    /**
45
     * @var Dashboard
46
     */
47
    private $currentDashboard;
48
49
    /**
50
     * @var BackendUserAuthentication
51
     */
52
    private $user;
53
54
    /**
55
     * @var array
56
     */
57
    private $requireJsModules = [];
58
    private $jsFiles = [];
59
    private $cssFiles = [];
60
61
    public function __construct(
62
        DashboardRepository $dashboardRepository,
63
        DashboardPresetRegistry $dashboardPresetRegistry
64
    ) {
65
        $this->dashboardRepository = $dashboardRepository;
66
        $this->dashboardPresetRegistry = $dashboardPresetRegistry;
67
    }
68
69
    public function initializeDashboards(BackendUserAuthentication $user): void
70
    {
71
        $this->user = $user;
72
        $this->currentDashboard = $this->defineCurrentDashboard();
73
74
        $this->currentDashboard->initializeWidgets();
75
        $this->defineResourcesOfWidgets($this->currentDashboard->getWidgets());
76
    }
77
78
    public function getCurrentDashboard(): Dashboard
79
    {
80
        return $this->currentDashboard;
81
    }
82
83
    protected function defineCurrentDashboard(): Dashboard
84
    {
85
        $currentDashboard = $this->dashboardRepository->getDashboardByIdentifier($this->loadCurrentDashboard($this->user));
86
        if (!$currentDashboard instanceof Dashboard) {
87
            $dashboards = $this->getDashboardsForUser();
88
            $currentDashboard = reset($dashboards);
89
            $this->saveCurrentDashboard($this->user, $currentDashboard->getIdentifier());
90
        }
91
92
        return $currentDashboard;
93
    }
94
95
    protected function createDefaultDashboards(): array
96
    {
97
        $dashboardsForUser = [];
98
99
        $userConfig = $this->user->getTSConfig();
100
        $dashboardsToCreate = GeneralUtility::trimExplode(
101
            ',',
102
            $userConfig['options.']['dashboard.']['dashboardPresetsForNewUsers'] ?? 'default'
103
        );
104
105
        /** @var DashboardPreset $dashboardPreset */
106
        foreach ($this->dashboardPresetRegistry->getDashboardPresets() as $dashboardPreset) {
107
            if (in_array($dashboardPreset->getIdentifier(), $dashboardsToCreate, true)) {
108
                $dashboard = $this->dashboardRepository->create(
109
                    $dashboardPreset,
110
                    (int)$this->user->user['uid']
111
                );
112
113
                if ($dashboard instanceof Dashboard) {
114
                    $dashboardsForUser[$dashboard->getIdentifier()] = $dashboard;
115
                }
116
            }
117
        }
118
119
        return $dashboardsForUser;
120
    }
121
122
    /**
123
     * @return Dashboard[]
124
     */
125
    public function getDashboardsForUser(): array
126
    {
127
        $dashboards = [];
128
        foreach ($this->dashboardRepository->getDashboardsForUser((int)$this->user->user['uid']) as $dashboard) {
129
            $dashboards[$dashboard->getIdentifier()] = $dashboard;
130
        }
131
132
        if ($dashboards === []) {
133
            $dashboards = $this->createDefaultDashboards();
134
        }
135
136
        return $dashboards;
137
    }
138
139
    /**
140
     * @param array $widgets
141
     */
142
    protected function defineResourcesOfWidgets(array $widgets): void
143
    {
144
        foreach ($widgets as $widget) {
145
            $concreteInstance = GeneralUtility::makeInstance($widget->getServiceName());
146
            if ($concreteInstance instanceof RequireJsModuleInterface) {
147
                $this->defineRequireJsModules($concreteInstance);
148
            }
149
            if ($concreteInstance instanceof AdditionalCssInterface) {
150
                $this->defineCssFiles($concreteInstance);
151
            }
152
            if ($concreteInstance instanceof AdditionalJavaScriptInterface) {
153
                $this->defineJsFiles($concreteInstance);
154
            }
155
        }
156
    }
157
158
    /**
159
     * Add the RequireJS modules needed by some widgets
160
     *
161
     * @param RequireJsModuleInterface $widgetInstance
162
     */
163
    protected function defineRequireJsModules(RequireJsModuleInterface $widgetInstance): void
164
    {
165
        foreach ($widgetInstance->getRequireJsModules() as $moduleNameOrIndex => $callbackOrModuleName) {
166
            if (is_string($moduleNameOrIndex)) {
167
                $this->requireJsModules[] = [$moduleNameOrIndex, $callbackOrModuleName];
168
            } else {
169
                $this->requireJsModules[] = $callbackOrModuleName;
170
            }
171
        }
172
    }
173
174
    /**
175
     * Define the correct path of the JS files of a widget and add them to the list of JS files that needs to be
176
     * included
177
     *
178
     * @param AdditionalJavaScriptInterface $widgetInstance
179
     */
180
    protected function defineJsFiles(AdditionalJavaScriptInterface $widgetInstance): void
181
    {
182
        foreach ($widgetInstance->getJsFiles() as $jsFile) {
183
            if (strpos($jsFile, 'EXT:') === 0) {
184
                $jsFile = PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($jsFile));
185
            }
186
            $this->jsFiles[$jsFile] = $jsFile;
187
        }
188
    }
189
190
    /**
191
     * Define the correct path of the CSS files of a widget and add them to the list of CSS files that needs to be
192
     * included
193
     *
194
     * @param AdditionalCssInterface $widgetInstance
195
     */
196
    protected function defineCssFiles(AdditionalCssInterface $widgetInstance): void
197
    {
198
        foreach ($widgetInstance->getCssFiles() as $cssFile) {
199
            if (strpos($cssFile, 'EXT:') === 0) {
200
                $cssFile = PathUtility::getAbsoluteWebPath(GeneralUtility::getFileAbsFileName($cssFile));
201
            }
202
            $this->cssFiles[$cssFile] = $cssFile;
203
        }
204
    }
205
206
    protected function loadCurrentDashboard(BackendUserAuthentication $user): string
207
    {
208
        return $user->getModuleData(self::MODULE_DATA_CURRENT_DASHBOARD_IDENTIFIER) ?? '';
209
    }
210
211
    protected function saveCurrentDashboard(BackendUserAuthentication $user, string $identifier): void
212
    {
213
        $user->pushModuleData(self::MODULE_DATA_CURRENT_DASHBOARD_IDENTIFIER, $identifier);
214
    }
215
216
    /**
217
     * @return array
218
     */
219
    public function getRequireJsModules(): array
220
    {
221
        return $this->requireJsModules;
222
    }
223
224
    /**
225
     * @return array
226
     */
227
    public function getJsFiles(): array
228
    {
229
        return $this->jsFiles;
230
    }
231
232
    /**
233
     * @return array
234
     */
235
    public function getCssFiles(): array
236
    {
237
        return $this->cssFiles;
238
    }
239
}
240