Passed
Push — master ( ca2bcf...ce616a )
by
unknown
24:29 queued 10:31
created

Request::getRequestUri()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

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