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 | $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 | $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 | $services, |
||
| 312 | 6 | $repoName . '.class', |
|
| 313 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] |
|
| 314 | ); |
||
| 315 | |||
| 316 | 6 | $this->addService( |
|
| 317 | $services, |
||
| 318 | $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 | $services, |
||
| 335 | 6 | $repoName . 'embedded.class', |
|
| 336 | 6 | $parameters['base'] . 'Repository\\' . $parameters['document'] . 'Embedded' |
|
| 337 | ); |
||
| 338 | |||
| 339 | 6 | $this->addService( |
|
| 340 | $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 | $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 | 7 | $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
@paramannotations 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.