GenerateEntitiesDoctrineCommand.php 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. /*
  3. * This file is part of the Doctrine Bundle
  4. *
  5. * The code was originally distributed inside the Symfony framework.
  6. *
  7. * (c) Fabien Potencier <fabien@symfony.com>
  8. * (c) Doctrine Project, Benjamin Eberlei <kontakt@beberlei.de>
  9. *
  10. * For the full copyright and license information, please view the LICENSE
  11. * file that was distributed with this source code.
  12. */
  13. namespace Doctrine\Bundle\DoctrineBundle\Command;
  14. use Symfony\Component\Console\Input\InputArgument;
  15. use Symfony\Component\Console\Input\InputOption;
  16. use Symfony\Component\Console\Input\InputInterface;
  17. use Symfony\Component\Console\Output\OutputInterface;
  18. use Doctrine\ORM\Tools\EntityRepositoryGenerator;
  19. use Doctrine\Bundle\DoctrineBundle\Mapping\DisconnectedMetadataFactory;
  20. /**
  21. * Generate entity classes from mapping information
  22. *
  23. * @author Fabien Potencier <fabien@symfony.com>
  24. * @author Jonathan H. Wage <jonwage@gmail.com>
  25. */
  26. class GenerateEntitiesDoctrineCommand extends DoctrineCommand
  27. {
  28. /**
  29. * {@inheritDoc}
  30. */
  31. protected function configure()
  32. {
  33. $this
  34. ->setName('doctrine:generate:entities')
  35. ->setAliases(array('generate:doctrine:entities'))
  36. ->setDescription('Generates entity classes and method stubs from your mapping information')
  37. ->addArgument('name', InputArgument::REQUIRED, 'A bundle name, a namespace, or a class name')
  38. ->addOption('path', null, InputOption::VALUE_REQUIRED, 'The path where to generate entities when it cannot be guessed')
  39. ->addOption('no-backup', null, InputOption::VALUE_NONE, 'Do not backup existing entities files.')
  40. ->setHelp(<<<EOT
  41. The <info>doctrine:generate:entities</info> command generates entity classes
  42. and method stubs from your mapping information:
  43. You have to limit generation of entities:
  44. * To a bundle:
  45. <info>php app/console doctrine:generate:entities MyCustomBundle</info>
  46. * To a single entity:
  47. <info>php app/console doctrine:generate:entities MyCustomBundle:User</info>
  48. <info>php app/console doctrine:generate:entities MyCustomBundle/Entity/User</info>
  49. * To a namespace
  50. <info>php app/console doctrine:generate:entities MyCustomBundle/Entity</info>
  51. If the entities are not stored in a bundle, and if the classes do not exist,
  52. the command has no way to guess where they should be generated. In this case,
  53. you must provide the <comment>--path</comment> option:
  54. <info>php app/console doctrine:generate:entities Blog/Entity --path=src/</info>
  55. By default, the unmodified version of each entity is backed up and saved
  56. (e.g. Product.php~). To prevent this task from creating the backup file,
  57. pass the <comment>--no-backup</comment> option:
  58. <info>php app/console doctrine:generate:entities Blog/Entity --no-backup</info>
  59. <error>Important:</error> Even if you specified Inheritance options in your
  60. XML or YAML Mapping files the generator cannot generate the base and
  61. child classes for you correctly, because it doesn't know which
  62. class is supposed to extend which. You have to adjust the entity
  63. code manually for inheritance to work!
  64. EOT
  65. );
  66. }
  67. /**
  68. * {@inheritDoc}
  69. */
  70. protected function execute(InputInterface $input, OutputInterface $output)
  71. {
  72. $manager = new DisconnectedMetadataFactory($this->getContainer()->get('doctrine'));
  73. try {
  74. $bundle = $this->getApplication()->getKernel()->getBundle($input->getArgument('name'));
  75. $output->writeln(sprintf('Generating entities for bundle "<info>%s</info>"', $bundle->getName()));
  76. $metadata = $manager->getBundleMetadata($bundle);
  77. } catch (\InvalidArgumentException $e) {
  78. $name = strtr($input->getArgument('name'), '/', '\\');
  79. if (false !== $pos = strpos($name, ':')) {
  80. $name = $this->getContainer()->get('doctrine')->getEntityNamespace(substr($name, 0, $pos)).'\\'.substr($name, $pos + 1);
  81. }
  82. if (class_exists($name)) {
  83. $output->writeln(sprintf('Generating entity "<info>%s</info>"', $name));
  84. $metadata = $manager->getClassMetadata($name, $input->getOption('path'));
  85. } else {
  86. $output->writeln(sprintf('Generating entities for namespace "<info>%s</info>"', $name));
  87. $metadata = $manager->getNamespaceMetadata($name, $input->getOption('path'));
  88. }
  89. }
  90. $generator = $this->getEntityGenerator();
  91. $backupExisting = !$input->getOption('no-backup');
  92. $generator->setBackupExisting($backupExisting);
  93. $repoGenerator = new EntityRepositoryGenerator();
  94. foreach ($metadata->getMetadata() as $m) {
  95. if ($backupExisting) {
  96. $basename = substr($m->name, strrpos($m->name, '\\') + 1);
  97. $output->writeln(sprintf(' > backing up <comment>%s.php</comment> to <comment>%s.php~</comment>', $basename, $basename));
  98. }
  99. // Getting the metadata for the entity class once more to get the correct path if the namespace has multiple occurrences
  100. try {
  101. $entityMetadata = $manager->getClassMetadata($m->getName(), $input->getOption('path'));
  102. } catch (\RuntimeException $e) {
  103. // fall back to the bundle metadata when no entity class could be found
  104. $entityMetadata = $metadata;
  105. }
  106. $output->writeln(sprintf(' > generating <comment>%s</comment>', $m->name));
  107. $generator->generate(array($m), $entityMetadata->getPath());
  108. if ($m->customRepositoryClassName && false !== strpos($m->customRepositoryClassName, $metadata->getNamespace())) {
  109. $repoGenerator->writeEntityRepositoryClass($m->customRepositoryClassName, $metadata->getPath());
  110. }
  111. }
  112. }
  113. }