*/ class ConfigDriver implements DriverInterface { private $bundles; private $config; public function __construct(array $bundles, array $config) { uasort($bundles, function($a, $b) { return strlen($b) - strlen($a); }); foreach ($bundles as $name => $namespace) { $bundles[$name] = substr($namespace, 0, strrpos($namespace, '\\')); } $this->bundles = $bundles; $this->config = $config; } public function loadMetadataForClass(\ReflectionClass $class) { $metadata = new ClassMetadata($class->name); foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED) as $method) { if ($method->getDeclaringClass()->name !== $class->name) { continue; } $expression = null; if (null !== $notation = $this->getControllerNotation($method)) { $expression = $this->getExpressionForSignature($notation); } if (null === $expression && null === $expression = $this->getExpressionForSignature($method->class.'::'.$method->name)) { continue; } $methodMetadata = new MethodMetadata($method->class, $method->name); $methodMetadata->roles = array(new Expression($expression)); $metadata->addMethodMetadata($methodMetadata); } if (!$metadata->methodMetadata) { return null; } return $metadata; } private function getExpressionForSignature($signature) { foreach ($this->config as $pattern => $expr) { if (!preg_match('#'.$pattern.'#i', $signature)) { continue; } return $expr; } return null; } // TODO: Is it feasible to reverse-engineer the notation for service controllers? private function getControllerNotation(\ReflectionMethod $method) { $signature = $method->class.'::'.$method->name; // check if class is a controller if (0 === preg_match('#\\\\Controller\\\\([^\\\\]+)Controller::(.+)Action$#', $signature, $match)) { return null; } foreach ($this->bundles as $name => $namespace) { if (0 !== strpos($method->class, $namespace)) { continue; } // controller notation (AcmeBundle:Foo:foo) return $name.':'.$match[1].':'.$match[2]; } return null; } }