[BUGFIX] Clean up error handler for site handling
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Site / Entity / Site.php
1 <?php
2 declare(strict_types = 1);
3
4 namespace TYPO3\CMS\Core\Site\Entity;
5
6 /*
7 * This file is part of the TYPO3 CMS project.
8 *
9 * It is free software; you can redistribute it and/or modify it under
10 * the terms of the GNU General Public License, either version 2
11 * of the License, or any later version.
12 *
13 * For the full copyright and license information, please read the
14 * LICENSE.txt file that was distributed with this source code.
15 *
16 * The TYPO3 project - inspiring people to share!
17 */
18
19 use TYPO3\CMS\Core\Error\PageErrorHandler\FluidPageErrorHandler;
20 use TYPO3\CMS\Core\Error\PageErrorHandler\InvalidPageErrorHandlerException;
21 use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler;
22 use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
23 use TYPO3\CMS\Core\Utility\GeneralUtility;
24
25 /**
26 * Entity representing a single site with available languages
27 */
28 class Site
29 {
30 protected const ERRORHANDLER_TYPE_PAGE = 'Page';
31 protected const ERRORHANDLER_TYPE_FLUID = 'Fluid';
32 protected const ERRORHANDLER_TYPE_PHP = 'PHP';
33
34 /**
35 * @var string
36 */
37 protected $identifier;
38
39 /**
40 * @var string
41 */
42 protected $base;
43
44 /**
45 * @var int
46 */
47 protected $rootPageId;
48
49 /**
50 * Any attributes for this site
51 * @var array
52 */
53 protected $configuration;
54
55 /**
56 * @var SiteLanguage[]
57 */
58 protected $languages;
59
60 /**
61 * @var array
62 */
63 protected $errorHandlers;
64
65 /**
66 * Sets up a site object, and its languages and error handlers
67 *
68 * @param string $identifier
69 * @param int $rootPageId
70 * @param array $configuration
71 */
72 public function __construct(string $identifier, int $rootPageId, array $configuration)
73 {
74 $this->identifier = $identifier;
75 $this->rootPageId = $rootPageId;
76 $this->configuration = $configuration;
77 $configuration['languages'] = $configuration['languages'] ?: [0 => [
78 'languageId' => 0,
79 'title' => 'Default',
80 'navigationTitle' => '',
81 'typo3Language' => 'default',
82 'flag' => 'us',
83 'locale' => 'en_US.UTF-8',
84 'iso-639-1' => 'en',
85 'hreflang' => 'en-US',
86 'direction' => '',
87 ]];
88 $this->base = $configuration['base'] ?? '';
89 foreach ($configuration['languages'] as $languageConfiguration) {
90 $languageUid = (int)$languageConfiguration['languageId'];
91 $base = '/';
92 if (!empty($languageConfiguration['base'])) {
93 $base = $languageConfiguration['base'];
94 }
95 $baseParts = parse_url($base);
96 if (empty($baseParts['scheme'])) {
97 $base = rtrim($this->base, '/') . '/' . ltrim($base, '/');
98 }
99 $this->languages[$languageUid] = new SiteLanguage(
100 $this,
101 $languageUid,
102 $languageConfiguration['locale'],
103 $base,
104 $languageConfiguration
105 );
106 }
107 foreach ($configuration['errorHandling'] ?? [] as $errorHandlingConfiguration) {
108 $code = $errorHandlingConfiguration['errorCode'];
109 unset($errorHandlingConfiguration['errorCode']);
110 $this->errorHandlers[(int)$code] = $errorHandlingConfiguration;
111 }
112 }
113
114 /**
115 * Gets the identifier of this site
116 *
117 * @return string
118 */
119 public function getIdentifier(): string
120 {
121 return $this->identifier;
122 }
123
124 /**
125 * Returns the base URL of this site
126 *
127 * @return string
128 */
129 public function getBase(): string
130 {
131 return $this->base;
132 }
133
134 /**
135 * Returns the root page ID of this site
136 *
137 * @return int
138 */
139 public function getRootPageId(): int
140 {
141 return $this->rootPageId;
142 }
143
144 /**
145 * Returns all available langauges of this site
146 *
147 * @return SiteLanguage[]
148 */
149 public function getLanguages(): array
150 {
151 return $this->languages;
152 }
153
154 /**
155 * Returns a language of this site, given by the sys_language_uid
156 *
157 * @param int $languageId
158 * @return SiteLanguage
159 * @throws \InvalidArgumentException
160 */
161 public function getLanguageById(int $languageId): SiteLanguage
162 {
163 if (isset($this->languages[$languageId])) {
164 return $this->languages[$languageId];
165 }
166 throw new \InvalidArgumentException(
167 'Language ' . $languageId . ' does not exist on site ' . $this->identifier . '.',
168 1522960188
169 );
170 }
171
172 /**
173 * Returns a ready-to-use error handler, to be used within the ErrorController
174 *
175 * @param int $statusCode
176 * @return PageErrorHandlerInterface
177 * @throws \RuntimeException
178 * @throws InvalidPageErrorHandlerException
179 */
180 public function getErrorHandler(int $statusCode): PageErrorHandlerInterface
181 {
182 $errorHandlerConfiguration = $this->errorHandlers[$statusCode] ?? null;
183 switch ($errorHandlerConfiguration['errorHandler']) {
184 case self::ERRORHANDLER_TYPE_FLUID:
185 return GeneralUtility::makeInstance(FluidPageErrorHandler::class, $statusCode, $errorHandlerConfiguration);
186 case self::ERRORHANDLER_TYPE_PAGE:
187 return GeneralUtility::makeInstance(PageContentErrorHandler::class, $statusCode, $errorHandlerConfiguration);
188 case self::ERRORHANDLER_TYPE_PHP:
189 $handler = GeneralUtility::makeInstance($errorHandlerConfiguration['errorPhpClassFQCN'], $statusCode, $errorHandlerConfiguration);
190 // Check if the interface is implemented
191 if (!($handler instanceof PageErrorHandlerInterface)) {
192 throw new InvalidPageErrorHandlerException('The configured error handler "' . (string)$errorHandlerConfiguration['errorPhpClassFQCN'] . '" for status code ' . $statusCode . ' must implement the PageErrorHandlerInterface.', 1527432330);
193 }
194 return $handler;
195 }
196 throw new \RuntimeException('No error handler given for the status code "' . $statusCode . '".', 1522495914);
197 }
198
199 /**
200 * Returns the whole configuration for this site
201 *
202 * @return array
203 */
204 public function getConfiguration(): array
205 {
206 return $this->configuration;
207 }
208
209 /**
210 * Returns a single configuration attribute
211 *
212 * @param string $attributeName
213 * @return mixed
214 * @throws \InvalidArgumentException
215 */
216 public function getAttribute(string $attributeName)
217 {
218 if (isset($this->configuration[$attributeName])) {
219 return $this->configuration[$attributeName];
220 }
221 throw new \InvalidArgumentException(
222 'Attribute ' . $attributeName . ' does not exist on site ' . $this->identifier . '.',
223 1522495954
224 );
225 }
226 }