Skip to main content
Drupal API
User account menu
  • Log in

Breadcrumb

  1. Drupal Core 11.1.x
  2. DebugCommand.php

class DebugCommand

Same name in this branch
  1. 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\Command
View 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&#039;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

API Navigation

  • Drupal Core 11.1.x
  • Topics
  • Classes
  • Functions
  • Constants
  • Globals
  • Files
  • Namespaces
  • Deprecated
  • Services
RSS feed
Powered by Drupal