Passed
Push — master ( 6449b0...8fde68 )
by
unknown
15:48
created

ExtbaseRequestParameters::getInternalArgument()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 1
b 0
f 1
cc 2
nc 2
nop 1
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\Extbase\Mvc;
17
18
use TYPO3\CMS\Core\Utility\ClassNamingUtility;
19
use TYPO3\CMS\Core\Utility\GeneralUtility;
20
use TYPO3\CMS\Extbase\Error\Result;
21
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException;
22
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidArgumentNameException;
23
use TYPO3\CMS\Extbase\Mvc\Exception\InvalidControllerNameException;
24
use TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException;
25
26
/**
27
 * Extbase request related state.
28
 * Attached as 'extbase' attribute to PSR-7 ServerRequestInterface.
29
 *
30
 * @internal Set up extbase internally, use TYPO3\CMS\Extbase\Mvc\Request instead.
31
 */
32
class ExtbaseRequestParameters
33
{
34
    /**
35
     * @var string Key of the plugin which identifies the plugin. It must be a string containing [a-z0-9]
36
     */
37
    protected $pluginName = '';
38
39
    /**
40
     * @var string Name of the extension which is supposed to handle this request. This is the extension name converted to UpperCamelCase
41
     *
42
     * @todo: Should probably at least init to empty string.
43
     */
44
    protected $controllerExtensionName;
45
46
    /**
47
     * @var string
48
     *
49
     * @todo: Should probably at least init to empty string.
50
     */
51
    protected $controllerObjectName;
52
53
    /**
54
     * @var string Object name of the controller which is supposed to handle this request.
55
     */
56
    protected $controllerName = 'Standard';
57
58
    /**
59
     * @var string Name of the action the controller is supposed to take.
60
     */
61
    protected $controllerActionName = 'index';
62
63
    /**
64
     * @var array The arguments for this request
65
     */
66
    protected $arguments = [];
67
68
    /**
69
     * Framework-internal arguments for this request, such as __referrer.
70
     * All framework-internal arguments start with double underscore (__),
71
     * and are only used from within the framework. Not for user consumption.
72
     * Internal Arguments can be objects, in contrast to public arguments
73
     *
74
     * @var array
75
     */
76
    protected array $internalArguments = [];
77
78
    /**
79
     * @var string The requested representation format
80
     */
81
    protected $format = 'html';
82
83
    /**
84
     * @var bool If this request has been changed and needs to be dispatched again
85
     * @deprecated since v11, will be removed in v12.
86
     */
87
    protected $dispatched = false;
88
89
    /**
90
     * If this request is a forward because of an error, the original request gets filled.
91
     *
92
     * @var \TYPO3\CMS\Extbase\Mvc\Request|null
93
     */
94
    protected $originalRequest;
95
96
    /**
97
     * If the request is a forward because of an error, these mapping results get filled here.
98
     *
99
     * @var \TYPO3\CMS\Extbase\Error\Result|null
100
     */
101
    protected $originalRequestMappingResults;
102
103
    /**
104
     * Sets the dispatched flag
105
     *
106
     * @param bool $flag If this request has been dispatched
107
     * @deprecated since v11, will be removed in v12.
108
     */
109
    public function setDispatched($flag)
110
    {
111
        $this->dispatched = (bool)$flag;
112
    }
113
114
    /**
115
     * If this request has been dispatched and addressed by the responsible
116
     * controller and the response is ready to be sent.
117
     *
118
     * The dispatcher will try to dispatch the request again if it has not been
119
     * addressed yet.
120
     *
121
     * @return bool TRUE if this request has been dispatched successfully
122
     * @deprecated since v11, will be removed in v12.
123
     */
124
    public function isDispatched()
125
    {
126
        return $this->dispatched;
127
    }
128
129
    /**
130
     * @param string $controllerClassName
131
     */
132
    public function __construct(string $controllerClassName = '')
133
    {
134
        $this->controllerObjectName = $controllerClassName;
135
    }
136
137
    /**
138
     * @return string
139
     */
140
    public function getControllerObjectName(): string
141
    {
142
        return $this->controllerObjectName;
143
    }
144
145
    /**
146
     * Explicitly sets the object name of the controller
147
     *
148
     * @param string $controllerObjectName The fully qualified controller object name
149
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
150
     */
151
    public function setControllerObjectName($controllerObjectName)
152
    {
153
        $nameParts = ClassNamingUtility::explodeObjectControllerName($controllerObjectName);
154
        $this->controllerExtensionName = $nameParts['extensionName'];
155
        $this->controllerName = $nameParts['controllerName'];
156
        return $this;
157
    }
158
159
    /**
160
     * Sets the plugin name.
161
     *
162
     * @param string|null $pluginName
163
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
164
     */
165
    public function setPluginName($pluginName = null)
166
    {
167
        if ($pluginName !== null) {
168
            $this->pluginName = $pluginName;
169
        }
170
        return $this;
171
    }
172
173
    /**
174
     * Returns the plugin key.
175
     *
176
     * @return string The plugin key
177
     */
178
    public function getPluginName()
179
    {
180
        return $this->pluginName;
181
    }
182
183
    /**
184
     * Sets the extension name of the controller.
185
     *
186
     * @param string $controllerExtensionName The extension name.
187
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidExtensionNameException if the extension name is not valid
188
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
189
     */
190
    public function setControllerExtensionName($controllerExtensionName): self
191
    {
192
        if ($controllerExtensionName !== null) {
0 ignored issues
show
introduced by
The condition $controllerExtensionName !== null is always true.
Loading history...
193
            $this->controllerExtensionName = $controllerExtensionName;
194
        }
195
        return $this;
196
    }
197
198
    /**
199
     * Returns the extension name of the specified controller.
200
     *
201
     * @return string The extension name
202
     */
203
    public function getControllerExtensionName()
204
    {
205
        return $this->controllerExtensionName;
206
    }
207
208
    /**
209
     * Returns the extension name of the specified controller.
210
     *
211
     * @return string The extension key
212
     */
213
    public function getControllerExtensionKey()
214
    {
215
        return GeneralUtility::camelCaseToLowerCaseUnderscored($this->controllerExtensionName);
216
    }
217
218
    /**
219
     * @var array
220
     */
221
    protected $controllerAliasToClassNameMapping = [];
222
223
    /**
224
     * @param array $controllerAliasToClassNameMapping
225
     */
226
    public function setControllerAliasToClassNameMapping(array $controllerAliasToClassNameMapping)
227
    {
228
        // this is only needed as long as forwarded requests are altered and unless there
229
        // is no new request object created by the request builder.
230
        $this->controllerAliasToClassNameMapping = $controllerAliasToClassNameMapping;
231
        return $this;
232
    }
233
234
    /**
235
     * Sets the name of the controller which is supposed to handle the request.
236
     * Note: This is not the object name of the controller!
237
     *
238
     * @param string $controllerName Name of the controller
239
     * @throws Exception\InvalidControllerNameException
240
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
241
     */
242
    public function setControllerName($controllerName): self
243
    {
244
        if (!is_string($controllerName) && $controllerName !== null) {
0 ignored issues
show
introduced by
The condition is_string($controllerName) is always true.
Loading history...
245
            throw new InvalidControllerNameException('The controller name must be a valid string, ' . gettype($controllerName) . ' given.', 1187176358);
246
        }
247
        if ($controllerName !== null) {
248
            $this->controllerName = $controllerName;
249
            $this->controllerObjectName = $this->controllerAliasToClassNameMapping[$controllerName] ?? '';
250
            // There might be no Controller Class, for example for Fluid Templates.
251
        }
252
        return $this;
253
    }
254
255
    /**
256
     * Returns the object name of the controller supposed to handle this request, if one
257
     * was set already (if not, the name of the default controller is returned)
258
     *
259
     * @return string Object name of the controller
260
     */
261
    public function getControllerName()
262
    {
263
        return $this->controllerName;
264
    }
265
266
    /**
267
     * Sets the name of the action contained in this request.
268
     *
269
     * Note that the action name must start with a lower case letter and is case sensitive.
270
     *
271
     * @param string $actionName Name of the action to execute by the controller
272
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\InvalidActionNameException if the action name is not valid
273
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
274
     */
275
    public function setControllerActionName($actionName): self
276
    {
277
        if (!is_string($actionName) && $actionName !== null) {
0 ignored issues
show
introduced by
The condition is_string($actionName) is always true.
Loading history...
278
            throw new InvalidActionNameException('The action name must be a valid string, ' . gettype($actionName) . ' given (' . $actionName . ').', 1187176359);
279
        }
280
        if ($actionName[0] !== strtolower($actionName[0]) && $actionName !== null) {
281
            throw new InvalidActionNameException('The action name must start with a lower case letter, "' . $actionName . '" does not match this criteria.', 1218473352);
282
        }
283
        if ($actionName !== null) {
284
            $this->controllerActionName = $actionName;
285
        }
286
        return $this;
287
    }
288
289
    /**
290
     * Returns the name of the action the controller is supposed to execute.
291
     *
292
     * @return string Action name
293
     */
294
    public function getControllerActionName(): string
295
    {
296
        $controllerObjectName = $this->getControllerObjectName();
297
        if ($controllerObjectName !== '' && $this->controllerActionName === strtolower($this->controllerActionName)) {
298
            // todo: this is nonsense! We can detect a non existing method in
299
            // todo: \TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin, if necessary.
300
            // todo: At this point, we want to have a getter for a fixed value.
301
            $actionMethodName = $this->controllerActionName . 'Action';
302
            $classMethods = get_class_methods($controllerObjectName);
303
            if (is_array($classMethods)) {
0 ignored issues
show
introduced by
The condition is_array($classMethods) is always true.
Loading history...
304
                foreach ($classMethods as $existingMethodName) {
305
                    if (strtolower($existingMethodName) === strtolower($actionMethodName)) {
306
                        $this->controllerActionName = substr($existingMethodName, 0, -6);
307
                        break;
308
                    }
309
                }
310
            }
311
        }
312
        return $this->controllerActionName;
313
    }
314
315
    /**
316
     * Sets the value of the specified argument
317
     *
318
     * @param string $argumentName Name of the argument to set
319
     * @param mixed $value The new value
320
     * @throws InvalidArgumentNameException
321
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
322
     */
323
    public function setArgument(string $argumentName, $value): self
324
    {
325
        if ($argumentName === '') {
326
            throw new InvalidArgumentNameException('Invalid argument name.', 1210858767);
327
        }
328
        if ($argumentName[0] === '_' && $argumentName[1] === '_') {
329
            $this->internalArguments[$argumentName] = $value;
330
            return $this;
331
        }
332
        if (!in_array($argumentName, ['@extension', '@subpackage', '@controller', '@action', '@format'], true)) {
333
            $this->arguments[$argumentName] = $value;
334
        }
335
        return $this;
336
    }
337
338
    /**
339
     * Sets the whole arguments array and therefore replaces any arguments
340
     * which existed before.
341
     *
342
     * @param array $arguments An array of argument names and their values
343
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
344
     */
345
    public function setArguments(array $arguments): self
346
    {
347
        $this->arguments = [];
348
        foreach ($arguments as $argumentName => $argumentValue) {
349
            $this->setArgument($argumentName, $argumentValue);
350
        }
351
        return $this;
352
    }
353
354
    /**
355
     * Returns an array of arguments and their values
356
     *
357
     * @return array Associative array of arguments and their values (which may be arguments and values as well)
358
     */
359
    public function getArguments()
360
    {
361
        return $this->arguments;
362
    }
363
364
    /**
365
     * Returns the value of the specified argument
366
     *
367
     * @param string $argumentName Name of the argument
368
     *
369
     * @return string|array Value of the argument
370
     * @throws \TYPO3\CMS\Extbase\Mvc\Exception\NoSuchArgumentException if such an argument does not exist
371
     */
372
    public function getArgument($argumentName)
373
    {
374
        if (!isset($this->arguments[$argumentName])) {
375
            throw new NoSuchArgumentException('An argument "' . $argumentName . '" does not exist for this request.', 1176558158);
376
        }
377
        return $this->arguments[$argumentName];
378
    }
379
380
    /**
381
     * Checks if an argument of the given name exists (is set)
382
     *
383
     * @param string $argumentName Name of the argument to check
384
     *
385
     * @return bool TRUE if the argument is set, otherwise FALSE
386
     */
387
    public function hasArgument($argumentName)
388
    {
389
        return isset($this->arguments[$argumentName]);
390
    }
391
392
    /**
393
     * Sets the requested representation format
394
     *
395
     * @param string $format The desired format, something like "html", "xml", "png", "json" or the like. Can even be something like "rss.xml".
396
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
397
     */
398
    public function setFormat(string $format): self
399
    {
400
        $this->format = $format;
401
        return $this;
402
    }
403
404
    /**
405
     * Returns the requested representation format
406
     *
407
     * @return string The desired format, something like "html", "xml", "png", "json" or the like.
408
     */
409
    public function getFormat()
410
    {
411
        return $this->format;
412
    }
413
414
    /**
415
     * Returns the original request. Filled only if a property mapping error occurred.
416
     *
417
     * @return \TYPO3\CMS\Extbase\Mvc\Request|null the original request.
418
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
419
     */
420
    public function getOriginalRequest(): ?Request
421
    {
422
        return $this->originalRequest;
423
    }
424
425
    /**
426
     * @param \TYPO3\CMS\Extbase\Mvc\Request $originalRequest
427
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
428
     */
429
    public function setOriginalRequest(\TYPO3\CMS\Extbase\Mvc\Request $originalRequest)
430
    {
431
        $this->originalRequest = $originalRequest;
432
    }
433
434
    /**
435
     * Get the request mapping results for the original request.
436
     *
437
     * @return \TYPO3\CMS\Extbase\Error\Result
438
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
439
     */
440
    public function getOriginalRequestMappingResults(): Result
441
    {
442
        if ($this->originalRequestMappingResults === null) {
443
            return new Result();
444
        }
445
        return $this->originalRequestMappingResults;
446
    }
447
448
    /**
449
     * @param \TYPO3\CMS\Extbase\Error\Result $originalRequestMappingResults
450
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
451
     */
452
    public function setOriginalRequestMappingResults(Result $originalRequestMappingResults)
453
    {
454
        $this->originalRequestMappingResults = $originalRequestMappingResults;
455
    }
456
457
    /**
458
     * Get the internal arguments of the request, i.e. every argument starting
459
     * with two underscores.
460
     *
461
     * @return array
462
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
463
     */
464
    public function getInternalArguments(): array
465
    {
466
        return $this->internalArguments;
467
    }
468
469
    /**
470
     * Returns the value of the specified argument
471
     *
472
     * @param string $argumentName Name of the argument
473
     * @return string|null Value of the argument, or NULL if not set.
474
     * @internal only to be used within Extbase, not part of TYPO3 Core API.
475
     */
476
    public function getInternalArgument($argumentName)
477
    {
478
        if (!isset($this->internalArguments[$argumentName])) {
479
            return null;
480
        }
481
        return $this->internalArguments[$argumentName];
482
    }
483
}
484