/** * @param Record $owningRecord * @param Relation $relation * @param string $refObjectId */ private function assertReferencedRelatedReferences(Record $owningRecord, Relation $relation, $refObjectId) { $oldIdentifier = Record::NEW_RECORD_ID_MARK . $owningRecord->getOid(); $newIdentifier = $owningRecord->getInternalId(); $rm = $owningRecord->getRecordManager(); /** @var ReferenceMap $referenceMap */ $referenceMap = self::readAttribute($relation, 'map'); $referenceMapping = $referenceMap->getMapping(); $refTable = $relation->getJoinTable($rm, $relation->getReferencedAlias()); $refTableRepository = $refTable->getRepository(); $referencedRecord = $refTableRepository->getByOid($refObjectId); $refId = $referencedRecord->getInternalId(); // assert that owning record id is mapped for referenced record $this->assertArrayHasKey($refId, $referenceMapping); if ($relation->isOneToMany()) { $this->assertNotContains($oldIdentifier, $referenceMapping[$refId]); $this->assertContains($newIdentifier, $referenceMapping[$refId]); } else { $this->assertEquals($newIdentifier, $referenceMapping[$refId]); } // assert record collection if ($relation->isOneToMany()) { $recordCollection = $referenceMap->getRelatedCollection($referencedRecord->getOid()); $this->assertNotNull($recordCollection); $this->assertTrue($recordCollection->has($owningRecord), "Expected '{$owningRecord}' is referenced in relation '" . $relation->getReferencedAlias() . "'"); } }
/** * Sets owning record reference to the referenced record given by it's id * * @param Record $record * @param string $newId */ public function setOwningReferenceByForeignKey(Record $record, $newId) { if (!$newId) { return; } $id = $record->getInternalId(); $this->assignReference($newId, $id); }
/** * @param Record $other * * @return string */ protected function failureDescription($other) { $otherId = $other->getInternalId(); $relation = $this->record->getTableRelation($this->relationName); $otherTableName = $relation->isOwningSide($this->relationName) ? $relation->getOwningTable() : $relation->getReferencedTable(); return $this->toString() . " to {$otherTableName}[{$otherId}]"; }
/** * Gets record referenced identifiers * * @param Record $record * @param string $relationName * @return bool|null|array|string * false: reference has not been loaded, yet * null: null-reference / not related * array: one-to-many related ids * string: referenced id */ public function getRecordReferencedIdentifiers(Record $record, $relationName) { $id = $record->getInternalId(); $isReferenceSide = $this->isReferencedSide($relationName); if ($isReferenceSide) { $owningOid = $record->getOid(); if ($this->map->hasFieldMapping($owningOid)) { $refOid = $this->map->getFieldMapping($owningOid); if ($refOid) { return Record::NEW_RECORD_ID_MARK . $refOid; } } return $record->get($this->owningField); } else { if (!$this->map->isReferenced($id) && !$this->map->hasNullReference($id)) { return false; } } return $this->map->getOwning($id); }
/** * @param Record $record * @param string $relationName * @param string $message */ private function assertRecordIsNotReferencedByRelation(Record $record, $relationName, $message = '') { $internalId = $record->getInternalId(); $relation = $record->getTableRelation($relationName); $isReferencedSide = $relation->isReferencedSide($relationName); /** @var ReferenceMap $referenceMap */ $referenceMap = self::readAttribute($relation, 'map'); $isOneToMany = $relation->isOneToMany(); /** @var RecordCollection[] $relatedCollections */ $relatedCollections = $isOneToMany ? self::readAttribute($referenceMap, 'relatedCollections') : null; $references = $referenceMap->getMapping(); $referencedMessage = $message . " expected not be referenced (relation '{$relationName}')"; $relatedCollectionMessage = $message . " expected not to be in a related collection (relation '{$relationName}')"; $oid = $record->getOid(); if ($isReferencedSide) { foreach ($references as $owningIds) { if ($isOneToMany) { $this->assertNotContains($internalId, $owningIds, $referencedMessage); } else { $this->assertNotEquals($internalId, $owningIds, $referencedMessage); } } if ($isOneToMany) { foreach ($relatedCollections as $relatedCollection) { $this->assertFalse($relatedCollection->has($record), $relatedCollectionMessage); } } $this->assertFalse($referenceMap->hasFieldMapping($oid)); } else { $this->assertArrayNotHasKey($internalId, $references, $referencedMessage); if ($isOneToMany) { $this->assertArrayNotHasKey($oid, $relatedCollections, $relatedCollectionMessage); } } }
/** * Sets owning record reference to the referenced record given by it's id * * @param Record $record * @param string $newId */ public function setOwningReferenceByForeignKey(Record $record, $newId) { if (!$newId) { return; } $id = $record->getInternalId(); if ($this->relation->isOneToMany()) { $refRepository = $this->getRefRepository($record, $this->relation->getOwningAlias()); $newRefRecord = $refRepository->getByInternalId($newId); if ($newRefRecord) { $relatedCollection = $this->getRelatedCollection($newRefRecord->getOid()); // TODO exception, or if not set create one?? if ($relatedCollection) { $relatedCollection->add($record); } } } $this->assignReference($newId, $id); }
/** * @param Record $record */ protected function unsetReferenceForOwningRecordOnUnloadedReference(Record $record) { $owningId = $record->getInternalId(); foreach ($this->references as $refId => $owningIds) { if ($this->removeOwningReference($refId, $owningId)) { break; } } $this->unsetFieldMapping($record->getOid()); }