123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372 |
- <?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.
- *
- * @return array|string
- */
- private function writeData(array $data, array $options)
- {
- $flags = isset($options['json_encoding']) ? $options['json_encoding'] : 0;
- if (\defined('JSON_PRETTY_PRINT')) {
- $flags |= JSON_PRETTY_PRINT;
- }
- $this->write(json_encode($data, $flags)."\n");
- }
- /**
- * @return array
- */
- protected function getRouteData(Route $route)
- {
- $requirements = $route->getRequirements();
- unset($requirements['_scheme'], $requirements['_method']);
- 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' => $requirements ?: '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(),
- 'scope' => $definition->getScope(false),
- 'public' => $definition->isPublic(),
- 'synthetic' => $definition->isSynthetic(),
- 'lazy' => $definition->isLazy(),
- 'shared' => $definition->isShared(),
- 'synchronized' => $definition->isSynchronized(false),
- 'abstract' => $definition->isAbstract(),
- 'autowire' => $definition->isAutowired(),
- 'autowiring_types' => array(),
- 'file' => $definition->getFile(),
- );
- foreach ($definition->getAutowiringTypes() as $autowiringType) {
- $data['autowiring_types'][] = $autowiringType;
- }
- if ($definition->getFactoryClass(false)) {
- $data['factory_class'] = $definition->getFactoryClass(false);
- }
- if ($definition->getFactoryService(false)) {
- $data['factory_service'] = $definition->getFactoryService(false);
- }
- if ($definition->getFactoryMethod(false)) {
- $data['factory_method'] = $definition->getFactoryMethod(false);
- }
- 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();
- foreach ($definition->getTags() as $tagName => $tagData) {
- foreach ($tagData as $parameters) {
- $data['tags'][] = array('name' => $tagName, 'parameters' => $parameters);
- }
- }
- }
- return $data;
- }
- /**
- * @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.');
- }
- }
|