diff --git a/core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php b/core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php index f785336..26583fa 100644 --- a/core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php +++ b/core/lib/Drupal/Component/ProxyBuilder/ProxyBuilder.php @@ -7,42 +7,63 @@ namespace Drupal\Component\ProxyBuilder; +/** + * Generates the string representation of the proxy service. + */ class ProxyBuilder { + /** + * Generates the used proxy class name from a given class name. + * + * @param string $class_name + * The class name of the actual service. + * + * @return string + * The class name of the proxy. + */ public function buildProxyClassName($class_name) { return str_replace('\\', '_', $class_name) . '_Proxy'; } + /** + * Builds a proxy class string. + * + * @param string $class_name + * The class name of the actual service. + * + * @return string + * The full string with namespace class and methods. + */ public function build($class_name) { $reflection = new \ReflectionClass($class_name); // The actual class; - $output = 'class ' . $this->buildProxyClassName($class_name); + $output = ''; + $class_start = 'class ' . $this->buildProxyClassName($class_name); if ($interfaces = $reflection->getInterfaceNames()) { -// foreach ($interfaces as &$interface) { -// $interface = '\\' . $interface; -// } $output .= ' implements ' . implode(', ', $interfaces); } $output .= " {\n"; // Add the variables. - $output .= "\n /** - * @var string - */ - protected \$serviceId;\n + $output .= "\n/** + * @var string + */ +protected \$serviceId; - /** - * @var \\$class_name - */ - protected \$service;\n"; +/** + * @var \\$class_name + */ +protected \$service;\n\n"; + // Add all the methods. $methods = []; $methods[] = $this->buildConstructorMethod(); $methods[] = $this->buildLazyLoadItselfMethod(); + // Add all the methods of the proxied service. $reflection_methods = $reflection->getMethods(); foreach ($reflection_methods as $method) { @@ -57,11 +78,19 @@ public function build($class_name) { $output .= implode("\n", $methods); - $output .= "\n}\n"; + // Intend the output. + $output = implode("\n", array_map(function($value) { + return " $value"; + }, explode("\n", $output))); - return $output; + return $class_start . $output . "\n\n}\n"; } + /** + * Generates the string for the method which loads the actual service. + * + * @return string + */ protected function buildLazyLoadItselfMethod() { $output = "protected function lazyLoadItself() { if (!isset(\$this->service)) { @@ -75,6 +104,14 @@ protected function buildLazyLoadItselfMethod() { return $output; } + /** + * Generates the string representation of a single method: signature, body. + * + * @param \ReflectionMethod $reflection_method + * A reflection method for the method. + * + * @return string + */ protected function buildMethod(\ReflectionMethod $reflection_method) { $parameters = []; @@ -83,10 +120,9 @@ protected function buildMethod(\ReflectionMethod $reflection_method) { } $function_name = $reflection_method->getName(); - $signature_line = 'public function ' . $function_name . '('; + $signature_line = 'public function ' . $function_name . '('; $signature_line .= implode(', ', $parameters); - $signature_line .= ')'; $output = $signature_line . ' {' . "\n"; @@ -97,14 +133,26 @@ protected function buildMethod(\ReflectionMethod $reflection_method) { return $output; } + /** + * Builds a string for a single parameter of a method. + * + * @param \ReflectionParameter $parameter + * A reflection object of the parameter. + * + * @return string + */ protected function buildParameter(\ReflectionParameter $parameter) { $parameter_string = ''; + if ($parameter->isArray()) { $parameter_string .= 'array '; } - if ($parameter->isCallable()) { + elseif ($parameter->isCallable()) { $parameter_string .= 'callable '; } + elseif ($class = $parameter->getClass()) { + $parameter_string .= $class->getName() . ' '; + } if ($parameter->isPassedByReference()) { $parameter_string .= '&'; @@ -120,6 +168,14 @@ protected function buildParameter(\ReflectionParameter $parameter) { return $parameter_string; } + /** + * Builds the body of a wrapped method. + * + * @param \ReflectionMethod $reflection_method + * A reflection method for the method. + * + * @return string + */ protected function buildMethodBody(\ReflectionMethod $reflection_method) { $output = ''; @@ -138,6 +194,11 @@ protected function buildMethodBody(\ReflectionMethod $reflection_method) { return $output; } + /** + * Builds the constructor used to inject the actual service ID. + * + * @return string + */ protected function buildConstructorMethod() { $output = 'public function __construct($service_id) { $this->serviceId = $service_id; diff --git a/core/lib/Drupal/Component/ProxyBuilder/ProxyDumper.php b/core/lib/Drupal/Component/ProxyBuilder/ProxyDumper.php index fb125d8..07e30ee 100644 --- a/core/lib/Drupal/Component/ProxyBuilder/ProxyDumper.php +++ b/core/lib/Drupal/Component/ProxyBuilder/ProxyDumper.php @@ -10,6 +10,9 @@ use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\LazyProxy\PhpDumper\DumperInterface; +/** + * Dumps the proxy service into the dumped PHP container file. + */ class ProxyDumper implements DumperInterface { /** @@ -35,6 +38,9 @@ public function isProxyCandidate(Definition $definition) { */ public function getProxyFactoryCode(Definition $definition, $id) { $id = var_export($id, TRUE); + // Note: the specific get method is called initially with $lazyLoad=TRUE; + // When you want to retrieve the actual service, the code generated in + // ProxyBuilder calls the method with lazy loading disabled. $output = " if (\$lazyLoad) {\n"; $output .= " return \$this->services[$id] = new " . $this->builder->buildProxyClassName($definition->getClass()) . '(' . $id . ");\n"; $output .= " }\n";