mirror of
https://github.com/Combodo/iTop.git
synced 2026-04-25 19:48:49 +02:00
migration symfony 5 4 (#300)
* symfony 5.4 (diff dev) * symfony 5.4 (working) * symfony 5.4 (update autoload) * symfony 5.4 (remove swiftmailer mailer implementation) * symfony 5.4 (php doc and split Global accessor class) ### Impacted packages: composer require php:">=7.2.5 <8.0.0" symfony/console:5.4.* symfony/dotenv:5.4.* symfony/framework-bundle:5.4.* symfony/twig-bundle:5.4.* symfony/yaml:5.4.* --update-with-dependencies composer require symfony/stopwatch:5.4.* symfony/web-profiler-bundle:5.4.* --dev --update-with-dependencies
This commit is contained in:
@@ -12,17 +12,17 @@
|
||||
namespace Symfony\Bundle\FrameworkBundle\Command;
|
||||
|
||||
use Symfony\Bundle\FrameworkBundle\Console\Helper\DescriptorHelper;
|
||||
use Symfony\Component\Config\ConfigCache;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Completion\CompletionInput;
|
||||
use Symfony\Component\Console\Completion\CompletionSuggestions;
|
||||
use Symfony\Component\Console\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
use Symfony\Component\Console\Input\InputInterface;
|
||||
use Symfony\Component\Console\Input\InputOption;
|
||||
use Symfony\Component\Console\Output\OutputInterface;
|
||||
use Symfony\Component\Console\Style\SymfonyStyle;
|
||||
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
|
||||
/**
|
||||
@@ -30,16 +30,14 @@ use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
*
|
||||
* @author Ryan Weaver <ryan@thatsquality.com>
|
||||
*
|
||||
* @internal since version 3.4
|
||||
* @internal
|
||||
*/
|
||||
class ContainerDebugCommand extends ContainerAwareCommand
|
||||
class ContainerDebugCommand extends Command
|
||||
{
|
||||
protected static $defaultName = 'debug:container';
|
||||
use BuildDebugContainerTrait;
|
||||
|
||||
/**
|
||||
* @var ContainerBuilder|null
|
||||
*/
|
||||
protected $containerBuilder;
|
||||
protected static $defaultName = 'debug:container';
|
||||
protected static $defaultDescription = 'Display current services for an application';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -49,34 +47,48 @@ class ContainerDebugCommand extends ContainerAwareCommand
|
||||
$this
|
||||
->setDefinition([
|
||||
new InputArgument('name', InputArgument::OPTIONAL, 'A service name (foo)'),
|
||||
new InputOption('show-private', null, InputOption::VALUE_NONE, 'Used to show public *and* private services'),
|
||||
new InputOption('show-arguments', null, InputOption::VALUE_NONE, 'Used to show arguments in services'),
|
||||
new InputOption('tag', null, InputOption::VALUE_REQUIRED, 'Shows all services with a specific tag'),
|
||||
new InputOption('tags', null, InputOption::VALUE_NONE, 'Displays tagged services for an application'),
|
||||
new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Displays a specific parameter for an application'),
|
||||
new InputOption('parameters', null, InputOption::VALUE_NONE, 'Displays parameters for an application'),
|
||||
new InputOption('types', null, InputOption::VALUE_NONE, 'Displays types (classes/interfaces) available in the container'),
|
||||
new InputOption('show-arguments', null, InputOption::VALUE_NONE, 'Show arguments in services'),
|
||||
new InputOption('show-hidden', null, InputOption::VALUE_NONE, 'Show hidden (internal) services'),
|
||||
new InputOption('tag', null, InputOption::VALUE_REQUIRED, 'Show all services with a specific tag'),
|
||||
new InputOption('tags', null, InputOption::VALUE_NONE, 'Display tagged services for an application'),
|
||||
new InputOption('parameter', null, InputOption::VALUE_REQUIRED, 'Display a specific parameter for an application'),
|
||||
new InputOption('parameters', null, InputOption::VALUE_NONE, 'Display parameters for an application'),
|
||||
new InputOption('types', null, InputOption::VALUE_NONE, 'Display types (classes/interfaces) available in the container'),
|
||||
new InputOption('env-var', null, InputOption::VALUE_REQUIRED, 'Display a specific environment variable used in the container'),
|
||||
new InputOption('env-vars', null, InputOption::VALUE_NONE, 'Display environment variables used in the container'),
|
||||
new InputOption('format', null, InputOption::VALUE_REQUIRED, 'The output format (txt, xml, json, or md)', 'txt'),
|
||||
new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'),
|
||||
new InputOption('deprecations', null, InputOption::VALUE_NONE, 'Display deprecations generated when compiling and warming up the container'),
|
||||
])
|
||||
->setDescription('Displays current services for an application')
|
||||
->setDescription(self::$defaultDescription)
|
||||
->setHelp(<<<'EOF'
|
||||
The <info>%command.name%</info> command displays all configured <comment>public</comment> services:
|
||||
|
||||
<info>php %command.full_name%</info>
|
||||
|
||||
To see deprecations generated during container compilation and cache warmup, use the <info>--deprecations</info> option:
|
||||
|
||||
<info>php %command.full_name% --deprecations</info>
|
||||
|
||||
To get specific information about a service, specify its name:
|
||||
|
||||
<info>php %command.full_name% validator</info>
|
||||
|
||||
To get specific information about a service including all its arguments, use the <info>--show-arguments</info> flag:
|
||||
|
||||
<info>php %command.full_name% validator --show-arguments</info>
|
||||
|
||||
To see available types that can be used for autowiring, use the <info>--types</info> flag:
|
||||
|
||||
<info>php %command.full_name% --types</info>
|
||||
|
||||
By default, private services are hidden. You can display all services by
|
||||
using the <info>--show-private</info> flag:
|
||||
To see environment variables used by the container, use the <info>--env-vars</info> flag:
|
||||
|
||||
<info>php %command.full_name% --show-private</info>
|
||||
<info>php %command.full_name% --env-vars</info>
|
||||
|
||||
Display a specific environment variable by specifying its name with the <info>--env-var</info> option:
|
||||
|
||||
<info>php %command.full_name% --env-var=APP_ENV</info>
|
||||
|
||||
Use the --tags option to display tagged <comment>public</comment> services grouped by tag:
|
||||
|
||||
@@ -94,6 +106,11 @@ Display a specific parameter by specifying its name with the <info>--parameter</
|
||||
|
||||
<info>php %command.full_name% --parameter=kernel.debug</info>
|
||||
|
||||
By default, internal services are hidden. You can display them
|
||||
using the <info>--show-hidden</info> flag:
|
||||
|
||||
<info>php %command.full_name% --show-hidden</info>
|
||||
|
||||
EOF
|
||||
)
|
||||
;
|
||||
@@ -102,16 +119,21 @@ EOF
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function execute(InputInterface $input, OutputInterface $output)
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
$io = new SymfonyStyle($input, $output);
|
||||
$errorIo = $io->getErrorStyle();
|
||||
|
||||
$this->validateInput($input);
|
||||
$object = $this->getContainerBuilder();
|
||||
$kernel = $this->getApplication()->getKernel();
|
||||
$object = $this->getContainerBuilder($kernel);
|
||||
|
||||
if ($input->getOption('types')) {
|
||||
$options = ['show_private' => true];
|
||||
if ($input->getOption('env-vars')) {
|
||||
$options = ['env-vars' => true];
|
||||
} elseif ($envVar = $input->getOption('env-var')) {
|
||||
$options = ['env-vars' => true, 'name' => $envVar];
|
||||
} elseif ($input->getOption('types')) {
|
||||
$options = [];
|
||||
$options['filter'] = [$this, 'filterToServiceTypes'];
|
||||
} elseif ($input->getOption('parameters')) {
|
||||
$parameters = [];
|
||||
@@ -123,33 +145,89 @@ EOF
|
||||
} elseif ($parameter = $input->getOption('parameter')) {
|
||||
$options = ['parameter' => $parameter];
|
||||
} elseif ($input->getOption('tags')) {
|
||||
$options = ['group_by' => 'tags', 'show_private' => $input->getOption('show-private')];
|
||||
$options = ['group_by' => 'tags'];
|
||||
} elseif ($tag = $input->getOption('tag')) {
|
||||
$options = ['tag' => $tag, 'show_private' => $input->getOption('show-private')];
|
||||
$options = ['tag' => $tag];
|
||||
} elseif ($name = $input->getArgument('name')) {
|
||||
$name = $this->findProperServiceName($input, $errorIo, $object, $name);
|
||||
$name = $this->findProperServiceName($input, $errorIo, $object, $name, $input->getOption('show-hidden'));
|
||||
$options = ['id' => $name];
|
||||
} elseif ($input->getOption('deprecations')) {
|
||||
$options = ['deprecations' => true];
|
||||
} else {
|
||||
$options = ['show_private' => $input->getOption('show-private')];
|
||||
$options = [];
|
||||
}
|
||||
|
||||
$helper = new DescriptorHelper();
|
||||
$options['format'] = $input->getOption('format');
|
||||
$options['show_arguments'] = $input->getOption('show-arguments');
|
||||
$options['show_hidden'] = $input->getOption('show-hidden');
|
||||
$options['raw_text'] = $input->getOption('raw');
|
||||
$options['output'] = $io;
|
||||
$options['is_debug'] = $this->getApplication()->getKernel()->isDebug();
|
||||
$helper->describe($io, $object, $options);
|
||||
$options['is_debug'] = $kernel->isDebug();
|
||||
|
||||
if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && $input->isInteractive()) {
|
||||
try {
|
||||
$helper->describe($io, $object, $options);
|
||||
|
||||
if (isset($options['id']) && isset($kernel->getContainer()->getRemovedIds()[$options['id']])) {
|
||||
$errorIo->note(sprintf('The "%s" service or alias has been removed or inlined when the container was compiled.', $options['id']));
|
||||
}
|
||||
} catch (ServiceNotFoundException $e) {
|
||||
if ('' !== $e->getId() && '@' === $e->getId()[0]) {
|
||||
throw new ServiceNotFoundException($e->getId(), $e->getSourceId(), null, [substr($e->getId(), 1)]);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
if (!$input->getArgument('name') && !$input->getOption('tag') && !$input->getOption('parameter') && !$input->getOption('env-vars') && !$input->getOption('env-var') && $input->isInteractive()) {
|
||||
if ($input->getOption('tags')) {
|
||||
$errorIo->comment('To search for a specific tag, re-run this command with a search term. (e.g. <comment>debug:container --tag=form.type</comment>)');
|
||||
} elseif ($input->getOption('parameters')) {
|
||||
$errorIo->comment('To search for a specific parameter, re-run this command with a search term. (e.g. <comment>debug:container --parameter=kernel.debug</comment>)');
|
||||
} else {
|
||||
} elseif (!$input->getOption('deprecations')) {
|
||||
$errorIo->comment('To search for a specific service, re-run this command with a search term. (e.g. <comment>debug:container log</comment>)');
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function complete(CompletionInput $input, CompletionSuggestions $suggestions): void
|
||||
{
|
||||
if ($input->mustSuggestOptionValuesFor('format')) {
|
||||
$helper = new DescriptorHelper();
|
||||
$suggestions->suggestValues($helper->getFormats());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$kernel = $this->getApplication()->getKernel();
|
||||
$object = $this->getContainerBuilder($kernel);
|
||||
|
||||
if ($input->mustSuggestArgumentValuesFor('name')
|
||||
&& !$input->getOption('tag') && !$input->getOption('tags')
|
||||
&& !$input->getOption('parameter') && !$input->getOption('parameters')
|
||||
&& !$input->getOption('env-var') && !$input->getOption('env-vars')
|
||||
&& !$input->getOption('types') && !$input->getOption('deprecations')
|
||||
) {
|
||||
$suggestions->suggestValues($this->findServiceIdsContaining(
|
||||
$object,
|
||||
$input->getCompletionValue(),
|
||||
(bool) $input->getOption('show-hidden')
|
||||
));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('tag')) {
|
||||
$suggestions->suggestValues($object->findTags());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($input->mustSuggestOptionValuesFor('parameter')) {
|
||||
$suggestions->suggestValues(array_keys($object->getParameterBag()->all()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -170,94 +248,66 @@ EOF
|
||||
|
||||
$name = $input->getArgument('name');
|
||||
if ((null !== $name) && ($optionsCount > 0)) {
|
||||
throw new InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined with the service name argument.');
|
||||
throw new InvalidArgumentException('The options tags, tag, parameters & parameter cannot be combined with the service name argument.');
|
||||
} elseif ((null === $name) && $optionsCount > 1) {
|
||||
throw new InvalidArgumentException('The options tags, tag, parameters & parameter can not be combined together.');
|
||||
throw new InvalidArgumentException('The options tags, tag, parameters & parameter cannot be combined together.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the ContainerBuilder from the cache.
|
||||
*
|
||||
* @return ContainerBuilder
|
||||
*
|
||||
* @throws \LogicException
|
||||
*/
|
||||
protected function getContainerBuilder()
|
||||
private function findProperServiceName(InputInterface $input, SymfonyStyle $io, ContainerBuilder $builder, string $name, bool $showHidden): string
|
||||
{
|
||||
if ($this->containerBuilder) {
|
||||
return $this->containerBuilder;
|
||||
}
|
||||
$name = ltrim($name, '\\');
|
||||
|
||||
$kernel = $this->getApplication()->getKernel();
|
||||
|
||||
if (!$kernel->isDebug() || !(new ConfigCache($kernel->getContainer()->getParameter('debug.container.dump'), true))->isFresh()) {
|
||||
$buildContainer = \Closure::bind(function () { return $this->buildContainer(); }, $kernel, \get_class($kernel));
|
||||
$container = $buildContainer();
|
||||
$container->getCompilerPassConfig()->setRemovingPasses([]);
|
||||
$container->getCompilerPassConfig()->setAfterRemovingPasses([]);
|
||||
$container->compile();
|
||||
} else {
|
||||
(new XmlFileLoader($container = new ContainerBuilder(), new FileLocator()))->load($kernel->getContainer()->getParameter('debug.container.dump'));
|
||||
$locatorPass = new ServiceLocatorTagPass();
|
||||
$locatorPass->process($container);
|
||||
}
|
||||
|
||||
return $this->containerBuilder = $container;
|
||||
}
|
||||
|
||||
private function findProperServiceName(InputInterface $input, SymfonyStyle $io, ContainerBuilder $builder, $name)
|
||||
{
|
||||
if ($builder->has($name) || !$input->isInteractive()) {
|
||||
return $name;
|
||||
}
|
||||
|
||||
$matchingServices = $this->findServiceIdsContaining($builder, $name);
|
||||
$matchingServices = $this->findServiceIdsContaining($builder, $name, $showHidden);
|
||||
if (empty($matchingServices)) {
|
||||
throw new InvalidArgumentException(sprintf('No services found that match "%s".', $name));
|
||||
}
|
||||
|
||||
$default = 1 === \count($matchingServices) ? $matchingServices[0] : null;
|
||||
|
||||
return $io->choice('Select one of the following services to display its information', $matchingServices, $default);
|
||||
}
|
||||
|
||||
private function findServiceIdsContaining(ContainerBuilder $builder, $name)
|
||||
{
|
||||
$serviceIds = $builder->getServiceIds();
|
||||
$foundServiceIds = [];
|
||||
foreach ($serviceIds as $serviceId) {
|
||||
if (false === stripos($serviceId, $name)) {
|
||||
continue;
|
||||
}
|
||||
$foundServiceIds[] = $serviceId;
|
||||
if (1 === \count($matchingServices)) {
|
||||
return $matchingServices[0];
|
||||
}
|
||||
|
||||
return $foundServiceIds;
|
||||
return $io->choice('Select one of the following services to display its information', $matchingServices);
|
||||
}
|
||||
|
||||
private function findServiceIdsContaining(ContainerBuilder $builder, string $name, bool $showHidden): array
|
||||
{
|
||||
$serviceIds = $builder->getServiceIds();
|
||||
$foundServiceIds = $foundServiceIdsIgnoringBackslashes = [];
|
||||
foreach ($serviceIds as $serviceId) {
|
||||
if (!$showHidden && str_starts_with($serviceId, '.')) {
|
||||
continue;
|
||||
}
|
||||
if (false !== stripos(str_replace('\\', '', $serviceId), $name)) {
|
||||
$foundServiceIdsIgnoringBackslashes[] = $serviceId;
|
||||
}
|
||||
if ('' === $name || false !== stripos($serviceId, $name)) {
|
||||
$foundServiceIds[] = $serviceId;
|
||||
}
|
||||
}
|
||||
|
||||
return $foundServiceIds ?: $foundServiceIdsIgnoringBackslashes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function filterToServiceTypes($serviceId)
|
||||
public function filterToServiceTypes(string $serviceId): bool
|
||||
{
|
||||
// filter out things that could not be valid class names
|
||||
if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $serviceId)) {
|
||||
if (!preg_match('/(?(DEFINE)(?<V>[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+))^(?&V)(?:\\\\(?&V))*+(?: \$(?&V))?$/', $serviceId)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// if the id has a \, assume it is a class
|
||||
if (false !== strpos($serviceId, '\\')) {
|
||||
if (str_contains($serviceId, '\\')) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
new \ReflectionClass($serviceId);
|
||||
|
||||
return true;
|
||||
} catch (\ReflectionException $e) {
|
||||
// the service id is not a valid class/interface
|
||||
return false;
|
||||
}
|
||||
return class_exists($serviceId) || interface_exists($serviceId, false);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user