Passed
Push — master ( 97a19b...f2b02b )
by
unknown
43:08 queued 27:22
created

Request::getInternalArgument()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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