/** * @param array $schema * @param PhpClass $class * * @SuppressWarnings(PHPMD.ExcessiveMethodLength) */ public function generateManyToManyAssociationMethods(array $schema, PhpClass $class) { $associationKind = $this->getAssociationKind(); $supportMethodName = AssociationNameGenerator::generateSupportTargetMethodName($associationKind); $getMethodName = AssociationNameGenerator::generateGetTargetsMethodName($associationKind); $hasMethodName = AssociationNameGenerator::generateHasTargetMethodName($associationKind); $addMethodName = AssociationNameGenerator::generateAddTargetMethodName($associationKind); $removeMethodName = AssociationNameGenerator::generateRemoveTargetMethodName($associationKind); $getAssociationsName = AssociationNameGenerator::generateGetTargetEntitiesMethodName($associationKind); $supportMethodBody = ['$className = \\Doctrine\\Common\\Util\\ClassUtils::getRealClass($targetClass);']; $getMethodBody = ['$className = \\Doctrine\\Common\\Util\\ClassUtils::getRealClass($targetClass);']; $hasMethodBody = ['$className = \\Doctrine\\Common\\Util\\ClassUtils::getClass($target);']; $addMethodBody = ['$className = \\Doctrine\\Common\\Util\\ClassUtils::getClass($target);']; $removeMethodBody = ['$className = \\Doctrine\\Common\\Util\\ClassUtils::getClass($target);']; $getAssociationsMethodBody = ['$associationEntities = [];']; foreach ($schema['relationData'] as $relationData) { if (!$this->isSupportedRelation($relationData)) { continue; } /** @var FieldConfigId $fieldConfigId */ $fieldConfigId = $relationData['field_id']; $fieldName = $fieldConfigId->getFieldName(); $targetClassName = $relationData['target_entity']; $supportMethodBody[] = sprintf('if ($className === \'%s\') { return true; }', $targetClassName); $getMethodBody[] = sprintf('if ($className === \'%s\') { return $this->%s; }', $targetClassName, $fieldName); $hasMethodBody[] = str_replace(['{class}', '{field}'], [$targetClassName, $fieldName], "if (\$className === '{class}') { return \$this->{field}->contains(\$target); }"); $addMethodBody[] = str_replace(['{class}', '{field}'], [$targetClassName, $fieldName], "if (\$className === '{class}') {\n" . " if (!\$this->{field}->contains(\$target)) { \$this->{field}->add(\$target); }\n" . " return \$this;\n}"); $removeMethodBody[] = str_replace(['{class}', '{field}'], [$targetClassName, $fieldName], "if (\$className === '{class}') {\n" . " if (\$this->{field}->contains(\$target)) { \$this->{field}->removeElement(\$target); }\n" . " return \$this;\n}"); $getAssociationsMethodBody[] = str_replace(['{field}'], [$fieldName], "\$entities = \$this->{field}->toArray();\n" . "if (!empty(\$entities)) {\n" . " \$associationEntities = array_merge(\$associationEntities, \$entities);\n" . "}"); } $throwStmt = 'throw new \\RuntimeException(' . 'sprintf(\'The association with "%s" entity was not configured.\', $className));'; $supportMethodBody[] = 'return false;'; $getMethodBody[] = $throwStmt; $hasMethodBody[] = 'return false;'; $addMethodBody[] = $throwStmt; $removeMethodBody[] = $throwStmt; $getAssociationsMethodBody[] = "return \$associationEntities;"; $supportMethodDocblock = "/**\n" . " * Checks if an entity of the given type can be associated with this entity\n" . " *\n" . " * @param string \$targetClass The class name of the target entity\n" . " * @return bool\n" . " */"; $getMethodDocblock = "/**\n" . " * Gets entities of the given type associated with this entity\n" . " *\n" . " * @param string \$targetClass The class name of the target entity\n" . " * @return object[]\n" . " */"; $hasMethodDocblock = "/**\n" . " * Checks is the given entity is associated with this entity\n" . " *\n" . " * @param object \$target Any configurable entity that can be associated with this type of entity\n" . " * @return bool\n" . " */"; $addMethodDocblock = "/**\n" . " * Associates the given entity with this entity\n" . " *\n" . " * @param object \$target Any configurable entity that can be associated with this type of entity\n" . " * @return object This object\n" . " */"; $removeMethodDocblock = "/**\n" . " * Removes the association of the given entity and this entity\n" . " *\n" . " * @param object \$target Any configurable entity that can be associated with this type of entity\n" . " * @return object This object\n" . " */"; $getAssociationsMethodDocblock = "/**\n" . " * Returns array with all associated entities\n" . " *\n" . " * @return array\n" . " */"; $class->setMethod($this->generateClassMethod($supportMethodName, implode("\n", $supportMethodBody), ['targetClass'])->setDocblock($supportMethodDocblock))->setMethod($this->generateClassMethod($getMethodName, implode("\n", $getMethodBody), ['targetClass'])->setDocblock($getMethodDocblock))->setMethod($this->generateClassMethod($hasMethodName, implode("\n", $hasMethodBody), ['target'])->setDocblock($hasMethodDocblock))->setMethod($this->generateClassMethod($addMethodName, implode("\n", $addMethodBody), ['target'])->setDocblock($addMethodDocblock))->setMethod($this->generateClassMethod($removeMethodName, implode("\n", $removeMethodBody), ['target'])->setDocblock($removeMethodDocblock))->setMethod($this->generateClassMethod($getAssociationsName, implode("\n", $getAssociationsMethodBody))->setDocblock($getAssociationsMethodDocblock)); }