1<?php 2 3/* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12namespace Symfony\Component\HttpKernel\DataCollector; 13 14use Symfony\Component\HttpFoundation\Request; 15use Symfony\Component\HttpFoundation\Response; 16use Symfony\Component\HttpKernel\Kernel; 17use Symfony\Component\HttpKernel\KernelInterface; 18use Symfony\Component\VarDumper\Caster\ClassStub; 19 20/** 21 * @author Fabien Potencier <fabien@symfony.com> 22 * 23 * @final since Symfony 4.4 24 */ 25class ConfigDataCollector extends DataCollector implements LateDataCollectorInterface 26{ 27 /** 28 * @var KernelInterface 29 */ 30 private $kernel; 31 private $name; 32 private $version; 33 34 public function __construct(string $name = null, string $version = null) 35 { 36 if (1 <= \func_num_args()) { 37 @trigger_error(sprintf('The "$name" argument in method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); 38 } 39 if (2 <= \func_num_args()) { 40 @trigger_error(sprintf('The "$version" argument in method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); 41 } 42 43 $this->name = $name; 44 $this->version = $version; 45 } 46 47 /** 48 * Sets the Kernel associated with this Request. 49 */ 50 public function setKernel(KernelInterface $kernel = null) 51 { 52 $this->kernel = $kernel; 53 } 54 55 /** 56 * {@inheritdoc} 57 * 58 * @param \Throwable|null $exception 59 */ 60 public function collect(Request $request, Response $response/*, \Throwable $exception = null*/) 61 { 62 $this->data = [ 63 'app_name' => $this->name, 64 'app_version' => $this->version, 65 'token' => $response->headers->get('X-Debug-Token'), 66 'symfony_version' => Kernel::VERSION, 67 'symfony_state' => 'unknown', 68 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a', 69 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a', 70 'php_version' => PHP_VERSION, 71 'php_architecture' => PHP_INT_SIZE * 8, 72 'php_intl_locale' => class_exists('Locale', false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a', 73 'php_timezone' => date_default_timezone_get(), 74 'xdebug_enabled' => \extension_loaded('xdebug'), 75 'apcu_enabled' => \extension_loaded('apcu') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN), 76 'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN), 77 'bundles' => [], 78 'sapi_name' => \PHP_SAPI, 79 ]; 80 81 if (isset($this->kernel)) { 82 foreach ($this->kernel->getBundles() as $name => $bundle) { 83 $this->data['bundles'][$name] = new ClassStub(\get_class($bundle)); 84 } 85 86 $this->data['symfony_state'] = $this->determineSymfonyState(); 87 $this->data['symfony_minor_version'] = sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION); 88 $this->data['symfony_lts'] = 4 === Kernel::MINOR_VERSION; 89 $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE); 90 $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE); 91 $this->data['symfony_eom'] = $eom->format('F Y'); 92 $this->data['symfony_eol'] = $eol->format('F Y'); 93 } 94 95 if (preg_match('~^(\d+(?:\.\d+)*)(.+)?$~', $this->data['php_version'], $matches) && isset($matches[2])) { 96 $this->data['php_version'] = $matches[1]; 97 $this->data['php_version_extra'] = $matches[2]; 98 } 99 } 100 101 /** 102 * {@inheritdoc} 103 */ 104 public function reset() 105 { 106 $this->data = []; 107 } 108 109 public function lateCollect() 110 { 111 $this->data = $this->cloneVar($this->data); 112 } 113 114 /** 115 * @deprecated since Symfony 4.2 116 */ 117 public function getApplicationName() 118 { 119 @trigger_error(sprintf('The method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); 120 121 return $this->data['app_name']; 122 } 123 124 /** 125 * @deprecated since Symfony 4.2 126 */ 127 public function getApplicationVersion() 128 { 129 @trigger_error(sprintf('The method "%s()" is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); 130 131 return $this->data['app_version']; 132 } 133 134 /** 135 * Gets the token. 136 * 137 * @return string|null The token 138 */ 139 public function getToken() 140 { 141 return $this->data['token']; 142 } 143 144 /** 145 * Gets the Symfony version. 146 * 147 * @return string The Symfony version 148 */ 149 public function getSymfonyVersion() 150 { 151 return $this->data['symfony_version']; 152 } 153 154 /** 155 * Returns the state of the current Symfony release. 156 * 157 * @return string One of: unknown, dev, stable, eom, eol 158 */ 159 public function getSymfonyState() 160 { 161 return $this->data['symfony_state']; 162 } 163 164 /** 165 * Returns the minor Symfony version used (without patch numbers of extra 166 * suffix like "RC", "beta", etc.). 167 * 168 * @return string 169 */ 170 public function getSymfonyMinorVersion() 171 { 172 return $this->data['symfony_minor_version']; 173 } 174 175 /** 176 * Returns if the current Symfony version is a Long-Term Support one. 177 */ 178 public function isSymfonyLts(): bool 179 { 180 return $this->data['symfony_lts']; 181 } 182 183 /** 184 * Returns the human redable date when this Symfony version ends its 185 * maintenance period. 186 * 187 * @return string 188 */ 189 public function getSymfonyEom() 190 { 191 return $this->data['symfony_eom']; 192 } 193 194 /** 195 * Returns the human redable date when this Symfony version reaches its 196 * "end of life" and won't receive bugs or security fixes. 197 * 198 * @return string 199 */ 200 public function getSymfonyEol() 201 { 202 return $this->data['symfony_eol']; 203 } 204 205 /** 206 * Gets the PHP version. 207 * 208 * @return string The PHP version 209 */ 210 public function getPhpVersion() 211 { 212 return $this->data['php_version']; 213 } 214 215 /** 216 * Gets the PHP version extra part. 217 * 218 * @return string|null The extra part 219 */ 220 public function getPhpVersionExtra() 221 { 222 return isset($this->data['php_version_extra']) ? $this->data['php_version_extra'] : null; 223 } 224 225 /** 226 * @return int The PHP architecture as number of bits (e.g. 32 or 64) 227 */ 228 public function getPhpArchitecture() 229 { 230 return $this->data['php_architecture']; 231 } 232 233 /** 234 * @return string 235 */ 236 public function getPhpIntlLocale() 237 { 238 return $this->data['php_intl_locale']; 239 } 240 241 /** 242 * @return string 243 */ 244 public function getPhpTimezone() 245 { 246 return $this->data['php_timezone']; 247 } 248 249 /** 250 * Gets the application name. 251 * 252 * @return string The application name 253 * 254 * @deprecated since Symfony 4.2 255 */ 256 public function getAppName() 257 { 258 @trigger_error(sprintf('The "%s()" method is deprecated since Symfony 4.2.', __METHOD__), E_USER_DEPRECATED); 259 260 return 'n/a'; 261 } 262 263 /** 264 * Gets the environment. 265 * 266 * @return string The environment 267 */ 268 public function getEnv() 269 { 270 return $this->data['env']; 271 } 272 273 /** 274 * Returns true if the debug is enabled. 275 * 276 * @return bool true if debug is enabled, false otherwise 277 */ 278 public function isDebug() 279 { 280 return $this->data['debug']; 281 } 282 283 /** 284 * Returns true if the XDebug is enabled. 285 * 286 * @return bool true if XDebug is enabled, false otherwise 287 */ 288 public function hasXDebug() 289 { 290 return $this->data['xdebug_enabled']; 291 } 292 293 /** 294 * Returns true if APCu is enabled. 295 * 296 * @return bool true if APCu is enabled, false otherwise 297 */ 298 public function hasApcu() 299 { 300 return $this->data['apcu_enabled']; 301 } 302 303 /** 304 * Returns true if Zend OPcache is enabled. 305 * 306 * @return bool true if Zend OPcache is enabled, false otherwise 307 */ 308 public function hasZendOpcache() 309 { 310 return $this->data['zend_opcache_enabled']; 311 } 312 313 public function getBundles() 314 { 315 return $this->data['bundles']; 316 } 317 318 /** 319 * Gets the PHP SAPI name. 320 * 321 * @return string The environment 322 */ 323 public function getSapiName() 324 { 325 return $this->data['sapi_name']; 326 } 327 328 /** 329 * {@inheritdoc} 330 */ 331 public function getName() 332 { 333 return 'config'; 334 } 335 336 /** 337 * Tries to retrieve information about the current Symfony version. 338 * 339 * @return string One of: dev, stable, eom, eol 340 */ 341 private function determineSymfonyState(): string 342 { 343 $now = new \DateTime(); 344 $eom = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->modify('last day of this month'); 345 $eol = \DateTime::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->modify('last day of this month'); 346 347 if ($now > $eol) { 348 $versionState = 'eol'; 349 } elseif ($now > $eom) { 350 $versionState = 'eom'; 351 } elseif ('' !== Kernel::EXTRA_VERSION) { 352 $versionState = 'dev'; 353 } else { 354 $versionState = 'stable'; 355 } 356 357 return $versionState; 358 } 359} 360