private function computeAssociationChanges($document, $class, $oid, $isNew, $changeSet, $assocType)
{
switch ($assocType) {
case 'reference':
$mappings = $class->referenceMappings;
$computeMethod = 'computeReferenceChanges';
break;
case 'referrer':
$mappings = $class->referrersMappings;
$computeMethod = 'computeReferrerChanges';
break;
default:
throw new InvalidArgumentException('Unsupported association type used: ' . $assocType);
}
foreach ($mappings as $fieldName) {
$mapping = $class->mappings[$fieldName];
if (ClassMetadata::MANY_TO_MANY === $mapping['type'] && 'reference' === $assocType || 'referrers' === $mapping['type'] && 'referrer' === $assocType) {
if ($changeSet[$fieldName] instanceof PersistentCollection) {
if (!$changeSet[$fieldName]->isInitialized()) {
continue;
}
} else {
if (null === $changeSet[$fieldName]) {
$changeSet[$fieldName] = array();
}
if (!is_array($changeSet[$fieldName]) && !$changeSet[$fieldName] instanceof Collection) {
throw PHPCRException::associationFieldNoArray(self::objToStr($document, $this->dm), $fieldName);
}
// convert to a PersistentCollection
switch ($assocType) {
case 'reference':
$targetDocument = isset($mapping['targetDocument']) ? $mapping['targetDocument'] : null;
$changeSet[$fieldName] = ReferenceManyCollection::createFromCollection($this->dm, $document, $mapping['property'], $changeSet[$fieldName], $targetDocument, !$isNew);
break;
case 'referrer':
$referringMeta = $this->dm->getClassMetadata($mapping['referringDocument']);
$referringField = $referringMeta->mappings[$mapping['referencedBy']];
$changeSet[$fieldName] = ReferrersCollection::createFromCollection($this->dm, $document, $changeSet[$fieldName], $referringField['strategy'], $referringField['property'], $mapping['referringDocument'], !$isNew);
break;
}
$class->setFieldValue($document, $fieldName, $changeSet[$fieldName]);
$this->originalData[$oid][$fieldName] = $changeSet[$fieldName];
}
$coid = spl_object_hash($changeSet[$fieldName]);
$this->visitedCollections[$coid] = $changeSet[$fieldName];
foreach ($changeSet[$fieldName] as $association) {
if ($association !== null) {
$this->{$computeMethod}($mapping, $association);
}
}
if (!$isNew && $mapping['cascade'] & ClassMetadata::CASCADE_REMOVE) {
if (!$this->originalData[$oid][$fieldName] instanceof PersistentCollection) {
throw new RuntimeException("OriginalData for a collection association contains something else than a PersistentCollection.");
}
$associations = $this->originalData[$oid][$fieldName]->getOriginalPaths();
foreach ($associations as $association) {
$association = $this->getDocumentById($association);
if ($association && !$this->originalData[$oid][$fieldName]->contains($association)) {
$this->scheduleRemove($association);
}
}
}
} elseif ($changeSet[$fieldName] && ClassMetadata::MANY_TO_ONE === $mapping['type'] && 'reference' === $assocType) {
$this->computeReferenceChanges($mapping, $changeSet[$fieldName]);
}
}
}