<?php
declare(strict_types=1);
/*
* This file is part of the Sonata Project package.
*
* (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
*
* 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.
*
* @deprecated since 3.12.0, to be removed in 4.0.
*/
class SonataDumpDoctrineMetaCommand extends ContainerAwareCommand
{
/**
* @var array
*/
protected $metadata;
protected function configure()
{
$this
->setName('sonata:core:dump-doctrine-metadata')
->setDefinition([
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')
;
}
protected function initialize(InputInterface $input, OutputInterface $output)
{
@trigger_error(
'The '.__CLASS__.' class is deprecated since version 3.12.0 and will be removed in 4.0.',
E_USER_DEPRECATED
);
$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);
}
}
protected function execute(InputInterface $input, OutputInterface $output)
{
if (!$this->metadata) {
$output->writeln('<error>No meta was found</error>');
return 1;
}
$this->dumpMetadata($this->metadata, $input, $output);
return 0;
}
/**
* Display the list of entities handled by Doctrine and their fields.
*/
private function dumpMetadata(array $metadata, InputInterface $input, OutputInterface $output)
{
foreach ($metadata as $name => $meta) {
$output->writeln(sprintf('<info>%s</info>', $name));
foreach ($meta['fields'] as $fieldName => $columnName) {
$output->writeln(sprintf(' <comment>></comment> %s <info>=></info> %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('<info>File %s/%s successfully created</info>', $directory, $filename));
} else {
$output->writeLn(sprintf('<error>File %s/%s could not be created</error>', $directory, $filename));
}
}
}
/**
* @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,
static function ($meta) use ($baseEntity) {
/* @var \Doctrine\ORM\Mapping\ClassMetadata $meta */
return $meta->rootEntityName === $baseEntity;
}
);
} elseif ($regex) {
$allowedMeta = array_filter(
$metadata,
static function ($meta) use ($regex) {
/* @var \Doctrine\ORM\Mapping\ClassMetadata $meta */
return preg_match($regex, $meta->rootEntityName);
}
);
} else {
$allowedMeta = $metadata;
}
return $allowedMeta;
}
/**
* @return array
*/
private function normalizeDoctrineORMMeta(ClassMetadata $meta)
{
$normalizedMeta = [];
$fieldMappings = $meta->fieldMappings;
$normalizedMeta['table'] = $meta->table['name'];
foreach ($fieldMappings as $field) {
$normalizedMeta['fields'][$field['fieldName']] = $field['columnName'] ?? null;
}
return $normalizedMeta;
}
}