* * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. */ namespace Sonata\CoreBundle\Command; use Doctrine\ORM\Mapping\ClassMetadata; use Gaufrette\Adapter\Local as LocalAdapter; use Gaufrette\Filesystem; use Symfony\Bundle\FrameworkBundle\Command\ContainerAwareCommand; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** * Return useful data on the database schema. */ class SonataDumpDoctrineMetaCommand extends ContainerAwareCommand { /** * @var array */ protected $metadata; /** * {@inheritdoc} */ protected function configure() { $this ->setName('sonata:core:dump-doctrine-metadata') ->setDefinition(array( new InputOption( 'entity-name', 'E', InputOption::VALUE_OPTIONAL, 'If entity-name is set, dump will only contain the specified entity and all its extended classes.', null ), new InputOption( 'regex', 'r', InputOption::VALUE_OPTIONAL, 'If regex is set, dump will only contain entities which name match the pattern.', null ), new InputOption( 'filename', 'f', InputOption::VALUE_OPTIONAL, 'If filename is specified, result will be dumped into this file under json format.', null ), )) ->setDescription('Get information on the current Doctrine\'s schema') ; } /** * {@inheritdoc} */ protected function initialize(InputInterface $input, OutputInterface $output) { $output->writeln('Initialising Doctrine metadata.'); $manager = $this->getContainer()->get('doctrine')->getManager(); $metadata = $manager->getMetadataFactory()->getAllMetadata(); $allowedMeta = $this->filterMetadata($metadata, $input, $output); /** @var ClassMetadata $meta */ foreach ($allowedMeta as $meta) { $this->metadata[$meta->getName()] = $this->normalizeDoctrineORMMeta($meta); } } /** * {@inheritdoc} */ protected function execute(InputInterface $input, OutputInterface $output) { if (!$this->metadata) { $output->writeln('No meta was found'); return 1; } $this->dumpMetadata($this->metadata, $input, $output); return 0; } /** * Display the list of entities handled by Doctrine and their fields. * * @param array $metadata * @param InputInterface $input * @param OutputInterface $output */ private function dumpMetadata(array $metadata, InputInterface $input, OutputInterface $output) { foreach ($metadata as $name => $meta) { $output->writeln(sprintf('%s', $name)); foreach ($meta['fields'] as $fieldName => $columnName) { $output->writeln(sprintf(' > %s => %s', $fieldName, $columnName)); } } $output->writeln('---------------'); $output->writeln('---- END ----'); $output->writeln('---------------'); $output->writeln(''); if ($input->getOption('filename')) { $directory = dirname($input->getOption('filename')); $filename = basename($input->getOption('filename')); if (empty($directory) || $directory === '.') { $directory = getcwd(); } $adapter = new LocalAdapter($directory, true); $fileSystem = new Filesystem($adapter); $success = $fileSystem->write($filename, json_encode($metadata), true); if ($success) { $output->writeLn(sprintf('File %s/%s successfully created', $directory, $filename)); } else { $output->writeLn(sprintf('File %s/%s could not be created', $directory, $filename)); } } } /** * @param array $metadata * @param InputInterface $input * @param OutputInterface $output * * @return array */ private function filterMetadata(array $metadata, InputInterface $input, OutputInterface $output) { $baseEntity = $input->getOption('entity-name'); $regex = $input->getOption('regex'); if ($baseEntity) { $allowedMeta = array_filter( $metadata, function ($meta) use ($baseEntity) { /* @var \Doctrine\ORM\Mapping\ClassMetadata $meta */ return $meta->rootEntityName === $baseEntity; } ); } elseif ($regex) { $allowedMeta = array_filter( $metadata, function ($meta) use ($regex) { /* @var \Doctrine\ORM\Mapping\ClassMetadata $meta */ return preg_match($regex, $meta->rootEntityName); } ); } else { $allowedMeta = $metadata; } return $allowedMeta; } /** * @param ClassMetadata $meta * * @return array */ private function normalizeDoctrineORMMeta(ClassMetadata $meta) { $normalizedMeta = array(); $fieldMappings = $meta->fieldMappings; $normalizedMeta['table'] = $meta->table['name']; foreach ($fieldMappings as $field) { $normalizedMeta['fields'][$field['fieldName']] = isset($field['columnName']) ? $field['columnName'] : null; } return $normalizedMeta; } }