vendor/symfony/config/Builder/ClassBuilder.php line 125

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Config\Builder;
  11. /**
  12.  * Build PHP classes to generate config.
  13.  *
  14.  * @internal
  15.  *
  16.  * @author Tobias Nyholm <tobias.nyholm@gmail.com>
  17.  */
  18. class ClassBuilder
  19. {
  20.     /** @var string */
  21.     private $namespace;
  22.     /** @var string */
  23.     private $name;
  24.     /** @var Property[] */
  25.     private $properties = [];
  26.     /** @var Method[] */
  27.     private $methods = [];
  28.     private $require = [];
  29.     private $use = [];
  30.     private $implements = [];
  31.     private $allowExtraKeys = false;
  32.     public function __construct(string $namespace, string $name)
  33.     {
  34.         $this->namespace = $namespace;
  35.         $this->name = ucfirst($this->camelCase($name)).'Config';
  36.     }
  37.     public function getDirectory(): string
  38.     {
  39.         return str_replace('\\', \DIRECTORY_SEPARATOR, $this->namespace);
  40.     }
  41.     public function getFilename(): string
  42.     {
  43.         return $this->name.'.php';
  44.     }
  45.     public function build(): string
  46.     {
  47.         $rootPath = explode(\DIRECTORY_SEPARATOR, $this->getDirectory());
  48.         $require = '';
  49.         foreach ($this->require as $class) {
  50.             // figure out relative path.
  51.             $path = explode(\DIRECTORY_SEPARATOR, $class->getDirectory());
  52.             $path[] = $class->getFilename();
  53.             foreach ($rootPath as $key => $value) {
  54.                 if ($path[$key] !== $value) {
  55.                     break;
  56.                 }
  57.                 unset($path[$key]);
  58.             }
  59.             $require .= sprintf('require_once __DIR__.\DIRECTORY_SEPARATOR.\'%s\';', implode('\'.\DIRECTORY_SEPARATOR.\'', $path))."\n";
  60.         }
  61.         $use = $require ? "\n" : '';
  62.         foreach (array_keys($this->use) as $statement) {
  63.             $use .= sprintf('use %s;', $statement)."\n";
  64.         }
  65.         $implements = [] === $this->implements ? '' : 'implements '.implode(', ', $this->implements);
  66.         $body = '';
  67.         foreach ($this->properties as $property) {
  68.             $body .= '    '.$property->getContent()."\n";
  69.         }
  70.         foreach ($this->methods as $method) {
  71.             $lines = explode("\n", $method->getContent());
  72.             foreach ($lines as $line) {
  73.                 $body .= ($line ? '    '.$line : '')."\n";
  74.             }
  75.         }
  76.         $content = strtr('<?php
  77. namespace NAMESPACE;
  78. REQUIREUSE
  79. /**
  80.  * This class is automatically generated to help in creating a config.
  81.  */
  82. class CLASS IMPLEMENTS
  83. {
  84. BODY
  85. }
  86. ', ['NAMESPACE' => $this->namespace, 'REQUIRE' => $require, 'USE' => $use, 'CLASS' => $this->getName(), 'IMPLEMENTS' => $implements, 'BODY' => $body]);
  87.         return $content;
  88.     }
  89.     public function addRequire(self $class): void
  90.     {
  91.         $this->require[] = $class;
  92.     }
  93.     public function addUse(string $class): void
  94.     {
  95.         $this->use[$class] = true;
  96.     }
  97.     public function addImplements(string $interface): void
  98.     {
  99.         $this->implements[] = '\\'.ltrim($interface, '\\');
  100.     }
  101.     public function addMethod(string $name, string $body, array $params = []): void
  102.     {
  103.         $this->methods[] = new Method(strtr($body, ['NAME' => $this->camelCase($name)] + $params));
  104.     }
  105.     public function addProperty(string $name, string $classType = null, string $defaultValue = null): Property
  106.     {
  107.         $property = new Property($name, '_' !== $name[0] ? $this->camelCase($name) : $name);
  108.         if (null !== $classType) {
  109.             $property->setType($classType);
  110.         }
  111.         $this->properties[] = $property;
  112.         $defaultValue = null !== $defaultValue ? sprintf(' = %s', $defaultValue) : '';
  113.         $property->setContent(sprintf('private $%s%s;', $property->getName(), $defaultValue));
  114.         return $property;
  115.     }
  116.     public function getProperties(): array
  117.     {
  118.         return $this->properties;
  119.     }
  120.     private function camelCase(string $input): string
  121.     {
  122.         $output = lcfirst(str_replace(' ', '', ucwords(str_replace('_', ' ', $input))));
  123.         return preg_replace('#\W#', '', $output);
  124.     }
  125.     public function getName(): string
  126.     {
  127.         return $this->name;
  128.     }
  129.     public function getNamespace(): string
  130.     {
  131.         return $this->namespace;
  132.     }
  133.     public function getFqcn(): string
  134.     {
  135.         return '\\'.$this->namespace.'\\'.$this->name;
  136.     }
  137.     public function setAllowExtraKeys(bool $allowExtraKeys): void
  138.     {
  139.         $this->allowExtraKeys = $allowExtraKeys;
  140.     }
  141.     public function shouldAllowExtraKeys(): bool
  142.     {
  143.         return $this->allowExtraKeys;
  144.     }
  145. }