Verzeichnisstruktur phpBB-3.1.0


Veröffentlicht
27.10.2014

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