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