Ответ 1
Я немного играл с кодом и, к сожалению, нет способа генерировать его по-разному с существующей настройкой. Все классы жестко закодированы, и нет возможности переопределить его с помощью команд или настроек Symfony.
Итак, я немного расширил классы генераторов и создал расширенную команду, которая принимает генератор в качестве параметра. Я также создал генератор выборок, который создал методы "is..." для установки булевых элементов.
К сожалению, существует некоторая копия-вставка из существующих классов, потому что ее невозможно расширить.
Отвечая на второй вопрос, я думаю, что это более личное предпочтение, используя свободный интерфейс. Я старый школьный разработчик, и я не привык к свободному интерфейсу в PHP. Я не вижу существенного влияния на производительность.
Для третьего вопроса. Разница между bool
и boolean
заключается в том, что bool
является объявление скалярного типа, а boolean
- тип переменной. См. "Предупреждение" в документации. Это объясняет многое.
<?php
// src/AppBundle/Command/GenerateDoctrineEntityExtendedCommand.php
namespace AppBundle\Command;
use Sensio\Bundle\GeneratorBundle\Command\GenerateDoctrineEntityCommand;
use Sensio\Bundle\GeneratorBundle\Generator\Generator;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
class GenerateDoctrineEntityExtendedCommand extends GenerateDoctrineEntityCommand
{
/** @var Generator */
private $generator;
protected function configure()
{
parent::configure();
$this->setName('doctrine:generate:entity:extended');
$this->setDescription($this->getDescription() . " Allows specifying generator class.");
$this->addOption('generator', null, InputOption::VALUE_REQUIRED, "The generator class to create entity.", 'Sensio\Bundle\GeneratorBundle\Generator\DoctrineEntityGenerator');
}
protected function initialize(InputInterface $input, OutputInterface $output)
{
parent::initialize($input, $output);
if ($class = $input->getOption('generator')) {
if (!class_exists($class)) {
throw new \Exception('Class ' . $class . 'does not exist.');
}
$this->generator = new $class($this->getContainer()->get('filesystem'), $this->getContainer()->get('doctrine'));
}
}
protected function createGenerator()
{
return $this->generator;
}
}
Замена DoctrineEntityGenerator:
<?php
// src/AppBundle/Generator/IsDoctrineEntityGenerator.php
namespace AppBundle\Generator;
use Sensio\Bundle\GeneratorBundle\Generator\DoctrineEntityGenerator;
class IsDoctrineEntityGenerator extends DoctrineEntityGenerator
{
protected function getEntityGenerator()
{
// This is the place where customized entity generator is instantiated instead of default
$entityGenerator = new IsEntityGenerator();
$entityGenerator->setGenerateAnnotations(false);
$entityGenerator->setGenerateStubMethods(true);
$entityGenerator->setRegenerateEntityIfExists(false);
$entityGenerator->setUpdateEntityIfExists(true);
$entityGenerator->setNumSpaces(4);
$entityGenerator->setAnnotationPrefix('ORM\\');
return $entityGenerator;
}
}
Замена EntityGenerator:
<?php
// src/AppBundle/Generator/IsEntityGenerator.php
namespace AppBundle\Generator;
use Doctrine\Common\Inflector\Inflector;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Tools\EntityGenerator;
use Doctrine\DBAL\Types\Type;
class IsEntityGenerator extends EntityGenerator
{
protected function generateEntityStubMethod(ClassMetadataInfo $metadata, $type, $fieldName, $typeHint = null, $defaultValue = null)
{
//
// This is the only line I've added compared to the original method
//
$methodPrefix = ($type == 'get' && $typeHint == 'boolean') ? 'is' : $type;
$methodName = $methodPrefix . Inflector::classify($fieldName);
$variableName = Inflector::camelize($fieldName);
if (in_array($type, array("add", "remove"))) {
$methodName = Inflector::singularize($methodName);
$variableName = Inflector::singularize($variableName);
}
if ($this->hasMethod($methodName, $metadata)) {
return '';
}
$this->staticReflection[$metadata->name]['methods'][] = strtolower($methodName);
$var = sprintf('%sMethodTemplate', $type);
$template = static::$$var;
$methodTypeHint = null;
$types = Type::getTypesMap();
$variableType = $typeHint ? $this->getType($typeHint) : null;
if ($typeHint && !isset($types[$typeHint])) {
$variableType = '\\' . ltrim($variableType, '\\');
$methodTypeHint = '\\' . $typeHint . ' ';
}
$replacements = array(
'<description>' => ucfirst($type) . ' ' . $variableName,
'<methodTypeHint>' => $methodTypeHint,
'<variableType>' => $variableType,
'<variableName>' => $variableName,
'<methodName>' => $methodName,
'<fieldName>' => $fieldName,
'<variableDefault>' => ($defaultValue !== null) ? (' = ' . $defaultValue) : '',
'<entity>' => $this->getClassName($metadata)
);
$method = str_replace(
array_keys($replacements),
array_values($replacements),
$template
);
return $this->prefixCodeWithSpaces($method);
}
}
Так что я боюсь единственного варианта того, что вы хотите до сих пор.