Passed
Push — master ( 1f97a6...84f90c )
by
unknown
13:06
created

Request::setMethod()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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