Checks whether a document is scheduled for insertion.
public isScheduledForInsert ( object $document ) : boolean | ||
$document | object | |
return | boolean |
/** * Determines whether a document instance is managed in this DocumentManager. * * @param object $document * @return boolean TRUE if this DocumentManager currently manages the given document, FALSE otherwise. */ public function contains($document) { if (!is_object($document)) { throw new \InvalidArgumentException(gettype($document)); } return $this->unitOfWork->isScheduledForInsert($document) || $this->unitOfWork->isInIdentityMap($document) && !$this->unitOfWork->isScheduledForDelete($document); }
/** * Prepares the update query to upsert a given document object in mongodb. * * @param object $document * @return array $updateData */ public function prepareUpsertData($document) { $class = $this->dm->getClassMetadata(get_class($document)); $changeset = $this->uow->getDocumentChangeSet($document); $updateData = array(); foreach ($changeset as $fieldName => $change) { $mapping = $class->fieldMappings[$fieldName]; list($old, $new) = $change; // @Inc if ($mapping['type'] === 'increment') { if ($new >= $old) { $updateData['$inc'][$mapping['name']] = $new - $old; } else { $updateData['$inc'][$mapping['name']] = ($old - $new) * -1; } // @Field, @String, @Date, etc. } elseif (!isset($mapping['association'])) { if (isset($new) || $mapping['nullable'] === true) { $updateData['$set'][$mapping['name']] = is_null($new) ? null : Type::getType($mapping['type'])->convertToDatabaseValue($new); } // @EmbedOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_ONE) { // If we have a new embedded document then lets set the whole thing if ($new && $this->uow->isScheduledForInsert($new)) { $updateData['$set'][$mapping['name']] = $this->prepareEmbeddedDocumentValue($mapping, $new); // If we don't have a new value then do nothing on upsert } elseif (!$new) { // Update existing embedded document } else { $update = $this->prepareUpsertData($new); foreach ($update as $cmd => $values) { foreach ($values as $key => $value) { $updateData[$cmd][$mapping['name'] . '.' . $key] = $value; } } } // @ReferenceOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::REFERENCE_ONE) { if (isset($new) || $mapping['nullable'] === true) { $updateData['$set'][$mapping['name']] = is_null($new) ? null : $this->prepareReferencedDocumentValue($mapping, $new); } // @ReferenceMany, @EmbedMany } elseif ($mapping['type'] === ClassMetadata::MANY && !$mapping['isInverseSide'] && $new instanceof PersistentCollection && $new->isDirty() && CollectionHelper::isAtomic($mapping['strategy'])) { $updateData['$set'][$mapping['name']] = $this->prepareAssociatedCollectionValue($new, true); } // @EmbedMany and @ReferenceMany are handled by CollectionPersister } // add discriminator if the class has one if (isset($class->discriminatorField)) { $updateData['$set'][$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name; } return $updateData; }
/** * Cascades the postUpdate and postPersist events to embedded documents. * * @param ClassMetadata $class * @param object $document */ private function cascadePostUpdate(ClassMetadata $class, $document) { foreach ($class->getEmbeddedFieldsMappings() as $mapping) { $value = $class->reflFields[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; } $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value; foreach ($values as $entry) { if (empty($this->uow->getDocumentChangeSet($entry)) && !$this->uow->hasScheduledCollections($entry)) { continue; } $entryClass = $this->dm->getClassMetadata(get_class($entry)); $event = $this->uow->isScheduledForInsert($entry) ? Events::postPersist : Events::postUpdate; $entryClass->invokeLifecycleCallbacks($event, $entry, array(new LifecycleEventArgs($entry, $this->dm))); $this->evm->dispatchEvent($event, new LifecycleEventArgs($entry, $this->dm)); $this->cascadePostUpdate($entryClass, $entry); } } }
/** * @param object $document * @return boolean */ private function isScheduledForInsert($document) { return $this->uow->isScheduledForInsert($document) || $this->uow->getDocumentPersister(get_class($document))->isQueuedForInsert($document); }
/** * Prepares the update query to update a given document object in mongodb. * * @param object $document * @return array $updateData */ public function prepareUpdateData($document) { $oid = spl_object_hash($document); $class = $this->dm->getClassMetadata(get_class($document)); $changeset = $this->uow->getDocumentChangeSet($document); $updateData = array(); foreach ($changeset as $fieldName => $change) { $mapping = $class->fieldMappings[$fieldName]; // skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { continue; } // Skip version and lock fields if (isset($mapping['version']) || isset($mapping['lock'])) { continue; } list($old, $new) = $change; // @Inc if ($mapping['type'] === 'increment') { if ($new >= $old) { $updateData[$this->cmd . 'inc'][$mapping['name']] = $new - $old; } else { $updateData[$this->cmd . 'inc'][$mapping['name']] = ($old - $new) * -1; } // @Field, @String, @Date, etc. } elseif (!isset($mapping['association'])) { if (isset($new) || $mapping['nullable'] === true) { $updateData[$this->cmd . 'set'][$mapping['name']] = Type::getType($mapping['type'])->convertToDatabaseValue($new); } else { $updateData[$this->cmd . 'unset'][$mapping['name']] = true; } // @EmbedOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_ONE) { // If we have a new embedded document then lets set the whole thing if ($new && $this->uow->isScheduledForInsert($new)) { $updateData[$this->cmd . 'set'][$mapping['name']] = $this->prepareEmbeddedDocumentValue($mapping, $new); // If we don't have a new value then lets unset the embedded document } elseif (!$new) { $updateData[$this->cmd . 'unset'][$mapping['name']] = true; // Update existing embedded document } else { $update = $this->prepareUpdateData($new); foreach ($update as $cmd => $values) { foreach ($values as $key => $value) { $updateData[$cmd][$mapping['name'] . '.' . $key] = $value; } } } // @EmbedMany } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_MANY) { foreach ($new as $key => $embeddedDoc) { if (!$this->uow->isScheduledForInsert($embeddedDoc)) { $update = $this->prepareUpdateData($embeddedDoc); foreach ($update as $cmd => $values) { foreach ($values as $name => $value) { $updateData[$cmd][$mapping['name'] . '.' . $key . '.' . $name] = $value; } } } } // @ReferenceOne } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::REFERENCE_ONE) { if (isset($new) || $mapping['nullable'] === true) { $updateData[$this->cmd . 'set'][$mapping['name']] = $this->prepareReferencedDocumentValue($mapping, $new); } else { $updateData[$this->cmd . 'unset'][$mapping['name']] = true; } // @ReferenceMany } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::REFERENCE_MANY) { // Do nothing right now } } return $updateData; }
/** * Determines whether a document instance is managed in this DocumentManager. * * @param object $document * @return boolean TRUE if this DocumentManager currently manages the given document, FALSE otherwise. */ public function contains($document) { return $this->unitOfWork->isScheduledForInsert($document) || $this->unitOfWork->isInIdentityMap($document) && !$this->unitOfWork->isScheduledForDelete($document); }
/** * Prepares update array for document, using atomic operators * * @param mixed $document * @return array */ public function prepareUpdateData($document) { $oid = spl_object_hash($document); $class = $this->dm->getClassMetadata(get_class($document)); $changeset = $this->uow->getDocumentChangeSet($document); $result = array(); foreach ($changeset as $fieldName => $change) { $mapping = $class->fieldMappings[$fieldName]; // many references are persisted with CollectionPersister later if (isset($mapping['reference']) && $mapping['type'] === 'many') { continue; } // skip not saved fields if (isset($mapping['notSaved']) && $mapping['notSaved'] === true) { continue; } // Skip version and lock fields if (isset($mapping['version']) || isset($mapping['lock'])) { continue; } list($old, $new) = $change; // Build query to persist updates to an embedded one association if (isset($mapping['embedded']) && $mapping['type'] === 'one') { // If we have a new embedded document then lets set the whole thing if ($new && $this->uow->isScheduledForInsert($new)) { $result[$this->cmd . 'set'][$mapping['name']] = $this->prepareEmbeddedDocValue($mapping, $new); // If we don't have a new value then lets unset the embedded document } else if ( ! $new) { $result[$this->cmd . 'unset'][$mapping['name']] = true; // Update existing embedded document } else { $update = $this->prepareUpdateData($new); foreach ($update as $cmd => $values) { foreach ($values as $key => $value) { $result[$cmd][$mapping['name'] . '.' . $key] = $value; } } } // Build query to persist updates to an embedded many association } else if (isset($mapping['embedded']) && $mapping['type'] === 'many') { foreach ($new as $key => $embeddedDoc) { if (!$this->uow->isScheduledForInsert($embeddedDoc)) { $update = $this->prepareUpdateData($embeddedDoc); foreach ($update as $cmd => $values) { foreach ($values as $name => $value) { $result[$cmd][$mapping['name'] . '.' . $key . '.' . $name] = $value; } } } } // Prepare increment type values } else if ($mapping['type'] === 'increment') { if ($new >= $old) { $result[$this->cmd . 'inc'][$mapping['name']] = $new - $old; } else { $result[$this->cmd . 'inc'][$mapping['name']] = ($old - $new) * -1; } // Persist all other types using $set and $unset } else { if (isset($new) || $mapping['nullable'] === true) { $new = $this->prepareValue($mapping, $new); $result[$this->cmd . 'set'][$mapping['name']] = $new; } else { $result[$this->cmd . 'unset'][$mapping['name']] = true; } } } return $result; }