diff --git a/src/Util/ClassSourceManipulator.php b/src/Util/ClassSourceManipulator.php index f4bc45a40..fb87c57e8 100644 --- a/src/Util/ClassSourceManipulator.php +++ b/src/Util/ClassSourceManipulator.php @@ -232,6 +232,12 @@ public function addGetter(string $propertyName, $returnType, bool $isReturnTypeN public function addSetter(string $propertyName, $type, bool $isNullable, array $commentLines = []) { $builder = $this->createSetterNodeBuilder($propertyName, $type, $isNullable, $commentLines); + $builder->addStmt( + new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $propertyName), + new Node\Expr\Variable($propertyName) + )) + ); $this->makeMethodFluent($builder); $this->addMethod($builder->getNode()); } @@ -411,13 +417,6 @@ private function createSetterNodeBuilder(string $propertyName, $type, bool $isNu } $setterNodeBuilder->addParam($paramBuilder->getNode()); - $setterNodeBuilder->addStmt( - new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $propertyName), - new Node\Expr\Variable($propertyName) - )) - ); - return $setterNodeBuilder; } @@ -538,11 +537,15 @@ private function addSingularRelation(BaseRelation $relation) // OneToOne is the only "singular" relation type that // may be the inverse side if ($relation instanceof RelationOneToOne && !$relation->isOwning()) { - $setterNodeBuilder->addStmt($this->createBlankLineNode(self::CONTEXT_CLASS_METHOD)); - $this->addNodesToSetOtherSideOfOneToOne($relation, $setterNodeBuilder); } + $setterNodeBuilder->addStmt( + new Node\Stmt\Expression(new Node\Expr\Assign( + new Node\Expr\PropertyFetch(new Node\Expr\Variable('this'), $relation->getPropertyName()), + new Node\Expr\Variable($relation->getPropertyName()) + )) + ); $this->makeMethodFluent($setterNodeBuilder); $this->addMethod($setterNodeBuilder->getNode()); } @@ -1213,50 +1216,74 @@ private function addNodesToSetOtherSideOfOneToOne(RelationOneToOne $relation, Bu )), ]; $setterNodeBuilder->addStmt($ifNode); + $setterNodeBuilder->addStmt($this->createBlankLineNode(self::CONTEXT_CLASS_METHOD)); return; } // at this point, we know the relation is nullable $setterNodeBuilder->addStmt($this->createSingleLineCommentNode( - 'set (or unset) the owning side of the relation if necessary', + 'unset the owning side of the relation if necessary', self::CONTEXT_CLASS_METHOD )); - $varName = 'new'.ucfirst($relation->getTargetPropertyName()); - // $newUserProfile = null === $user ? null : $this; - $setterNodeBuilder->addStmt( - new Node\Stmt\Expression(new Node\Expr\Assign( - new Node\Expr\Variable($varName), - new Node\Expr\Ternary( - new Node\Expr\BinaryOp\Identical( - $this->createNullConstant(), - new Node\Expr\Variable($relation->getPropertyName()) - ), - $this->createNullConstant(), - new Node\Expr\Variable('this') - ) - )) - ); - - // if ($user->getUserProfile() !== $newUserProfile) { - $ifNode = new Node\Stmt\If_(new Node\Expr\BinaryOp\NotIdentical( - new Node\Expr\MethodCall( + // if ($user !== null && $user->getUserProfile() !== $this) + $ifNode = new Node\Stmt\If_(new Node\Expr\BinaryOp\BooleanAnd( + new Node\Expr\BinaryOp\Identical( new Node\Expr\Variable($relation->getPropertyName()), - $relation->getTargetGetterMethodName() + $this->createNullConstant() ), - new Node\Expr\Variable($varName) + new Node\Expr\BinaryOp\NotIdentical( + new Node\Expr\PropertyFetch( + new Node\Expr\Variable('this'), + $relation->getPropertyName() + ), + $this->createNullConstant() + ) )); + $ifNode->stmts = [ + // $this->user->setUserProfile(null) + new Node\Stmt\Expression(new Node\Expr\MethodCall( + new Node\Expr\PropertyFetch( + new Node\Expr\Variable('this'), + $relation->getPropertyName() + ), + $relation->getTargetSetterMethodName(), + [new Node\Arg($this->createNullConstant())] + )), + ]; + $setterNodeBuilder->addStmt($ifNode); - // $user->setUserProfile($newUserProfile); + $setterNodeBuilder->addStmt($this->createBlankLineNode(self::CONTEXT_CLASS_METHOD)); + $setterNodeBuilder->addStmt($this->createSingleLineCommentNode( + 'set the owning side of the relation if necessary', + self::CONTEXT_CLASS_METHOD + )); + + // if ($user === null && $this->user !== null) + $ifNode = new Node\Stmt\If_(new Node\Expr\BinaryOp\BooleanAnd( + new Node\Expr\BinaryOp\NotIdentical( + new Node\Expr\Variable($relation->getPropertyName()), + $this->createNullConstant() + ), + new Node\Expr\BinaryOp\NotIdentical( + new Node\Expr\MethodCall( + new Node\Expr\Variable($relation->getPropertyName()), + $relation->getTargetGetterMethodName() + ), + new Node\Expr\Variable('this') + ) + )); $ifNode->stmts = [ new Node\Stmt\Expression(new Node\Expr\MethodCall( new Node\Expr\Variable($relation->getPropertyName()), $relation->getTargetSetterMethodName(), - [new Node\Arg(new Node\Expr\Variable($varName))] + [new Node\Arg(new Node\Expr\Variable('this'))] )), ]; $setterNodeBuilder->addStmt($ifNode); + + $setterNodeBuilder->addStmt($this->createBlankLineNode(self::CONTEXT_CLASS_METHOD)); } private function methodExists(string $methodName): bool diff --git a/tests/Doctrine/fixtures/expected_overwrite/src/Entity/User.php b/tests/Doctrine/fixtures/expected_overwrite/src/Entity/User.php index 91fdbcee3..c812013bd 100644 --- a/tests/Doctrine/fixtures/expected_overwrite/src/Entity/User.php +++ b/tests/Doctrine/fixtures/expected_overwrite/src/Entity/User.php @@ -51,14 +51,18 @@ public function customMethod() public function setUserProfile(?UserProfile $userProfile): self { - $this->userProfile = $userProfile; + // unset the owning side of the relation if necessary + if ($userProfile === null && $this->userProfile !== null) { + $this->userProfile->setUser(null); + } - // set (or unset) the owning side of the relation if necessary - $newUser = null === $userProfile ? null : $this; - if ($userProfile->getUser() !== $newUser) { - $userProfile->setUser($newUser); + // set the owning side of the relation if necessary + if ($userProfile !== null && $userProfile->getUser() !== $this) { + $userProfile->setUser($this); } + $this->userProfile = $userProfile; + return $this; } diff --git a/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse.php b/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse.php index 016967a30..6ca0ec0d6 100644 --- a/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse.php +++ b/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse.php @@ -33,14 +33,18 @@ public function getUser(): ?User public function setUser(?User $user): self { - $this->user = $user; + // unset the owning side of the relation if necessary + if ($user === null && $this->user !== null) { + $this->user->setUserProfile(null); + } - // set (or unset) the owning side of the relation if necessary - $newUserProfile = null === $user ? null : $this; - if ($user->getUserProfile() !== $newUserProfile) { - $user->setUserProfile($newUserProfile); + // set the owning side of the relation if necessary + if ($user !== null && $user->getUserProfile() !== $this) { + $user->setUserProfile($this); } + $this->user = $user; + return $this; } } diff --git a/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse_not_nullable.php b/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse_not_nullable.php index 45c80a7fc..e52100ee3 100644 --- a/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse_not_nullable.php +++ b/tests/Util/fixtures/add_one_to_one_relation/UserProfile_simple_inverse_not_nullable.php @@ -33,13 +33,13 @@ public function getUser(): ?User public function setUser(User $user): self { - $this->user = $user; - // set the owning side of the relation if necessary if ($user->getUserProfile() !== $this) { $user->setUserProfile($this); } + $this->user = $user; + return $this; } }