Doctrine\ODM\CouchDB\UnitOfWork::computeChangeSet PHP Method

computeChangeSet() public method

public computeChangeSet ( ClassMetadata $class, object $document ) : void
$class Doctrine\ODM\CouchDB\Mapping\ClassMetadata
$document object
return void
    public function computeChangeSet(ClassMetadata $class, $document)
    {
        if ($document instanceof Proxy && !$document->__isInitialized__) {
            return;
        }
        $oid = \spl_object_hash($document);
        $actualData = array();
        $embeddedActualData = array();
        // 1. compute the actual values of the current document
        foreach ($class->reflFields as $fieldName => $reflProperty) {
            $value = $reflProperty->getValue($document);
            if ($class->isCollectionValuedAssociation($fieldName) && $value !== null && !$value instanceof PersistentCollection) {
                if (!$value instanceof Collection) {
                    $value = new ArrayCollection($value);
                }
                if ($class->associationsMappings[$fieldName]['isOwning']) {
                    $coll = new PersistentIdsCollection($value, $class->associationsMappings[$fieldName]['targetDocument'], $this->dm, array());
                } else {
                    $coll = new PersistentViewCollection($value, $this->dm, $this->documentIdentifiers[$oid], $class->associationsMappings[$fieldName]);
                }
                $class->reflFields[$fieldName]->setValue($document, $coll);
                $actualData[$fieldName] = $coll;
            } else {
                $actualData[$fieldName] = $value;
                if (isset($class->fieldMappings[$fieldName]['embedded']) && $value !== null) {
                    // serializing embedded value right here, to be able to detect changes for later invocations
                    $embeddedActualData[$fieldName] = $this->embeddedSerializer->serializeEmbeddedDocument($value, $class->fieldMappings[$fieldName]);
                }
            }
            // TODO: ORM transforms arrays and collections into persistent collections
        }
        // unset the revision field if necessary, it is not to be managed by the user in write scenarios.
        if ($class->isVersioned) {
            unset($actualData[$class->versionField]);
        }
        // 2. Compare to the original, or find out that this document is new.
        if (!isset($this->originalData[$oid])) {
            // document is New and should be inserted
            $this->originalData[$oid] = $actualData;
            $this->scheduledUpdates[$oid] = $document;
            $this->originalEmbeddedData[$oid] = $embeddedActualData;
        } else {
            // document is "fully" MANAGED: it was already fully persisted before
            // and we have a copy of the original data
            $changed = false;
            foreach ($actualData as $fieldName => $fieldValue) {
                // Important to not check embeded values here, because those are objects, equality check isn't enough
                //
                if (isset($class->fieldMappings[$fieldName]) && !isset($class->fieldMappings[$fieldName]['embedded']) && $this->originalData[$oid][$fieldName] !== $fieldValue) {
                    $changed = true;
                    break;
                } else {
                    if (isset($class->associationsMappings[$fieldName])) {
                        if (!$class->associationsMappings[$fieldName]['isOwning']) {
                            continue;
                        }
                        if ($class->associationsMappings[$fieldName]['type'] & ClassMetadata::TO_ONE && $this->originalData[$oid][$fieldName] !== $fieldValue) {
                            $changed = true;
                            break;
                        } else {
                            if ($class->associationsMappings[$fieldName]['type'] & ClassMetadata::TO_MANY) {
                                if (!$fieldValue instanceof PersistentCollection) {
                                    // if its not a persistent collection and the original value changed. otherwise it could just be null
                                    $changed = true;
                                    break;
                                } else {
                                    if ($fieldValue->changed()) {
                                        $this->visitedCollections[] = $fieldValue;
                                        $changed = true;
                                        break;
                                    }
                                }
                            }
                        }
                    } else {
                        if ($class->hasAttachments && $fieldName == $class->attachmentField) {
                            // array of value objects, can compare that stricly
                            if ($this->originalData[$oid][$fieldName] !== $fieldValue) {
                                $changed = true;
                                break;
                            }
                        }
                    }
                }
            }
            // Check embedded documents here, only if there is no change yet
            if (!$changed) {
                foreach ($embeddedActualData as $fieldName => $fieldValue) {
                    if (!isset($this->originalEmbeddedData[$oid][$fieldName])) {
                        $changed = true;
                        break;
                    }
                    $changed = $this->embeddedSerializer->isChanged($actualData[$fieldName], $this->originalEmbeddedData[$oid][$fieldName], $class->fieldMappings[$fieldName]);
                    if ($changed) {
                        break;
                    }
                }
            }
            if ($changed) {
                $this->originalData[$oid] = $actualData;
                $this->scheduledUpdates[$oid] = $document;
                $this->originalEmbeddedData[$oid] = $embeddedActualData;
            }
        }
        // 3. check if any cascading needs to happen
        foreach ($class->associationsMappings as $name => $assoc) {
            if ($this->originalData[$oid][$name]) {
                $this->computeAssociationChanges($assoc, $this->originalData[$oid][$name]);
            }
        }
    }