Passed
Push — master ( 962042...97a19b )
by
unknown
29:59 queued 16:18
created

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