ImportMappingDoctrineCommand.php 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. <?php
  2. namespace Doctrine\Bundle\DoctrineBundle\Command;
  3. use Doctrine\ORM\Mapping\Driver\DatabaseDriver;
  4. use Doctrine\ORM\Tools\Console\MetadataFilter;
  5. use Doctrine\ORM\Tools\DisconnectedClassMetadataFactory;
  6. use Doctrine\ORM\Tools\Export\ClassMetadataExporter;
  7. use Doctrine\Persistence\ManagerRegistry;
  8. use InvalidArgumentException;
  9. use Symfony\Component\Console\Input\InputArgument;
  10. use Symfony\Component\Console\Input\InputInterface;
  11. use Symfony\Component\Console\Input\InputOption;
  12. use Symfony\Component\Console\Output\OutputInterface;
  13. use function chmod;
  14. use function dirname;
  15. use function file_put_contents;
  16. use function is_dir;
  17. use function mkdir;
  18. use function sprintf;
  19. use function str_replace;
  20. /**
  21. * Import Doctrine ORM metadata mapping information from an existing database.
  22. *
  23. * @deprecated
  24. *
  25. * @final
  26. */
  27. class ImportMappingDoctrineCommand extends DoctrineCommand
  28. {
  29. /** @var string[] */
  30. private $bundles;
  31. /**
  32. * @param string[] $bundles
  33. */
  34. public function __construct(ManagerRegistry $doctrine, array $bundles)
  35. {
  36. parent::__construct($doctrine);
  37. $this->bundles = $bundles;
  38. }
  39. /**
  40. * {@inheritDoc}
  41. */
  42. protected function configure()
  43. {
  44. $this
  45. ->setName('doctrine:mapping:import')
  46. ->addArgument('name', InputArgument::REQUIRED, 'The bundle or namespace to import the mapping information to')
  47. ->addArgument('mapping-type', InputArgument::OPTIONAL, 'The mapping type to export the imported mapping information to')
  48. ->addOption('em', null, InputOption::VALUE_OPTIONAL, 'The entity manager to use for this command')
  49. ->addOption('shard', null, InputOption::VALUE_REQUIRED, 'The shard connection to use for this command')
  50. ->addOption('filter', null, InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY, 'A string pattern used to match entities that should be mapped.')
  51. ->addOption('force', null, InputOption::VALUE_NONE, 'Force to overwrite existing mapping files.')
  52. ->addOption('path', null, InputOption::VALUE_REQUIRED, 'The path where the files would be generated (not used when a bundle is passed).')
  53. ->setDescription('Imports mapping information from an existing database')
  54. ->setHelp(<<<EOT
  55. The <info>%command.name%</info> command imports mapping information
  56. from an existing database:
  57. Generate annotation mappings into the src/ directory using App as the namespace:
  58. <info>php %command.full_name% App\\\Entity annotation --path=src/Entity</info>
  59. Generate xml mappings into the config/doctrine/ directory using App as the namespace:
  60. <info>php %command.full_name% App\\\Entity xml --path=config/doctrine</info>
  61. Generate XML mappings into a bundle:
  62. <info>php %command.full_name% "MyCustomBundle" xml</info>
  63. You can also optionally specify which entity manager to import from with the
  64. <info>--em</info> option:
  65. <info>php %command.full_name% "MyCustomBundle" xml --em=default</info>
  66. If you don't want to map every entity that can be found in the database, use the
  67. <info>--filter</info> option. It will try to match the targeted mapped entity with the
  68. provided pattern string.
  69. <info>php %command.full_name% "MyCustomBundle" xml --filter=MyMatchedEntity</info>
  70. Use the <info>--force</info> option, if you want to override existing mapping files:
  71. <info>php %command.full_name% "MyCustomBundle" xml --force</info>
  72. EOT
  73. );
  74. }
  75. /**
  76. * {@inheritDoc}
  77. */
  78. protected function execute(InputInterface $input, OutputInterface $output)
  79. {
  80. $type = $input->getArgument('mapping-type') ?: 'xml';
  81. if ($type === 'yaml') {
  82. $type = 'yml';
  83. }
  84. $namespaceOrBundle = $input->getArgument('name');
  85. if (isset($this->bundles[$namespaceOrBundle])) {
  86. $bundle = $this->getApplication()->getKernel()->getBundle($namespaceOrBundle);
  87. $namespace = $bundle->getNamespace() . '\Entity';
  88. $destPath = $bundle->getPath();
  89. if ($type === 'annotation') {
  90. $destPath .= '/Entity';
  91. } else {
  92. $destPath .= '/Resources/config/doctrine';
  93. }
  94. } else {
  95. // assume a namespace has been passed
  96. $namespace = $namespaceOrBundle;
  97. $destPath = $input->getOption('path');
  98. if ($destPath === null) {
  99. throw new InvalidArgumentException('The --path option is required when passing a namespace (e.g. --path=src). If you intended to pass a bundle name, check your spelling.');
  100. }
  101. }
  102. $cme = new ClassMetadataExporter();
  103. $exporter = $cme->getExporter($type);
  104. $exporter->setOverwriteExistingFiles($input->getOption('force'));
  105. if ($type === 'annotation') {
  106. $entityGenerator = $this->getEntityGenerator();
  107. $exporter->setEntityGenerator($entityGenerator);
  108. }
  109. $em = $this->getEntityManager($input->getOption('em'), $input->getOption('shard'));
  110. $databaseDriver = new DatabaseDriver($em->getConnection()->getSchemaManager());
  111. $em->getConfiguration()->setMetadataDriverImpl($databaseDriver);
  112. $emName = $input->getOption('em');
  113. $emName = $emName ? $emName : 'default';
  114. $cmf = new DisconnectedClassMetadataFactory();
  115. $cmf->setEntityManager($em);
  116. $metadata = $cmf->getAllMetadata();
  117. $metadata = MetadataFilter::filter($metadata, $input->getOption('filter'));
  118. if ($metadata) {
  119. $output->writeln(sprintf('Importing mapping information from "<info>%s</info>" entity manager', $emName));
  120. foreach ($metadata as $class) {
  121. $className = $class->name;
  122. $class->name = $namespace . '\\' . $className;
  123. if ($type === 'annotation') {
  124. $path = $destPath . '/' . str_replace('\\', '.', $className) . '.php';
  125. } else {
  126. $path = $destPath . '/' . str_replace('\\', '.', $className) . '.orm.' . $type;
  127. }
  128. $output->writeln(sprintf(' > writing <comment>%s</comment>', $path));
  129. $code = $exporter->exportClassMetadata($class);
  130. $dir = dirname($path);
  131. if (! is_dir($dir)) {
  132. mkdir($dir, 0775, true);
  133. }
  134. file_put_contents($path, $code);
  135. chmod($path, 0664);
  136. }
  137. return 0;
  138. }
  139. $output->writeln('Database does not have any mapping information.');
  140. $output->writeln('');
  141. return 1;
  142. }
  143. }