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

DashboardController::addFrontendResources()   A

Complexity

Conditions 5
Paths 12

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 12
nop 1
dl 0
loc 14
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\Controller;
19
20
use Psr\Http\Message\ResponseInterface;
21
use Psr\Http\Message\ServerRequestInterface;
22
use TYPO3\CMS\Backend\Routing\Exception\RouteNotFoundException as RouteNotFoundExceptionAlias;
23
use TYPO3\CMS\Backend\Routing\UriBuilder;
24
use TYPO3\CMS\Backend\Template\ModuleTemplate;
25
use TYPO3\CMS\Core\Http\HtmlResponse;
26
use TYPO3\CMS\Core\Http\RedirectResponse;
27
use TYPO3\CMS\Core\Page\PageRenderer;
28
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Core\Utility\PathUtility;
31
use TYPO3\CMS\Dashboard\Dashboard;
32
use TYPO3\CMS\Dashboard\DashboardInitializationService;
33
use TYPO3\CMS\Dashboard\DashboardPresetRegistry;
34
use TYPO3\CMS\Dashboard\DashboardRepository;
35
use TYPO3\CMS\Dashboard\WidgetGroupInitializationService;
36
use TYPO3\CMS\Extbase\Mvc\View\ViewInterface;
37
use TYPO3\CMS\Fluid\View\StandaloneView;
38
39
/**
40
 * @internal
41
 */
42
class DashboardController extends AbstractController
43
{
44
    /**
45
     * @var ModuleTemplate
46
     */
47
    private $moduleTemplate;
48
49
    /**
50
     * @var UriBuilder
51
     */
52
    protected $uriBuilder;
53
54
    /**
55
     * @var ViewInterface
56
     */
57
    protected $view;
58
59
    /**
60
     * @var Dashboard
61
     */
62
    protected $currentDashboard;
63
64
    /**
65
     * @var DashboardPresetRegistry
66
     */
67
    protected $dashboardPresetRepository;
68
69
    /**
70
     * @var DashboardRepository
71
     */
72
    protected $dashboardRepository;
73
74
    /**
75
     * @var DashboardInitializationService
76
     */
77
    private $dashboardInitializationService;
78
79
    /**
80
     * @var WidgetGroupInitializationService
81
     */
82
    private $widgetGroupInitializationService;
83
84
    public function __construct(
85
        ModuleTemplate $moduleTemplate,
86
        UriBuilder $uriBuilder,
87
        DashboardPresetRegistry $dashboardPresetRepository,
88
        DashboardRepository $dashboardRepository,
89
        DashboardInitializationService $dashboardInitializationService,
90
        WidgetGroupInitializationService $widgetGroupInitializationService
91
    ) {
92
        $this->moduleTemplate = $moduleTemplate;
93
        $this->uriBuilder = $uriBuilder;
94
        $this->dashboardPresetRepository = $dashboardPresetRepository;
95
        $this->dashboardRepository = $dashboardRepository;
96
        $this->dashboardInitializationService = $dashboardInitializationService;
97
98
        $this->dashboardInitializationService->initializeDashboards($this->getBackendUser());
99
        $this->currentDashboard = $this->dashboardInitializationService->getCurrentDashboard();
100
        $this->widgetGroupInitializationService = $widgetGroupInitializationService;
101
    }
102
103
    /**
104
     * This action is responsible for the main view of the dashboard and is just adding all collected data
105
     * to the view
106
     *
107
     * @throws RouteNotFoundExceptionAlias
108
     */
109
    public function mainAction(): void
110
    {
111
        $this->view->assignMultiple([
112
            'availableDashboards' => $this->dashboardInitializationService->getDashboardsForUser(),
113
            'dashboardPresets' => $this->dashboardPresetRepository->getDashboardPresets(),
114
            'widgetGroups' => $this->widgetGroupInitializationService->buildWidgetGroupsConfiguration(),
115
            'currentDashboard' => $this->currentDashboard,
116
            'addWidgetUri' => (string)$this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'addWidget']),
117
            'addDashboardUri' => (string)$this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'addDashboard']),
118
            'deleteDashboardUri' => (string)$this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'deleteDashboard']),
119
            'configureDashboardUri' => (string)$this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'configureDashboard']),
120
        ]);
121
    }
122
123
    /**
124
     * Main entry method: Dispatch to other actions - those method names that end with "Action".
125
     *
126
     * @param ServerRequestInterface $request the current request
127
     * @return ResponseInterface the response with the content
128
     */
129
    public function handleRequest(ServerRequestInterface $request): ResponseInterface
130
    {
131
        $pageRenderer = $this->moduleTemplate->getPageRenderer();
132
        $this->preparePageRenderer($pageRenderer);
133
134
        $action = $request->getQueryParams()['action'] ?? $request->getParsedBody()['action'] ?? 'main';
135
        $this->initializeView('Dashboard/' . ucfirst($action));
136
        $result = $this->{$action . 'Action'}($request);
137
        if ($result instanceof ResponseInterface) {
138
            return $result;
139
        }
140
        $this->addFrontendResources($pageRenderer);
141
        $this->moduleTemplate->setContent($this->view->render());
142
        return new HtmlResponse($this->moduleTemplate->renderContent());
143
    }
144
145
    /**
146
     * @param ServerRequestInterface $request
147
     * @return ResponseInterface
148
     * @throws RouteNotFoundExceptionAlias
149
     */
150
    public function configureDashboardAction(ServerRequestInterface $request): ResponseInterface
151
    {
152
        $parameters = $request->getParsedBody();
153
        $currentDashboard = $parameters['currentDashboard'] ?? '';
154
        $route = $this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main'], UriBuilder::ABSOLUTE_URL);
155
156
        if ($currentDashboard !== '' && isset($parameters['dashboard'])) {
157
            $this->dashboardRepository->updateDashboardSettings($currentDashboard, $parameters['dashboard']);
158
        }
159
160
        return new RedirectResponse($route);
161
    }
162
163
    /**
164
     * @param ServerRequestInterface $request
165
     * @return ResponseInterface
166
     * @throws RouteNotFoundExceptionAlias
167
     */
168
    public function setActiveDashboardAction(ServerRequestInterface $request): ResponseInterface
169
    {
170
        $this->saveCurrentDashboard($request->getQueryParams()['currentDashboard']);
171
        $route = $this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']);
172
        return new RedirectResponse($route);
173
    }
174
175
    /**
176
     * @param ServerRequestInterface $request
177
     * @return ResponseInterface
178
     * @throws RouteNotFoundExceptionAlias
179
     */
180
    public function addDashboardAction(ServerRequestInterface $request): ResponseInterface
181
    {
182
        $parameters = $request->getParsedBody();
183
        $dashboardIdentifier = $parameters['dashboard'] ?? '';
184
185
        if ($dashboardIdentifier !== '') {
186
            $dashboard = $this->dashboardRepository->create($this->dashboardPresetRepository->getDashboardPresets()[$dashboardIdentifier], (int)$this->getBackendUser()->user['uid'], $parameters['dashboard-title']);
187
188
            if ($dashboard instanceof Dashboard) {
189
                $this->saveCurrentDashboard($dashboard->getIdentifier());
190
            }
191
        }
192
193
        return new RedirectResponse($this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']));
194
    }
195
196
    /**
197
     * @return ResponseInterface
198
     * @throws RouteNotFoundExceptionAlias
199
     */
200
    public function deleteDashboardAction(): ResponseInterface
201
    {
202
        $this->dashboardRepository->delete($this->currentDashboard);
203
        return new RedirectResponse($this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']));
204
    }
205
206
    /**
207
     * @param ServerRequestInterface $request
208
     * @return ResponseInterface
209
     * @throws RouteNotFoundExceptionAlias
210
     */
211
    public function addWidgetAction(ServerRequestInterface $request): ResponseInterface
212
    {
213
        $parameters = $request->getQueryParams();
214
        $widgetKey = $parameters['widget'];
215
216
        if ($widgetKey) {
217
            $widgets = $this->currentDashboard->getWidgetConfig();
218
            $hash = sha1($widgetKey . '-' . time());
219
            $widgets[$hash] = ['identifier' => $widgetKey];
220
            $this->dashboardRepository->updateWidgetConfig($this->currentDashboard, $widgets);
221
        }
222
223
        $route = $this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']);
224
        return new RedirectResponse($route);
225
    }
226
227
    /**
228
     * @param ServerRequestInterface $request
229
     * @return ResponseInterface
230
     * @throws RouteNotFoundExceptionAlias
231
     */
232
    public function removeWidgetAction(ServerRequestInterface $request): ResponseInterface
233
    {
234
        $parameters = $request->getQueryParams();
235
        $widgetHash = $parameters['widgetHash'];
236
        $widgets = $this->currentDashboard->getWidgetConfig();
237
238
        if (array_key_exists($widgetHash, $widgets)) {
239
            unset($widgets[$widgetHash]);
240
            $this->dashboardRepository->updateWidgetConfig($this->currentDashboard, $widgets);
241
        }
242
        $route = $this->uriBuilder->buildUriFromRoute('dashboard', ['action' => 'main']);
243
        return new RedirectResponse($route);
244
    }
245
246
    /**
247
     * Sets up the Fluid View.
248
     *
249
     * @param string $templateName
250
     */
251
    protected function initializeView(string $templateName): void
252
    {
253
        $this->view = GeneralUtility::makeInstance(StandaloneView::class);
254
        $this->view->setTemplate($templateName);
255
256
        $this->view->getRenderingContext()->getTemplatePaths()->fillDefaultsByPackageName('dashboard');
257
        $this->moduleTemplate->getDocHeaderComponent()->disable();
258
    }
259
260
    /**
261
     * Adds CSS and JS files that are necessary for widgets to the page renderer
262
     *
263
     * @param PageRenderer $pageRenderer
264
     */
265
    protected function addFrontendResources(PageRenderer $pageRenderer): void
266
    {
267
        foreach ($this->dashboardInitializationService->getRequireJsModules() as $requireJsModule) {
268
            if (is_array($requireJsModule)) {
269
                $pageRenderer->loadRequireJsModule($requireJsModule[0], $requireJsModule[1]);
270
            } else {
271
                $pageRenderer->loadRequireJsModule($requireJsModule);
272
            }
273
        }
274
        foreach ($this->dashboardInitializationService->getCssFiles() as $cssFile) {
275
            $pageRenderer->addCssFile($cssFile);
276
        }
277
        foreach ($this->dashboardInitializationService->getJsFiles() as $jsFile) {
278
            $pageRenderer->addJsFile($jsFile);
279
        }
280
    }
281
282
    /**
283
     * Add the CSS and JS of the dashboard module to the page renderer
284
     *
285
     * @param PageRenderer $pageRenderer
286
     */
287
    protected function preparePageRenderer(PageRenderer $pageRenderer): void
288
    {
289
        $publicResourcesPath =
290
            PathUtility::getAbsoluteWebPath(ExtensionManagementUtility::extPath('dashboard')) . 'Resources/Public/';
291
292
        $pageRenderer->addRequireJsConfiguration(
293
            [
294
                'paths' => [
295
                    'muuri' => $publicResourcesPath . 'JavaScript/Contrib/muuri',
296
                    'web-animate' => $publicResourcesPath . 'JavaScript/Contrib/web-animate',
297
                ],
298
            ]
299
        );
300
301
        $pageRenderer->loadRequireJsModule('muuri');
302
        $pageRenderer->loadRequireJsModule('web-animate');
303
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/Grid');
304
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/WidgetContentCollector');
305
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/WidgetSelector');
306
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/WidgetRemover');
307
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/DashboardModal');
308
        $pageRenderer->loadRequireJsModule('TYPO3/CMS/Dashboard/DashboardDelete');
309
        $pageRenderer->addCssFile($publicResourcesPath . 'Css/dashboard.css');
310
    }
311
}
312