ConfigDataCollector.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpKernel\DataCollector;
  11. use Symfony\Component\HttpFoundation\Request;
  12. use Symfony\Component\HttpFoundation\Response;
  13. use Symfony\Component\HttpKernel\Kernel;
  14. use Symfony\Component\HttpKernel\KernelInterface;
  15. use Symfony\Component\VarDumper\Caster\ClassStub;
  16. use Symfony\Component\VarDumper\Cloner\Data;
  17. /**
  18. * @author Fabien Potencier <fabien@symfony.com>
  19. *
  20. * @final
  21. */
  22. class ConfigDataCollector extends DataCollector implements LateDataCollectorInterface
  23. {
  24. private KernelInterface $kernel;
  25. /**
  26. * Sets the Kernel associated with this Request.
  27. */
  28. public function setKernel(KernelInterface $kernel): void
  29. {
  30. $this->kernel = $kernel;
  31. }
  32. public function collect(Request $request, Response $response, ?\Throwable $exception = null): void
  33. {
  34. $eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE);
  35. $eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE);
  36. $xdebugMode = getenv('XDEBUG_MODE') ?: \ini_get('xdebug.mode');
  37. $this->data = [
  38. 'token' => $response->headers->get('X-Debug-Token'),
  39. 'symfony_version' => Kernel::VERSION,
  40. 'symfony_minor_version' => \sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION),
  41. 'symfony_lts' => 4 === Kernel::MINOR_VERSION,
  42. 'symfony_state' => $this->determineSymfonyState(),
  43. 'symfony_eom' => $eom->format('F Y'),
  44. 'symfony_eol' => $eol->format('F Y'),
  45. 'env' => isset($this->kernel) ? $this->kernel->getEnvironment() : 'n/a',
  46. 'debug' => isset($this->kernel) ? $this->kernel->isDebug() : 'n/a',
  47. 'php_version' => \PHP_VERSION,
  48. 'php_architecture' => \PHP_INT_SIZE * 8,
  49. 'php_intl_locale' => class_exists(\Locale::class, false) && \Locale::getDefault() ? \Locale::getDefault() : 'n/a',
  50. 'php_timezone' => date_default_timezone_get(),
  51. 'xdebug_enabled' => \extension_loaded('xdebug'),
  52. 'xdebug_status' => \extension_loaded('xdebug') ? ($xdebugMode && 'off' !== $xdebugMode ? 'Enabled (' . $xdebugMode . ')' : 'Not enabled') : 'Not installed',
  53. 'apcu_enabled' => \extension_loaded('apcu') && filter_var(\ini_get('apc.enabled'), \FILTER_VALIDATE_BOOL),
  54. 'apcu_status' => \extension_loaded('apcu') ? (filter_var(\ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? 'Enabled' : 'Not enabled') : 'Not installed',
  55. 'zend_opcache_enabled' => \extension_loaded('Zend OPcache') && filter_var(\ini_get('opcache.enable'), \FILTER_VALIDATE_BOOL),
  56. 'zend_opcache_status' => \extension_loaded('Zend OPcache') ? (filter_var(\ini_get('opcache.enable'), FILTER_VALIDATE_BOOLEAN) ? 'Enabled' : 'Not enabled') : 'Not installed',
  57. 'bundles' => [],
  58. 'sapi_name' => \PHP_SAPI,
  59. ];
  60. if (isset($this->kernel)) {
  61. foreach ($this->kernel->getBundles() as $name => $bundle) {
  62. $this->data['bundles'][$name] = new ClassStub($bundle::class);
  63. }
  64. }
  65. if (preg_match('~^(\d+(?:\.\d+)*)(.+)?$~', $this->data['php_version'], $matches) && isset($matches[2])) {
  66. $this->data['php_version'] = $matches[1];
  67. $this->data['php_version_extra'] = $matches[2];
  68. }
  69. }
  70. public function lateCollect(): void
  71. {
  72. $this->data = $this->cloneVar($this->data);
  73. }
  74. /**
  75. * Gets the token.
  76. */
  77. public function getToken(): ?string
  78. {
  79. return $this->data['token'];
  80. }
  81. /**
  82. * Gets the Symfony version.
  83. */
  84. public function getSymfonyVersion(): string
  85. {
  86. return $this->data['symfony_version'];
  87. }
  88. /**
  89. * Returns the state of the current Symfony release
  90. * as one of: unknown, dev, stable, eom, eol.
  91. */
  92. public function getSymfonyState(): string
  93. {
  94. return $this->data['symfony_state'];
  95. }
  96. /**
  97. * Returns the minor Symfony version used (without patch numbers of extra
  98. * suffix like "RC", "beta", etc.).
  99. */
  100. public function getSymfonyMinorVersion(): string
  101. {
  102. return $this->data['symfony_minor_version'];
  103. }
  104. public function isSymfonyLts(): bool
  105. {
  106. return $this->data['symfony_lts'];
  107. }
  108. /**
  109. * Returns the human readable date when this Symfony version ends its
  110. * maintenance period.
  111. */
  112. public function getSymfonyEom(): string
  113. {
  114. return $this->data['symfony_eom'];
  115. }
  116. /**
  117. * Returns the human readable date when this Symfony version reaches its
  118. * "end of life" and won't receive bugs or security fixes.
  119. */
  120. public function getSymfonyEol(): string
  121. {
  122. return $this->data['symfony_eol'];
  123. }
  124. /**
  125. * Gets the PHP version.
  126. */
  127. public function getPhpVersion(): string
  128. {
  129. return $this->data['php_version'];
  130. }
  131. /**
  132. * Gets the PHP version extra part.
  133. */
  134. public function getPhpVersionExtra(): ?string
  135. {
  136. return $this->data['php_version_extra'] ?? null;
  137. }
  138. public function getPhpArchitecture(): int
  139. {
  140. return $this->data['php_architecture'];
  141. }
  142. public function getPhpIntlLocale(): string
  143. {
  144. return $this->data['php_intl_locale'];
  145. }
  146. public function getPhpTimezone(): string
  147. {
  148. return $this->data['php_timezone'];
  149. }
  150. /**
  151. * Gets the environment.
  152. */
  153. public function getEnv(): string
  154. {
  155. return $this->data['env'];
  156. }
  157. /**
  158. * Returns true if the debug is enabled.
  159. *
  160. * @return bool|string true if debug is enabled, false otherwise or a string if no kernel was set
  161. */
  162. public function isDebug(): bool|string
  163. {
  164. return $this->data['debug'];
  165. }
  166. /**
  167. * Returns true if the Xdebug is enabled.
  168. */
  169. public function hasXdebug(): bool
  170. {
  171. return $this->data['xdebug_enabled'];
  172. }
  173. public function getXdebugStatus(): string
  174. {
  175. return $this->data['xdebug_status'];
  176. }
  177. /**
  178. * Returns true if the function xdebug_info is available.
  179. */
  180. public function hasXdebugInfo(): bool
  181. {
  182. return \function_exists('xdebug_info');
  183. }
  184. /**
  185. * Returns true if APCu is enabled.
  186. */
  187. public function hasApcu(): bool
  188. {
  189. return $this->data['apcu_enabled'];
  190. }
  191. public function getApcuStatus(): string
  192. {
  193. return $this->data['apcu_status'];
  194. }
  195. /**
  196. * Returns true if Zend OPcache is enabled.
  197. */
  198. public function hasZendOpcache(): bool
  199. {
  200. return $this->data['zend_opcache_enabled'];
  201. }
  202. public function getZendOpcacheStatus(): string
  203. {
  204. return $this->data['zend_opcache_status'];
  205. }
  206. public function getBundles(): array|Data
  207. {
  208. return $this->data['bundles'];
  209. }
  210. /**
  211. * Gets the PHP SAPI name.
  212. */
  213. public function getSapiName(): string
  214. {
  215. return $this->data['sapi_name'];
  216. }
  217. public function getName(): string
  218. {
  219. return 'config';
  220. }
  221. private function determineSymfonyState(): string
  222. {
  223. $now = new \DateTimeImmutable();
  224. $eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE)->modify('last day of this month');
  225. $eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE)->modify('last day of this month');
  226. if ($now > $eol) {
  227. $versionState = 'eol';
  228. } elseif ($now > $eom) {
  229. $versionState = 'eom';
  230. } elseif ('' !== Kernel::EXTRA_VERSION) {
  231. $versionState = 'dev';
  232. } else {
  233. $versionState = 'stable';
  234. }
  235. return $versionState;
  236. }
  237. }