commiting uncommited changes on live site
[weblabels.fsf.org.git] / crm.fsf.org / 20131203 / files / sites / all / modules-old / civicrm / vendor / symfony / dependency-injection / Symfony / Component / DependencyInjection / Dumper / XmlDumper.php
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\ContainerInterface;
15 use Symfony\Component\DependencyInjection\Parameter;
16 use Symfony\Component\DependencyInjection\Reference;
17 use Symfony\Component\DependencyInjection\Definition;
18 use Symfony\Component\DependencyInjection\Alias;
19 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
20
21 /**
22 * XmlDumper dumps a service container as an XML string.
23 *
24 * @author Fabien Potencier <fabien@symfony.com>
25 * @author Martin HasoĊˆ <martin.hason@gmail.com>
26 */
27 class XmlDumper extends Dumper
28 {
29 /**
30 * @var \DOMDocument
31 */
32 private $document;
33
34 /**
35 * Dumps the service container as an XML string.
36 *
37 * @param array $options An array of options
38 *
39 * @return string An xml string representing of the service container
40 */
41 public function dump(array $options = array())
42 {
43 $this->document = new \DOMDocument('1.0', 'utf-8');
44 $this->document->formatOutput = true;
45
46 $container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container');
47 $container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
48 $container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd');
49
50 $this->addParameters($container);
51 $this->addServices($container);
52
53 $this->document->appendChild($container);
54 $xml = $this->document->saveXML();
55 $this->document = null;
56
57 return $xml;
58 }
59
60 /**
61 * Adds parameters.
62 *
63 * @param \DOMElement $parent
64 */
65 private function addParameters(\DOMElement $parent)
66 {
67 $data = $this->container->getParameterBag()->all();
68 if (!$data) {
69 return;
70 }
71
72 if ($this->container->isFrozen()) {
73 $data = $this->escape($data);
74 }
75
76 $parameters = $this->document->createElement('parameters');
77 $parent->appendChild($parameters);
78 $this->convertParameters($data, 'parameter', $parameters);
79 }
80
81 /**
82 * Adds method calls.
83 *
84 * @param array $methodcalls
85 * @param \DOMElement $parent
86 */
87 private function addMethodCalls(array $methodcalls, \DOMElement $parent)
88 {
89 foreach ($methodcalls as $methodcall) {
90 $call = $this->document->createElement('call');
91 $call->setAttribute('method', $methodcall[0]);
92 if (count($methodcall[1])) {
93 $this->convertParameters($methodcall[1], 'argument', $call);
94 }
95 $parent->appendChild($call);
96 }
97 }
98
99 /**
100 * Adds a service.
101 *
102 * @param Definition $definition
103 * @param string $id
104 * @param \DOMElement $parent
105 */
106 private function addService($definition, $id, \DOMElement $parent)
107 {
108 $service = $this->document->createElement('service');
109 if (null !== $id) {
110 $service->setAttribute('id', $id);
111 }
112 if ($class = $definition->getClass()) {
113 if ('\\' === substr($class, 0, 1)) {
114 $class = substr($class, 1);
115 }
116
117 $service->setAttribute('class', $class);
118 }
119 if ($definition->getFactoryMethod()) {
120 $service->setAttribute('factory-method', $definition->getFactoryMethod());
121 }
122 if ($definition->getFactoryClass()) {
123 $service->setAttribute('factory-class', $definition->getFactoryClass());
124 }
125 if ($definition->getFactoryService()) {
126 $service->setAttribute('factory-service', $definition->getFactoryService());
127 }
128 if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope()) {
129 $service->setAttribute('scope', $scope);
130 }
131 if (!$definition->isPublic()) {
132 $service->setAttribute('public', 'false');
133 }
134 if ($definition->isSynthetic()) {
135 $service->setAttribute('synthetic', 'true');
136 }
137 if ($definition->isSynchronized()) {
138 $service->setAttribute('synchronized', 'true');
139 }
140 if ($definition->isLazy()) {
141 $service->setAttribute('lazy', 'true');
142 }
143
144 foreach ($definition->getTags() as $name => $tags) {
145 foreach ($tags as $attributes) {
146 $tag = $this->document->createElement('tag');
147 $tag->setAttribute('name', $name);
148 foreach ($attributes as $key => $value) {
149 $tag->setAttribute($key, $value);
150 }
151 $service->appendChild($tag);
152 }
153 }
154
155 if ($definition->getFile()) {
156 $file = $this->document->createElement('file');
157 $file->appendChild($this->document->createTextNode($definition->getFile()));
158 $service->appendChild($file);
159 }
160
161 if ($parameters = $definition->getArguments()) {
162 $this->convertParameters($parameters, 'argument', $service);
163 }
164
165 if ($parameters = $definition->getProperties()) {
166 $this->convertParameters($parameters, 'property', $service, 'name');
167 }
168
169 $this->addMethodCalls($definition->getMethodCalls(), $service);
170
171 if ($callable = $definition->getConfigurator()) {
172 $configurator = $this->document->createElement('configurator');
173 if (is_array($callable)) {
174 $configurator->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
175 $configurator->setAttribute('method', $callable[1]);
176 } else {
177 $configurator->setAttribute('function', $callable);
178 }
179 $service->appendChild($configurator);
180 }
181
182 $parent->appendChild($service);
183 }
184
185 /**
186 * Adds a service alias.
187 *
188 * @param string $alias
189 * @param Alias $id
190 * @param \DOMElement $parent
191 */
192 private function addServiceAlias($alias, Alias $id, \DOMElement $parent)
193 {
194 $service = $this->document->createElement('service');
195 $service->setAttribute('id', $alias);
196 $service->setAttribute('alias', $id);
197 if (!$id->isPublic()) {
198 $service->setAttribute('public', 'false');
199 }
200 $parent->appendChild($service);
201 }
202
203 /**
204 * Adds services.
205 *
206 * @param \DOMElement $parent
207 */
208 private function addServices(\DOMElement $parent)
209 {
210 $definitions = $this->container->getDefinitions();
211 if (!$definitions) {
212 return;
213 }
214
215 $services = $this->document->createElement('services');
216 foreach ($definitions as $id => $definition) {
217 $this->addService($definition, $id, $services);
218 }
219
220 $aliases = $this->container->getAliases();
221 foreach ($aliases as $alias => $id) {
222 while (isset($aliases[(string) $id])) {
223 $id = $aliases[(string) $id];
224 }
225 $this->addServiceAlias($alias, $id, $services);
226 }
227 $parent->appendChild($services);
228 }
229
230 /**
231 * Converts parameters.
232 *
233 * @param array $parameters
234 * @param string $type
235 * @param \DOMElement $parent
236 * @param string $keyAttribute
237 */
238 private function convertParameters($parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
239 {
240 $withKeys = array_keys($parameters) !== range(0, count($parameters) - 1);
241 foreach ($parameters as $key => $value) {
242 $element = $this->document->createElement($type);
243 if ($withKeys) {
244 $element->setAttribute($keyAttribute, $key);
245 }
246
247 if (is_array($value)) {
248 $element->setAttribute('type', 'collection');
249 $this->convertParameters($value, $type, $element, 'key');
250 } elseif ($value instanceof Reference) {
251 $element->setAttribute('type', 'service');
252 $element->setAttribute('id', (string) $value);
253 $behaviour = $value->getInvalidBehavior();
254 if ($behaviour == ContainerInterface::NULL_ON_INVALID_REFERENCE) {
255 $element->setAttribute('on-invalid', 'null');
256 } elseif ($behaviour == ContainerInterface::IGNORE_ON_INVALID_REFERENCE) {
257 $element->setAttribute('on-invalid', 'ignore');
258 }
259 if (!$value->isStrict()) {
260 $element->setAttribute('strict', 'false');
261 }
262 } elseif ($value instanceof Definition) {
263 $element->setAttribute('type', 'service');
264 $this->addService($value, null, $element);
265 } else {
266 if (in_array($value, array('null', 'true', 'false'), true)) {
267 $element->setAttribute('type', 'string');
268 }
269 $text = $this->document->createTextNode(self::phpToXml($value));
270 $element->appendChild($text);
271 }
272 $parent->appendChild($element);
273 }
274 }
275
276 /**
277 * Escapes arguments.
278 *
279 * @param array $arguments
280 *
281 * @return array
282 */
283 private function escape($arguments)
284 {
285 $args = array();
286 foreach ($arguments as $k => $v) {
287 if (is_array($v)) {
288 $args[$k] = $this->escape($v);
289 } elseif (is_string($v)) {
290 $args[$k] = str_replace('%', '%%', $v);
291 } else {
292 $args[$k] = $v;
293 }
294 }
295
296 return $args;
297 }
298
299 /**
300 * Converts php types to xml types.
301 *
302 * @param mixed $value Value to convert
303 *
304 * @return string
305 *
306 * @throws RuntimeException When trying to dump object or resource
307 */
308 public static function phpToXml($value)
309 {
310 switch (true) {
311 case null === $value:
312 return 'null';
313 case true === $value:
314 return 'true';
315 case false === $value:
316 return 'false';
317 case $value instanceof Parameter:
318 return '%'.$value.'%';
319 case is_object($value) || is_resource($value):
320 throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
321 default:
322 return (string) $value;
323 }
324 }
325 }