Passed
Push — master ( c14a0b...566b5b )
by
unknown
27:12 queued 10:19
created

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