Passed
Push — master ( ff1a76...9dbd27 )
by
unknown
13:17
created

RecyclerModuleController::getBackendUser()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
/*
4
 * This file is part of the TYPO3 CMS project.
5
 *
6
 * It is free software; you can redistribute it and/or modify it under
7
 * the terms of the GNU General Public License, either version 2
8
 * of the License, or any later version.
9
 *
10
 * For the full copyright and license information, please read the
11
 * LICENSE.txt file that was distributed with this source code.
12
 *
13
 * The TYPO3 project - inspiring people to share!
14
 */
15
16
namespace TYPO3\CMS\Recycler\Controller;
17
18
use Psr\Http\Message\ResponseInterface;
19
use Psr\Http\Message\ServerRequestInterface;
20
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
21
use TYPO3\CMS\Backend\Template\ModuleTemplate;
22
use TYPO3\CMS\Backend\Utility\BackendUtility;
23
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
24
use TYPO3\CMS\Core\Http\HtmlResponse;
25
use TYPO3\CMS\Core\Http\NormalizedParams;
26
use TYPO3\CMS\Core\Imaging\Icon;
27
use TYPO3\CMS\Core\Localization\LanguageService;
28
use TYPO3\CMS\Core\Type\Bitmask\Permission;
29
use TYPO3\CMS\Core\Utility\GeneralUtility;
30
use TYPO3\CMS\Core\Utility\MathUtility;
31
use TYPO3\CMS\Fluid\View\StandaloneView;
32
33
/**
34
 * Backend Module for the 'recycler' extension.
35
 * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
36
 */
37
class RecyclerModuleController
38
{
39
40
    /**
41
     * @var array
42
     */
43
    protected $pageRecord = [];
44
45
    /**
46
     * @var bool
47
     */
48
    protected $isAccessibleForCurrentUser = false;
49
50
    /**
51
     * @var bool
52
     */
53
    protected $allowDelete = false;
54
55
    /**
56
     * @var int
57
     */
58
    protected $recordsPageLimit = 50;
59
60
    /**
61
     * @var int
62
     */
63
    protected $id;
64
65
    /**
66
     * @var StandaloneView
67
     */
68
    protected $view;
69
70
    /**
71
     * @var ModuleTemplate
72
     */
73
    protected $moduleTemplate;
74
75
    /**
76
     * Injects the request object for the current request, and renders correct action
77
     *
78
     * @param ServerRequestInterface $request the current request
79
     * @return ResponseInterface the response with the content
80
     */
81
    public function handleRequest(ServerRequestInterface $request): ResponseInterface
82
    {
83
        $this->id = (int)($request->getQueryParams()['id'] ?? $request->getParsedBody()['id'] ?? 0);
84
        $backendUser = $this->getBackendUser();
85
        $this->pageRecord = BackendUtility::readPageAccess($this->id, $backendUser->getPagePermsClause(Permission::PAGE_SHOW));
0 ignored issues
show
Documentation Bug introduced by
It seems like TYPO3\CMS\Backend\Utilit...Permission::PAGE_SHOW)) can also be of type false. However, the property $pageRecord is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
86
        $this->isAccessibleForCurrentUser = $this->id && is_array($this->pageRecord) || !$this->id && $this->getBackendUser()->isAdmin();
0 ignored issues
show
introduced by
Consider adding parentheses for clarity. Current Interpretation: $this->isAccessibleForCu...ckendUser()->isAdmin()), Probably Intended Meaning: $this->isAccessibleForCu...ckendUser()->isAdmin())
Loading history...
87
        $this->moduleTemplate = GeneralUtility::makeInstance(ModuleTemplate::class);
88
89
        // don't access in workspace
90
        if ($backendUser->workspace !== 0) {
91
            $this->isAccessibleForCurrentUser = false;
92
        }
93
94
        // read configuration
95
        if ($backendUser->isAdmin()) {
96
            $this->allowDelete = true;
97
        } else {
98
            $this->allowDelete = (bool)($backendUser->getTSConfig()['mod.']['recycler.']['allowDelete'] ?? false);
99
        }
100
101
        $this->recordsPageLimit = MathUtility::forceIntegerInRange(
102
            (int)($backendUser->getTSConfig()['mod.']['recycler.']['recordsPageLimit'] ?? 25),
103
            1
104
        );
105
106
        $action = 'index';
107
        $this->initializeView($action);
108
109
        $result = call_user_func_array([$this, $action . 'Action'], [$request]);
110
        if ($result instanceof ResponseInterface) {
111
            return $result;
112
        }
113
114
        $this->registerDocheaderButtons($request->getQueryParams()['route']);
115
116
        $this->moduleTemplate->setContent($this->view->render());
117
        return new HtmlResponse($this->moduleTemplate->renderContent());
118
    }
119
120
    /**
121
     * @param string $templateName
122
     */
123
    protected function initializeView(string $templateName)
124
    {
125
        $this->view = GeneralUtility::makeInstance(StandaloneView::class);
126
        $this->view->setTemplate($templateName);
127
        $this->view->setTemplateRootPaths(['EXT:recycler/Resources/Private/Templates/RecyclerModule']);
128
        $this->view->setPartialRootPaths(['EXT:recycler/Resources/Private/Partials']);
129
        $this->view->setLayoutRootPaths(['EXT:recycler/Resources/Private/Layouts']);
130
        $this->view->getRequest()->setControllerExtensionName('Recycler');
131
    }
132
133
    /**
134
     * Renders the content of the module.
135
     *
136
     * @param ServerRequestInterface $request
137
     */
138
    public function indexAction(ServerRequestInterface $request)
139
    {
140
        $this->moduleTemplate->getPageRenderer()->addInlineSettingArray('Recycler', $this->getJavaScriptConfiguration($request->getAttribute('normalizedParams')));
141
        $this->moduleTemplate->getPageRenderer()->addInlineLanguageLabelFile('EXT:recycler/Resources/Private/Language/locallang.xlf');
142
        if ($this->isAccessibleForCurrentUser) {
143
            $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($this->pageRecord);
144
        }
145
146
        $this->view->assign('allowDelete', $this->allowDelete);
147
    }
148
149
    /**
150
     * Registers the Icons into the docheader
151
     *
152
     * @param string $route
153
     * @throws \InvalidArgumentException
154
     */
155
    protected function registerDocheaderButtons(string $route)
156
    {
157
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
158
159
        $shortcutButton = $buttonBar->makeShortcutButton()
160
            ->setModuleName('web_RecyclerRecycler')
161
            ->setDisplayName($this->getShortcutTitle())
162
            ->setArguments([
163
                'route' => $route,
164
                'id' => (int)$this->id
165
            ]);
166
        $buttonBar->addButton($shortcutButton);
167
168
        $reloadButton = $buttonBar->makeLinkButton()
169
            ->setHref('#')
170
            ->setDataAttributes(['action' => 'reload'])
171
            ->setTitle($this->getLanguageService()->sL('LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:button.reload'))
172
            ->setIcon($this->moduleTemplate->getIconFactory()->getIcon('actions-refresh', Icon::SIZE_SMALL));
173
        $buttonBar->addButton($reloadButton, ButtonBar::BUTTON_POSITION_RIGHT);
174
    }
175
176
    /**
177
     * Gets the JavaScript configuration.
178
     *
179
     * @param NormalizedParams $normalizedParams
180
     * @return array The JavaScript configuration
181
     */
182
    protected function getJavaScriptConfiguration(NormalizedParams $normalizedParams): array
183
    {
184
        return [
185
            'pagingSize' => $this->recordsPageLimit,
186
            'showDepthMenu' => true,
187
            'startUid' => $this->id,
188
            'isSSL' => $normalizedParams->isHttps(),
189
            'deleteDisable' => !$this->allowDelete,
190
            'depthSelection' => $this->getDataFromSession('depthSelection', '0'),
191
            'tableSelection' => $this->getDataFromSession('tableSelection', ''),
192
            'States' => $this->getBackendUser()->uc['moduleData']['web_recycler']['States']
193
        ];
194
    }
195
196
    /**
197
     * Gets data from the session of the current backend user.
198
     *
199
     * @param string $identifier The identifier to be used to get the data
200
     * @param string $default The default date to be used if nothing was found in the session
201
     * @return string The accordant data in the session of the current backend user
202
     */
203
    protected function getDataFromSession($identifier, $default = null)
204
    {
205
        $sessionData = &$this->getBackendUser()->uc['tx_recycler'];
206
        if (isset($sessionData[$identifier]) && $sessionData[$identifier]) {
207
            $data = $sessionData[$identifier];
208
        } else {
209
            $data = $default;
210
        }
211
        return $data;
212
    }
213
214
    /**
215
     * Returns the shortcut title for the current page
216
     *
217
     * @return string
218
     */
219
    protected function getShortcutTitle(): string
220
    {
221
        return sprintf(
222
            '%s: %s [%d]',
223
            $this->getLanguageService()->sL('LLL:EXT:recycler/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab'),
224
            BackendUtility::getRecordTitle('pages', $this->pageRecord),
225
            $this->id
226
        );
227
    }
228
229
    /**
230
     * Returns the current BE user.
231
     *
232
     * @return BackendUserAuthentication
233
     */
234
    protected function getBackendUser(): BackendUserAuthentication
235
    {
236
        return $GLOBALS['BE_USER'];
237
    }
238
239
    /**
240
     * Returns an instance of LanguageService
241
     *
242
     * @return LanguageService
243
     */
244
    protected function getLanguageService(): LanguageService
245
    {
246
        return $GLOBALS['LANG'];
247
    }
248
}
249