public function testOtoRelationship() { $mapper = new AnnotationMapper(); $user = new User(); $user_meta = $mapper->getEntityMetadata($user); $relationships = $user_meta->getRelationships(); $this->assertCount(1, $relationships); $address_relationship = $user_meta->getRelationshipByName('address'); $this->assertEquals(User::class, $address_relationship->getSource()); $this->assertEquals(Address::class, $address_relationship->getTarget()); $this->assertEquals('user', $address_relationship->getInversedBy()); $this->assertEquals(RelationshipType::ONETOONE(), $address_relationship->getRelationshipType()); }
/** * Get the inverse relationship type of the given relationship type * * @param RelationshipType $relationship_type * @return RelationshipType */ public static function getInverseRelationship(RelationshipType $relationship_type) { switch ($relationship_type) { default: throw new InvalidEntityException("Unknown relationship type: " . $relationship_type->key()); case RelationshipType::ONETOONE(): return RelationshipType::ONETOONE(); case RelationshipType::ONETOMANY(): return RelationshipType::MANYTOONE(); case RelationshipType::MANYTOONE(): return RelationshipType::ONETOMANY(); case RelationshipType::MANYTOMANY(): return RelationshipType::MANYTOMANY(); } }
/** * When adding an entity on a one-to-many relationship, the foreign entity might have had a pre-existing entity * assigned in the inverted 'to-one' index. If it had a value, we now need to break that existing relationship as * we have inadvertently removed it by assigning it to a new local entity. * * This operation should only ever be applied to 'to-one' relationships, which should be the inverse of a 'to-many' * relationship. Other use is illogical. * * This call will remove only the inverse of the relationship provided (which would be the former forward of the * relationship that triggered this), breaking the forward relationship is assumed when overwriting the new * relationship. * * @param Relationship $relationship * @param string $source_id */ private function breakFormerRelationship(Relationship $relationship, $source_id) { $key = $this->getRelationshipKey($relationship, $source_id); $this->getDriver()->debugLog('Checking for breakable former relationship: ' . $key); $old_value = $this->getDriver()->getSingleValueIndex($key); if (!$old_value) { // No former relationship to break return; } $inverse_relationship = $this->invertRelationship($relationship); // Relationship keys $inverse_key = $this->getRelationshipKey($inverse_relationship, $old_value); $this->getDriver()->debugLog('@Breaking former relationship: ' . $inverse_key); if ($inverse_relationship->getRelationshipType() == RelationshipType::MANYTOONE() || $inverse_relationship->getRelationshipType() == RelationshipType::ONETOONE()) { $this->getDriver()->clearSingleValueIndex($inverse_key); } else { $this->getDriver()->removeMultiValueIndex($inverse_key, $source_id); } // Sorted index keys foreach ($inverse_relationship->getSortableBy() as $sortable) { $sort_key = $this->getSortIndexKey($inverse_relationship, $sortable->getName(), $old_value); $this->getDriver()->removeSortedIndex($sort_key, $source_id); } }
/** * Get all relationships in the entity * * @return Relationship[] */ public function getRelationships() { $r = []; $properties = $this->reflection_obj->getProperties(); foreach ($properties as $property) { /** @var OneToOne $oto */ $oto = $this->annotation_reader->getPropertyAnnotation($property, self::OTO_ANNOTATION); if ($oto) { $r[] = $this->createRelationship($property->getName(), RelationshipType::ONETOONE(), $oto); } /** @var OneToMany $otm */ $otm = $this->annotation_reader->getPropertyAnnotation($property, self::OTM_ANNOTATION); if ($otm) { $r[] = $this->createRelationship($property->getName(), RelationshipType::ONETOMANY(), $otm); } /** @var ManyToOne $mto */ $mto = $this->annotation_reader->getPropertyAnnotation($property, self::MTO_ANNOTATION); if ($mto) { $r[] = $this->createRelationship($property->getName(), RelationshipType::MANYTOONE(), $mto); } /** @var ManyToMany $mtm */ $mtm = $this->annotation_reader->getPropertyAnnotation($property, self::MTM_ANNOTATION); if ($mtm) { $r[] = $this->createRelationship($property->getName(), RelationshipType::MANYTOMANY(), $mtm); } } return $r; }