X-Git-Url: http://www.aleph1.co.uk/gitweb/?p=yaffs-website;a=blobdiff_plain;f=vendor%2Fsymfony%2Fhttp-kernel%2FDependencyInjection%2FAddClassesToCachePass.php;fp=vendor%2Fsymfony%2Fhttp-kernel%2FDependencyInjection%2FAddClassesToCachePass.php;h=e9d012033d6d4f7d5730a6286e458fe372b7b077;hp=09af6bd25d93810147b2fda8dc93b2cd741fd660;hb=9917807b03b64faf00f6a1f29dcb6eafc454efa5;hpb=aea91e65e895364e460983b890e295aa5d5540a5 diff --git a/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php b/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php index 09af6bd25..e9d012033 100644 --- a/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php +++ b/vendor/symfony/http-kernel/DependencyInjection/AddClassesToCachePass.php @@ -11,6 +11,8 @@ namespace Symfony\Component\HttpKernel\DependencyInjection; +use Composer\Autoload\ClassLoader; +use Symfony\Component\Debug\DebugClassLoader; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; use Symfony\Component\HttpKernel\Kernel; @@ -35,12 +37,113 @@ class AddClassesToCachePass implements CompilerPassInterface public function process(ContainerBuilder $container) { $classes = array(); + $annotatedClasses = array(); foreach ($container->getExtensions() as $extension) { if ($extension instanceof Extension) { $classes = array_merge($classes, $extension->getClassesToCompile()); + $annotatedClasses = array_merge($annotatedClasses, $extension->getAnnotatedClassesToCompile()); } } - $this->kernel->setClassCache(array_unique($container->getParameterBag()->resolveValue($classes))); + $classes = $container->getParameterBag()->resolveValue($classes); + $annotatedClasses = $container->getParameterBag()->resolveValue($annotatedClasses); + $existingClasses = $this->getClassesInComposerClassMaps(); + + $this->kernel->setClassCache($this->expandClasses($classes, $existingClasses)); + $this->kernel->setAnnotatedClassCache($this->expandClasses($annotatedClasses, $existingClasses)); + } + + /** + * Expands the given class patterns using a list of existing classes. + * + * @param array $patterns The class patterns to expand + * @param array $classes The existing classes to match against the patterns + * + * @return array A list of classes derivated from the patterns + */ + private function expandClasses(array $patterns, array $classes) + { + $expanded = array(); + + // Explicit classes declared in the patterns are returned directly + foreach ($patterns as $key => $pattern) { + if (substr($pattern, -1) !== '\\' && false === strpos($pattern, '*')) { + unset($patterns[$key]); + $expanded[] = ltrim($pattern, '\\'); + } + } + + // Match patterns with the classes list + $regexps = $this->patternsToRegexps($patterns); + + foreach ($classes as $class) { + $class = ltrim($class, '\\'); + + if ($this->matchAnyRegexps($class, $regexps)) { + $expanded[] = $class; + } + } + + return array_unique($expanded); + } + + private function getClassesInComposerClassMaps() + { + $classes = array(); + + foreach (spl_autoload_functions() as $function) { + if (!is_array($function)) { + continue; + } + + if ($function[0] instanceof DebugClassLoader) { + $function = $function[0]->getClassLoader(); + } + + if (is_array($function) && $function[0] instanceof ClassLoader) { + $classes += array_filter($function[0]->getClassMap()); + } + } + + return array_keys($classes); + } + + private function patternsToRegexps($patterns) + { + $regexps = array(); + + foreach ($patterns as $pattern) { + // Escape user input + $regex = preg_quote(ltrim($pattern, '\\')); + + // Wildcards * and ** + $regex = strtr($regex, array('\\*\\*' => '.*?', '\\*' => '[^\\\\]*?')); + + // If this class does not end by a slash, anchor the end + if (substr($regex, -1) !== '\\') { + $regex .= '$'; + } + + $regexps[] = '{^\\\\'.$regex.'}'; + } + + return $regexps; + } + + private function matchAnyRegexps($class, $regexps) + { + $blacklisted = false !== strpos($class, 'Test'); + + foreach ($regexps as $regex) { + if ($blacklisted && false === strpos($regex, 'Test')) { + continue; + } + + if (preg_match($regex, '\\'.$class)) { + return true; + } + } + + return false; } }