/** * {@inheritdoc} */ public function getProxyFactoryCode(Definition $definition, $id) { // 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 = <<<'EOS' if ($lazyLoad) { return $this->services['{{ id }}'] = new {{ class_name }}($this, '{{ id }}'); } EOS; $output = str_replace('{{ id }}', $id, $output); $output = str_replace('{{ class_name }}', $this->builder->buildProxyClassName($definition->getClass()), $output); return $output; }
/** * Constructs the expected class output. * * @param string $expected_methods_body * The expected body of decorated methods. * * @return string * The code of the entire proxy. */ protected function buildExpectedClass($class, $expected_methods_body, $interface_string = '') { $proxy_class = $this->proxyBuilder->buildProxyClassName($class); $expected_string = <<<'EOS' /** * Provides a proxy class for \{{ class }}. * * @see \Drupal\Component\ProxyBuilder */ class {{ proxy_class }}{{ interface_string }} { /** * @var string */ protected $serviceId; /** * @var \{{ class }} */ protected $service; /** * The service container. * * @var \Symfony\Component\DependencyInjection\ContainerInterface */ protected $container; public function __construct(\Symfony\Component\DependencyInjection\ContainerInterface $container, $serviceId) { $this->container = $container; $this->serviceId = $serviceId; } protected function lazyLoadItself() { if (!isset($this->service)) { $method_name = 'get' . Container::camelize($this->serviceId) . 'Service'; $this->service = $this->container->$method_name(false); } return $this->service; } {{ expected_methods_body }} } EOS; $expected_string = str_replace('{{ proxy_class }}', $proxy_class, $expected_string); $expected_string = str_replace('{{ class }}', $class, $expected_string); $expected_string = str_replace('{{ expected_methods_body }}', $expected_methods_body, $expected_string); $expected_string = str_replace('{{ interface_string }}', $interface_string, $expected_string); return $expected_string; }
/** * {@inheritdoc} */ public function process(ContainerBuilder $container) { foreach ($container->getDefinitions() as $service_id => $definition) { if ($definition->isLazy()) { $proxy_class = ProxyBuilder::buildProxyClassName($definition->getClass()); if (class_exists($proxy_class)) { // Copy the existing definition to a new entry. $definition->setLazy(FALSE); // Ensure that the service is accessible. $definition->setPublic(TRUE); $new_service_id = 'drupal.proxy_original_service.' . $service_id; $container->setDefinition($new_service_id, $definition); $container->register($service_id, $proxy_class)->setArguments([new Reference('service_container'), $new_service_id]); } else { $class_name = $definition->getClass(); // Find the root namespace. $match = []; preg_match('/([a-zA-Z0-9_]+\\\\[a-zA-Z0-9_]+)\\\\(.+)/', $class_name, $match); $root_namespace = $match[1]; // Find the root namespace path. $root_namespace_dir = '[namespace_root_path]'; $namespaces = $container->getParameter('container.namespaces'); // Hardcode Drupal Core, because it is not registered. $namespaces['Drupal\\Core'] = 'core/lib/Drupal/Core'; if (isset($namespaces[$root_namespace])) { $root_namespace_dir = $namespaces[$root_namespace]; } $message = <<<EOF Missing proxy class '{$proxy_class}' for lazy service '{$service_id}'. Use the following command to generate the proxy class: php core/scripts/generate-proxy-class.php '{$class_name}' "{$root_namespace_dir}" EOF; trigger_error($message, E_USER_WARNING); } } } }
/** * @covers ::buildProxyClassName */ public function testBuildProxyClassNameForModule() { $class_name = $this->proxyBuilder->buildProxyClassName('Drupal\\views_ui\\ParamConverter\\ViewUIConverter'); $this->assertEquals('Drupal\\views_ui\\ProxyClass\\ParamConverter\\ViewUIConverter', $class_name); }