class DebugCommand
Same name in this branch
- 11.1.x vendor/symfony/serializer/Command/DebugCommand.php \Symfony\Component\Serializer\Command\DebugCommand
A console command to debug Validators information.
@author Loïc Frémont <lc.fremont@gmail.com>
Hierarchy
- class \Symfony\Component\Console\Command\Command
- class \Symfony\Component\Validator\Command\DebugCommand extends \Symfony\Component\Console\Command\Command
Expanded class hierarchy of DebugCommand
File
-
vendor/
symfony/ validator/ Command/ DebugCommand.php, line 38
Namespace
Symfony\Component\Validator\CommandView source
class DebugCommand extends Command {
public function __construct(MetadataFactoryInterface $validator) {
parent::__construct();
}
protected function configure() : void {
$this->addArgument('class', InputArgument::REQUIRED, 'A fully qualified class name or a path')
->addOption('show-all', null, InputOption::VALUE_NONE, 'Show all classes even if they have no validation constraints')
->setHelp(<<<'EOF'
The <info>%command.name% 'App\Entity\Dummy'</info> command dumps the validators for the dummy class.
The <info>%command.name% src/</info> command dumps the validators for the `src` directory.
EOF
);
}
protected function execute(InputInterface $input, OutputInterface $output) : int {
$class = $input->getArgument('class');
if (class_exists($class)) {
$this->dumpValidatorsForClass($input, $output, $class);
return 0;
}
try {
foreach ($this->getResourcesByPath($class) as $class) {
$this->dumpValidatorsForClass($input, $output, $class);
}
} catch (DirectoryNotFoundException) {
$io = new SymfonyStyle($input, $output);
$io->error(\sprintf('Neither class nor path were found with "%s" argument.', $input->getArgument('class')));
return 1;
}
return 0;
}
private function dumpValidatorsForClass(InputInterface $input, OutputInterface $output, string $class) : void {
$io = new SymfonyStyle($input, $output);
$title = \sprintf('<info>%s</info>', $class);
$rows = [];
$dump = new Dumper($output);
/** @var ClassMetadataInterface $classMetadata */
$classMetadata = $this->validator
->getMetadataFor($class);
foreach ($this->getClassConstraintsData($classMetadata) as $data) {
$rows[] = [
'-',
$data['class'],
implode(', ', $data['groups']),
$dump($data['options']),
];
}
foreach ($this->getConstrainedPropertiesData($classMetadata) as $propertyName => $constraintsData) {
foreach ($constraintsData as $data) {
$rows[] = [
$propertyName,
$data['class'],
implode(', ', $data['groups']),
$dump($data['options']),
];
}
}
if (!$rows) {
if (false === $input->getOption('show-all')) {
return;
}
$io->section($title);
$io->text('No validators were found for this class.');
return;
}
$io->section($title);
$table = new Table($output);
$table->setHeaders([
'Property',
'Name',
'Groups',
'Options',
]);
$table->setRows($rows);
$table->setColumnMaxWidth(3, 80);
$table->render();
}
private function getClassConstraintsData(ClassMetadataInterface $classMetadata) : iterable {
foreach ($classMetadata->getConstraints() as $constraint) {
(yield [
'class' => $constraint::class,
'groups' => $constraint->groups,
'options' => $this->getConstraintOptions($constraint),
]);
}
}
private function getConstrainedPropertiesData(ClassMetadataInterface $classMetadata) : array {
$data = [];
foreach ($classMetadata->getConstrainedProperties() as $constrainedProperty) {
$data[$constrainedProperty] = $this->getPropertyData($classMetadata, $constrainedProperty);
}
return $data;
}
private function getPropertyData(ClassMetadataInterface $classMetadata, string $constrainedProperty) : array {
$data = [];
$propertyMetadata = $classMetadata->getPropertyMetadata($constrainedProperty);
foreach ($propertyMetadata as $metadata) {
$autoMapingStrategy = 'Not supported';
if ($metadata instanceof GenericMetadata) {
$autoMapingStrategy = match ($metadata->getAutoMappingStrategy()) { AutoMappingStrategy::ENABLED => 'Enabled',
AutoMappingStrategy::DISABLED => 'Disabled',
AutoMappingStrategy::NONE => 'None',
};
}
$traversalStrategy = 'None';
if (TraversalStrategy::TRAVERSE === $metadata->getTraversalStrategy()) {
$traversalStrategy = 'Traverse';
}
if (TraversalStrategy::IMPLICIT === $metadata->getTraversalStrategy()) {
$traversalStrategy = 'Implicit';
}
$data[] = [
'class' => 'property options',
'groups' => [],
'options' => [
'cascadeStrategy' => CascadingStrategy::CASCADE === $metadata->getCascadingStrategy() ? 'Cascade' : 'None',
'autoMappingStrategy' => $autoMapingStrategy,
'traversalStrategy' => $traversalStrategy,
],
];
foreach ($metadata->getConstraints() as $constraint) {
$data[] = [
'class' => $constraint::class,
'groups' => $constraint->groups,
'options' => $this->getConstraintOptions($constraint),
];
}
}
return $data;
}
private function getConstraintOptions(Constraint $constraint) : array {
$options = [];
foreach (array_keys(get_object_vars($constraint)) as $propertyName) {
// Groups are dumped on a specific column.
if ('groups' === $propertyName) {
continue;
}
$options[$propertyName] = $constraint->{$propertyName};
}
ksort($options);
return $options;
}
private function getResourcesByPath(string $path) : array {
$finder = new Finder();
$finder->files()
->in($path)
->name('*.php')
->sortByName(true);
$classes = [];
foreach ($finder as $file) {
$fileContent = file_get_contents($file->getRealPath());
preg_match('/namespace (.+);/', $fileContent, $matches);
$namespace = $matches[1] ?? null;
if (!preg_match('/class +([^{ ]+)/', $fileContent, $matches)) {
// no class found
continue;
}
$className = trim($matches[1]);
if (null !== $namespace) {
$classes[] = $namespace . '\\' . $className;
}
else {
$classes[] = $className;
}
}
return $classes;
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
Command::$aliases | private | property | 1 | ||
Command::$application | private | property | |||
Command::$code | private | property | |||
Command::$definition | private | property | |||
Command::$description | private | property | 1 | ||
Command::$fullDefinition | private | property | |||
Command::$help | private | property | |||
Command::$helperSet | private | property | |||
Command::$hidden | private | property | |||
Command::$ignoreValidationErrors | private | property | 2 | ||
Command::$name | private | property | |||
Command::$processTitle | private | property | |||
Command::$synopsis | private | property | |||
Command::$usages | private | property | |||
Command::addArgument | public | function | Adds an argument. | 2 | |
Command::addOption | public | function | Adds an option. | 2 | |
Command::addUsage | public | function | Add a command usage example, it'll be prefixed with the command name. | 2 | |
Command::complete | public | function | Supplies suggestions when resolving possible completion options for input (e.g. option or argument). | 5 | |
Command::FAILURE | public | constant | |||
Command::getAliases | public | function | Returns the aliases for the command. | ||
Command::getApplication | public | function | Gets the application instance for this command. | 2 | |
Command::getDefaultDescription | public static | function | |||
Command::getDefaultName | public static | function | |||
Command::getDefinition | public | function | Gets the InputDefinition attached to this Command. | 2 | |
Command::getDescription | public | function | Returns the description for the command. | ||
Command::getHelp | public | function | Returns the help for the command. | 2 | |
Command::getHelper | public | function | Gets a helper instance by name. | 2 | |
Command::getHelperSet | public | function | Gets the helper set. | 1 | |
Command::getName | public | function | Returns the command name. | ||
Command::getNativeDefinition | public | function | Gets the InputDefinition to be used to create representations of this Command. | 2 | |
Command::getProcessedHelp | public | function | Returns the processed help for the command replacing the %command.name% and %command.full_name% patterns with the real values dynamically. |
2 | |
Command::getSynopsis | public | function | Returns the synopsis for the command. | 2 | |
Command::getUsages | public | function | Returns alternative usages of the command. | 2 | |
Command::ignoreValidationErrors | public | function | Ignores validation errors. | 2 | |
Command::initialize | protected | function | Initializes the command after the input has been bound and before the input is validated. |
4 | |
Command::interact | protected | function | Interacts with the user. | 5 | |
Command::INVALID | public | constant | |||
Command::isEnabled | public | function | Checks whether the command is enabled or not in the current environment. | 2 | |
Command::isHidden | public | function | |||
Command::mergeApplicationDefinition | public | function | Merges the application definition with the command definition. | 2 | |
Command::run | public | function | Runs the command. | 4 | |
Command::setAliases | public | function | Sets the aliases for the command. | ||
Command::setApplication | public | function | 2 | ||
Command::setCode | public | function | Sets the code to execute when running this command. | 2 | |
Command::setDefinition | public | function | Sets an array of argument and option instances. | 2 | |
Command::setDescription | public | function | Sets the description for the command. | ||
Command::setHelp | public | function | Sets the help for the command. | 2 | |
Command::setHelperSet | public | function | 2 | ||
Command::setHidden | public | function | |||
Command::setName | public | function | Sets the name of the command. | ||
Command::setProcessTitle | public | function | Sets the process title of the command. | 2 | |
Command::SUCCESS | public | constant | |||
Command::validateName | private | function | Validates a command name. | ||
DebugCommand::configure | protected | function | Configures the current command. | Overrides Command::configure | |
DebugCommand::dumpValidatorsForClass | private | function | |||
DebugCommand::execute | protected | function | Executes the current command. | Overrides Command::execute | |
DebugCommand::getClassConstraintsData | private | function | |||
DebugCommand::getConstrainedPropertiesData | private | function | |||
DebugCommand::getConstraintOptions | private | function | |||
DebugCommand::getPropertyData | private | function | |||
DebugCommand::getResourcesByPath | private | function | |||
DebugCommand::__construct | public | function | Overrides Command::__construct |