Updates a managed document.

@param object $document
484731
public function update($document): void
    {
        $class = $this->dm->getClassMetadata(get_class($document));
        $data = $this->prepareUpdateData($document);
        $id = $class->getSingleIdentifier($document);

        $this->collection->update((string) $id, $data['body'], $data['script']);
    }
1168914
public function deleteDocument(Document $document)
    {
        if (Document::DOCUMENT_TYPE_FILE === $document->getType()) {
            $data = $document->getFile();

            if (isset($data['url'])) {
                $this->fileSystem->remove($this->filesDir.DIRECTORY_SEPARATOR.$data['url']);
            }
        }
        $this->om->remove($document);
        $this->om->flush();

        $this->eventDispatcher->dispatch('log', new LogDocumentDeleteEvent($document->getDrop()->getDropzone(), $document->getDrop(), $document));
    }
318780
public function repair($document, $text): void
    {
        if ($document instanceof Document) {
            $document = $document->getId();
        }

        $this->getClient()->call(null, $document, self::ENDPOINT, OriginalFile::class, false, 'POST', sprintf(
                '/repair?repair_description=%s', urlencode($text))
        );
    }
1174455
public function prepareUpdateData($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 non embedded document identifiers
            if ( ! $class->isEmbeddedDocument && ! empty($mapping['id'])) {
                continue;
            }

            list($old, $new) = $change;

            // @Inc
            if ($mapping['type'] === 'increment') {
                if ($new === null) {
                    if ($mapping['nullable'] === true) {
                        $updateData['$set'][$mapping['name']] = null;
                    } else {
                        $updateData['$unset'][$mapping['name']] = true;
                    }
                } elseif ($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));
                } else {
                    $updateData['$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['$set'][$mapping['name']] = $this->prepareEmbeddedDocumentValue($mapping, $new);

                // If we don't have a new value then lets unset the embedded document
                } elseif ( ! $new) {
                    $updateData['$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) {
                if (null !== $new) {
                    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 && $mapping['isOwningSide']) {
                if (isset($new) || $mapping['nullable'] === true) {
                    $updateData['$set'][$mapping['name']] = (is_null($new) ? null : $this->prepareReferencedDocumentValue($mapping, $new));
                } else {
                    $updateData['$unset'][$mapping['name']] = true;
                }

            // @ReferenceMany
            } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::REFERENCE_MANY) {
                // Do nothing right now
            }
        }
        return $updateData;
    }
1075518
public function prepareUpsertData($document)
    {
        $class     = $this->dm->getClassMetadata(get_class($document));
        $changeset = $this->uow->getDocumentChangeSet($document);

        $updateData = [];
        foreach ($changeset as $fieldName => $change) {
            $mapping = $class->fieldMappings[$fieldName];

            [$old, $new] = $change;

            // Scalar fields
            if (! isset($mapping['association'])) {
                if ($new !== null) {
                    if (empty($mapping['id']) && isset($mapping['strategy']) && $mapping['strategy'] === ClassMetadata::STORAGE_STRATEGY_INCREMENT) {
                        $operator = '$inc';
                        $value    = Type::getType($mapping['type'])->convertToDatabaseValue($new - $old);
                    } else {
                        $operator = '$set';
                        $value    = Type::getType($mapping['type'])->convertToDatabaseValue($new);
                    }

                    $updateData[$operator][$mapping['name']] = $value;
                } elseif ($mapping['nullable'] === true) {
                    $updateData['$setOnInsert'][$mapping['name']] = null;
                }

            // @EmbedOne
            } elseif (isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_ONE) {
                // If we don't have a new value then do nothing on upsert
                // 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);
                } elseif ($new) {
                    // Update existing embedded document
                    $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']] = $new === null ? null : $this->prepareReferencedDocumentValue($mapping, $new);
                }

            // @ReferenceMany, @EmbedMany
            } elseif ($mapping['type'] === ClassMetadata::MANY && ! $mapping['isInverseSide']
                    && $new instanceof PersistentCollectionInterface && $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)) {
            $discriminatorValue = $class->discriminatorValue;

            if ($discriminatorValue === null) {
                if (! empty($class->discriminatorMap)) {
                    throw MappingException::unlistedClassInDiscriminatorMap($class->name);
                }

                $discriminatorValue = $class->name;
            }

            $updateData['$set'][$class->discriminatorField] = $discriminatorValue;
        }

        return $updateData;
    }
866949
private function executeUpsert(object $document, array $options) : void
    {
        $options['upsert'] = true;
        $criteria          = $this->getQueryForDocument($document);

        $data = $this->pb->prepareUpsertData($document);

        // Set the initial version for each upsert
        if ($this->class->isVersioned) {
            $versionMapping = $this->class->fieldMappings[$this->class->versionField];
            $nextVersion    = null;
            if ($versionMapping['type'] === 'int') {
                $nextVersion = max(1, (int) $this->class->reflFields[$this->class->versionField]->getValue($document));
                $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersion);
            } elseif ($versionMapping['type'] === 'date') {
                $nextVersionDateTime = new DateTime();
                $nextVersion         = Type::convertPHPToDatabaseValue($nextVersionDateTime);
                $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersionDateTime);
            }
            $data['$set'][$versionMapping['name']] = $nextVersion;
        }

        foreach (array_keys($criteria) as $field) {
            unset($data['$set'][$field]);
            unset($data['$inc'][$field]);
            unset($data['$setOnInsert'][$field]);
        }

        // Do not send empty update operators
        foreach (['$set', '$inc', '$setOnInsert'] as $operator) {
            if (! empty($data[$operator])) {
                continue;
            }

            unset($data[$operator]);
        }

        /* If there are no modifiers remaining, we're upserting a document with
         * an identifier as its only field. Since a document with the identifier
         * may already exist, the desired behavior is "insert if not exists" and
         * NOOP otherwise. MongoDB 2.6+ does not allow empty modifiers, so $set
         * the identifier to the same value in our criteria.
         *
         * This will fail for versions before MongoDB 2.6, which require an
         * empty $set modifier. The best we can do (without attempting to check
         * server versions in advance) is attempt the 2.6+ behavior and retry
         * after the relevant exception.
         *
         * See: https://jira.mongodb.org/browse/SERVER-12266
         */
        if (empty($data)) {
            $retry = true;
            $data  = ['$set' => ['_id' => $criteria['_id']]];
        }

        try {
            assert($this->collection instanceof Collection);
            $this->collection->updateOne($criteria, $data, $options);
            return;
        } catch (WriteException $e) {
            if (empty($retry) || strpos($e->getMessage(), 'Mod on _id not allowed') === false) {
                throw $e;
            }
        }

        assert($this->collection instanceof Collection);
        $this->collection->updateOne($criteria, ['$set' => new stdClass()], $options);
    }
442399
public function unlock(object $document) : void
    {
        $id          = $this->uow->getDocumentIdentifier($document);
        $criteria    = ['_id' => $this->class->getDatabaseIdentifierValue($id)];
        $lockMapping = $this->class->fieldMappings[$this->class->lockField];
        assert($this->collection instanceof Collection);
        $this->collection->updateOne($criteria, ['$unset' => [$lockMapping['name'] => true]]);
        $this->class->reflFields[$this->class->lockField]->setValue($document, null);
    }
449836
public function lock($document, $lockMode)
    {
        $id = $this->uow->getDocumentIdentifier($document);
        $criteria = array('_id' => $this->class->getDatabaseIdentifierValue($id));
        $lockMapping = $this->class->fieldMappings[$this->class->lockField];
        $this->collection->update($criteria, array('$set' => array($lockMapping['name'] => $lockMode)));
        $this->class->reflFields[$this->class->lockField]->setValue($document, $lockMode);
    }
59479
private function executeUpdates($documents, $dispatchEvents = true)
    {
        foreach ($documents as $oid => $document) {
            if (!$this->contains($oid)) {
                continue;
            }

            $class = $this->dm->getClassMetadata(get_class($document));
            $node = $this->session->getNode($this->getDocumentId($document));

            if ($this->writeMetadata) {
                $this->documentClassMapper->writeMetadata($this->dm, $node, $class->name);
            }

            if ($dispatchEvents) {
                if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::preUpdate)) {
                    $this->eventListenersInvoker->invoke(
                        $class,
                        Event::preUpdate,
                        $document,
                        new PreUpdateEventArgs($document, $this->dm, $this->documentChangesets[$oid]),
                        $invoke
                    );
                    $this->changesetComputed = array_diff($this->changesetComputed, [$oid]);
                    $this->computeChangeSet($class, $document);
                }
            }

            $fields = $this->documentChangesets[$oid]['fields'] ?? [];
            foreach ($fields as $fieldName => $data) {
                $fieldValue = $data[1];

                // PHPCR does not validate nullable unless we would start to
                // generate custom node types, which we at the moment don't.
                // the ORM can delegate this validation to the relational database
                // that is using a strict schema.
                // do this after the preUpdate events to give listener a last
                // chance to provide values
                if (null === $fieldValue
                    && in_array($fieldName, $class->fieldMappings) // only care about non-virtual fields
                    && !$class->isNullable($fieldName)
                    && !$this->isAutocreatedProperty($class, $fieldName)
                ) {
                    throw new PHPCRException(sprintf('Field "%s" of class "%s" is not nullable', $fieldName, $class->name));
                }

                // Ignore translatable fields (they will be persisted by the translation strategy)
                if (in_array($fieldName, $class->translatableFields)) {
                    continue;
                }

                $mapping = $class->mappings[$fieldName];
                if (in_array($fieldName, $class->fieldMappings)) {
                    $type = PropertyType::valueFromName($mapping['type']);
                    if ($mapping['multivalue']) {
                        $value = empty($fieldValue) ? null : ($fieldValue instanceof Collection ? $fieldValue->toArray() : $fieldValue);
                        if ($value && isset($mapping['assoc'])) {
                            $value = $this->processAssoc($node, $mapping, $value);
                        }
                    } else {
                        $value = $fieldValue;
                    }
                    $node->setProperty($mapping['property'], $value, $type);
                } elseif ($mapping['type'] === $class::MANY_TO_ONE
                    || $mapping['type'] === $class::MANY_TO_MANY
                ) {
                    if (!$this->writeMetadata) {
                        continue;
                    }
                    if ($node->hasProperty($mapping['property']) && is_null($fieldValue)) {
                        $node->getProperty($mapping['property'])->remove();
                        if (isset($mapping['assoc'])) {
                            $this->removeAssoc($node, $mapping);
                        }
                        continue;
                    }

                    switch ($mapping['strategy']) {
                        case 'hard':
                            $strategy = PropertyType::REFERENCE;
                            break;
                        case 'path':
                            $strategy = PropertyType::PATH;
                            break;
                        default:
                            $strategy = PropertyType::WEAKREFERENCE;
                            break;
                    }

                    if ($mapping['type'] === $class::MANY_TO_MANY) {
                        if (isset($fieldValue)) {
                            $refNodesIds = [];
                            foreach ($fieldValue as $fv) {
                                if ($fv === null) {
                                    continue;
                                }

                                $associatedNode = $this->session->getNode($this->getDocumentId($fv));
                                if ($strategy === PropertyType::PATH) {
                                    $refNodesIds[] = $associatedNode->getPath();
                                } else {
                                    $refClass = $this->dm->getClassMetadata(get_class($fv));
                                    $this->setMixins($refClass, $associatedNode, $fv);
                                    if (!$associatedNode->isNodeType('mix:referenceable')) {
                                        throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: '.self::objToStr($document, $this->dm), ClassUtils::getClass($fv)));
                                    }
                                    $refNodesIds[] = $associatedNode->getIdentifier();
                                }
                            }

                            $refNodesIds = empty($refNodesIds) ? null : $refNodesIds;
                            $node->setProperty($mapping['property'], $refNodesIds, $strategy);
                        }
                    } elseif ($mapping['type'] === $class::MANY_TO_ONE) {
                        if (isset($fieldValue)) {
                            $associatedNode = $this->session->getNode($this->getDocumentId($fieldValue));

                            if ($strategy === PropertyType::PATH) {
                                $node->setProperty($fieldName, $associatedNode->getPath(), $strategy);
                            } else {
                                $refClass = $this->dm->getClassMetadata(get_class($fieldValue));
                                $this->setMixins($refClass, $associatedNode, $document);
                                if (!$associatedNode->isNodeType('mix:referenceable')) {
                                    throw new PHPCRException(sprintf('Referenced document %s is not referenceable. Use referenceable=true in Document annotation: '.self::objToStr($document, $this->dm), ClassUtils::getClass($fieldValue)));
                                }
                                $node->setProperty($mapping['property'], $associatedNode->getIdentifier(), $strategy);
                            }
                        }
                    }
                } elseif ('referrers' === $mapping['type']) {
                    if (isset($fieldValue)) {

                        /*
                         * each document in referrers field is supposed to
                         * reference this document, so we have to update its
                         * referencing property to contain the uuid of this
                         * document
                         */
                        foreach ($fieldValue as $fv) {
                            if ($fv === null) {
                                continue;
                            }

                            if (!$fv instanceof $mapping['referringDocument']) {
                                throw new PHPCRException(sprintf('%s is not an instance of %s for document %s field %s', self::objToStr($fv, $this->dm), $mapping['referencedBy'], self::objToStr($document, $this->dm), $mapping['fieldName']));
                            }

                            $referencingNode = $this->session->getNode($this->getDocumentId($fv));
                            $referencingMeta = $this->dm->getClassMetadata($mapping['referringDocument']);
                            $referencingField = $referencingMeta->getAssociation($mapping['referencedBy']);

                            $uuid = $node->getIdentifier();
                            $strategy = $referencingField['strategy'] == 'weak' ? PropertyType::WEAKREFERENCE : PropertyType::REFERENCE;
                            switch ($referencingField['type']) {
                                case ClassMetadata::MANY_TO_ONE:
                                    $ref = $referencingMeta->getFieldValue($fv, $referencingField['fieldName']);
                                    if ($ref !== null && $ref !== $document) {
                                        throw new PHPCRException(sprintf('Conflicting settings for referrer and reference: Document %s field %s points to %s but document %s has set first document as referrer on field %s', self::objToStr($fv, $this->dm), $referencingField['fieldName'], self::objToStr($ref, $this->dm), self::objToStr($document, $this->dm), $mapping['fieldName']));
                                    }
                                    // update the referencing document field to point to this document
                                    $referencingMeta->setFieldValue($fv, $referencingField['fieldName'], $document);
                                    // and make sure the reference is not deleted in this change because the field could be null
                                    unset($this->documentChangesets[spl_object_hash($fv)]['fields'][$referencingField['fieldName']]);
                                    // store the change in PHPCR
                                    $referencingNode->setProperty($referencingField['property'], $uuid, $strategy);
                                    break;
                                case ClassMetadata::MANY_TO_MANY:
                                    /** @var $collection ReferenceManyCollection */
                                    $collection = $referencingMeta->getFieldValue($fv, $referencingField['fieldName']);
                                    if ($collection instanceof PersistentCollection && $collection->isDirty()) {
                                        throw new PHPCRException(sprintf('You may not modify the reference and referrer collections of interlinked documents as this is ambiguous. Reference %s on document %s and referrers %s on document %s are both modified', self::objToStr($fv, $this->dm), $referencingField['fieldName'], self::objToStr($document, $this->dm), $mapping['fieldName']));
                                    }
                                    if ($collection) {
                                        // make sure the reference is not deleted in this change because the field could be null
                                        unset($this->documentChangesets[spl_object_hash($fv)]['fields'][$referencingField['fieldName']]);
                                    } else {
                                        $collection = new ReferenceManyCollection($this->dm, $fv, $referencingField['property'], [$node], $class->name, null, $this->getReferenceManyCollectionTypeFromMetadata($mapping));
                                        $referencingMeta->setFieldValue($fv, $referencingField['fieldName'], $collection);
                                    }

                                    if ($referencingNode->hasProperty($referencingField['property'])) {
                                        if (!in_array($uuid, $referencingNode->getProperty($referencingField['property'])->getString())) {
                                            if (!$collection instanceof PersistentCollection || !$collection->isDirty()) {
                                                // update the reference collection: add us to it
                                                $collection->add($document);
                                            }
                                            // store the change in PHPCR
                                            $referencingNode->getProperty($referencingField['property'])->addValue($uuid); // property should be correct type already
                                        }
                                    } else {
                                        // store the change in PHPCR
                                        $referencingNode->setProperty($referencingField['property'], [$uuid], $strategy);
                                    }

                                    // avoid confusion later, this change to the reference collection is already saved
                                    $collection->setDirty(false);
                                    break;
                                default:
                                    // in class metadata we only did a santiy check but not look at the actual mapping
                                    throw new MappingException(sprintf('Field "%s" of document "%s" is not a reference field. Error in referrer annotation: '.self::objToStr($document, $this->dm), $mapping['referencedBy'], ClassUtils::getClass($fv)));
                            }
                        }
                    }
                } elseif ('child' === $mapping['type']) {
                    if ($fieldValue === null && $node->hasNode($mapping['nodeName'])) {
                        $child = $node->getNode($mapping['nodeName']);
                        $childDocument = $this->getOrCreateDocument(null, $child);
                        $this->purgeChildren($childDocument);
                        $child->remove();
                    }
                }
            }

            if (!empty($this->documentChangesets[$oid]['reorderings'])) {
                foreach ($this->documentChangesets[$oid]['reorderings'] as $reorderings) {
                    foreach ($reorderings as $srcChildRelPath => $destChildRelPath) {
                        $node->orderBefore($srcChildRelPath, $destChildRelPath);
                    }
                }
            }

            $this->doSaveTranslation($document, $node, $class);

            if ($dispatchEvents) {
                if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postUpdate)) {
                    $this->eventListenersInvoker->invoke(
                        $class,
                        Event::postUpdate,
                        $document,
                        new LifecycleEventArgs($document, $this->dm),
                        $invoke
                    );
                }
            }
        }
    }
1292135
public function put($docs)
    {
        if($docs instanceof Document) {
            $this->obj_gateway->put([$docs]);
        } elseif (is_array($docs)) {
            $this->obj_gateway->put($docs);
        } else {
            throw new \InvalidArgumentException('Parameter must be one or more \Search\Document objects');
        }
    }
25782
public function unlock($document)
    {
        if ($this->getDocumentState($document) != self::STATE_MANAGED) {
            throw new \InvalidArgumentException("Document is not MANAGED.");
        }
        $documentName = get_class($document);
        $this->getDocumentPersister($documentName)->unlock($document);
    }
495123
public function update()
    {
        $this->exitIfModelNotSet();

        if (!$this->model->exists) {
            throw new \Exception('Model not persisted yet');
        }

        $document = $this->model->getDocumentData();

        $params = [
            'id'    => $this->model->getKey(),
            'type'  => $this->model->getDocumentType(),
            'index' => $this->model->getDocumentIndex(),
            'body'  => [
                'doc' => $document,
            ],
        ];

        return $this->connection->updateStatement($params);
    }
689497
public function delete($document): void
    {
        $class = $this->dm->getClassMetadata(get_class($document));
        $id = $class->getSingleIdentifier($document);

        $this->collection->delete((string) $id);
    }
1181023
public function update($data) {
        $data = Values::of(array('Data' => Serialize::jsonObject($data), ));

        $payload = $this->version->update(
            'POST',
            $this->uri,
            array(),
            $data
        );

        return new DocumentInstance(
            $this->version,
            $payload,
            $this->solution['serviceSid'],
            $this->solution['sid']
        );
    }
19194
public function persist($document)
    {
        $documentArray = $this->converter->convertToArray($document);
        $type = $this->getMetadataCollector()->getDocumentType(get_class($document));

        $this->bulk('index', $type, $documentArray);
    }
356324
public function persist(Document $document)
    {
        $this->pool->attach($document, self::STATE_SAVE);

        return $this;
    }
619915
public function update($object)
    {
        if (!($object instanceof $this->objectType)) {
            throw new IllegalObjectTypeException('The modified object given to update() was not of the type (' . $this->objectType . ') this repository manages.', 1249479625);
        }
        $this->persistenceManager->update($object);
    }