Actualización

This commit is contained in:
Xes
2025-04-10 12:24:57 +02:00
parent 8969cc929d
commit 45420b6f0d
39760 changed files with 4303286 additions and 0 deletions

View File

@@ -0,0 +1,127 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\Console\Application as BaseApplication;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Application.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class Application extends BaseApplication
{
private $kernel;
private $commandsRegistered = false;
/**
* Constructor.
*
* @param KernelInterface $kernel A KernelInterface instance
*/
public function __construct(KernelInterface $kernel)
{
$this->kernel = $kernel;
parent::__construct('Symfony', Kernel::VERSION.' - '.$kernel->getName().'/'.$kernel->getEnvironment().($kernel->isDebug() ? '/debug' : ''));
$this->getDefinition()->addOption(new InputOption('--env', '-e', InputOption::VALUE_REQUIRED, 'The Environment name.', $kernel->getEnvironment()));
$this->getDefinition()->addOption(new InputOption('--no-debug', null, InputOption::VALUE_NONE, 'Switches off debug mode.'));
}
/**
* Gets the Kernel associated with this Console.
*
* @return KernelInterface A KernelInterface instance
*/
public function getKernel()
{
return $this->kernel;
}
/**
* Runs the current application.
*
* @param InputInterface $input An Input instance
* @param OutputInterface $output An Output instance
*
* @return int 0 if everything went fine, or an error code
*/
public function doRun(InputInterface $input, OutputInterface $output)
{
$this->kernel->boot();
$container = $this->kernel->getContainer();
foreach ($this->all() as $command) {
if ($command instanceof ContainerAwareInterface) {
$command->setContainer($container);
}
}
$this->setDispatcher($container->get('event_dispatcher'));
return parent::doRun($input, $output);
}
/**
* {@inheritdoc}
*/
public function get($name)
{
$this->registerCommands();
return parent::get($name);
}
/**
* {@inheritdoc}
*/
public function all($namespace = null)
{
$this->registerCommands();
return parent::all($namespace);
}
protected function registerCommands()
{
if ($this->commandsRegistered) {
return;
}
$this->commandsRegistered = true;
$this->kernel->boot();
$container = $this->kernel->getContainer();
foreach ($this->kernel->getBundles() as $bundle) {
if ($bundle instanceof Bundle) {
$bundle->registerCommands($this);
}
}
if ($container->hasParameter('console.command.ids')) {
foreach ($container->getParameter('console.command.ids') as $id) {
$this->add($container->get($id));
}
}
}
}

View File

@@ -0,0 +1,312 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\Console\Descriptor\DescriptorInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
abstract class Descriptor implements DescriptorInterface
{
/**
* @var OutputInterface
*/
protected $output;
/**
* {@inheritdoc}
*/
public function describe(OutputInterface $output, $object, array $options = array())
{
$this->output = $output;
switch (true) {
case $object instanceof RouteCollection:
$this->describeRouteCollection($object, $options);
break;
case $object instanceof Route:
$this->describeRoute($object, $options);
break;
case $object instanceof ParameterBag:
$this->describeContainerParameters($object, $options);
break;
case $object instanceof ContainerBuilder && isset($options['group_by']) && 'tags' === $options['group_by']:
$this->describeContainerTags($object, $options);
break;
case $object instanceof ContainerBuilder && isset($options['id']):
$this->describeContainerService($this->resolveServiceDefinition($object, $options['id']), $options);
break;
case $object instanceof ContainerBuilder && isset($options['parameter']):
$this->describeContainerParameter($object->getParameter($options['parameter']), $options);
break;
case $object instanceof ContainerBuilder:
$this->describeContainerServices($object, $options);
break;
case $object instanceof Definition:
$this->describeContainerDefinition($object, $options);
break;
case $object instanceof Alias:
$this->describeContainerAlias($object, $options);
break;
case $object instanceof EventDispatcherInterface:
$this->describeEventDispatcherListeners($object, $options);
break;
case is_callable($object):
$this->describeCallable($object, $options);
break;
default:
throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_class($object)));
}
}
/**
* Returns the output.
*
* @return OutputInterface The output
*/
protected function getOutput()
{
return $this->output;
}
/**
* Writes content to output.
*
* @param string $content
* @param bool $decorated
*/
protected function write($content, $decorated = false)
{
$this->output->write($content, false, $decorated ? OutputInterface::OUTPUT_NORMAL : OutputInterface::OUTPUT_RAW);
}
/**
* Describes an InputArgument instance.
*
* @param RouteCollection $routes
* @param array $options
*/
abstract protected function describeRouteCollection(RouteCollection $routes, array $options = array());
/**
* Describes an InputOption instance.
*
* @param Route $route
* @param array $options
*/
abstract protected function describeRoute(Route $route, array $options = array());
/**
* Describes container parameters.
*
* @param ParameterBag $parameters
* @param array $options
*/
abstract protected function describeContainerParameters(ParameterBag $parameters, array $options = array());
/**
* Describes container tags.
*
* @param ContainerBuilder $builder
* @param array $options
*/
abstract protected function describeContainerTags(ContainerBuilder $builder, array $options = array());
/**
* Describes a container service by its name.
*
* Common options are:
* * name: name of described service
*
* @param Definition|Alias|object $service
* @param array $options
*/
abstract protected function describeContainerService($service, array $options = array());
/**
* Describes container services.
*
* Common options are:
* * tag: filters described services by given tag
*
* @param ContainerBuilder $builder
* @param array $options
*/
abstract protected function describeContainerServices(ContainerBuilder $builder, array $options = array());
/**
* Describes a service definition.
*
* @param Definition $definition
* @param array $options
*/
abstract protected function describeContainerDefinition(Definition $definition, array $options = array());
/**
* Describes a service alias.
*
* @param Alias $alias
* @param array $options
*/
abstract protected function describeContainerAlias(Alias $alias, array $options = array());
/**
* Describes a container parameter.
*
* @param string $parameter
* @param array $options
*/
abstract protected function describeContainerParameter($parameter, array $options = array());
/**
* Describes event dispatcher listeners.
*
* Common options are:
* * name: name of listened event
*
* @param EventDispatcherInterface $eventDispatcher
* @param array $options
*/
abstract protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = array());
/**
* Describes a callable.
*
* @param callable $callable
* @param array $options
*/
abstract protected function describeCallable($callable, array $options = array());
/**
* Formats a value as string.
*
* @param mixed $value
*
* @return string
*/
protected function formatValue($value)
{
if (is_object($value)) {
return sprintf('object(%s)', get_class($value));
}
if (is_string($value)) {
return $value;
}
return preg_replace("/\n\s*/s", '', var_export($value, true));
}
/**
* Formats a parameter.
*
* @param mixed $value
*
* @return string
*/
protected function formatParameter($value)
{
if (is_bool($value) || is_array($value) || (null === $value)) {
$jsonString = json_encode($value);
if (preg_match('/^(.{60})./us', $jsonString, $matches)) {
return $matches[1].'...';
}
return $jsonString;
}
return (string) $value;
}
/**
* @param ContainerBuilder $builder
* @param string $serviceId
*
* @return mixed
*/
protected function resolveServiceDefinition(ContainerBuilder $builder, $serviceId)
{
if ($builder->hasDefinition($serviceId)) {
return $builder->getDefinition($serviceId);
}
// Some service IDs don't have a Definition, they're simply an Alias
if ($builder->hasAlias($serviceId)) {
return $builder->getAlias($serviceId);
}
if ('service_container' === $serviceId) {
return $builder;
}
// the service has been injected in some special way, just return the service
return $builder->get($serviceId);
}
/**
* @param ContainerBuilder $builder
* @param bool $showPrivate
*
* @return array
*/
protected function findDefinitionsByTag(ContainerBuilder $builder, $showPrivate)
{
$definitions = array();
$tags = $builder->findTags();
asort($tags);
foreach ($tags as $tag) {
foreach ($builder->findTaggedServiceIds($tag) as $serviceId => $attributes) {
$definition = $this->resolveServiceDefinition($builder, $serviceId);
if (!$definition instanceof Definition || !$showPrivate && !$definition->isPublic()) {
continue;
}
if (!isset($definitions[$tag])) {
$definitions[$tag] = array();
}
$definitions[$tag][$serviceId] = $definition;
}
}
return $definitions;
}
protected function sortParameters(ParameterBag $parameters)
{
$parameters = $parameters->all();
ksort($parameters);
return $parameters;
}
protected function sortServiceIds(array $serviceIds)
{
asort($serviceIds);
return $serviceIds;
}
}

View File

@@ -0,0 +1,367 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
class JsonDescriptor extends Descriptor
{
/**
* {@inheritdoc}
*/
protected function describeRouteCollection(RouteCollection $routes, array $options = array())
{
$data = array();
foreach ($routes->all() as $name => $route) {
$data[$name] = $this->getRouteData($route);
}
$this->writeData($data, $options);
}
/**
* {@inheritdoc}
*/
protected function describeRoute(Route $route, array $options = array())
{
$this->writeData($this->getRouteData($route), $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameters(ParameterBag $parameters, array $options = array())
{
$this->writeData($this->sortParameters($parameters), $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerTags(ContainerBuilder $builder, array $options = array())
{
$showPrivate = isset($options['show_private']) && $options['show_private'];
$data = array();
foreach ($this->findDefinitionsByTag($builder, $showPrivate) as $tag => $definitions) {
$data[$tag] = array();
foreach ($definitions as $definition) {
$data[$tag][] = $this->getContainerDefinitionData($definition, true);
}
}
$this->writeData($data, $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerService($service, array $options = array())
{
if (!isset($options['id'])) {
throw new \InvalidArgumentException('An "id" option must be provided.');
}
if ($service instanceof Alias) {
$this->writeData($this->getContainerAliasData($service), $options);
} elseif ($service instanceof Definition) {
$this->writeData($this->getContainerDefinitionData($service), $options);
} else {
$this->writeData(get_class($service), $options);
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerServices(ContainerBuilder $builder, array $options = array())
{
$serviceIds = isset($options['tag']) && $options['tag'] ? array_keys($builder->findTaggedServiceIds($options['tag'])) : $builder->getServiceIds();
$showPrivate = isset($options['show_private']) && $options['show_private'];
$data = array('definitions' => array(), 'aliases' => array(), 'services' => array());
foreach ($this->sortServiceIds($serviceIds) as $serviceId) {
$service = $this->resolveServiceDefinition($builder, $serviceId);
if ($service instanceof Alias) {
$data['aliases'][$serviceId] = $this->getContainerAliasData($service);
} elseif ($service instanceof Definition) {
if (($showPrivate || $service->isPublic())) {
$data['definitions'][$serviceId] = $this->getContainerDefinitionData($service);
}
} else {
$data['services'][$serviceId] = get_class($service);
}
}
$this->writeData($data, $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerDefinition(Definition $definition, array $options = array())
{
$this->writeData($this->getContainerDefinitionData($definition, isset($options['omit_tags']) && $options['omit_tags']), $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerAlias(Alias $alias, array $options = array())
{
$this->writeData($this->getContainerAliasData($alias), $options);
}
/**
* {@inheritdoc}
*/
protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = array())
{
$this->writeData($this->getEventDispatcherListenersData($eventDispatcher, array_key_exists('event', $options) ? $options['event'] : null), $options);
}
/**
* {@inheritdoc}
*/
protected function describeCallable($callable, array $options = array())
{
$this->writeData($this->getCallableData($callable, $options), $options);
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameter($parameter, array $options = array())
{
$key = isset($options['parameter']) ? $options['parameter'] : '';
$this->writeData(array($key => $parameter), $options);
}
/**
* Writes data as json.
*
* @param array $data
* @param array $options
*
* @return array|string
*/
private function writeData(array $data, array $options)
{
$flags = isset($options['json_encoding']) ? $options['json_encoding'] : 0;
$this->write(json_encode($data, $flags | JSON_PRETTY_PRINT)."\n");
}
/**
* @param Route $route
*
* @return array
*/
protected function getRouteData(Route $route)
{
return array(
'path' => $route->getPath(),
'pathRegex' => $route->compile()->getRegex(),
'host' => '' !== $route->getHost() ? $route->getHost() : 'ANY',
'hostRegex' => '' !== $route->getHost() ? $route->compile()->getHostRegex() : '',
'scheme' => $route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY',
'method' => $route->getMethods() ? implode('|', $route->getMethods()) : 'ANY',
'class' => get_class($route),
'defaults' => $route->getDefaults(),
'requirements' => $route->getRequirements() ?: 'NO CUSTOM',
'options' => $route->getOptions(),
);
}
/**
* @param Definition $definition
* @param bool $omitTags
*
* @return array
*/
private function getContainerDefinitionData(Definition $definition, $omitTags = false)
{
$data = array(
'class' => (string) $definition->getClass(),
'public' => $definition->isPublic(),
'synthetic' => $definition->isSynthetic(),
'lazy' => $definition->isLazy(),
);
if (method_exists($definition, 'isShared')) {
$data['shared'] = $definition->isShared();
}
$data['abstract'] = $definition->isAbstract();
if (method_exists($definition, 'isAutowired')) {
$data['autowire'] = $definition->isAutowired();
$data['autowiring_types'] = array();
foreach ($definition->getAutowiringTypes() as $autowiringType) {
$data['autowiring_types'][] = $autowiringType;
}
}
$data['file'] = $definition->getFile();
if ($factory = $definition->getFactory()) {
if (is_array($factory)) {
if ($factory[0] instanceof Reference) {
$data['factory_service'] = (string) $factory[0];
} elseif ($factory[0] instanceof Definition) {
throw new \InvalidArgumentException('Factory is not describable.');
} else {
$data['factory_class'] = $factory[0];
}
$data['factory_method'] = $factory[1];
} else {
$data['factory_function'] = $factory;
}
}
if (!$omitTags) {
$data['tags'] = array();
if (count($definition->getTags())) {
foreach ($definition->getTags() as $tagName => $tagData) {
foreach ($tagData as $parameters) {
$data['tags'][] = array('name' => $tagName, 'parameters' => $parameters);
}
}
}
}
return $data;
}
/**
* @param Alias $alias
*
* @return array
*/
private function getContainerAliasData(Alias $alias)
{
return array(
'service' => (string) $alias,
'public' => $alias->isPublic(),
);
}
/**
* @param EventDispatcherInterface $eventDispatcher
* @param string|null $event
*
* @return array
*/
private function getEventDispatcherListenersData(EventDispatcherInterface $eventDispatcher, $event = null)
{
$data = array();
$registeredListeners = $eventDispatcher->getListeners($event);
if (null !== $event) {
foreach ($registeredListeners as $listener) {
$l = $this->getCallableData($listener);
$l['priority'] = $eventDispatcher->getListenerPriority($event, $listener);
$data[] = $l;
}
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
foreach ($eventListeners as $eventListener) {
$l = $this->getCallableData($eventListener);
$l['priority'] = $eventDispatcher->getListenerPriority($eventListened, $eventListener);
$data[$eventListened][] = $l;
}
}
}
return $data;
}
/**
* @param callable $callable
* @param array $options
*
* @return array
*/
private function getCallableData($callable, array $options = array())
{
$data = array();
if (is_array($callable)) {
$data['type'] = 'function';
if (is_object($callable[0])) {
$data['name'] = $callable[1];
$data['class'] = get_class($callable[0]);
} else {
if (0 !== strpos($callable[1], 'parent::')) {
$data['name'] = $callable[1];
$data['class'] = $callable[0];
$data['static'] = true;
} else {
$data['name'] = substr($callable[1], 8);
$data['class'] = $callable[0];
$data['static'] = true;
$data['parent'] = true;
}
}
return $data;
}
if (is_string($callable)) {
$data['type'] = 'function';
if (false === strpos($callable, '::')) {
$data['name'] = $callable;
} else {
$callableParts = explode('::', $callable);
$data['name'] = $callableParts[1];
$data['class'] = $callableParts[0];
$data['static'] = true;
}
return $data;
}
if ($callable instanceof \Closure) {
$data['type'] = 'closure';
return $data;
}
if (method_exists($callable, '__invoke')) {
$data['type'] = 'object';
$data['name'] = get_class($callable);
return $data;
}
throw new \InvalidArgumentException('Callable is not describable.');
}
}

View File

@@ -0,0 +1,366 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
class MarkdownDescriptor extends Descriptor
{
/**
* {@inheritdoc}
*/
protected function describeRouteCollection(RouteCollection $routes, array $options = array())
{
$first = true;
foreach ($routes->all() as $name => $route) {
if ($first) {
$first = false;
} else {
$this->write("\n\n");
}
$this->describeRoute($route, array('name' => $name));
}
$this->write("\n");
}
/**
* {@inheritdoc}
*/
protected function describeRoute(Route $route, array $options = array())
{
$output = '- Path: '.$route->getPath()
."\n".'- Path Regex: '.$route->compile()->getRegex()
."\n".'- Host: '.('' !== $route->getHost() ? $route->getHost() : 'ANY')
."\n".'- Host Regex: '.('' !== $route->getHost() ? $route->compile()->getHostRegex() : '')
."\n".'- Scheme: '.($route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY')
."\n".'- Method: '.($route->getMethods() ? implode('|', $route->getMethods()) : 'ANY')
."\n".'- Class: '.get_class($route)
."\n".'- Defaults: '.$this->formatRouterConfig($route->getDefaults())
."\n".'- Requirements: '.($route->getRequirements() ? $this->formatRouterConfig($route->getRequirements()) : 'NO CUSTOM')
."\n".'- Options: '.$this->formatRouterConfig($route->getOptions());
$this->write(isset($options['name'])
? $options['name']."\n".str_repeat('-', strlen($options['name']))."\n\n".$output
: $output);
$this->write("\n");
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameters(ParameterBag $parameters, array $options = array())
{
$this->write("Container parameters\n====================\n");
foreach ($this->sortParameters($parameters) as $key => $value) {
$this->write(sprintf("\n- `%s`: `%s`", $key, $this->formatParameter($value)));
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerTags(ContainerBuilder $builder, array $options = array())
{
$showPrivate = isset($options['show_private']) && $options['show_private'];
$this->write("Container tags\n==============");
foreach ($this->findDefinitionsByTag($builder, $showPrivate) as $tag => $definitions) {
$this->write("\n\n".$tag."\n".str_repeat('-', strlen($tag)));
foreach ($definitions as $serviceId => $definition) {
$this->write("\n\n");
$this->describeContainerDefinition($definition, array('omit_tags' => true, 'id' => $serviceId));
}
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerService($service, array $options = array())
{
if (!isset($options['id'])) {
throw new \InvalidArgumentException('An "id" option must be provided.');
}
$childOptions = array('id' => $options['id'], 'as_array' => true);
if ($service instanceof Alias) {
$this->describeContainerAlias($service, $childOptions);
} elseif ($service instanceof Definition) {
$this->describeContainerDefinition($service, $childOptions);
} else {
$this->write(sprintf('**`%s`:** `%s`', $options['id'], get_class($service)));
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerServices(ContainerBuilder $builder, array $options = array())
{
$showPrivate = isset($options['show_private']) && $options['show_private'];
$title = $showPrivate ? 'Public and private services' : 'Public services';
if (isset($options['tag'])) {
$title .= ' with tag `'.$options['tag'].'`';
}
$this->write($title."\n".str_repeat('=', strlen($title)));
$serviceIds = isset($options['tag']) && $options['tag'] ? array_keys($builder->findTaggedServiceIds($options['tag'])) : $builder->getServiceIds();
$showPrivate = isset($options['show_private']) && $options['show_private'];
$services = array('definitions' => array(), 'aliases' => array(), 'services' => array());
foreach ($this->sortServiceIds($serviceIds) as $serviceId) {
$service = $this->resolveServiceDefinition($builder, $serviceId);
if ($service instanceof Alias) {
$services['aliases'][$serviceId] = $service;
} elseif ($service instanceof Definition) {
if (($showPrivate || $service->isPublic())) {
$services['definitions'][$serviceId] = $service;
}
} else {
$services['services'][$serviceId] = $service;
}
}
if (!empty($services['definitions'])) {
$this->write("\n\nDefinitions\n-----------\n");
foreach ($services['definitions'] as $id => $service) {
$this->write("\n");
$this->describeContainerDefinition($service, array('id' => $id));
}
}
if (!empty($services['aliases'])) {
$this->write("\n\nAliases\n-------\n");
foreach ($services['aliases'] as $id => $service) {
$this->write("\n");
$this->describeContainerAlias($service, array('id' => $id));
}
}
if (!empty($services['services'])) {
$this->write("\n\nServices\n--------\n");
foreach ($services['services'] as $id => $service) {
$this->write("\n");
$this->write(sprintf('- `%s`: `%s`', $id, get_class($service)));
}
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerDefinition(Definition $definition, array $options = array())
{
$output = '- Class: `'.$definition->getClass().'`'
."\n".'- Public: '.($definition->isPublic() ? 'yes' : 'no')
."\n".'- Synthetic: '.($definition->isSynthetic() ? 'yes' : 'no')
."\n".'- Lazy: '.($definition->isLazy() ? 'yes' : 'no')
;
if (method_exists($definition, 'isShared')) {
$output .= "\n".'- Shared: '.($definition->isShared() ? 'yes' : 'no');
}
$output .= "\n".'- Abstract: '.($definition->isAbstract() ? 'yes' : 'no');
if (method_exists($definition, 'isAutowired')) {
$output .= "\n".'- Autowired: '.($definition->isAutowired() ? 'yes' : 'no');
foreach ($definition->getAutowiringTypes() as $autowiringType) {
$output .= "\n".'- Autowiring Type: `'.$autowiringType.'`';
}
}
if ($definition->getFile()) {
$output .= "\n".'- File: `'.$definition->getFile().'`';
}
if ($factory = $definition->getFactory()) {
if (is_array($factory)) {
if ($factory[0] instanceof Reference) {
$output .= "\n".'- Factory Service: `'.$factory[0].'`';
} elseif ($factory[0] instanceof Definition) {
throw new \InvalidArgumentException('Factory is not describable.');
} else {
$output .= "\n".'- Factory Class: `'.$factory[0].'`';
}
$output .= "\n".'- Factory Method: `'.$factory[1].'`';
} else {
$output .= "\n".'- Factory Function: `'.$factory.'`';
}
}
if (!(isset($options['omit_tags']) && $options['omit_tags'])) {
foreach ($definition->getTags() as $tagName => $tagData) {
foreach ($tagData as $parameters) {
$output .= "\n".'- Tag: `'.$tagName.'`';
foreach ($parameters as $name => $value) {
$output .= "\n".' - '.ucfirst($name).': '.$value;
}
}
}
}
$this->write(isset($options['id']) ? sprintf("%s\n%s\n\n%s\n", $options['id'], str_repeat('~', strlen($options['id'])), $output) : $output);
}
/**
* {@inheritdoc}
*/
protected function describeContainerAlias(Alias $alias, array $options = array())
{
$output = '- Service: `'.$alias.'`'
."\n".'- Public: '.($alias->isPublic() ? 'yes' : 'no');
$this->write(isset($options['id']) ? sprintf("%s\n%s\n\n%s\n", $options['id'], str_repeat('~', strlen($options['id'])), $output) : $output);
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameter($parameter, array $options = array())
{
$this->write(isset($options['parameter']) ? sprintf("%s\n%s\n\n%s", $options['parameter'], str_repeat('=', strlen($options['parameter'])), $this->formatParameter($parameter)) : $parameter);
}
/**
* {@inheritdoc}
*/
protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = array())
{
$event = array_key_exists('event', $options) ? $options['event'] : null;
$title = 'Registered listeners';
if (null !== $event) {
$title .= sprintf(' for event `%s` ordered by descending priority', $event);
}
$this->write(sprintf('# %s', $title)."\n");
$registeredListeners = $eventDispatcher->getListeners($event);
if (null !== $event) {
foreach ($registeredListeners as $order => $listener) {
$this->write("\n".sprintf('## Listener %d', $order + 1)."\n");
$this->describeCallable($listener);
$this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($event, $listener))."\n");
}
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
$this->write("\n".sprintf('## %s', $eventListened)."\n");
foreach ($eventListeners as $order => $eventListener) {
$this->write("\n".sprintf('### Listener %d', $order + 1)."\n");
$this->describeCallable($eventListener);
$this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($eventListened, $eventListener))."\n");
}
}
}
}
/**
* {@inheritdoc}
*/
protected function describeCallable($callable, array $options = array())
{
$string = '';
if (is_array($callable)) {
$string .= "\n- Type: `function`";
if (is_object($callable[0])) {
$string .= "\n".sprintf('- Name: `%s`', $callable[1]);
$string .= "\n".sprintf('- Class: `%s`', get_class($callable[0]));
} else {
if (0 !== strpos($callable[1], 'parent::')) {
$string .= "\n".sprintf('- Name: `%s`', $callable[1]);
$string .= "\n".sprintf('- Class: `%s`', $callable[0]);
$string .= "\n- Static: yes";
} else {
$string .= "\n".sprintf('- Name: `%s`', substr($callable[1], 8));
$string .= "\n".sprintf('- Class: `%s`', $callable[0]);
$string .= "\n- Static: yes";
$string .= "\n- Parent: yes";
}
}
return $this->write($string."\n");
}
if (is_string($callable)) {
$string .= "\n- Type: `function`";
if (false === strpos($callable, '::')) {
$string .= "\n".sprintf('- Name: `%s`', $callable);
} else {
$callableParts = explode('::', $callable);
$string .= "\n".sprintf('- Name: `%s`', $callableParts[1]);
$string .= "\n".sprintf('- Class: `%s`', $callableParts[0]);
$string .= "\n- Static: yes";
}
return $this->write($string."\n");
}
if ($callable instanceof \Closure) {
$string .= "\n- Type: `closure`";
return $this->write($string."\n");
}
if (method_exists($callable, '__invoke')) {
$string .= "\n- Type: `object`";
$string .= "\n".sprintf('- Name: `%s`', get_class($callable));
return $this->write($string."\n");
}
throw new \InvalidArgumentException('Callable is not describable.');
}
/**
* @param array $array
*
* @return string
*/
private function formatRouterConfig(array $array)
{
if (!count($array)) {
return 'NONE';
}
$string = '';
ksort($array);
foreach ($array as $name => $value) {
$string .= "\n".' - `'.$name.'`: '.$this->formatValue($value);
}
return $string;
}
}

View File

@@ -0,0 +1,454 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Style\SymfonyStyle;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
class TextDescriptor extends Descriptor
{
/**
* {@inheritdoc}
*/
protected function describeRouteCollection(RouteCollection $routes, array $options = array())
{
$showControllers = isset($options['show_controllers']) && $options['show_controllers'];
$tableHeaders = array('Name', 'Method', 'Scheme', 'Host', 'Path');
if ($showControllers) {
$tableHeaders[] = 'Controller';
}
$tableRows = array();
foreach ($routes->all() as $name => $route) {
$row = array(
$name,
$route->getMethods() ? implode('|', $route->getMethods()) : 'ANY',
$route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY',
'' !== $route->getHost() ? $route->getHost() : 'ANY',
$route->getPath(),
);
if ($showControllers) {
$controller = $route->getDefault('_controller');
if ($controller instanceof \Closure) {
$controller = 'Closure';
} elseif (is_object($controller)) {
$controller = get_class($controller);
}
$row[] = $controller;
}
$tableRows[] = $row;
}
if (isset($options['output'])) {
$options['output']->table($tableHeaders, $tableRows);
} else {
$table = new Table($this->getOutput());
$table->setHeaders($tableHeaders)->setRows($tableRows);
$table->render();
}
}
/**
* {@inheritdoc}
*/
protected function describeRoute(Route $route, array $options = array())
{
$tableHeaders = array('Property', 'Value');
$tableRows = array(
array('Route Name', isset($options['name']) ? $options['name'] : ''),
array('Path', $route->getPath()),
array('Path Regex', $route->compile()->getRegex()),
array('Host', ('' !== $route->getHost() ? $route->getHost() : 'ANY')),
array('Host Regex', ('' !== $route->getHost() ? $route->compile()->getHostRegex() : '')),
array('Scheme', ($route->getSchemes() ? implode('|', $route->getSchemes()) : 'ANY')),
array('Method', ($route->getMethods() ? implode('|', $route->getMethods()) : 'ANY')),
array('Requirements', ($route->getRequirements() ? $this->formatRouterConfig($route->getRequirements()) : 'NO CUSTOM')),
array('Class', get_class($route)),
array('Defaults', $this->formatRouterConfig($route->getDefaults())),
array('Options', $this->formatRouterConfig($route->getOptions())),
);
$table = new Table($this->getOutput());
$table->setHeaders($tableHeaders)->setRows($tableRows);
$table->render();
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameters(ParameterBag $parameters, array $options = array())
{
$tableHeaders = array('Parameter', 'Value');
$tableRows = array();
foreach ($this->sortParameters($parameters) as $parameter => $value) {
$tableRows[] = array($parameter, $this->formatParameter($value));
}
$options['output']->title('Symfony Container Parameters');
$options['output']->table($tableHeaders, $tableRows);
}
/**
* {@inheritdoc}
*/
protected function describeContainerTags(ContainerBuilder $builder, array $options = array())
{
$showPrivate = isset($options['show_private']) && $options['show_private'];
if ($showPrivate) {
$options['output']->title('Symfony Container Public and Private Tags');
} else {
$options['output']->title('Symfony Container Public Tags');
}
foreach ($this->findDefinitionsByTag($builder, $showPrivate) as $tag => $definitions) {
$options['output']->section(sprintf('"%s" tag', $tag));
$options['output']->listing(array_keys($definitions));
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerService($service, array $options = array())
{
if (!isset($options['id'])) {
throw new \InvalidArgumentException('An "id" option must be provided.');
}
if ($service instanceof Alias) {
$this->describeContainerAlias($service, $options);
} elseif ($service instanceof Definition) {
$this->describeContainerDefinition($service, $options);
} else {
$options['output']->title(sprintf('Information for Service "<info>%s</info>"', $options['id']));
$options['output']->table(
array('Service ID', 'Class'),
array(
array(isset($options['id']) ? $options['id'] : '-', get_class($service)),
)
);
}
}
/**
* {@inheritdoc}
*/
protected function describeContainerServices(ContainerBuilder $builder, array $options = array())
{
$showPrivate = isset($options['show_private']) && $options['show_private'];
$showTag = isset($options['tag']) ? $options['tag'] : null;
if ($showPrivate) {
$title = 'Symfony Container Public and Private Services';
} else {
$title = 'Symfony Container Public Services';
}
if ($showTag) {
$title .= sprintf(' Tagged with "%s" Tag', $options['tag']);
}
$options['output']->title($title);
$serviceIds = isset($options['tag']) && $options['tag'] ? array_keys($builder->findTaggedServiceIds($options['tag'])) : $builder->getServiceIds();
$maxTags = array();
foreach ($serviceIds as $key => $serviceId) {
$definition = $this->resolveServiceDefinition($builder, $serviceId);
if ($definition instanceof Definition) {
// filter out private services unless shown explicitly
if (!$showPrivate && !$definition->isPublic()) {
unset($serviceIds[$key]);
continue;
}
if ($showTag) {
$tags = $definition->getTag($showTag);
foreach ($tags as $tag) {
foreach ($tag as $key => $value) {
if (!isset($maxTags[$key])) {
$maxTags[$key] = strlen($key);
}
if (strlen($value) > $maxTags[$key]) {
$maxTags[$key] = strlen($value);
}
}
}
}
}
}
$tagsCount = count($maxTags);
$tagsNames = array_keys($maxTags);
$tableHeaders = array_merge(array('Service ID'), $tagsNames, array('Class name'));
$tableRows = array();
foreach ($this->sortServiceIds($serviceIds) as $serviceId) {
$definition = $this->resolveServiceDefinition($builder, $serviceId);
if ($definition instanceof Definition) {
if ($showTag) {
foreach ($definition->getTag($showTag) as $key => $tag) {
$tagValues = array();
foreach ($tagsNames as $tagName) {
$tagValues[] = isset($tag[$tagName]) ? $tag[$tagName] : '';
}
if (0 === $key) {
$tableRows[] = array_merge(array($serviceId), $tagValues, array($definition->getClass()));
} else {
$tableRows[] = array_merge(array(' "'), $tagValues, array(''));
}
}
} else {
$tableRows[] = array($serviceId, $definition->getClass());
}
} elseif ($definition instanceof Alias) {
$alias = $definition;
$tableRows[] = array_merge(array($serviceId, sprintf('alias for "%s"', $alias)), $tagsCount ? array_fill(0, $tagsCount, '') : array());
} else {
$tableRows[] = array_merge(array($serviceId, get_class($definition)), $tagsCount ? array_fill(0, $tagsCount, '') : array());
}
}
$options['output']->table($tableHeaders, $tableRows);
}
/**
* {@inheritdoc}
*/
protected function describeContainerDefinition(Definition $definition, array $options = array())
{
if (isset($options['id'])) {
$options['output']->title(sprintf('Information for Service "<info>%s</info>"', $options['id']));
}
$tableHeaders = array('Option', 'Value');
$tableRows[] = array('Service ID', isset($options['id']) ? $options['id'] : '-');
$tableRows[] = array('Class', $definition->getClass() ?: '-');
$tags = $definition->getTags();
if (count($tags)) {
$tagInformation = '';
foreach ($tags as $tagName => $tagData) {
foreach ($tagData as $tagParameters) {
$parameters = array_map(function ($key, $value) {
return sprintf('<info>%s</info>: %s', $key, $value);
}, array_keys($tagParameters), array_values($tagParameters));
$parameters = implode(', ', $parameters);
if ('' === $parameters) {
$tagInformation .= sprintf('%s', $tagName);
} else {
$tagInformation .= sprintf('%s (%s)', $tagName, $parameters);
}
}
}
} else {
$tagInformation = '-';
}
$tableRows[] = array('Tags', $tagInformation);
$tableRows[] = array('Public', $definition->isPublic() ? 'yes' : 'no');
$tableRows[] = array('Synthetic', $definition->isSynthetic() ? 'yes' : 'no');
$tableRows[] = array('Lazy', $definition->isLazy() ? 'yes' : 'no');
if (method_exists($definition, 'isShared')) {
$tableRows[] = array('Shared', $definition->isShared() ? 'yes' : 'no');
}
$tableRows[] = array('Abstract', $definition->isAbstract() ? 'yes' : 'no');
if (method_exists($definition, 'isAutowired')) {
$tableRows[] = array('Autowired', $definition->isAutowired() ? 'yes' : 'no');
$autowiringTypes = $definition->getAutowiringTypes();
if (count($autowiringTypes)) {
$autowiringTypesInformation = implode(', ', $autowiringTypes);
} else {
$autowiringTypesInformation = '-';
}
$tableRows[] = array('Autowiring Types', $autowiringTypesInformation);
}
if ($definition->getFile()) {
$tableRows[] = array('Required File', $definition->getFile() ? $definition->getFile() : '-');
}
if ($factory = $definition->getFactory()) {
if (is_array($factory)) {
if ($factory[0] instanceof Reference) {
$tableRows[] = array('Factory Service', $factory[0]);
} elseif ($factory[0] instanceof Definition) {
throw new \InvalidArgumentException('Factory is not describable.');
} else {
$tableRows[] = array('Factory Class', $factory[0]);
}
$tableRows[] = array('Factory Method', $factory[1]);
} else {
$tableRows[] = array('Factory Function', $factory);
}
}
$options['output']->table($tableHeaders, $tableRows);
}
/**
* {@inheritdoc}
*/
protected function describeContainerAlias(Alias $alias, array $options = array())
{
$options['output']->comment(sprintf('This service is an alias for the service <info>%s</info>', (string) $alias));
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameter($parameter, array $options = array())
{
$options['output']->table(
array('Parameter', 'Value'),
array(
array($options['parameter'], $this->formatParameter($parameter),
),
));
}
/**
* {@inheritdoc}
*/
protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = array())
{
$event = array_key_exists('event', $options) ? $options['event'] : null;
if (null !== $event) {
$title = sprintf('Registered Listeners for "%s" Event', $event);
} else {
$title = 'Registered Listeners Grouped by Event';
}
$options['output']->title($title);
$registeredListeners = $eventDispatcher->getListeners($event);
if (null !== $event) {
$this->renderEventListenerTable($eventDispatcher, $event, $registeredListeners, $options['output']);
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
$options['output']->section(sprintf('"%s" event', $eventListened));
$this->renderEventListenerTable($eventDispatcher, $eventListened, $eventListeners, $options['output']);
}
}
}
/**
* {@inheritdoc}
*/
protected function describeCallable($callable, array $options = array())
{
$this->writeText($this->formatCallable($callable), $options);
}
/**
* @param array $array
*/
private function renderEventListenerTable(EventDispatcherInterface $eventDispatcher, $event, array $eventListeners, SymfonyStyle $io)
{
$tableHeaders = array('Order', 'Callable', 'Priority');
$tableRows = array();
$order = 1;
foreach ($eventListeners as $order => $listener) {
$tableRows[] = array(sprintf('#%d', $order + 1), $this->formatCallable($listener), $eventDispatcher->getListenerPriority($event, $listener));
}
$io->table($tableHeaders, $tableRows);
}
/**
* @param array $config
*
* @return string
*/
private function formatRouterConfig(array $config)
{
if (empty($config)) {
return 'NONE';
}
ksort($config);
$configAsString = '';
foreach ($config as $key => $value) {
$configAsString .= sprintf("\n%s: %s", $key, $this->formatValue($value));
}
return trim($configAsString);
}
/**
* @param callable $callable
*
* @return string
*/
private function formatCallable($callable)
{
if (is_array($callable)) {
if (is_object($callable[0])) {
return sprintf('%s::%s()', get_class($callable[0]), $callable[1]);
}
return sprintf('%s::%s()', $callable[0], $callable[1]);
}
if (is_string($callable)) {
return sprintf('%s()', $callable);
}
if ($callable instanceof \Closure) {
return '\Closure()';
}
if (method_exists($callable, '__invoke')) {
return sprintf('%s::__invoke()', get_class($callable));
}
throw new \InvalidArgumentException('Callable is not describable.');
}
/**
* @param string $content
* @param array $options
*/
private function writeText($content, array $options = array())
{
$this->write(
isset($options['raw_text']) && $options['raw_text'] ? strip_tags($content) : $content,
isset($options['raw_output']) ? !$options['raw_output'] : true
);
}
}

View File

@@ -0,0 +1,531 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Descriptor;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Routing\Route;
use Symfony\Component\Routing\RouteCollection;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
class XmlDescriptor extends Descriptor
{
/**
* {@inheritdoc}
*/
protected function describeRouteCollection(RouteCollection $routes, array $options = array())
{
$this->writeDocument($this->getRouteCollectionDocument($routes));
}
/**
* {@inheritdoc}
*/
protected function describeRoute(Route $route, array $options = array())
{
$this->writeDocument($this->getRouteDocument($route, isset($options['name']) ? $options['name'] : null));
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameters(ParameterBag $parameters, array $options = array())
{
$this->writeDocument($this->getContainerParametersDocument($parameters));
}
/**
* {@inheritdoc}
*/
protected function describeContainerTags(ContainerBuilder $builder, array $options = array())
{
$this->writeDocument($this->getContainerTagsDocument($builder, isset($options['show_private']) && $options['show_private']));
}
/**
* {@inheritdoc}
*/
protected function describeContainerService($service, array $options = array())
{
if (!isset($options['id'])) {
throw new \InvalidArgumentException('An "id" option must be provided.');
}
$this->writeDocument($this->getContainerServiceDocument($service, $options['id']));
}
/**
* {@inheritdoc}
*/
protected function describeContainerServices(ContainerBuilder $builder, array $options = array())
{
$this->writeDocument($this->getContainerServicesDocument($builder, isset($options['tag']) ? $options['tag'] : null, isset($options['show_private']) && $options['show_private']));
}
/**
* {@inheritdoc}
*/
protected function describeContainerDefinition(Definition $definition, array $options = array())
{
$this->writeDocument($this->getContainerDefinitionDocument($definition, isset($options['id']) ? $options['id'] : null, isset($options['omit_tags']) && $options['omit_tags']));
}
/**
* {@inheritdoc}
*/
protected function describeContainerAlias(Alias $alias, array $options = array())
{
$this->writeDocument($this->getContainerAliasDocument($alias, isset($options['id']) ? $options['id'] : null));
}
/**
* {@inheritdoc}
*/
protected function describeEventDispatcherListeners(EventDispatcherInterface $eventDispatcher, array $options = array())
{
$this->writeDocument($this->getEventDispatcherListenersDocument($eventDispatcher, array_key_exists('event', $options) ? $options['event'] : null));
}
/**
* {@inheritdoc}
*/
protected function describeCallable($callable, array $options = array())
{
$this->writeDocument($this->getCallableDocument($callable));
}
/**
* {@inheritdoc}
*/
protected function describeContainerParameter($parameter, array $options = array())
{
$this->writeDocument($this->getContainerParameterDocument($parameter, $options));
}
/**
* Writes DOM document.
*
* @param \DOMDocument $dom
*
* @return \DOMDocument|string
*/
private function writeDocument(\DOMDocument $dom)
{
$dom->formatOutput = true;
$this->write($dom->saveXML());
}
/**
* @param RouteCollection $routes
*
* @return \DOMDocument
*/
private function getRouteCollectionDocument(RouteCollection $routes)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($routesXML = $dom->createElement('routes'));
foreach ($routes->all() as $name => $route) {
$routeXML = $this->getRouteDocument($route, $name);
$routesXML->appendChild($routesXML->ownerDocument->importNode($routeXML->childNodes->item(0), true));
}
return $dom;
}
/**
* @param Route $route
* @param string|null $name
*
* @return \DOMDocument
*/
private function getRouteDocument(Route $route, $name = null)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($routeXML = $dom->createElement('route'));
if ($name) {
$routeXML->setAttribute('name', $name);
}
$routeXML->setAttribute('class', get_class($route));
$routeXML->appendChild($pathXML = $dom->createElement('path'));
$pathXML->setAttribute('regex', $route->compile()->getRegex());
$pathXML->appendChild(new \DOMText($route->getPath()));
if ('' !== $route->getHost()) {
$routeXML->appendChild($hostXML = $dom->createElement('host'));
$hostXML->setAttribute('regex', $route->compile()->getHostRegex());
$hostXML->appendChild(new \DOMText($route->getHost()));
}
foreach ($route->getSchemes() as $scheme) {
$routeXML->appendChild($schemeXML = $dom->createElement('scheme'));
$schemeXML->appendChild(new \DOMText($scheme));
}
foreach ($route->getMethods() as $method) {
$routeXML->appendChild($methodXML = $dom->createElement('method'));
$methodXML->appendChild(new \DOMText($method));
}
if (count($route->getDefaults())) {
$routeXML->appendChild($defaultsXML = $dom->createElement('defaults'));
foreach ($route->getDefaults() as $attribute => $value) {
$defaultsXML->appendChild($defaultXML = $dom->createElement('default'));
$defaultXML->setAttribute('key', $attribute);
$defaultXML->appendChild(new \DOMText($this->formatValue($value)));
}
}
if (count($route->getRequirements())) {
$routeXML->appendChild($requirementsXML = $dom->createElement('requirements'));
foreach ($route->getRequirements() as $attribute => $pattern) {
$requirementsXML->appendChild($requirementXML = $dom->createElement('requirement'));
$requirementXML->setAttribute('key', $attribute);
$requirementXML->appendChild(new \DOMText($pattern));
}
}
if (count($route->getOptions())) {
$routeXML->appendChild($optionsXML = $dom->createElement('options'));
foreach ($route->getOptions() as $name => $value) {
$optionsXML->appendChild($optionXML = $dom->createElement('option'));
$optionXML->setAttribute('key', $name);
$optionXML->appendChild(new \DOMText($this->formatValue($value)));
}
}
return $dom;
}
/**
* @param ParameterBag $parameters
*
* @return \DOMDocument
*/
private function getContainerParametersDocument(ParameterBag $parameters)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($parametersXML = $dom->createElement('parameters'));
foreach ($this->sortParameters($parameters) as $key => $value) {
$parametersXML->appendChild($parameterXML = $dom->createElement('parameter'));
$parameterXML->setAttribute('key', $key);
$parameterXML->appendChild(new \DOMText($this->formatParameter($value)));
}
return $dom;
}
/**
* @param ContainerBuilder $builder
* @param bool $showPrivate
*
* @return \DOMDocument
*/
private function getContainerTagsDocument(ContainerBuilder $builder, $showPrivate = false)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($containerXML = $dom->createElement('container'));
foreach ($this->findDefinitionsByTag($builder, $showPrivate) as $tag => $definitions) {
$containerXML->appendChild($tagXML = $dom->createElement('tag'));
$tagXML->setAttribute('name', $tag);
foreach ($definitions as $serviceId => $definition) {
$definitionXML = $this->getContainerDefinitionDocument($definition, $serviceId, true);
$tagXML->appendChild($dom->importNode($definitionXML->childNodes->item(0), true));
}
}
return $dom;
}
/**
* @param mixed $service
* @param string $id
*
* @return \DOMDocument
*/
private function getContainerServiceDocument($service, $id)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
if ($service instanceof Alias) {
$dom->appendChild($dom->importNode($this->getContainerAliasDocument($service, $id)->childNodes->item(0), true));
} elseif ($service instanceof Definition) {
$dom->appendChild($dom->importNode($this->getContainerDefinitionDocument($service, $id)->childNodes->item(0), true));
} else {
$dom->appendChild($serviceXML = $dom->createElement('service'));
$serviceXML->setAttribute('id', $id);
$serviceXML->setAttribute('class', get_class($service));
}
return $dom;
}
/**
* @param ContainerBuilder $builder
* @param string|null $tag
* @param bool $showPrivate
*
* @return \DOMDocument
*/
private function getContainerServicesDocument(ContainerBuilder $builder, $tag = null, $showPrivate = false)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($containerXML = $dom->createElement('container'));
$serviceIds = $tag ? array_keys($builder->findTaggedServiceIds($tag)) : $builder->getServiceIds();
foreach ($this->sortServiceIds($serviceIds) as $serviceId) {
$service = $this->resolveServiceDefinition($builder, $serviceId);
if ($service instanceof Definition && !($showPrivate || $service->isPublic())) {
continue;
}
$serviceXML = $this->getContainerServiceDocument($service, $serviceId);
$containerXML->appendChild($containerXML->ownerDocument->importNode($serviceXML->childNodes->item(0), true));
}
return $dom;
}
/**
* @param Definition $definition
* @param string|null $id
* @param bool $omitTags
*
* @return \DOMDocument
*/
private function getContainerDefinitionDocument(Definition $definition, $id = null, $omitTags = false)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($serviceXML = $dom->createElement('definition'));
if ($id) {
$serviceXML->setAttribute('id', $id);
}
$serviceXML->setAttribute('class', $definition->getClass());
if ($factory = $definition->getFactory()) {
$serviceXML->appendChild($factoryXML = $dom->createElement('factory'));
if (is_array($factory)) {
if ($factory[0] instanceof Reference) {
$factoryXML->setAttribute('service', (string) $factory[0]);
} elseif ($factory[0] instanceof Definition) {
throw new \InvalidArgumentException('Factory is not describable.');
} else {
$factoryXML->setAttribute('class', $factory[0]);
}
$factoryXML->setAttribute('method', $factory[1]);
} else {
$factoryXML->setAttribute('function', $factory);
}
}
$serviceXML->setAttribute('public', $definition->isPublic() ? 'true' : 'false');
$serviceXML->setAttribute('synthetic', $definition->isSynthetic() ? 'true' : 'false');
$serviceXML->setAttribute('lazy', $definition->isLazy() ? 'true' : 'false');
if (method_exists($definition, 'isShared')) {
$serviceXML->setAttribute('shared', $definition->isShared() ? 'true' : 'false');
}
$serviceXML->setAttribute('abstract', $definition->isAbstract() ? 'true' : 'false');
if (method_exists($definition, 'isAutowired')) {
$serviceXML->setAttribute('autowired', $definition->isAutowired() ? 'true' : 'false');
}
$serviceXML->setAttribute('file', $definition->getFile());
if (!$omitTags) {
$tags = $definition->getTags();
if (count($tags) > 0) {
$serviceXML->appendChild($tagsXML = $dom->createElement('tags'));
foreach ($tags as $tagName => $tagData) {
foreach ($tagData as $parameters) {
$tagsXML->appendChild($tagXML = $dom->createElement('tag'));
$tagXML->setAttribute('name', $tagName);
foreach ($parameters as $name => $value) {
$tagXML->appendChild($parameterXML = $dom->createElement('parameter'));
$parameterXML->setAttribute('name', $name);
$parameterXML->appendChild(new \DOMText($this->formatParameter($value)));
}
}
}
}
}
return $dom;
}
/**
* @param Alias $alias
* @param string|null $id
*
* @return \DOMDocument
*/
private function getContainerAliasDocument(Alias $alias, $id = null)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($aliasXML = $dom->createElement('alias'));
if ($id) {
$aliasXML->setAttribute('id', $id);
}
$aliasXML->setAttribute('service', (string) $alias);
$aliasXML->setAttribute('public', $alias->isPublic() ? 'true' : 'false');
return $dom;
}
/**
* @param string $parameter
* @param array $options
*
* @return \DOMDocument
*/
private function getContainerParameterDocument($parameter, $options = array())
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($parameterXML = $dom->createElement('parameter'));
if (isset($options['parameter'])) {
$parameterXML->setAttribute('key', $options['parameter']);
}
$parameterXML->appendChild(new \DOMText($this->formatParameter($parameter)));
return $dom;
}
/**
* @param EventDispatcherInterface $eventDispatcher
* @param string|null $event
*
* @return \DOMDocument
*/
private function getEventDispatcherListenersDocument(EventDispatcherInterface $eventDispatcher, $event = null)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($eventDispatcherXML = $dom->createElement('event-dispatcher'));
$registeredListeners = $eventDispatcher->getListeners($event);
if (null !== $event) {
$this->appendEventListenerDocument($eventDispatcher, $event, $eventDispatcherXML, $registeredListeners);
} else {
ksort($registeredListeners);
foreach ($registeredListeners as $eventListened => $eventListeners) {
$eventDispatcherXML->appendChild($eventXML = $dom->createElement('event'));
$eventXML->setAttribute('name', $eventListened);
$this->appendEventListenerDocument($eventDispatcher, $eventListened, $eventXML, $eventListeners);
}
}
return $dom;
}
/**
* @param \DOMElement $element
* @param array $eventListeners
*/
private function appendEventListenerDocument(EventDispatcherInterface $eventDispatcher, $event, \DOMElement $element, array $eventListeners)
{
foreach ($eventListeners as $listener) {
$callableXML = $this->getCallableDocument($listener);
$callableXML->childNodes->item(0)->setAttribute('priority', $eventDispatcher->getListenerPriority($event, $listener));
$element->appendChild($element->ownerDocument->importNode($callableXML->childNodes->item(0), true));
}
}
/**
* @param callable $callable
*
* @return \DOMDocument
*/
private function getCallableDocument($callable)
{
$dom = new \DOMDocument('1.0', 'UTF-8');
$dom->appendChild($callableXML = $dom->createElement('callable'));
if (is_array($callable)) {
$callableXML->setAttribute('type', 'function');
if (is_object($callable[0])) {
$callableXML->setAttribute('name', $callable[1]);
$callableXML->setAttribute('class', get_class($callable[0]));
} else {
if (0 !== strpos($callable[1], 'parent::')) {
$callableXML->setAttribute('name', $callable[1]);
$callableXML->setAttribute('class', $callable[0]);
$callableXML->setAttribute('static', 'true');
} else {
$callableXML->setAttribute('name', substr($callable[1], 8));
$callableXML->setAttribute('class', $callable[0]);
$callableXML->setAttribute('static', 'true');
$callableXML->setAttribute('parent', 'true');
}
}
return $dom;
}
if (is_string($callable)) {
$callableXML->setAttribute('type', 'function');
if (false === strpos($callable, '::')) {
$callableXML->setAttribute('name', $callable);
} else {
$callableParts = explode('::', $callable);
$callableXML->setAttribute('name', $callableParts[1]);
$callableXML->setAttribute('class', $callableParts[0]);
$callableXML->setAttribute('static', 'true');
}
return $dom;
}
if ($callable instanceof \Closure) {
$callableXML->setAttribute('type', 'closure');
return $dom;
}
if (method_exists($callable, '__invoke')) {
$callableXML->setAttribute('type', 'object');
$callableXML->setAttribute('name', get_class($callable));
return $dom;
}
throw new \InvalidArgumentException('Callable is not describable.');
}
}

View File

@@ -0,0 +1,39 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\FrameworkBundle\Console\Helper;
use Symfony\Bundle\FrameworkBundle\Console\Descriptor\JsonDescriptor;
use Symfony\Bundle\FrameworkBundle\Console\Descriptor\MarkdownDescriptor;
use Symfony\Bundle\FrameworkBundle\Console\Descriptor\TextDescriptor;
use Symfony\Bundle\FrameworkBundle\Console\Descriptor\XmlDescriptor;
use Symfony\Component\Console\Helper\DescriptorHelper as BaseDescriptorHelper;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*
* @internal
*/
class DescriptorHelper extends BaseDescriptorHelper
{
/**
* Constructor.
*/
public function __construct()
{
$this
->register('txt', new TextDescriptor())
->register('xml', new XmlDescriptor())
->register('json', new JsonDescriptor())
->register('md', new MarkdownDescriptor())
;
}
}