Complex classes like ResourceGenerator often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ResourceGenerator, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
29 | class ResourceGenerator extends AbstractGenerator |
||
30 | { |
||
31 | /** |
||
32 | * @private Filesystem |
||
33 | */ |
||
34 | private $filesystem; |
||
35 | |||
36 | /** |
||
37 | * @private DoctrineRegistry |
||
38 | */ |
||
39 | private $doctrine; |
||
40 | |||
41 | /** |
||
42 | * @private HttpKernelInterface |
||
43 | */ |
||
44 | private $kernel; |
||
45 | |||
46 | /** |
||
47 | * our json file definition |
||
48 | * |
||
49 | * @var JsonDefinition|null |
||
50 | */ |
||
51 | private $json = null; |
||
52 | |||
53 | /** |
||
54 | * @var ArrayCollection |
||
55 | */ |
||
56 | protected $xmlParameters; |
||
57 | |||
58 | /** |
||
59 | * @var \DomDocument |
||
60 | */ |
||
61 | private $serviceDOM; |
||
62 | |||
63 | /** |
||
64 | * @var FieldMapper |
||
65 | */ |
||
66 | private $mapper; |
||
67 | |||
68 | /** |
||
69 | * @var boolean |
||
70 | */ |
||
71 | private $generateController = false; |
||
72 | |||
73 | /** |
||
74 | * @var ParameterBuilder |
||
75 | */ |
||
76 | private $parameterBuilder; |
||
77 | |||
78 | /** |
||
79 | * Instantiates generator object |
||
80 | * |
||
81 | * @param Filesystem $filesystem fs abstraction layer |
||
82 | * @param DoctrineRegistry $doctrine odm registry |
||
83 | * @param HttpKernelInterface $kernel app kernel |
||
84 | * @param FieldMapper $mapper field type mapper |
||
85 | * @param ParameterBuilder $parameterBuilder param builder |
||
86 | */ |
||
87 | 4 | public function __construct( |
|
101 | |||
102 | /** |
||
103 | * @param JsonDefinition $json optional JsonDefinition object |
||
104 | * |
||
105 | * @return void |
||
106 | */ |
||
107 | public function setJson(JsonDefinition $json) |
||
111 | |||
112 | /** |
||
113 | * @param boolean $generateController should the controller be generated or not |
||
114 | * |
||
115 | * @return void |
||
116 | */ |
||
117 | public function setGenerateController($generateController) |
||
121 | |||
122 | /** |
||
123 | * generate the resource with all its bits and parts |
||
124 | * |
||
125 | * @param BundleInterface $bundle bundle |
||
126 | * @param string $document document name |
||
127 | * @param string $format format of config files (please use xml) |
||
128 | * @param array $fields fields to add |
||
129 | * |
||
130 | * @return EntityGeneratorResult |
||
131 | */ |
||
132 | public function generate( |
||
133 | BundleInterface $bundle, |
||
134 | $document, |
||
135 | $format, |
||
136 | array $fields |
||
137 | ) { |
||
138 | $dir = $bundle->getPath(); |
||
139 | $basename = $this->getBundleBaseName($document); |
||
140 | $bundleNamespace = substr(get_class($bundle), 0, 0 - strlen($bundle->getName())); |
||
141 | |||
142 | if (!is_null($this->json)) { |
||
143 | $this->json->setNamespace($bundleNamespace); |
||
144 | } |
||
145 | |||
146 | // add more info to the fields array |
||
147 | $mapper = $this->mapper; |
||
148 | $fields = array_map( |
||
149 | function ($field) use ($mapper) { |
||
150 | return $mapper->map($field, $this->json); |
||
151 | }, |
||
152 | $fields |
||
153 | ); |
||
154 | |||
155 | $parameters = $this->parameterBuilder |
||
156 | ->setParameter('document', $document) |
||
157 | ->setParameter('base', $bundleNamespace) |
||
158 | ->setParameter('bundle', $bundle->getName()) |
||
159 | ->setParameter('format', $format) |
||
160 | ->setParameter('json', $this->json) |
||
161 | ->setParameter('fields', $fields) |
||
162 | ->setParameter('basename', $basename) |
||
163 | ->setParameter('isrecordOriginFlagSet', $this->json->isRecordOriginFlagSet()) |
||
164 | ->setParameter('recordOriginModifiable', $this->json->isRecordOriginModifiable()) |
||
165 | ->setParameter('isVersioning', $this->json->isVersionedService()) |
||
166 | ->setParameter('collection', $this->json->getServiceCollection()) |
||
167 | ->setParameter('indexes', $this->json->getIndexes()) |
||
168 | ->setParameter('textIndexes', $this->json->getAllTextIndexes()) |
||
169 | ->getParameters(); |
||
170 | |||
171 | $this->generateDocument($parameters, $dir, $document); |
||
172 | $this->generateSerializer($parameters, $dir, $document); |
||
173 | $this->generateModel($parameters, $dir, $document); |
||
174 | |||
175 | if ($this->json instanceof JsonDefinition && $this->json->hasFixtures() === true) { |
||
176 | $this->generateFixtures($parameters, $dir, $document); |
||
177 | } |
||
178 | |||
179 | if ($this->generateController) { |
||
180 | $this->generateController($parameters, $dir, $document); |
||
181 | } |
||
182 | |||
183 | $this->generateParameters($dir); |
||
184 | |||
185 | return new EntityGeneratorResult( |
||
186 | $dir . '/Document/' . $document . '.php', |
||
187 | $dir . '/Repository/' . $document . 'Repository.php', |
||
188 | $dir . '/Resources/config/doctrine/' . $document . '.mongodb.xml' |
||
189 | ); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Writes the current services definition to a file. |
||
194 | * |
||
195 | * @param string $dir base bundle dir |
||
196 | * |
||
197 | * @return void |
||
198 | */ |
||
199 | 8 | protected function persistServicesXML($dir) |
|
205 | |||
206 | /** |
||
207 | * generate document part of a resource |
||
208 | * |
||
209 | * @param array $parameters twig parameters |
||
210 | * @param string $dir base bundle dir |
||
211 | * @param string $document document name |
||
212 | * |
||
213 | * @return void |
||
214 | */ |
||
215 | 6 | protected function generateDocument($parameters, $dir, $document) |
|
216 | { |
||
217 | // doctrine mapping normal class |
||
218 | 6 | $this->renderFile( |
|
219 | 6 | 'document/Document.mongodb.xml.twig', |
|
220 | 6 | $dir . '/Resources/config/doctrine/' . $document . '.mongodb.xml', |
|
221 | 6 | $parameters |
|
222 | ); |
||
223 | |||
224 | // doctrine mapping embedded |
||
225 | 6 | $this->renderFile( |
|
226 | 6 | 'document/Document.mongodb.xml.twig', |
|
227 | 6 | $dir . '/Resources/config/doctrine/' . $document . 'Embedded.mongodb.xml', |
|
228 | 6 | array_merge( |
|
229 | 6 | $parameters, |
|
230 | [ |
||
231 | 6 | 'document' => $document.'Embedded', |
|
232 | 6 | 'docType' => 'embedded-document' |
|
233 | ] |
||
234 | ) |
||
235 | ); |
||
236 | |||
237 | 6 | $this->renderFile( |
|
238 | 6 | 'document/Document.php.twig', |
|
239 | 6 | $dir . '/Document/' . $document . '.php', |
|
240 | 6 | $parameters |
|
241 | ); |
||
242 | 6 | $this->renderFile( |
|
243 | 6 | 'document/DocumentEmbedded.php.twig', |
|
244 | 6 | $dir . '/Document/' . $document . 'Embedded.php', |
|
245 | 6 | $parameters |
|
246 | ); |
||
247 | 6 | $this->renderFile( |
|
248 | 6 | 'document/DocumentBase.php.twig', |
|
249 | 6 | $dir . '/Document/' . $document . 'Base.php', |
|
250 | 6 | $parameters |
|
251 | ); |
||
252 | |||
253 | 6 | $this->generateServices($parameters, $dir, $document); |
|
254 | 6 | } |
|
255 | |||
256 | /** |
||
257 | * update xml services |
||
258 | * |
||
259 | * @param array $parameters twig parameters |
||
260 | * @param string $dir base bundle dir |
||
261 | * @param string $document document name |
||
262 | * |
||
263 | * @return void |
||
264 | */ |
||
265 | 6 | protected function generateServices($parameters, $dir, $document) |
|
266 | { |
||
267 | 6 | $services = $this->loadServices($dir); |
|
268 | |||
269 | 6 | $bundleParts = explode('\\', $parameters['base']); |
|
270 | 6 | $shortName = $bundleParts[0]; |
|
271 | 6 | $shortBundle = $this->getBundleBaseName($bundleParts[1]); |
|
272 | |||
273 | 6 | $docName = implode( |
|
274 | 6 | '.', |
|
275 | array( |
||
276 | 6 | strtolower($shortName), |
|
277 | 6 | strtolower($shortBundle), |
|
278 | 6 | 'document', |
|
279 | 6 | strtolower($parameters['document']) |
|
280 | ) |
||
281 | ); |
||
282 | |||
283 | 6 | $this->addXMLParameter( |
|
284 | 6 | $parameters['base'] . 'Document\\' . $parameters['document'], |
|
285 | 6 | $docName . '.class' |
|
286 | ); |
||
287 | |||
288 | 6 | $this->addXMLParameter( |
|
289 | 6 | $parameters['json']->getRoles(), |
|
290 | 6 | $docName . '.roles', |
|
291 | 6 | 'collection' |
|
292 | ); |
||
293 | |||
294 | 6 | $services = $this->addService( |
|
295 | 6 | $services, |
|
296 | 6 | $docName |
|
297 | ); |
||
298 | |||
299 | 6 | $repoName = implode( |
|
300 | 6 | '.', |
|
301 | array( |
||
302 | 6 | strtolower($shortName), |
|
303 | 6 | strtolower($shortBundle), |
|
304 | 6 | 'repository', |
|
305 | 6 | strtolower($parameters['document']) |
|
306 | ) |
||
307 | ); |
||
308 | |||
309 | // normal repo service |
||
310 | 6 | $services = $this->addParam( |
|
311 | 6 | $services, |
|
312 | 6 | $repoName . '.class', |
|
313 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] |
|
314 | ); |
||
315 | |||
316 | 6 | $this->addService( |
|
317 | 6 | $services, |
|
318 | 6 | $repoName, |
|
319 | 6 | null, |
|
320 | 6 | array(), |
|
321 | 6 | null, |
|
322 | array( |
||
323 | array( |
||
324 | 6 | 'type' => 'string', |
|
325 | 6 | 'value' => $parameters['bundle'] . ':' . $document |
|
326 | ) |
||
327 | ), |
||
328 | 6 | 'doctrine_mongodb.odm.default_document_manager', |
|
329 | 6 | 'getRepository' |
|
330 | ); |
||
331 | |||
332 | // embedded repo service |
||
333 | 6 | $services = $this->addParam( |
|
334 | 6 | $services, |
|
335 | 6 | $repoName . 'embedded.class', |
|
336 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] . 'Embedded' |
|
337 | ); |
||
338 | |||
339 | 6 | $this->addService( |
|
340 | 6 | $services, |
|
341 | 6 | $repoName . 'embedded', |
|
342 | 6 | null, |
|
343 | 6 | array(), |
|
344 | 6 | null, |
|
345 | array( |
||
346 | array( |
||
347 | 6 | 'type' => 'string', |
|
348 | 6 | 'value' => $parameters['bundle'] . ':' . $document . 'Embedded' |
|
349 | ) |
||
350 | ), |
||
351 | 6 | 'doctrine_mongodb.odm.default_document_manager', |
|
352 | 6 | 'getRepository' |
|
353 | ); |
||
354 | |||
355 | 6 | $this->renderFile( |
|
356 | 6 | 'document/DocumentRepository.php.twig', |
|
357 | 6 | $dir . '/Repository/' . $document . 'Repository.php', |
|
358 | 6 | $parameters |
|
359 | ); |
||
360 | 6 | $this->renderFile( |
|
361 | 6 | 'document/DocumentRepository.php.twig', |
|
362 | 6 | $dir . '/Repository/' . $document . 'EmbeddedRepository.php', |
|
363 | 6 | array_merge( |
|
364 | 6 | $parameters, |
|
365 | [ |
||
366 | 6 | 'document' => $document.'Embedded', |
|
367 | ] |
||
368 | ) |
||
369 | ); |
||
370 | |||
371 | 6 | $this->persistServicesXML($dir); |
|
372 | 6 | } |
|
373 | |||
374 | /** |
||
375 | * Generates the parameters section of the services.xml file. |
||
376 | * |
||
377 | * @param string $dir base bundle dir |
||
378 | * |
||
379 | * @return void |
||
380 | */ |
||
381 | 2 | protected function generateParameters($dir) |
|
382 | { |
||
383 | 2 | if ($this->xmlParameters->count() > 0) { |
|
384 | 2 | $services = $this->loadServices($dir); |
|
385 | |||
386 | 2 | foreach ($this->xmlParameters as $parameter) { |
|
387 | 2 | switch ($parameter['type']) { |
|
388 | 2 | case 'collection': |
|
389 | 2 | $this->addCollectionParam($services, $parameter['key'], $parameter['content']); |
|
390 | 2 | break; |
|
391 | 2 | case 'string': |
|
392 | default: |
||
393 | 2 | $this->addParam($services, $parameter['key'], $parameter['content']); |
|
394 | } |
||
395 | } |
||
396 | } |
||
397 | |||
398 | 2 | $this->persistServicesXML($dir); |
|
399 | 2 | } |
|
400 | |||
401 | /** |
||
402 | * Registers information to be generated to a parameter tag. |
||
403 | * |
||
404 | * @param mixed $value Content of the tag |
||
405 | * @param string $key Content of the key attribute |
||
406 | * @param string $type Type of the tag |
||
407 | * |
||
408 | * @return void |
||
409 | */ |
||
410 | 2 | protected function addXmlParameter($value, $key, $type = 'string') |
|
411 | { |
||
412 | $element = array( |
||
413 | 2 | 'content' => $value, |
|
414 | 2 | 'key' => $key, |
|
415 | 2 | 'type' => strtolower($type), |
|
416 | ); |
||
417 | |||
418 | 2 | if (!isset($this->xmlParameters)) { |
|
419 | $this->xmlParameters = new ArrayCollection(); |
||
420 | } |
||
421 | |||
422 | 2 | if (!$this->xmlParameters->contains($element)) { |
|
423 | 2 | $this->xmlParameters->add($element); |
|
424 | } |
||
425 | 2 | } |
|
426 | |||
427 | /** |
||
428 | * load services.xml |
||
429 | * |
||
430 | * @param string $dir base dir |
||
431 | * |
||
432 | * @return \DOMDocument |
||
433 | */ |
||
434 | 4 | protected function loadServices($dir) |
|
435 | { |
||
436 | 4 | if (empty($this->serviceDOM)) { |
|
437 | 4 | $this->serviceDOM = new \DOMDocument; |
|
438 | 4 | $this->serviceDOM->formatOutput = true; |
|
439 | 4 | $this->serviceDOM->preserveWhiteSpace = false; |
|
440 | 4 | $this->serviceDOM->load($dir . '/Resources/config/services.xml'); |
|
441 | } |
||
442 | |||
443 | 4 | return $this->serviceDOM; |
|
444 | } |
||
445 | |||
446 | /** |
||
447 | * add param to services.xml |
||
448 | * |
||
449 | * @param \DOMDocument $dom services.xml document |
||
450 | * @param string $key parameter key |
||
451 | * @param string $value parameter value |
||
452 | * |
||
453 | * @return \DOMDocument |
||
454 | */ |
||
455 | 12 | protected function addParam(\DOMDocument $dom, $key, $value) |
|
456 | { |
||
457 | 12 | $paramNode = $this->addNodeIfMissing($dom, 'parameters', '//services'); |
|
458 | |||
459 | 12 | if (!$this->parameterNodeExists($dom, $key)) { |
|
460 | 12 | $attrNode = $dom->createElement('parameter', $value); |
|
461 | |||
462 | 12 | $this->addAttributeToNode('key', $key, $dom, $attrNode); |
|
463 | |||
464 | 12 | $paramNode->appendChild($attrNode); |
|
465 | } |
||
466 | |||
467 | 12 | return $dom; |
|
468 | } |
||
469 | |||
470 | /** |
||
471 | * Adds a new parameter tag to parameters section reflecting the defined roles. |
||
472 | * |
||
473 | * @param \DOMDocument $dom services.xml document |
||
474 | * @param string $key parameter key |
||
475 | * @param array $values parameter value |
||
476 | * |
||
477 | * @return void |
||
478 | * |
||
479 | * @link http://symfony.com/doc/current/book/service_container.html#array-parameters |
||
480 | */ |
||
481 | 4 | protected function addCollectionParam(\DomDocument $dom, $key, array $values) |
|
482 | { |
||
483 | 4 | $paramNode = $this->addNodeIfMissing($dom, 'parameters', '//services'); |
|
484 | |||
485 | 4 | if (!$this->parameterNodeExists($dom, $key)) { |
|
486 | 4 | if (!empty($values)) { |
|
487 | 4 | $rolesNode = $dom->createElement('parameter'); |
|
488 | 4 | $this->addAttributeToNode('key', $key, $dom, $rolesNode); |
|
489 | 4 | $this->addAttributeToNode('type', 'collection', $dom, $rolesNode); |
|
490 | |||
491 | 4 | foreach ($values as $item) { |
|
492 | 4 | $roleNode = $dom->createElement('parameter', $item); |
|
493 | 4 | $rolesNode->appendChild($roleNode); |
|
494 | } |
||
495 | |||
496 | 4 | $paramNode->appendChild($rolesNode); |
|
497 | } |
||
498 | } |
||
499 | 4 | } |
|
500 | |||
501 | /** |
||
502 | * Determines, if the provided key attribute was already claimed by a parameter node. |
||
503 | * |
||
504 | * @param \DomDocument $dom Current document |
||
505 | * @param string $key Key to be found in document |
||
506 | * |
||
507 | * @return bool |
||
508 | */ |
||
509 | 14 | private function parameterNodeExists(\DomDocument $dom, $key) |
|
516 | |||
517 | /** |
||
518 | * add node if missing |
||
519 | * |
||
520 | * @param \DOMDocument $dom document |
||
521 | * @param string $element name for new node element |
||
522 | * @param string $insertBefore xPath query of the new node shall be added before |
||
523 | * @param string $container name of container tag |
||
524 | * |
||
525 | * @return \DOMNode new element node |
||
526 | */ |
||
527 | 14 | private function addNodeIfMissing(&$dom, $element, $insertBefore = '', $container = 'container') |
|
528 | { |
||
529 | 14 | $container = $dom->getElementsByTagName($container) |
|
530 | 14 | ->item(0); |
|
531 | 14 | $nodes = $dom->getElementsByTagName($element); |
|
532 | 14 | if ($nodes->length < 1) { |
|
533 | 14 | $newNode = $dom->createElement($element); |
|
534 | |||
535 | 14 | if (!empty($insertBefore)) { |
|
536 | 14 | $xpath = new \DomXpath($dom); |
|
537 | 14 | $found = $xpath->query($insertBefore); |
|
538 | |||
539 | 14 | if ($found->length > 0) { |
|
540 | $container->insertBefore($newNode, $found->item(0)); |
||
541 | } else { |
||
542 | 14 | $container->appendChild($newNode); |
|
543 | } |
||
544 | } else { |
||
545 | $container->appendChild($newNode); |
||
546 | } |
||
547 | } else { |
||
548 | 4 | $newNode = $nodes->item(0); |
|
549 | } |
||
550 | |||
551 | 14 | return $newNode; |
|
552 | } |
||
553 | |||
554 | /** |
||
555 | * add attribute to node if needed |
||
556 | * |
||
557 | * @param string $name attribute name |
||
558 | * @param string $value attribute value |
||
559 | * @param \DOMDocument $dom document |
||
560 | * @param \DOMElement $node parent node |
||
561 | * |
||
562 | * @return void |
||
563 | */ |
||
564 | 14 | private function addAttributeToNode($name, $value, $dom, $node) |
|
565 | { |
||
566 | 14 | if ($value) { |
|
567 | 14 | $attr = $dom->createAttribute($name); |
|
568 | 14 | $attr->value = $value; |
|
569 | 14 | $node->appendChild($attr); |
|
570 | } |
||
571 | 14 | } |
|
572 | |||
573 | /** |
||
574 | * add service to services.xml |
||
575 | * |
||
576 | * @param \DOMDocument $dom services.xml dom |
||
577 | * @param string $id id of new service |
||
578 | * @param string $parent parent for service |
||
|
|||
579 | * @param array $calls methodCalls to add |
||
580 | * @param string $tag tag name or empty if no tag needed |
||
581 | * @param array $arguments service arguments |
||
582 | * @param string $factoryService factory service id |
||
583 | * @param string $factoryMethod factory method name |
||
584 | * |
||
585 | * @return \DOMDocument |
||
586 | */ |
||
587 | protected function addService( |
||
588 | $dom, |
||
589 | $id, |
||
590 | $parent = null, |
||
591 | array $calls = array(), |
||
592 | $tag = null, |
||
593 | array $arguments = array(), |
||
594 | $factoryService = null, |
||
595 | $factoryMethod = null |
||
596 | ) { |
||
597 | $servicesNode = $this->addNodeIfMissing($dom, 'services'); |
||
598 | |||
599 | $xpath = new \DomXpath($dom); |
||
600 | |||
601 | // add controller to services |
||
602 | $nodes = $xpath->query('//services/service[@id="' . $id . '"]'); |
||
603 | if ($nodes->length < 1) { |
||
604 | $attrNode = $dom->createElement('service'); |
||
605 | |||
606 | $this->addAttributeToNode('id', $id, $dom, $attrNode); |
||
607 | $this->addAttributeToNode('class', '%' . $id . '.class%', $dom, $attrNode); |
||
608 | $this->addAttributeToNode('parent', $parent, $dom, $attrNode); |
||
609 | if ($factoryService && $factoryMethod) { |
||
610 | $factoryNode = $dom->createElement('factory'); |
||
611 | $this->addAttributeToNode('service', $factoryService, $dom, $factoryNode); |
||
612 | $this->addAttributeToNode('method', $factoryMethod, $dom, $factoryNode); |
||
613 | $attrNode->appendChild($factoryNode); |
||
614 | } |
||
615 | $this->addCallsToService($calls, $dom, $attrNode); |
||
616 | |||
617 | if ($tag) { |
||
618 | $tagNode = $dom->createElement('tag'); |
||
619 | |||
620 | $this->addAttributeToNode('name', $tag, $dom, $tagNode); |
||
621 | |||
622 | // get stuff from json definition |
||
623 | if ($this->json instanceof JsonDefinition) { |
||
624 | // id is also name of collection in mongodb |
||
625 | $this->addAttributeToNode('collection', $this->json->getId(), $dom, $tagNode); |
||
626 | |||
627 | // is this read only? |
||
628 | if ($this->json->isReadOnlyService()) { |
||
629 | $this->addAttributeToNode('read-only', 'true', $dom, $tagNode); |
||
630 | } |
||
631 | |||
632 | // router base defined? |
||
633 | $routerBase = $this->json->getRouterBase(); |
||
634 | if ($routerBase !== false) { |
||
635 | $this->addAttributeToNode('router-base', $routerBase, $dom, $tagNode); |
||
636 | } |
||
637 | } |
||
638 | |||
639 | $attrNode->appendChild($tagNode); |
||
640 | } |
||
641 | |||
642 | $this->addArgumentsToService($arguments, $dom, $attrNode); |
||
643 | |||
644 | $servicesNode->appendChild($attrNode); |
||
645 | } |
||
646 | |||
647 | return $dom; |
||
648 | } |
||
649 | |||
650 | /** |
||
651 | * add calls to service |
||
652 | * |
||
653 | * @param array $calls info on calls to create |
||
654 | * @param \DOMDocument $dom current domdocument |
||
655 | * @param \DOMElement $node node to add call to |
||
656 | * |
||
657 | * @return void |
||
658 | */ |
||
659 | private function addCallsToService($calls, $dom, $node) |
||
660 | { |
||
661 | foreach ($calls as $call) { |
||
662 | $this->addCallToService($call, $dom, $node); |
||
663 | } |
||
664 | } |
||
665 | |||
666 | /** |
||
667 | * add call to service |
||
668 | * |
||
669 | * @param array $call info on call node to create |
||
670 | * @param \DOMDocument $dom current domdocument |
||
671 | * @param \DOMElement $node node to add call to |
||
672 | * |
||
673 | * @return void |
||
674 | */ |
||
675 | private function addCallToService($call, $dom, $node) |
||
697 | |||
698 | /** |
||
699 | * add arguments to servie |
||
700 | * |
||
701 | * @param array $arguments arguments to create |
||
702 | * @param \DOMDocument $dom dom document to add to |
||
703 | * @param \DOMElement $node node to use as parent |
||
704 | * |
||
705 | * @return void |
||
706 | */ |
||
707 | private function addArgumentsToService($arguments, $dom, $node) |
||
708 | { |
||
709 | foreach ($arguments as $argument) { |
||
710 | $this->addArgumentToService($argument, $dom, $node); |
||
711 | } |
||
712 | } |
||
713 | |||
714 | /** |
||
715 | * add argument to service |
||
716 | * |
||
717 | * @param array $argument info on argument to create |
||
718 | * @param \DOMDocument $dom dom document to add to |
||
719 | * @param \DOMElement $node node to use as parent |
||
720 | * |
||
721 | * @return void |
||
722 | */ |
||
723 | private function addArgumentToService($argument, $dom, $node) |
||
724 | { |
||
725 | $isService = $argument['type'] == 'service'; |
||
726 | |||
727 | if ($isService) { |
||
728 | $argNode = $dom->createElement('argument'); |
||
729 | |||
730 | $idArg = $dom->createAttribute('id'); |
||
731 | $idArg->value = $argument['id']; |
||
732 | $argNode->appendChild($idArg); |
||
733 | } else { |
||
734 | $argNode = $dom->createElement('argument', $argument['value']); |
||
735 | } |
||
736 | |||
737 | $argType = $dom->createAttribute('type'); |
||
738 | $argType->value = $argument['type']; |
||
739 | $argNode->appendChild($argType); |
||
740 | |||
741 | $node->appendChild($argNode); |
||
742 | } |
||
743 | |||
744 | /** |
||
745 | * generate serializer part of a resource |
||
746 | * |
||
747 | * @param array $parameters twig parameters |
||
748 | * @param string $dir base bundle dir |
||
749 | * @param string $document document name |
||
750 | * |
||
751 | * @return void |
||
752 | */ |
||
753 | protected function generateSerializer(array $parameters, $dir, $document) |
||
754 | { |
||
755 | // @TODO in Embedded and document just render the differences.. |
||
756 | $this->renderFile( |
||
757 | 'serializer/Document.xml.twig', |
||
758 | $dir . '/Resources/config/serializer/Document.' . $document . 'Embedded.xml', |
||
759 | array_merge( |
||
760 | $parameters, |
||
761 | [ |
||
762 | 'document' => $document.'Embedded', |
||
763 | 'noIdField' => true, |
||
764 | 'realIdField' => true |
||
765 | ] |
||
766 | ) |
||
767 | ); |
||
768 | |||
769 | foreach ($parameters['fields'] as $key => $field) { |
||
770 | if (substr($field['serializerType'], 0, 14) == 'array<Graviton' && |
||
771 | strpos($field['serializerType'], '\\Entity') === false && |
||
772 | $field['relType'] == 'embed' |
||
773 | ) { |
||
774 | $parameters['fields'][$key]['serializerType'] = substr($field['serializerType'], 0, -1).'Embedded>'; |
||
775 | } elseif (substr($field['serializerType'], 0, 8) == 'Graviton' && |
||
776 | strpos($field['serializerType'], '\\Entity') === false && |
||
777 | $field['relType'] == 'embed' |
||
778 | ) { |
||
779 | $parameters['fields'][$key]['serializerType'] = $field['serializerType'].'Embedded'; |
||
780 | } |
||
781 | } |
||
782 | $this->renderFile( |
||
783 | 'serializer/Document.xml.twig', |
||
784 | $dir . '/Resources/config/serializer/Document.' . $document . '.xml', |
||
785 | array_merge( |
||
786 | $parameters, |
||
787 | [ |
||
788 | 'realIdField' => false |
||
789 | ] |
||
790 | ) |
||
791 | ); |
||
792 | $this->renderFile( |
||
793 | 'serializer/Document.xml.twig', |
||
794 | $dir . '/Resources/config/serializer/Document.' . $document . 'Base.xml', |
||
795 | array_merge( |
||
796 | $parameters, |
||
797 | [ |
||
798 | 'document' => $document.'Base', |
||
799 | 'realIdField' => false |
||
800 | ] |
||
801 | ) |
||
802 | ); |
||
803 | } |
||
804 | |||
805 | /** |
||
806 | * generate model part of a resource |
||
807 | * |
||
808 | * @param array $parameters twig parameters |
||
809 | * @param string $dir base bundle dir |
||
810 | * @param string $document document name |
||
811 | * |
||
812 | * @return void |
||
813 | */ |
||
814 | protected function generateModel(array $parameters, $dir, $document) |
||
815 | { |
||
816 | $this->renderFile( |
||
817 | 'model/Model.php.twig', |
||
818 | $dir . '/Model/' . $document . '.php', |
||
819 | $parameters |
||
820 | ); |
||
821 | $this->renderFile( |
||
822 | 'model/schema.json.twig', |
||
823 | $dir . '/Resources/config/schema/' . $document . '.json', |
||
824 | $parameters |
||
825 | ); |
||
826 | |||
827 | // embedded versions |
||
828 | $this->renderFile( |
||
829 | 'model/Model.php.twig', |
||
830 | $dir . '/Model/' . $document . 'Embedded.php', |
||
831 | array_merge($parameters, ['document' => $document.'Embedded']) |
||
832 | ); |
||
833 | $this->renderFile( |
||
834 | 'model/schema.json.twig', |
||
835 | $dir . '/Resources/config/schema/' . $document . 'Embedded.json', |
||
836 | array_merge($parameters, ['document' => $document.'Embedded']) |
||
837 | ); |
||
838 | |||
839 | $services = $this->loadServices($dir); |
||
840 | |||
841 | $bundleParts = explode('\\', $parameters['base']); |
||
842 | $shortName = strtolower($bundleParts[0]); |
||
843 | $shortBundle = strtolower(substr($bundleParts[1], 0, -6)); |
||
844 | $paramName = implode('.', array($shortName, $shortBundle, 'model', strtolower($parameters['document']))); |
||
845 | $repoName = implode('.', array($shortName, $shortBundle, 'repository', strtolower($parameters['document']))); |
||
846 | |||
847 | $this->addXmlParameter($parameters['base'] . 'Model\\' . $parameters['document'], $paramName . '.class'); |
||
848 | |||
849 | // normal service |
||
850 | $this->addService( |
||
851 | $services, |
||
852 | $paramName, |
||
853 | 'graviton.rest.model', |
||
854 | array( |
||
855 | [ |
||
856 | 'method' => 'setRepository', |
||
857 | 'service' => $repoName |
||
858 | ], |
||
859 | ), |
||
860 | null |
||
861 | ); |
||
862 | |||
863 | // embedded service |
||
864 | $this->addXmlParameter( |
||
865 | $parameters['base'] . 'Model\\' . $parameters['document'] . 'Embedded', |
||
866 | $paramName . 'embedded.class' |
||
867 | ); |
||
868 | |||
869 | $this->addService( |
||
870 | $services, |
||
871 | $paramName . 'embedded', |
||
872 | 'graviton.rest.model', |
||
873 | array( |
||
874 | [ |
||
875 | 'method' => 'setRepository', |
||
876 | 'service' => $repoName . 'embedded' |
||
877 | ], |
||
878 | ), |
||
879 | null |
||
880 | ); |
||
881 | |||
882 | $this->persistServicesXML($dir); |
||
883 | } |
||
884 | |||
885 | /** |
||
886 | * generate RESTful controllers ans service configs |
||
887 | * |
||
888 | * @param array $parameters twig parameters |
||
889 | * @param string $dir base bundle dir |
||
890 | * @param string $document document name |
||
891 | * |
||
892 | * @return void |
||
893 | */ |
||
894 | protected function generateController(array $parameters, $dir, $document) |
||
895 | { |
||
896 | $this->renderFile( |
||
897 | 'controller/DocumentController.php.twig', |
||
898 | $dir . '/Controller/' . $document . 'Controller.php', |
||
899 | $parameters |
||
900 | ); |
||
901 | |||
902 | $services = $this->loadServices($dir); |
||
903 | |||
904 | $bundleParts = explode('\\', $parameters['base']); |
||
905 | $shortName = strtolower($bundleParts[0]); |
||
906 | $shortBundle = strtolower(substr($bundleParts[1], 0, -6)); |
||
907 | $paramName = implode('.', array($shortName, $shortBundle, 'controller', strtolower($parameters['document']))); |
||
908 | |||
909 | $this->addXmlParameter( |
||
910 | $parameters['base'] . 'Controller\\' . $parameters['document'] . 'Controller', |
||
911 | $paramName . '.class' |
||
912 | ); |
||
913 | |||
914 | $this->addService( |
||
915 | $services, |
||
916 | $paramName, |
||
917 | $parameters['parent'], |
||
918 | array( |
||
919 | array( |
||
920 | 'method' => 'setModel', |
||
921 | 'service' => implode( |
||
922 | '.', |
||
923 | array($shortName, $shortBundle, 'model', strtolower($parameters['document'])) |
||
924 | ) |
||
925 | ) |
||
926 | ), |
||
927 | 'graviton.rest' |
||
928 | ); |
||
929 | |||
930 | $this->persistServicesXML($dir); |
||
931 | } |
||
932 | |||
933 | /** |
||
934 | * generates fixtures |
||
935 | * |
||
936 | * @param array $parameters twig parameters |
||
937 | * @param string $dir base bundle dir |
||
938 | * @param string $document document name |
||
939 | * |
||
940 | * @return void |
||
941 | */ |
||
942 | protected function generateFixtures(array $parameters, $dir, $document) |
||
953 | } |
||
954 |
This check looks for
@param
annotations where the type inferred by our type inference engine differs from the declared type.It makes a suggestion as to what type it considers more descriptive.
Most often this is a case of a parameter that can be null in addition to its declared types.