Completed
Branch master (d17104)
by Christian
21:20
created

MainController::initializeModules()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 7
eloc 9
nc 5
nop 2
dl 0
loc 14
rs 8.8333
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
4
namespace TYPO3\CMS\Adminpanel\Controller;
5
6
/*
7
 * This file is part of the TYPO3 CMS project.
8
 *
9
 * It is free software; you can redistribute it and/or modify it under
10
 * the terms of the GNU General Public License, either version 2
11
 * of the License, or any later version.
12
 *
13
 * For the full copyright and license information, please read the
14
 * LICENSE.txt file that was distributed with this source code.
15
 *
16
 * The TYPO3 project - inspiring people to share!
17
 */
18
19
use Psr\Http\Message\ServerRequestInterface;
20
use TYPO3\CMS\Adminpanel\ModuleApi\ConfigurableInterface;
21
use TYPO3\CMS\Adminpanel\ModuleApi\DataProviderInterface;
22
use TYPO3\CMS\Adminpanel\ModuleApi\InitializableInterface;
23
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleDataStorageCollection;
24
use TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface;
25
use TYPO3\CMS\Adminpanel\ModuleApi\PageSettingsProviderInterface;
26
use TYPO3\CMS\Adminpanel\ModuleApi\ShortInfoProviderInterface;
27
use TYPO3\CMS\Adminpanel\ModuleApi\SubmoduleProviderInterface;
28
use TYPO3\CMS\Adminpanel\Service\ConfigurationService;
29
use TYPO3\CMS\Adminpanel\Service\ModuleLoader;
30
use TYPO3\CMS\Adminpanel\Utility\ResourceUtility;
31
use TYPO3\CMS\Adminpanel\Utility\StateUtility;
32
use TYPO3\CMS\Adminpanel\View\AdminPanelView;
33
use TYPO3\CMS\Backend\Routing\UriBuilder;
34
use TYPO3\CMS\Core\Cache\CacheManager;
35
use TYPO3\CMS\Core\SingletonInterface;
36
use TYPO3\CMS\Core\Utility\GeneralUtility;
37
use TYPO3\CMS\Fluid\View\StandaloneView;
38
39
/**
40
 * Main controller for the admin panel
41
 *
42
 * @internal
43
 */
44
class MainController implements SingletonInterface
45
{
46
    /**
47
     * @var \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[]
48
     */
49
    protected $modules = [];
50
51
    /**
52
     * @var ModuleLoader
53
     */
54
    protected $moduleLoader;
55
56
    /**
57
     * @var UriBuilder
58
     */
59
    protected $uriBuilder;
60
61
    /**
62
     * @var ConfigurationService
63
     */
64
    protected $configurationService;
65
66
    /**
67
     * @var array
68
     */
69
    protected $adminPanelModuleConfiguration;
70
71
    /**
72
     * @param ModuleLoader $moduleLoader
73
     * @param UriBuilder $uriBuilder
74
     * @param ConfigurationService $configurationService
75
     */
76
    public function __construct(
77
        ModuleLoader $moduleLoader = null,
78
        UriBuilder $uriBuilder = null,
79
        ConfigurationService $configurationService = null
80
    ) {
81
        $this->moduleLoader = $moduleLoader ?? GeneralUtility::makeInstance(ModuleLoader::class);
82
        $this->uriBuilder = $uriBuilder ?? GeneralUtility::makeInstance(UriBuilder::class);
83
        $this->configurationService = $configurationService
84
                                      ??
85
                                      GeneralUtility::makeInstance(ConfigurationService::class);
86
        $this->adminPanelModuleConfiguration = $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules'] ?? [];
87
    }
88
89
    /**
90
     * Initializes settings for the admin panel.
91
     *
92
     * @param ServerRequestInterface $request
93
     */
94
    public function initialize(ServerRequestInterface $request): void
95
    {
96
        $this->modules = $this->moduleLoader->validateSortAndInitializeModules(
97
            $this->adminPanelModuleConfiguration
98
        );
99
100
        if (StateUtility::isActivatedForUser()) {
101
            $this->initializeModules($request, $this->modules);
102
        }
103
    }
104
105
    /**
106
     * Renders the admin panel - Called in PSR-15 Middleware
107
     *
108
     * @see \TYPO3\CMS\Adminpanel\Middleware\AdminPanelRenderer
109
     * @param \Psr\Http\Message\ServerRequestInterface $request
110
     * @return string
111
     */
112
    public function render(ServerRequestInterface $request): string
113
    {
114
        // legacy handling, deprecated, will be removed in TYPO3 v10.0.
115
        $adminPanelView = GeneralUtility::makeInstance(AdminPanelView::class);
116
        $hookObjectContent = $adminPanelView->callDeprecatedHookObject();
117
        // end legacy handling
118
119
        $resources = ResourceUtility::getResources();
120
121
        $view = GeneralUtility::makeInstance(StandaloneView::class);
122
        $templateNameAndPath = 'EXT:adminpanel/Resources/Private/Templates/Main.html';
123
        $view->setTemplatePathAndFilename(GeneralUtility::getFileAbsFileName($templateNameAndPath));
124
        $view->setPartialRootPaths(['EXT:adminpanel/Resources/Private/Partials']);
125
        $view->setLayoutRootPaths(['EXT:adminpanel/Resources/Private/Layouts']);
126
127
        $view->assignMultiple(
128
            [
129
                'toggleActiveUrl' => $this->generateBackendUrl('ajax_adminPanel_toggle'),
130
                'resources' => $resources,
131
                'adminPanelActive' => StateUtility::isOpen(),
132
            ]
133
        );
134
        if (StateUtility::isOpen()) {
135
            $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('adminpanel_requestcache');
136
            $requestId = $request->getAttribute('adminPanelRequestId');
137
            $data = $cache->get($requestId);
138
            $moduleResources = ResourceUtility::getAdditionalResourcesForModules($this->modules);
139
            $settingsModules = array_filter($this->modules, function (ModuleInterface $module) {
140
                return $module instanceof PageSettingsProviderInterface;
141
            });
142
            $parentModules = array_filter(
143
                $this->modules,
144
                function (ModuleInterface $module) {
145
                    return $module instanceof SubmoduleProviderInterface && $module instanceof ShortInfoProviderInterface;
146
                }
147
            );
148
            $view->assignMultiple(
149
                [
150
                    'modules' => $this->modules,
151
                    'settingsModules' => $settingsModules,
152
                    'parentModules' => $parentModules,
153
                    'hookObjectContent' => $hookObjectContent,
154
                    'saveUrl' => $this->generateBackendUrl('ajax_adminPanel_saveForm'),
155
                    'moduleResources' => $moduleResources,
156
                    'requestId' => $requestId,
157
                    'data' => $data ?? [],
158
                ]
159
            );
160
        }
161
        return $view->render();
162
    }
163
164
    /**
165
     * Stores data for admin panel in cache - Called in PSR-15 Middleware
166
     *
167
     * @see \TYPO3\CMS\Adminpanel\Middleware\AdminPanelDataPersister
168
     * @param \Psr\Http\Message\ServerRequestInterface $request
169
     * @throws \TYPO3\CMS\Core\Cache\Exception\NoSuchCacheException
170
     */
171
    public function storeData(ServerRequestInterface $request): void
172
    {
173
        if (StateUtility::isOpen()) {
174
            $data = $this->storeDataPerModule(
175
                $request,
176
                $this->modules,
177
                GeneralUtility::makeInstance(ModuleDataStorageCollection::class)
178
            );
179
            $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('adminpanel_requestcache');
180
            $cache->set($request->getAttribute('adminPanelRequestId'), $data);
181
            $cache->collectGarbage();
182
        }
183
    }
184
185
    /**
186
     * Generate a url to a backend route
187
     *
188
     * @param string $route
189
     * @return string
190
     */
191
    protected function generateBackendUrl(string $route): string
192
    {
193
        return (string)$this->uriBuilder->buildUriFromRoute($route);
194
    }
195
196
    /**
197
     * @param \Psr\Http\Message\ServerRequestInterface $request
198
     * @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $modules
199
     */
200
    protected function initializeModules(ServerRequestInterface $request, array $modules): void
201
    {
202
        foreach ($modules as $module) {
203
            if (
204
                ($module instanceof InitializableInterface)
205
                && (
206
                    (($module instanceof ConfigurableInterface) && $module->isEnabled())
207
                    || (!($module instanceof ConfigurableInterface))
208
                )
209
            ) {
210
                $module->initializeModule($request);
211
            }
212
            if ($module instanceof SubmoduleProviderInterface) {
213
                $this->initializeModules($request, $module->getSubModules());
214
            }
215
        }
216
    }
217
218
    /**
219
     * @param \Psr\Http\Message\ServerRequestInterface $request
220
     * @param \TYPO3\CMS\Adminpanel\ModuleApi\ModuleInterface[] $modules
221
     * @param ModuleDataStorageCollection $data
222
     * @return ModuleDataStorageCollection
223
     */
224
    protected function storeDataPerModule(ServerRequestInterface $request, array $modules, ModuleDataStorageCollection $data): ModuleDataStorageCollection
225
    {
226
        foreach ($modules as $module) {
227
            if (
228
                ($module instanceof DataProviderInterface)
229
                && (
230
                    (($module instanceof ConfigurableInterface) && $module->isEnabled())
231
                    || (!($module instanceof ConfigurableInterface))
232
                )
233
            ) {
234
                $data->addModuleData($module, $module->getDataToStore($request));
235
            }
236
237
            if ($module instanceof SubmoduleProviderInterface) {
238
                $this->storeDataPerModule($request, $module->getSubModules(), $data);
239
            }
240
        }
241
        return $data;
242
    }
243
}
244