PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / trunk
Matomo Analytics – Powerful, Privacy-First Insights for WordPress vtrunk
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / vendor / prefixed / symfony / http-kernel / Kernel.php
matomo / app / vendor / prefixed / symfony / http-kernel Last commit date
Attribute 2 years ago Bundle 1 year ago CacheClearer 2 years ago CacheWarmer 1 year ago Config 1 year ago Controller 1 year ago ControllerMetadata 1 year ago DataCollector 1 year ago Debug 1 year ago DependencyInjection 1 year ago Event 1 year ago EventListener 1 year ago Exception 1 year ago Fragment 1 year ago HttpCache 1 year ago Log 1 year ago Profiler 1 year ago Resources 2 years ago HttpClientKernel.php 1 year ago HttpKernel.php 1 year ago HttpKernelBrowser.php 1 year ago HttpKernelInterface.php 1 year ago Kernel.php 1 month ago KernelEvents.php 2 years ago KernelInterface.php 2 years ago LICENSE 2 years ago README.md 2 years ago RebootableInterface.php 2 years ago TerminableInterface.php 2 years ago UriSigner.php 1 year ago
Kernel.php
720 lines
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 namespace Matomo\Dependencies\Symfony\Component\HttpKernel;
12
13 use Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator;
14 use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
15 use Symfony\Component\Config\Builder\ConfigBuilderGenerator;
16 use Symfony\Component\Config\ConfigCache;
17 use Symfony\Component\Config\Loader\DelegatingLoader;
18 use Symfony\Component\Config\Loader\LoaderResolver;
19 use Symfony\Component\Debug\DebugClassLoader as LegacyDebugClassLoader;
20 use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
21 use Symfony\Component\DependencyInjection\Compiler\PassConfig;
22 use Symfony\Component\DependencyInjection\ContainerBuilder;
23 use Symfony\Component\DependencyInjection\ContainerInterface;
24 use Symfony\Component\DependencyInjection\Dumper\PhpDumper;
25 use Symfony\Component\DependencyInjection\Dumper\Preloader;
26 use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
27 use Symfony\Component\DependencyInjection\Loader\ClosureLoader;
28 use Symfony\Component\DependencyInjection\Loader\DirectoryLoader;
29 use Symfony\Component\DependencyInjection\Loader\GlobFileLoader;
30 use Symfony\Component\DependencyInjection\Loader\IniFileLoader;
31 use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
32 use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
33 use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
34 use Matomo\Dependencies\Symfony\Component\ErrorHandler\DebugClassLoader;
35 use Symfony\Component\Filesystem\Filesystem;
36 use Matomo\Dependencies\Symfony\Component\HttpFoundation\Request;
37 use Matomo\Dependencies\Symfony\Component\HttpFoundation\Response;
38 use Matomo\Dependencies\Symfony\Component\HttpKernel\Bundle\BundleInterface;
39 use Matomo\Dependencies\Symfony\Component\HttpKernel\CacheWarmer\WarmableInterface;
40 use Matomo\Dependencies\Symfony\Component\HttpKernel\Config\FileLocator;
41 use Matomo\Dependencies\Symfony\Component\HttpKernel\DependencyInjection\AddAnnotatedClassesToCachePass;
42 use Matomo\Dependencies\Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
43 // Help opcache.preload discover always-needed symbols
44 class_exists(ConfigCache::class);
45 /**
46 * The Kernel is the heart of the Symfony system.
47 *
48 * It manages an environment made of bundles.
49 *
50 * Environment names must always start with a letter and
51 * they must only contain letters and numbers.
52 *
53 * @author Fabien Potencier <fabien@symfony.com>
54 */
55 abstract class Kernel implements KernelInterface, RebootableInterface, TerminableInterface
56 {
57 /**
58 * @var array<string, BundleInterface>
59 */
60 protected $bundles = [];
61 protected $container;
62 protected $environment;
63 protected $debug;
64 protected $booted = \false;
65 protected $startTime;
66 private $projectDir;
67 private $warmupDir;
68 private $requestStackSize = 0;
69 private $resetServices = \false;
70 /**
71 * @var array<string, bool>
72 */
73 private static $freshCache = [];
74 public const VERSION = '5.4.53';
75 public const VERSION_ID = 50453;
76 public const MAJOR_VERSION = 5;
77 public const MINOR_VERSION = 4;
78 public const RELEASE_VERSION = 53;
79 public const EXTRA_VERSION = '';
80 public const END_OF_MAINTENANCE = '11/2024';
81 public const END_OF_LIFE = '02/2029';
82 public function __construct(string $environment, bool $debug)
83 {
84 if (!($this->environment = $environment)) {
85 throw new \InvalidArgumentException(sprintf('Invalid environment provided to "%s": the environment cannot be empty.', get_debug_type($this)));
86 }
87 $this->debug = $debug;
88 }
89 public function __clone()
90 {
91 $this->booted = \false;
92 $this->container = null;
93 $this->requestStackSize = 0;
94 $this->resetServices = \false;
95 }
96 /**
97 * {@inheritdoc}
98 */
99 public function boot()
100 {
101 if (\true === $this->booted) {
102 if (!$this->requestStackSize && $this->resetServices) {
103 if ($this->container->has('services_resetter')) {
104 $this->container->get('services_resetter')->reset();
105 }
106 $this->resetServices = \false;
107 if ($this->debug) {
108 $this->startTime = microtime(\true);
109 }
110 }
111 return;
112 }
113 if (null === $this->container) {
114 $this->preBoot();
115 }
116 foreach ($this->getBundles() as $bundle) {
117 $bundle->setContainer($this->container);
118 $bundle->boot();
119 }
120 $this->booted = \true;
121 }
122 /**
123 * {@inheritdoc}
124 */
125 public function reboot(?string $warmupDir)
126 {
127 $this->shutdown();
128 $this->warmupDir = $warmupDir;
129 $this->boot();
130 }
131 /**
132 * {@inheritdoc}
133 */
134 public function terminate(Request $request, Response $response)
135 {
136 if (\false === $this->booted) {
137 return;
138 }
139 if ($this->getHttpKernel() instanceof TerminableInterface) {
140 $this->getHttpKernel()->terminate($request, $response);
141 }
142 }
143 /**
144 * {@inheritdoc}
145 */
146 public function shutdown()
147 {
148 if (\false === $this->booted) {
149 return;
150 }
151 $this->booted = \false;
152 foreach ($this->getBundles() as $bundle) {
153 $bundle->shutdown();
154 $bundle->setContainer(null);
155 }
156 $this->container = null;
157 $this->requestStackSize = 0;
158 $this->resetServices = \false;
159 }
160 /**
161 * {@inheritdoc}
162 */
163 public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = \true)
164 {
165 if (!$this->booted) {
166 $container = $this->container ?? $this->preBoot();
167 if ($container->has('http_cache')) {
168 return $container->get('http_cache')->handle($request, $type, $catch);
169 }
170 }
171 $this->boot();
172 ++$this->requestStackSize;
173 $this->resetServices = \true;
174 try {
175 return $this->getHttpKernel()->handle($request, $type, $catch);
176 } finally {
177 --$this->requestStackSize;
178 }
179 }
180 /**
181 * Gets an HTTP kernel from the container.
182 *
183 * @return HttpKernelInterface
184 */
185 protected function getHttpKernel()
186 {
187 return $this->container->get('http_kernel');
188 }
189 /**
190 * {@inheritdoc}
191 */
192 public function getBundles()
193 {
194 return $this->bundles;
195 }
196 /**
197 * {@inheritdoc}
198 */
199 public function getBundle(string $name)
200 {
201 if (!isset($this->bundles[$name])) {
202 throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this)));
203 }
204 return $this->bundles[$name];
205 }
206 /**
207 * {@inheritdoc}
208 */
209 public function locateResource(string $name)
210 {
211 if ('@' !== $name[0]) {
212 throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name));
213 }
214 if (str_contains($name, '..')) {
215 throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name));
216 }
217 $bundleName = substr($name, 1);
218 $path = '';
219 if (str_contains($bundleName, '/')) {
220 [$bundleName, $path] = explode('/', $bundleName, 2);
221 }
222 $bundle = $this->getBundle($bundleName);
223 if (file_exists($file = $bundle->getPath() . '/' . $path)) {
224 return $file;
225 }
226 throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name));
227 }
228 /**
229 * {@inheritdoc}
230 */
231 public function getEnvironment()
232 {
233 return $this->environment;
234 }
235 /**
236 * {@inheritdoc}
237 */
238 public function isDebug()
239 {
240 return $this->debug;
241 }
242 /**
243 * Gets the application root dir (path of the project's composer file).
244 *
245 * @return string
246 */
247 public function getProjectDir()
248 {
249 if (null === $this->projectDir) {
250 $r = new \ReflectionObject($this);
251 if (!is_file($dir = $r->getFileName())) {
252 throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name));
253 }
254 $dir = $rootDir = \dirname($dir);
255 while (!is_file($dir . '/composer.json')) {
256 if ($dir === \dirname($dir)) {
257 return $this->projectDir = $rootDir;
258 }
259 $dir = \dirname($dir);
260 }
261 $this->projectDir = $dir;
262 }
263 return $this->projectDir;
264 }
265 /**
266 * {@inheritdoc}
267 */
268 public function getContainer()
269 {
270 if (!$this->container) {
271 throw new \LogicException('Cannot retrieve the container from a non-booted kernel.');
272 }
273 return $this->container;
274 }
275 /**
276 * @internal
277 */
278 public function setAnnotatedClassCache(array $annotatedClasses)
279 {
280 file_put_contents(($this->warmupDir ?: $this->getBuildDir()) . '/annotations.map', sprintf('<?php return %s;', var_export($annotatedClasses, \true)));
281 }
282 /**
283 * {@inheritdoc}
284 */
285 public function getStartTime()
286 {
287 return $this->debug && null !== $this->startTime ? $this->startTime : -\INF;
288 }
289 /**
290 * {@inheritdoc}
291 */
292 public function getCacheDir()
293 {
294 return $this->getProjectDir() . '/var/cache/' . $this->environment;
295 }
296 /**
297 * {@inheritdoc}
298 */
299 public function getBuildDir() : string
300 {
301 // Returns $this->getCacheDir() for backward compatibility
302 return $this->getCacheDir();
303 }
304 /**
305 * {@inheritdoc}
306 */
307 public function getLogDir()
308 {
309 return $this->getProjectDir() . '/var/log';
310 }
311 /**
312 * {@inheritdoc}
313 */
314 public function getCharset()
315 {
316 return 'UTF-8';
317 }
318 /**
319 * Gets the patterns defining the classes to parse and cache for annotations.
320 */
321 public function getAnnotatedClassesToCompile() : array
322 {
323 return [];
324 }
325 /**
326 * Initializes bundles.
327 *
328 * @throws \LogicException if two bundles share a common name
329 */
330 protected function initializeBundles()
331 {
332 // init bundles
333 $this->bundles = [];
334 foreach ($this->registerBundles() as $bundle) {
335 $name = $bundle->getName();
336 if (isset($this->bundles[$name])) {
337 throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s".', $name));
338 }
339 $this->bundles[$name] = $bundle;
340 }
341 }
342 /**
343 * The extension point similar to the Bundle::build() method.
344 *
345 * Use this method to register compiler passes and manipulate the container during the building process.
346 */
347 protected function build(ContainerBuilder $container)
348 {
349 }
350 /**
351 * Gets the container class.
352 *
353 * @return string
354 *
355 * @throws \InvalidArgumentException If the generated classname is invalid
356 */
357 protected function getContainerClass()
358 {
359 $class = static::class;
360 $class = str_contains($class, "@anonymous\x00") ? get_parent_class($class) . str_replace('.', '_', ContainerBuilder::hash($class)) : $class;
361 $class = str_replace('\\', '_', $class) . ucfirst($this->environment) . ($this->debug ? 'Debug' : '') . 'Container';
362 if (!preg_match('/^[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*$/', $class)) {
363 throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment));
364 }
365 return $class;
366 }
367 /**
368 * Gets the container's base class.
369 *
370 * All names except Container must be fully qualified.
371 *
372 * @return string
373 */
374 protected function getContainerBaseClass()
375 {
376 return 'Container';
377 }
378 /**
379 * Initializes the service container.
380 *
381 * The built version of the service container is used when fresh, otherwise the
382 * container is built.
383 */
384 protected function initializeContainer()
385 {
386 $class = $this->getContainerClass();
387 $buildDir = $this->warmupDir ?: $this->getBuildDir();
388 $cache = new ConfigCache($buildDir . '/' . $class . '.php', $this->debug);
389 $cachePath = $cache->getPath();
390 // Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors
391 $errorLevel = error_reporting(\E_ALL ^ \E_WARNING);
392 try {
393 if (is_file($cachePath) && \is_object($this->container = (include $cachePath)) && (!$this->debug || (self::$freshCache[$cachePath] ?? $cache->isFresh()))) {
394 self::$freshCache[$cachePath] = \true;
395 $this->container->set('kernel', $this);
396 error_reporting($errorLevel);
397 return;
398 }
399 } catch (\Throwable $e) {
400 }
401 $oldContainer = \is_object($this->container) ? new \ReflectionClass($this->container) : ($this->container = null);
402 try {
403 is_dir($buildDir) ?: mkdir($buildDir, 0777, \true);
404 if ($lock = fopen($cachePath . '.lock', 'w+')) {
405 if (!flock($lock, \LOCK_EX | \LOCK_NB, $wouldBlock) && !flock($lock, $wouldBlock ? \LOCK_SH : \LOCK_EX)) {
406 fclose($lock);
407 $lock = null;
408 } elseif (!is_file($cachePath) || !\is_object($this->container = (include $cachePath))) {
409 $this->container = null;
410 } elseif (!$oldContainer || \get_class($this->container) !== $oldContainer->name) {
411 flock($lock, \LOCK_UN);
412 fclose($lock);
413 $this->container->set('kernel', $this);
414 return;
415 }
416 }
417 } catch (\Throwable $e) {
418 } finally {
419 error_reporting($errorLevel);
420 }
421 if ($collectDeprecations = $this->debug && !\defined('PHPUNIT_COMPOSER_INSTALL')) {
422 $collectedLogs = [];
423 $previousHandler = set_error_handler(function ($type, $message, $file, $line) use(&$collectedLogs, &$previousHandler) {
424 if (\E_USER_DEPRECATED !== $type && \E_DEPRECATED !== $type) {
425 return $previousHandler ? $previousHandler($type, $message, $file, $line) : \false;
426 }
427 if (isset($collectedLogs[$message])) {
428 ++$collectedLogs[$message]['count'];
429 return null;
430 }
431 $backtrace = debug_backtrace(\DEBUG_BACKTRACE_IGNORE_ARGS, 5);
432 // Clean the trace by removing first frames added by the error handler itself.
433 for ($i = 0; isset($backtrace[$i]); ++$i) {
434 if (isset($backtrace[$i]['file'], $backtrace[$i]['line']) && $backtrace[$i]['line'] === $line && $backtrace[$i]['file'] === $file) {
435 $backtrace = \array_slice($backtrace, 1 + $i);
436 break;
437 }
438 }
439 for ($i = 0; isset($backtrace[$i]); ++$i) {
440 if (!isset($backtrace[$i]['file'], $backtrace[$i]['line'], $backtrace[$i]['function'])) {
441 continue;
442 }
443 if (!isset($backtrace[$i]['class']) && 'trigger_deprecation' === $backtrace[$i]['function']) {
444 $file = $backtrace[$i]['file'];
445 $line = $backtrace[$i]['line'];
446 $backtrace = \array_slice($backtrace, 1 + $i);
447 break;
448 }
449 }
450 // Remove frames added by DebugClassLoader.
451 for ($i = \count($backtrace) - 2; 0 < $i; --$i) {
452 if (\in_array($backtrace[$i]['class'] ?? null, [DebugClassLoader::class, LegacyDebugClassLoader::class], \true)) {
453 $backtrace = [$backtrace[$i + 1]];
454 break;
455 }
456 }
457 $collectedLogs[$message] = ['type' => $type, 'message' => $message, 'file' => $file, 'line' => $line, 'trace' => [$backtrace[0]], 'count' => 1];
458 return null;
459 });
460 }
461 try {
462 $container = null;
463 $container = $this->buildContainer();
464 $container->compile();
465 } finally {
466 if ($collectDeprecations) {
467 restore_error_handler();
468 @file_put_contents($buildDir . '/' . $class . 'Deprecations.log', serialize(array_values($collectedLogs)));
469 @file_put_contents($buildDir . '/' . $class . 'Compiler.log', null !== $container ? implode("\n", $container->getCompiler()->getLog()) : '');
470 }
471 }
472 $this->dumpContainer($cache, $container, $class, $this->getContainerBaseClass());
473 if ($lock) {
474 flock($lock, \LOCK_UN);
475 fclose($lock);
476 }
477 $this->container = (require $cachePath);
478 $this->container->set('kernel', $this);
479 if ($oldContainer && \get_class($this->container) !== $oldContainer->name) {
480 // Because concurrent requests might still be using them,
481 // old container files are not removed immediately,
482 // but on a next dump of the container.
483 static $legacyContainers = [];
484 $oldContainerDir = \dirname($oldContainer->getFileName());
485 $legacyContainers[$oldContainerDir . '.legacy'] = \true;
486 foreach (glob(\dirname($oldContainerDir) . \DIRECTORY_SEPARATOR . '*.legacy', \GLOB_NOSORT) as $legacyContainer) {
487 if (!isset($legacyContainers[$legacyContainer]) && @unlink($legacyContainer)) {
488 (new Filesystem())->remove(substr($legacyContainer, 0, -7));
489 }
490 }
491 touch($oldContainerDir . '.legacy');
492 }
493 $preload = $this instanceof WarmableInterface ? (array) $this->warmUp($this->container->getParameter('kernel.cache_dir')) : [];
494 if ($this->container->has('cache_warmer')) {
495 $preload = array_merge($preload, (array) $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir')));
496 }
497 if ($preload && method_exists(Preloader::class, 'append') && file_exists($preloadFile = $buildDir . '/' . $class . '.preload.php')) {
498 Preloader::append($preloadFile, $preload);
499 }
500 }
501 /**
502 * Returns the kernel parameters.
503 *
504 * @return array
505 */
506 protected function getKernelParameters()
507 {
508 $bundles = [];
509 $bundlesMetadata = [];
510 foreach ($this->bundles as $name => $bundle) {
511 $bundles[$name] = \get_class($bundle);
512 $bundlesMetadata[$name] = ['path' => $bundle->getPath(), 'namespace' => $bundle->getNamespace()];
513 }
514 return ['kernel.project_dir' => realpath($this->getProjectDir()) ?: $this->getProjectDir(), 'kernel.environment' => $this->environment, 'kernel.runtime_environment' => '%env(default:kernel.environment:APP_RUNTIME_ENV)%', 'kernel.debug' => $this->debug, 'kernel.build_dir' => realpath($buildDir = $this->warmupDir ?: $this->getBuildDir()) ?: $buildDir, 'kernel.cache_dir' => realpath($cacheDir = $this->getCacheDir() === $this->getBuildDir() ? $this->warmupDir ?: $this->getCacheDir() : $this->getCacheDir()) ?: $cacheDir, 'kernel.logs_dir' => realpath($this->getLogDir()) ?: $this->getLogDir(), 'kernel.bundles' => $bundles, 'kernel.bundles_metadata' => $bundlesMetadata, 'kernel.charset' => $this->getCharset(), 'kernel.container_class' => $this->getContainerClass()];
515 }
516 /**
517 * Builds the service container.
518 *
519 * @return ContainerBuilder
520 *
521 * @throws \RuntimeException
522 */
523 protected function buildContainer()
524 {
525 foreach (['cache' => $this->getCacheDir(), 'build' => $this->warmupDir ?: $this->getBuildDir(), 'logs' => $this->getLogDir()] as $name => $dir) {
526 if (!is_dir($dir)) {
527 if (\false === @mkdir($dir, 0777, \true) && !is_dir($dir)) {
528 throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir));
529 }
530 } elseif (!is_writable($dir)) {
531 throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir));
532 }
533 }
534 $container = $this->getContainerBuilder();
535 $container->addObjectResource($this);
536 $this->prepareContainer($container);
537 if (null !== ($cont = $this->registerContainerConfiguration($this->getContainerLoader($container)))) {
538 trigger_deprecation('symfony/http-kernel', '5.3', 'Returning a ContainerBuilder from "%s::registerContainerConfiguration()" is deprecated.', get_debug_type($this));
539 $container->merge($cont);
540 }
541 $container->addCompilerPass(new AddAnnotatedClassesToCachePass($this));
542 return $container;
543 }
544 /**
545 * Prepares the ContainerBuilder before it is compiled.
546 */
547 protected function prepareContainer(ContainerBuilder $container)
548 {
549 $extensions = [];
550 foreach ($this->bundles as $bundle) {
551 if ($extension = $bundle->getContainerExtension()) {
552 $container->registerExtension($extension);
553 }
554 if ($this->debug) {
555 $container->addObjectResource($bundle);
556 }
557 }
558 foreach ($this->bundles as $bundle) {
559 $bundle->build($container);
560 }
561 $this->build($container);
562 foreach ($container->getExtensions() as $extension) {
563 $extensions[] = $extension->getAlias();
564 }
565 // ensure these extensions are implicitly loaded
566 $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions));
567 }
568 /**
569 * Gets a new ContainerBuilder instance used to build the service container.
570 *
571 * @return ContainerBuilder
572 */
573 protected function getContainerBuilder()
574 {
575 $container = new ContainerBuilder();
576 $container->getParameterBag()->add($this->getKernelParameters());
577 if ($this instanceof ExtensionInterface) {
578 $container->registerExtension($this);
579 }
580 if ($this instanceof CompilerPassInterface) {
581 $container->addCompilerPass($this, PassConfig::TYPE_BEFORE_OPTIMIZATION, -10000);
582 }
583 if (class_exists(\ProxyManager\Configuration::class) && class_exists(RuntimeInstantiator::class)) {
584 $container->setProxyInstantiator(new RuntimeInstantiator());
585 }
586 return $container;
587 }
588 /**
589 * Dumps the service container to PHP code in the cache.
590 *
591 * @param string $class The name of the class to generate
592 * @param string $baseClass The name of the container's base class
593 */
594 protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, string $class, string $baseClass)
595 {
596 // cache the container
597 $dumper = new PhpDumper($container);
598 if (class_exists(\ProxyManager\Configuration::class) && class_exists(ProxyDumper::class)) {
599 $dumper->setProxyDumper(new ProxyDumper());
600 }
601 $content = $dumper->dump(['class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath(), 'as_files' => \true, 'debug' => $this->debug, 'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(), 'preload_classes' => array_map('get_class', $this->bundles)]);
602 $rootCode = array_pop($content);
603 $dir = \dirname($cache->getPath()) . '/';
604 $fs = new Filesystem();
605 foreach ($content as $file => $code) {
606 $fs->dumpFile($dir . $file, $code);
607 @chmod($dir . $file, 0666 & ~umask());
608 }
609 $legacyFile = \dirname($dir . key($content)) . '.legacy';
610 if (is_file($legacyFile)) {
611 @unlink($legacyFile);
612 }
613 $cache->write($rootCode, $container->getResources());
614 }
615 /**
616 * Returns a loader for the container.
617 *
618 * @return DelegatingLoader
619 */
620 protected function getContainerLoader(ContainerInterface $container)
621 {
622 $env = $this->getEnvironment();
623 $locator = new FileLocator($this);
624 $resolver = new LoaderResolver([new XmlFileLoader($container, $locator, $env), new YamlFileLoader($container, $locator, $env), new IniFileLoader($container, $locator, $env), new PhpFileLoader($container, $locator, $env, class_exists(ConfigBuilderGenerator::class) ? new ConfigBuilderGenerator($this->getBuildDir()) : null), new GlobFileLoader($container, $locator, $env), new DirectoryLoader($container, $locator, $env), new ClosureLoader($container, $env)]);
625 return new DelegatingLoader($resolver);
626 }
627 private function preBoot() : ContainerInterface
628 {
629 if ($this->debug) {
630 $this->startTime = microtime(\true);
631 }
632 if ($this->debug && !isset($_ENV['SHELL_VERBOSITY']) && !isset($_SERVER['SHELL_VERBOSITY'])) {
633 if (\function_exists('putenv')) {
634 putenv('SHELL_VERBOSITY=3');
635 }
636 $_ENV['SHELL_VERBOSITY'] = 3;
637 $_SERVER['SHELL_VERBOSITY'] = 3;
638 }
639 $this->initializeBundles();
640 $this->initializeContainer();
641 $container = $this->container;
642 if ($container->hasParameter('kernel.trusted_hosts') && ($trustedHosts = $container->getParameter('kernel.trusted_hosts'))) {
643 Request::setTrustedHosts($trustedHosts);
644 }
645 if ($container->hasParameter('kernel.trusted_proxies') && $container->hasParameter('kernel.trusted_headers') && ($trustedProxies = $container->getParameter('kernel.trusted_proxies'))) {
646 Request::setTrustedProxies(\is_array($trustedProxies) ? $trustedProxies : array_map('trim', explode(',', $trustedProxies)), $container->getParameter('kernel.trusted_headers'));
647 }
648 return $container;
649 }
650 /**
651 * Removes comments from a PHP source string.
652 *
653 * We don't use the PHP php_strip_whitespace() function
654 * as we want the content to be readable and well-formatted.
655 *
656 * @return string
657 */
658 public static function stripComments(string $source)
659 {
660 if (!\function_exists('token_get_all')) {
661 return $source;
662 }
663 $rawChunk = '';
664 $output = '';
665 $tokens = token_get_all($source);
666 $ignoreSpace = \false;
667 for ($i = 0; isset($tokens[$i]); ++$i) {
668 $token = $tokens[$i];
669 if (!isset($token[1]) || 'b"' === $token) {
670 $rawChunk .= $token;
671 } elseif (\T_START_HEREDOC === $token[0]) {
672 $output .= $rawChunk . $token[1];
673 do {
674 $token = $tokens[++$i];
675 $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token;
676 } while (\T_END_HEREDOC !== $token[0]);
677 $rawChunk = '';
678 } elseif (\T_WHITESPACE === $token[0]) {
679 if ($ignoreSpace) {
680 $ignoreSpace = \false;
681 continue;
682 }
683 // replace multiple new lines with a single newline
684 $rawChunk .= preg_replace(['/\\n{2,}/S'], "\n", $token[1]);
685 } elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) {
686 if (!\in_array($rawChunk[\strlen($rawChunk) - 1], [' ', "\n", "\r", "\t"], \true)) {
687 $rawChunk .= ' ';
688 }
689 $ignoreSpace = \true;
690 } else {
691 $rawChunk .= $token[1];
692 // The PHP-open tag already has a new-line
693 if (\T_OPEN_TAG === $token[0]) {
694 $ignoreSpace = \true;
695 } else {
696 $ignoreSpace = \false;
697 }
698 }
699 }
700 $output .= $rawChunk;
701 unset($tokens, $rawChunk);
702 gc_mem_caches();
703 return $output;
704 }
705 /**
706 * @return array
707 */
708 public function __sleep()
709 {
710 return ['environment', 'debug'];
711 }
712 public function __wakeup()
713 {
714 if (\is_object($this->environment) || \is_object($this->debug)) {
715 throw new \BadMethodCallException('Cannot unserialize ' . __CLASS__);
716 }
717 $this->__construct($this->environment, $this->debug);
718 }
719 }
720