Verzeichnisstruktur phpBB-3.2.0


Veröffentlicht
06.01.2017

So funktioniert es


Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück

Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis.
Auf den Verzeichnisnamen klicken, dies zeigt nur das Verzeichnis mit Inhalt an

      (Beispiel Datei-Icons)

Auf das Icon klicken um den Quellcode anzuzeigen

GraphvizDumper.php

Zuletzt modifiziert: 09.10.2024, 12:56 - Dateigröße: 9.96 KiB


 001  <?php
 002   
 003  /*
 004   * This file is part of the Symfony package.
 005   *
 006   * (c) Fabien Potencier <fabien@symfony.com>
 007   *
 008   * For the full copyright and license information, please view the LICENSE
 009   * file that was distributed with this source code.
 010   */
 011   
 012  namespace Symfony\Component\DependencyInjection\Dumper;
 013   
 014  use Symfony\Component\DependencyInjection\Definition;
 015  use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
 016  use Symfony\Component\DependencyInjection\Reference;
 017  use Symfony\Component\DependencyInjection\Parameter;
 018  use Symfony\Component\DependencyInjection\ContainerInterface;
 019  use Symfony\Component\DependencyInjection\ContainerBuilder;
 020  use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
 021  use Symfony\Component\DependencyInjection\Scope;
 022   
 023  /**
 024   * GraphvizDumper dumps a service container as a graphviz file.
 025   *
 026   * You can convert the generated dot file with the dot utility (http://www.graphviz.org/):
 027   *
 028   *   dot -Tpng container.dot > foo.png
 029   *
 030   * @author Fabien Potencier <fabien@symfony.com>
 031   */
 032  class GraphvizDumper extends Dumper
 033  {
 034      private $nodes;
 035      private $edges;
 036      private $options = array(
 037              'graph' => array('ratio' => 'compress'),
 038              'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'),
 039              'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5),
 040              'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'),
 041              'node.definition' => array('fillcolor' => '#eeeeee'),
 042              'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'),
 043          );
 044   
 045      /**
 046       * Dumps the service container as a graphviz graph.
 047       *
 048       * Available options:
 049       *
 050       *  * graph: The default options for the whole graph
 051       *  * node: The default options for nodes
 052       *  * edge: The default options for edges
 053       *  * node.instance: The default options for services that are defined directly by object instances
 054       *  * node.definition: The default options for services that are defined via service definition instances
 055       *  * node.missing: The default options for missing services
 056       *
 057       * @param array $options An array of options
 058       *
 059       * @return string The dot representation of the service container
 060       */
 061      public function dump(array $options = array())
 062      {
 063          foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) {
 064              if (isset($options[$key])) {
 065                  $this->options[$key] = array_merge($this->options[$key], $options[$key]);
 066              }
 067          }
 068   
 069          $this->nodes = $this->findNodes();
 070   
 071          $this->edges = array();
 072          foreach ($this->container->getDefinitions() as $id => $definition) {
 073              $this->edges[$id] = array_merge(
 074                  $this->findEdges($id, $definition->getArguments(), true, ''),
 075                  $this->findEdges($id, $definition->getProperties(), false, '')
 076              );
 077   
 078              foreach ($definition->getMethodCalls() as $call) {
 079                  $this->edges[$id] = array_merge(
 080                      $this->edges[$id],
 081                      $this->findEdges($id, $call[1], false, $call[0].'()')
 082                  );
 083              }
 084          }
 085   
 086          return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot();
 087      }
 088   
 089      /**
 090       * Returns all nodes.
 091       *
 092       * @return string A string representation of all nodes
 093       */
 094      private function addNodes()
 095      {
 096          $code = '';
 097          foreach ($this->nodes as $id => $node) {
 098              $aliases = $this->getAliases($id);
 099   
 100              $code .= sprintf("  node_%s [label=\"%s\\n%s\\n\", shape=%s%s];\n", $this->dotize($id), $id.($aliases ? ' ('.implode(', ', $aliases).')' : ''), $node['class'], $this->options['node']['shape'], $this->addAttributes($node['attributes']));
 101          }
 102   
 103          return $code;
 104      }
 105   
 106      /**
 107       * Returns all edges.
 108       *
 109       * @return string A string representation of all edges
 110       */
 111      private function addEdges()
 112      {
 113          $code = '';
 114          foreach ($this->edges as $id => $edges) {
 115              foreach ($edges as $edge) {
 116                  $code .= sprintf("  node_%s -> node_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed');
 117              }
 118          }
 119   
 120          return $code;
 121      }
 122   
 123      /**
 124       * Finds all edges belonging to a specific service id.
 125       *
 126       * @param string $id        The service id used to find edges
 127       * @param array  $arguments An array of arguments
 128       * @param bool   $required
 129       * @param string $name
 130       *
 131       * @return array An array of edges
 132       */
 133      private function findEdges($id, array $arguments, $required, $name)
 134      {
 135          $edges = array();
 136          foreach ($arguments as $argument) {
 137              if ($argument instanceof Parameter) {
 138                  $argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null;
 139              } elseif (is_string($argument) && preg_match('/^%([^%]+)%$/', $argument, $match)) {
 140                  $argument = $this->container->hasParameter($match[1]) ? $this->container->getParameter($match[1]) : null;
 141              }
 142   
 143              if ($argument instanceof Reference) {
 144                  if (!$this->container->has((string) $argument)) {
 145                      $this->nodes[(string) $argument] = array('name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']);
 146                  }
 147   
 148                  $edges[] = array('name' => $name, 'required' => $required, 'to' => $argument);
 149              } elseif (is_array($argument)) {
 150                  $edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name));
 151              }
 152          }
 153   
 154          return $edges;
 155      }
 156   
 157      /**
 158       * Finds all nodes.
 159       *
 160       * @return array An array of all nodes
 161       */
 162      private function findNodes()
 163      {
 164          $nodes = array();
 165   
 166          $container = $this->cloneContainer();
 167   
 168          foreach ($container->getDefinitions() as $id => $definition) {
 169              $class = $definition->getClass();
 170   
 171              if ('\\' === substr($class, 0, 1)) {
 172                  $class = substr($class, 1);
 173              }
 174   
 175              try {
 176                  $class = $this->container->getParameterBag()->resolveValue($class);
 177              } catch (ParameterNotFoundException $e) {
 178              }
 179   
 180              $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted')));
 181              $container->setDefinition($id, new Definition('stdClass'));
 182          }
 183   
 184          foreach ($container->getServiceIds() as $id) {
 185              $service = $container->get($id);
 186   
 187              if (array_key_exists($id, $container->getAliases())) {
 188                  continue;
 189              }
 190   
 191              if (!$container->hasDefinition($id)) {
 192                  $class = ('service_container' === $id) ? get_class($this->container) : get_class($service);
 193                  $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']);
 194              }
 195          }
 196   
 197          return $nodes;
 198      }
 199   
 200      private function cloneContainer()
 201      {
 202          $parameterBag = new ParameterBag($this->container->getParameterBag()->all());
 203   
 204          $container = new ContainerBuilder($parameterBag);
 205          $container->setDefinitions($this->container->getDefinitions());
 206          $container->setAliases($this->container->getAliases());
 207          $container->setResources($this->container->getResources());
 208          foreach ($this->container->getScopes(false) as $scope => $parentScope) {
 209              $container->addScope(new Scope($scope, $parentScope));
 210          }
 211          foreach ($this->container->getExtensions() as $extension) {
 212              $container->registerExtension($extension);
 213          }
 214   
 215          return $container;
 216      }
 217   
 218      /**
 219       * Returns the start dot.
 220       *
 221       * @return string The string representation of a start dot
 222       */
 223      private function startDot()
 224      {
 225          return sprintf("digraph sc {\n  %s\n  node [%s];\n  edge [%s];\n\n",
 226              $this->addOptions($this->options['graph']),
 227              $this->addOptions($this->options['node']),
 228              $this->addOptions($this->options['edge'])
 229          );
 230      }
 231   
 232      /**
 233       * Returns the end dot.
 234       *
 235       * @return string
 236       */
 237      private function endDot()
 238      {
 239          return "}\n";
 240      }
 241   
 242      /**
 243       * Adds attributes.
 244       *
 245       * @param array $attributes An array of attributes
 246       *
 247       * @return string A comma separated list of attributes
 248       */
 249      private function addAttributes(array $attributes)
 250      {
 251          $code = array();
 252          foreach ($attributes as $k => $v) {
 253              $code[] = sprintf('%s="%s"', $k, $v);
 254          }
 255   
 256          return $code ? ', '.implode(', ', $code) : '';
 257      }
 258   
 259      /**
 260       * Adds options.
 261       *
 262       * @param array $options An array of options
 263       *
 264       * @return string A space separated list of options
 265       */
 266      private function addOptions(array $options)
 267      {
 268          $code = array();
 269          foreach ($options as $k => $v) {
 270              $code[] = sprintf('%s="%s"', $k, $v);
 271          }
 272   
 273          return implode(' ', $code);
 274      }
 275   
 276      /**
 277       * Dotizes an identifier.
 278       *
 279       * @param string $id The identifier to dotize
 280       *
 281       * @return string A dotized string
 282       */
 283      private function dotize($id)
 284      {
 285          return strtolower(preg_replace('/\W/i', '_', $id));
 286      }
 287   
 288      /**
 289       * Compiles an array of aliases for a specified service id.
 290       *
 291       * @param string $id A service id
 292       *
 293       * @return array An array of aliases
 294       */
 295      private function getAliases($id)
 296      {
 297          $aliases = array();
 298          foreach ($this->container->getAliases() as $alias => $origin) {
 299              if ($id == $origin) {
 300                  $aliases[] = $alias;
 301              }
 302          }
 303   
 304          return $aliases;
 305      }
 306  }
 307