Passed
Push — master ( d5a28b...d12ca0 )
by
unknown
17:01
created

FileUploadController::getLanguageService()   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
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\Filelist\Controller\File;
19
20
use Psr\Http\Message\ResponseInterface;
21
use Psr\Http\Message\ServerRequestInterface;
22
use TYPO3\CMS\Backend\Routing\UriBuilder;
23
use TYPO3\CMS\Backend\Template\ModuleTemplate;
24
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
25
use TYPO3\CMS\Core\Http\HtmlResponse;
26
use TYPO3\CMS\Core\Imaging\Icon;
27
use TYPO3\CMS\Core\Imaging\IconFactory;
28
use TYPO3\CMS\Core\Localization\LanguageService;
29
use TYPO3\CMS\Core\Page\PageRenderer;
30
use TYPO3\CMS\Core\Resource\Exception\InsufficientFolderAccessPermissionsException;
31
use TYPO3\CMS\Core\Resource\ResourceFactory;
32
use TYPO3\CMS\Core\Utility\GeneralUtility;
33
34
/**
35
 * Script Class for display up to 10 upload fields
36
 * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
37
 */
38
class FileUploadController
39
{
40
    /**
41
     * Set with the target path inputted in &target
42
     *
43
     * @var string
44
     */
45
    protected $target;
46
47
    /**
48
     * Return URL of list module.
49
     *
50
     * @var string
51
     */
52
    protected $returnUrl;
53
54
    /**
55
     * Accumulating content
56
     *
57
     * @var string
58
     */
59
    protected $content;
60
61
    /**
62
     * The folder object which is the target directory for the upload
63
     *
64
     * @var \TYPO3\CMS\Core\Resource\Folder $folderObject
65
     */
66
    protected $folderObject;
67
68
    /**
69
     * ModuleTemplate object
70
     *
71
     * @var ModuleTemplate
72
     */
73
    protected $moduleTemplate;
74
75
    protected IconFactory $iconFactory;
76
    protected PageRenderer $pageRenderer;
77
    protected UriBuilder $uriBuilder;
78
    protected ResourceFactory $resourceFactory;
79
    protected ModuleTemplateFactory $moduleTemplateFactory;
80
81
    public function __construct(
82
        IconFactory $iconFactory,
83
        PageRenderer $pageRenderer,
84
        UriBuilder $uriBuilder,
85
        ResourceFactory $resourceFactory,
86
        ModuleTemplateFactory $moduleTemplateFactory
87
    ) {
88
        $this->iconFactory = $iconFactory;
89
        $this->pageRenderer = $pageRenderer;
90
        $this->uriBuilder = $uriBuilder;
91
        $this->resourceFactory = $resourceFactory;
92
        $this->moduleTemplateFactory = $moduleTemplateFactory;
93
    }
94
95
    /**
96
     * Processes the request, currently everything is handled and put together via "renderContent()"
97
     *
98
     * @param ServerRequestInterface $request the current request
99
     * @return ResponseInterface the response with the content
100
     */
101
    public function mainAction(ServerRequestInterface $request): ResponseInterface
102
    {
103
        $this->moduleTemplate = $this->moduleTemplateFactory->create($request);
104
        $this->getLanguageService()->includeLLFile('EXT:core/Resources/Private/Language/locallang_misc.xlf');
105
        $this->init($request);
106
        $this->renderContent();
107
        return new HtmlResponse($this->moduleTemplate->renderContent());
108
    }
109
110
    /**
111
     * Initialize
112
     *
113
     * @param ServerRequestInterface $request
114
     * @throws InsufficientFolderAccessPermissionsException
115
     */
116
    protected function init(ServerRequestInterface $request): void
117
    {
118
        $parsedBody = $request->getParsedBody();
119
        $queryParams = $request->getQueryParams();
120
121
        // Initialize GPvars:
122
        $this->target = $parsedBody['target'] ?? $queryParams['target'] ?? null;
123
        $this->returnUrl = GeneralUtility::sanitizeLocalUrl($parsedBody['returnUrl'] ?? $queryParams['returnUrl'] ?? '');
124
        if (!$this->returnUrl) {
125
            $this->returnUrl = (string)$this->uriBuilder->buildUriFromRoute('file_list', [
126
                'id' => rawurlencode($this->target)
0 ignored issues
show
Bug introduced by
It seems like $this->target can also be of type null; however, parameter $string of rawurlencode() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

126
                'id' => rawurlencode(/** @scrutinizer ignore-type */ $this->target)
Loading history...
127
            ]);
128
        }
129
        // Create the folder object
130
        if ($this->target) {
131
            $this->folderObject = $this->resourceFactory->retrieveFileOrFolderObject($this->target);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->resourceFactory->...erObject($this->target) can also be of type TYPO3\CMS\Core\Resource\File. However, the property $folderObject is declared as type TYPO3\CMS\Core\Resource\Folder. 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...
132
        }
133
        if ($this->folderObject->getStorage()->getUid() === 0) {
134
            throw new InsufficientFolderAccessPermissionsException(
135
                'You are not allowed to access folders outside your storages',
136
                1375889834
137
            );
138
        }
139
140
        // Cleaning and checking target directory
141
        if (!$this->folderObject) {
142
            $title = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:paramError');
143
            $message = $this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang_mod_file_list.xlf:targetNoDir');
144
            throw new \RuntimeException($title . ': ' . $message, 1294586843);
145
        }
146
147
        // Setting up the context sensitive menu
148
        $this->pageRenderer->loadRequireJsModule('TYPO3/CMS/Backend/ContextMenu');
149
150
        // building pathInfo for metaInformation
151
        $pathInfo = [
152
            'combined_identifier' => $this->folderObject->getCombinedIdentifier(),
153
        ];
154
        $this->moduleTemplate->getDocHeaderComponent()->setMetaInformation($pathInfo);
155
    }
156
157
    /**
158
     * Render module content
159
     */
160
    protected function renderContent(): void
161
    {
162
        $lang = $this->getLanguageService();
163
164
        // set page title
165
        $this->moduleTemplate->setTitle($lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.pagetitle'));
166
167
        $pageContent = '<form action="'
168
            . htmlspecialchars((string)$this->uriBuilder->buildUriFromRoute('tce_file'))
169
            . '" method="post" id="FileUploadController" name="editform" enctype="multipart/form-data">';
170
        // Make page header:
171
        $pageContent .= '<h1>' . $lang->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.pagetitle') . '</h1>';
172
        $pageContent .= $this->renderUploadFormInternal();
173
174
        // Header Buttons
175
        $buttonBar = $this->moduleTemplate->getDocHeaderComponent()->getButtonBar();
176
177
        // csh button
178
        $cshButton = $buttonBar->makeHelpButton()
179
            ->setModuleName('xMOD_csh_corebe')
180
            ->setFieldName('file_upload');
181
        $buttonBar->addButton($cshButton);
182
183
        // back button
184
        if ($this->returnUrl) {
185
            $backButton = $buttonBar->makeLinkButton()
186
                ->setHref($this->returnUrl)
187
                ->setTitle($lang->sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.goBack'))
188
                ->setIcon($this->iconFactory->getIcon('actions-view-go-back', Icon::SIZE_SMALL));
189
            $buttonBar->addButton($backButton);
190
        }
191
192
        $pageContent .= '</form>';
193
        $this->content .= '<div>' . $pageContent . '</div>';
194
        $this->moduleTemplate->setContent($this->content);
195
    }
196
197
    /**
198
     * This function renders the upload form
199
     *
200
     * @return string The HTML form as a string, ready for outputting
201
     */
202
    protected function renderUploadFormInternal(): string
203
    {
204
        $content = '
205
            <div class="form-group">
206
                <input type="file" multiple="multiple" class="form-control" name="upload_1[]" />
207
                <input type="hidden" name="data[upload][1][target]" value="' . htmlspecialchars($this->folderObject->getCombinedIdentifier()) . '" />
208
                <input type="hidden" name="data[upload][1][data]" value="1" />
209
            </div>
210
            <div class="form-check">
211
                <input class="form-check-input" type="checkbox" name="overwriteExistingFiles" id="overwriteExistingFiles" value="replace" />
212
                <label class="form-check-label" for="overwriteExistingFiles"> ' . htmlspecialchars($this->getLanguageService()->getLL('overwriteExistingFiles')) . '</label>
213
            </div>
214
            <div>
215
                <input type="hidden" name="data[upload][1][redirect]" value="' . $this->returnUrl . '" />
216
                <input class="btn btn-primary" type="submit" value="' . htmlspecialchars($this->getLanguageService()->sL('LLL:EXT:filelist/Resources/Private/Language/locallang.xlf:file_upload.php.submit')) . '" />
217
            </div>
218
            <div class="callout callout-warning">
219
              ' . htmlspecialchars($this->getLanguageService()->getLL('uploadMultipleFilesInfo')) . '
220
            </div>
221
        ';
222
223
        return $content;
224
    }
225
226
    /**
227
     * @return LanguageService
228
     */
229
    protected function getLanguageService(): LanguageService
230
    {
231
        return $GLOBALS['LANG'];
232
    }
233
}
234