[ Index ] |
PHP Cross Reference of phpBB-3.1.12-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\DependencyInjection\Dumper; 13 14 use Symfony\Component\DependencyInjection\Definition; 15 use Symfony\Component\DependencyInjection\Reference; 16 use Symfony\Component\DependencyInjection\Parameter; 17 use Symfony\Component\DependencyInjection\ContainerInterface; 18 use Symfony\Component\DependencyInjection\ContainerBuilder; 19 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; 20 use Symfony\Component\DependencyInjection\Scope; 21 22 /** 23 * GraphvizDumper dumps a service container as a graphviz file. 24 * 25 * You can convert the generated dot file with the dot utility (http://www.graphviz.org/): 26 * 27 * dot -Tpng container.dot > foo.png 28 * 29 * @author Fabien Potencier <fabien@symfony.com> 30 */ 31 class GraphvizDumper extends Dumper 32 { 33 private $nodes; 34 private $edges; 35 private $options = array( 36 'graph' => array('ratio' => 'compress'), 37 'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'), 38 'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5), 39 'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'), 40 'node.definition' => array('fillcolor' => '#eeeeee'), 41 'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'), 42 ); 43 44 /** 45 * Dumps the service container as a graphviz graph. 46 * 47 * Available options: 48 * 49 * * graph: The default options for the whole graph 50 * * node: The default options for nodes 51 * * edge: The default options for edges 52 * * node.instance: The default options for services that are defined directly by object instances 53 * * node.definition: The default options for services that are defined via service definition instances 54 * * node.missing: The default options for missing services 55 * 56 * @param array $options An array of options 57 * 58 * @return string The dot representation of the service container 59 */ 60 public function dump(array $options = array()) 61 { 62 foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) { 63 if (isset($options[$key])) { 64 $this->options[$key] = array_merge($this->options[$key], $options[$key]); 65 } 66 } 67 68 $this->nodes = $this->findNodes(); 69 70 $this->edges = array(); 71 foreach ($this->container->getDefinitions() as $id => $definition) { 72 $this->edges[$id] = array_merge( 73 $this->findEdges($id, $definition->getArguments(), true, ''), 74 $this->findEdges($id, $definition->getProperties(), false, '') 75 ); 76 77 foreach ($definition->getMethodCalls() as $call) { 78 $this->edges[$id] = array_merge( 79 $this->edges[$id], 80 $this->findEdges($id, $call[1], false, $call[0].'()') 81 ); 82 } 83 } 84 85 return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot(); 86 } 87 88 /** 89 * Returns all nodes. 90 * 91 * @return string A string representation of all nodes 92 */ 93 private function addNodes() 94 { 95 $code = ''; 96 foreach ($this->nodes as $id => $node) { 97 $aliases = $this->getAliases($id); 98 99 $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 $class = $definition->getClass(); 169 170 if ('\\' === substr($class, 0, 1)) { 171 $class = substr($class, 1); 172 } 173 174 $nodes[$id] = array('class' => str_replace('\\', '\\\\', $this->container->getParameterBag()->resolveValue($class)), 'attributes' => array_merge($this->options['node.definition'], array('style' => ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope() ? 'filled' : 'dotted'))); 175 176 $container->setDefinition($id, new Definition('stdClass')); 177 } 178 179 foreach ($container->getServiceIds() as $id) { 180 $service = $container->get($id); 181 182 if (array_key_exists($id, $container->getAliases())) { 183 continue; 184 } 185 186 if (!$container->hasDefinition($id)) { 187 $class = ('service_container' === $id) ? get_class($this->container) : get_class($service); 188 $nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']); 189 } 190 } 191 192 return $nodes; 193 } 194 195 private function cloneContainer() 196 { 197 $parameterBag = new ParameterBag($this->container->getParameterBag()->all()); 198 199 $container = new ContainerBuilder($parameterBag); 200 $container->setDefinitions($this->container->getDefinitions()); 201 $container->setAliases($this->container->getAliases()); 202 $container->setResources($this->container->getResources()); 203 foreach ($this->container->getScopes() as $scope => $parentScope) { 204 $container->addScope(new Scope($scope, $parentScope)); 205 } 206 foreach ($this->container->getExtensions() as $extension) { 207 $container->registerExtension($extension); 208 } 209 210 return $container; 211 } 212 213 /** 214 * Returns the start dot. 215 * 216 * @return string The string representation of a start dot 217 */ 218 private function startDot() 219 { 220 return sprintf("digraph sc {\n %s\n node [%s];\n edge [%s];\n\n", 221 $this->addOptions($this->options['graph']), 222 $this->addOptions($this->options['node']), 223 $this->addOptions($this->options['edge']) 224 ); 225 } 226 227 /** 228 * Returns the end dot. 229 * 230 * @return string 231 */ 232 private function endDot() 233 { 234 return "}\n"; 235 } 236 237 /** 238 * Adds attributes. 239 * 240 * @param array $attributes An array of attributes 241 * 242 * @return string A comma separated list of attributes 243 */ 244 private function addAttributes($attributes) 245 { 246 $code = array(); 247 foreach ($attributes as $k => $v) { 248 $code[] = sprintf('%s="%s"', $k, $v); 249 } 250 251 return $code ? ', '.implode(', ', $code) : ''; 252 } 253 254 /** 255 * Adds options. 256 * 257 * @param array $options An array of options 258 * 259 * @return string A space separated list of options 260 */ 261 private function addOptions($options) 262 { 263 $code = array(); 264 foreach ($options as $k => $v) { 265 $code[] = sprintf('%s="%s"', $k, $v); 266 } 267 268 return implode(' ', $code); 269 } 270 271 /** 272 * Dotizes an identifier. 273 * 274 * @param string $id The identifier to dotize 275 * 276 * @return string A dotized string 277 */ 278 private function dotize($id) 279 { 280 return strtolower(preg_replace('/\W/i', '_', $id)); 281 } 282 283 /** 284 * Compiles an array of aliases for a specified service id. 285 * 286 * @param string $id A service id 287 * 288 * @return array An array of aliases 289 */ 290 private function getAliases($id) 291 { 292 $aliases = array(); 293 foreach ($this->container->getAliases() as $alias => $origin) { 294 if ($id == $origin) { 295 $aliases[] = $alias; 296 } 297 } 298 299 return $aliases; 300 } 301 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Jan 11 00:25:41 2018 | Cross-referenced by PHPXref 0.7.1 |