diff -r 000000000000 -r 7f95f8617b0b vendor/bundles/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/bundles/Sensio/Bundle/GeneratorBundle/Command/GenerateDoctrineEntityCommand.php Sat Sep 24 15:40:41 2011 +0200 @@ -0,0 +1,314 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Sensio\Bundle\GeneratorBundle\Command; + +use Sensio\Bundle\GeneratorBundle\Generator\DoctrineEntityGenerator; +use Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; +use Doctrine\ORM\Mapping\ClassMetadataInfo; +use Doctrine\DBAL\Types\Type; + +/** + * Initializes a Doctrine entity inside a bundle. + * + * @author Fabien Potencier + */ +class GenerateDoctrineEntityCommand extends GenerateDoctrineCommand +{ + private $generator; + + protected function configure() + { + $this + ->setName('doctrine:generate:entity') + ->setAliases(array('generate:doctrine:entity')) + ->setDescription('Generates a new Doctrine entity inside a bundle') + ->addOption('entity', null, InputOption::VALUE_REQUIRED, 'The entity class name to initialize (shortcut notation)') + ->addOption('fields', null, InputOption::VALUE_REQUIRED, 'The fields to create with the new entity') + ->addOption('format', null, InputOption::VALUE_REQUIRED, 'Use the format for configuration files (php, xml, yml, or annotation)', 'annotation') + ->addOption('with-repository', null, InputOption::VALUE_NONE, 'Whether to generate the entity repository or not') + ->setHelp(<<doctrine:generate:entity task generates a new Doctrine +entity inside a bundle: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post + +The above command would initialize a new entity in the following entity +namespace Acme\BlogBundle\Entity\Blog\Post. + +You can also optionally specify the fields you want to generate in the new +entity: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --fields="title:string(255) body:text" + +The command can also generate the corresponding entity repository class with the +--with-repository option: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --with-repository + +By default, the command uses annotations for the mapping information; change it +with --format: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --format=yml + +To deactivate the interaction mode, simply use the `--no-interaction` option +whitout forgetting to pass all needed options: + +php app/console doctrine:generate:entity --entity=AcmeBlogBundle:Blog/Post --format=annotation --field="title:string(255) body:text" --with-repository --no-interaction +EOT + ); + } + + /** + * @throws \InvalidArgumentException When the bundle doesn't end with Bundle (Example: "Bundle/MySampleBundle") + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + + if ($input->isInteractive()) { + if (!$dialog->askConfirmation($output, $dialog->getQuestion('Do you confirm generation', 'yes', '?'), true)) { + $output->writeln('Command aborted'); + + return 1; + } + } + + $entity = Validators::validateEntityName($input->getOption('entity')); + list($bundle, $entity) = $this->parseShortcutNotation($entity); + $format = Validators::validateFormat($input->getOption('format')); + $fields = $this->parseFields($input->getOption('fields')); + + $dialog->writeSection($output, 'Entity generation'); + + $bundle = $this->getContainer()->get('kernel')->getBundle($bundle); + + $generator = $this->getGenerator(); + $generator->generate($bundle, $entity, $format, array_values($fields), $input->getOption('with-repository')); + + $output->writeln('Generating the entity code: OK'); + + $dialog->writeGeneratorSummary($output, array()); + } + + protected function interact(InputInterface $input, OutputInterface $output) + { + $dialog = $this->getDialogHelper(); + $dialog->writeSection($output, 'Welcome to the Doctrine2 entity generator'); + + // namespace + $output->writeln(array( + '', + 'This command helps you generate Doctrine2 entities.', + '', + 'First, you need to give the entity name you want to generate.', + 'You must use the shortcut notation like AcmeBlogBundle:Post.', + '' + )); + + while (true) { + $entity = $dialog->askAndValidate($output, $dialog->getQuestion('The Entity shortcut name', $input->getOption('entity')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateEntityName'), false, $input->getOption('entity')); + + list($bundle, $entity) = $this->parseShortcutNotation($entity); + + // check reserved words + $keywordList = $this->getContainer()->get('doctrine')->getConnection()->getDatabasePlatform()->getReservedKeywordsList(); + if($keywordList->isKeyword($entity)){ + $output->writeln(sprintf(' "%s" is a reserved word.', $entity)); + continue; + } + + try { + $b = $this->getContainer()->get('kernel')->getBundle($bundle); + + if (!file_exists($b->getPath().'/Entity/'.str_replace('\\', '/', $entity).'.php')) { + break; + } + + $output->writeln(sprintf('Entity "%s:%s" already exists.', $bundle, $entity)); + } catch (\Exception $e) { + $output->writeln(sprintf('Bundle "%s" does not exist.', $bundle)); + } + } + $input->setOption('entity', $bundle.':'.$entity); + + // format + $output->writeln(array( + '', + 'Determine the format to use for the mapping information.', + '', + )); + $format = $dialog->askAndValidate($output, $dialog->getQuestion('Configuration format (yml, xml, php, or annotation)', $input->getOption('format')), array('Sensio\Bundle\GeneratorBundle\Command\Validators', 'validateFormat'), false, $input->getOption('format')); + $input->setOption('format', $format); + + // fields + $input->setOption('fields', $this->addFields($input, $output, $dialog)); + + // repository? + $output->writeln(''); + $withRepository = $dialog->askConfirmation($output, $dialog->getQuestion('Do you want to generate an empty repository class', $input->getOption('with-repository') ? 'yes' : 'no', '?'), $input->getOption('with-repository')); + $input->setOption('with-repository', $withRepository); + + // summary + $output->writeln(array( + '', + $this->getHelper('formatter')->formatBlock('Summary before generation', 'bg=blue;fg=white', true), + '', + sprintf("You are going to generate a \"%s:%s\" Doctrine2 entity", $bundle, $entity), + sprintf("using the \"%s\" format.", $format), + '', + )); + } + + private function parseFields($input) + { + if (is_array($input)) { + return $input; + } + + $fields = array(); + foreach (explode(' ', $input) as $value) { + $elements = explode(':', $value); + $name = $elements[0]; + if (strlen($name)) { + $type = isset($elements[1]) ? $elements[1] : 'string'; + preg_match_all('/(.*)\((.*)\)/', $type, $matches); + $type = isset($matches[1][0]) ? $matches[1][0] : $type; + $length = isset($matches[2][0]) ? $matches[2][0] : null; + + $fields[$name] = array('fieldName' => $name, 'type' => $type, 'length' => $length); + } + } + + return $fields; + } + + private function addFields(InputInterface $input, OutputInterface $output, DialogHelper $dialog) + { + $fields = $this->parseFields($input->getOption('fields')); + $output->writeln(array( + '', + 'Instead of starting with a blank entity, you can add some fields now.', + 'Note that the primary key will be added automatically (named id).', + '', + )); + $output->write('Available types: '); + + $types = array_keys(Type::getTypesMap()); + $count = 20; + foreach ($types as $i => $type) { + if ($count > 50) { + $count = 0; + $output->writeln(''); + } + $count += strlen($type); + $output->write(sprintf('%s', $type)); + if (count($types) != $i + 1) { + $output->write(', '); + } else { + $output->write('.'); + } + } + $output->writeln(''); + + $fieldValidator = function ($type) use ($types) { + // FIXME: take into account user-defined field types + if (!in_array($type, $types)) { + throw new \InvalidArgumentException(sprintf('Invalid type "%s".', $type)); + } + + return $type; + }; + + $lengthValidator = function ($length) { + if (!$length) { + return $length; + } + + $result = filter_var($length, FILTER_VALIDATE_INT, array( + 'options' => array('min_range' => 1) + )); + + if (false === $result) { + throw new \InvalidArgumentException(sprintf('Invalid length "%s".', $length)); + } + + return $length; + }; + + while (true) { + $output->writeln(''); + $keywordList = $this->getContainer()->get('doctrine')->getConnection()->getDatabasePlatform()->getReservedKeywordsList(); + $name = $dialog->askAndValidate($output, $dialog->getQuestion('New field name (press to stop adding fields)', null), function ($name) use ($fields,$keywordList) { + if (isset($fields[$name]) || 'id' == $name) { + throw new \InvalidArgumentException(sprintf('Field "%s" is already defined.', $name)); + } + + // check reserved words + if($keywordList->isKeyword($name)){ + throw new \InvalidArgumentException(sprintf('Name "%s" is a reserved word.', $name)); + } + + return $name; + }); + if (!$name) { + break; + } + + $defaultType = 'string'; + + if (substr($name, -3) == '_at') { + $defaultType = 'datetime'; + } else if (substr($name, -3) == '_id') { + $defaultType = 'integer'; + } + + $type = $dialog->askAndValidate($output, $dialog->getQuestion('Field type', $defaultType), $fieldValidator, false, $defaultType); + + $data = array('fieldName' => $name, 'type' => $type); + + if ($type == 'string') { + $data['length'] = $dialog->askAndValidate($output, $dialog->getQuestion('Field length', 255), $lengthValidator, false, 255); + } + + $fields[$name] = $data; + } + + return $fields; + } + + protected function getGenerator() + { + if (null === $this->generator) { + $this->generator = new DoctrineEntityGenerator($this->getContainer()->get('filesystem'), $this->getContainer()->get('doctrine')); + } + + return $this->generator; + } + + public function setGenerator(DoctrineEntityGenerator $generator) + { + $this->generator = $generator; + } + + protected function getDialogHelper() + { + $dialog = $this->getHelperSet()->get('dialog'); + if (!$dialog || get_class($dialog) !== 'Sensio\Bundle\GeneratorBundle\Command\Helper\DialogHelper') { + $this->getHelperSet()->set($dialog = new DialogHelper()); + } + + return $dialog; + } +}