Get a Document Snapshot.

Example:
```
$snapshot = $transaction->snapshot($document);
```

@param DocumentReference $document The document to retrieve.
@param array $options Configuration options.
@return DocumentSnapshot
778629
public function snapshot(DocumentReference $document, array $options = [])
    {
        return $this->createSnapshot($this->connection, $this->valueMapper, $document, [
            'transaction' => $this->transaction,
        ] + $options);
    }
849958
public function insertOne($document, $options = [])
    {
        $objectDatas = $this->hydrator->unhydrate($document);

        $stream = $objectDatas["stream"];
        unset($objectDatas["stream"]);

        if (!isset($objectDatas["filename"])) {
            $filename = stream_get_meta_data($stream)["uri"];
        } else {
            $filename = $objectDatas["filename"];
        }

        unset($objectDatas["filename"]);

        $id = $this->bucket->uploadFromStream($filename, $stream, $objectDatas);
        $data['_id'] = $id;

        $data["stream"] = $this->bucket->openDownloadStream($data['_id']);
        $this->hydrator->hydrate($document, $data, true);

        $this->documentManager->setObjectState($document, ObjectManager::OBJ_MANAGED);
        $this->cacheObject($document);

        return true;
    }
1098548
public function getFieldValue($document, $field)
    {
        if (isset($this->reflFields[$field])) {
            return $this->reflFields[$field]->getValue($document);
        }
    }
220815
private function getDocumentId($document)
    {
        $documentId = $document;
        if ($document instanceof Document) {
            $documentId = $document->getId();
        }

        if (!(is_int($documentId) || is_string($documentId) || is_float($documentId) || trim($documentId) === '')) {
            throw new ClientException('Cannot alter a document without a document id');
        }

        return $documentId;
    }
1373936
public function snapshot(): DocumentSnapshot
    {
        $value = $this->apiClient->get($this->uri);

        $data = $this->valueMapper->decodeValues($value['fields']);

        return new DocumentSnapshot($this, [], $data, true);
    }
1257623
public function mCreateDocument($documents, array $options = [])
    {
        if (!is_array($documents)) {
            throw new InvalidArgumentException('Collection.mCreateDocument: documents parameter format is invalid (should be an array of documents)');
        }

        $documents = array_map(function ($document) {
            return $document instanceof Document ? $document->serialize() : $document;
        }, $documents);

        $data = ['body' => ['documents' => $documents]];

        $response = $this->kuzzle->query(
            $this->buildQueryArgs('document', 'mCreate'),
            $this->kuzzle->addHeaders($data, $this->headers),
            $options
        );

        return $response['result'];
    }
90022
public function get_document($record, $options = array()) {
        try {
            $context = \context_course::instance($record->id);
        } catch (\moodle_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document, not all required data is available: ' .
                $ex->getMessage(), DEBUG_DEVELOPER);
            return false;
        }
        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        $doc->set('title', content_to_text($record->fullname, false));
        $doc->set('content', content_to_text($record->summary, $record->summaryformat));
        $doc->set('contextid', $context->id);
        $doc->set('courseid', $record->id);
        $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
        $doc->set('modified', $record->timemodified);
        $doc->set('description1', $record->shortname);

        // Check if this document should be considered new.
        if (isset($options['lastindexedtime']) && $options['lastindexedtime'] < $record->timecreated) {
            // If the document was created after the last index time, it must be new.
            $doc->set_is_new(true);
        }

        return $doc;
    }
244606
public function get_document($record, $options = array()) {

        // Check if user still exists, before proceeding.
        $user = \core_user::get_user($options['user1id'], 'deleted');
        if ($user->deleted == 1) {
            return false;
        }

        // Get user context.
        try {
            $usercontext = \context_user::instance($options['user1id']);
        } catch (\moodle_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document, not all required data is available: ' .
                    $ex->getMessage(), DEBUG_DEVELOPER);
            return false;
        }
        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        $doc->set('title', content_to_text($record->subject, false));
        $doc->set('itemid', $record->id);
        $doc->set('content', content_to_text($record->smallmessage, false));
        $doc->set('contextid', $usercontext->id);
        $doc->set('courseid', SITEID);
        $doc->set('owneruserid', $options['user1id']);
        $doc->set('userid', $options['user2id']);
        $doc->set('modified', $record->timecreated);

        // Check if this document should be considered new.
        if (isset($options['lastindexedtime']) && $options['lastindexedtime'] < $record->timecreated) {
            // If the document was created after the last index time, it must be new.
            $doc->set_is_new(true);
        }

        return $doc;
    }
630263
public function create($document, $options = null)
    {
        $this->assertProperties($document, ['_type'], 'create');
        return $this->createDocument($document, 'create', $options);
    }
1210253
public function getObjectPropertyAnnotations($document)
    {
        $cacheKey = "object_property_annotations_" . get_class($document);
        if (!$this->cache->contains($cacheKey)) {
            $refObject   = new \ReflectionObject($document);
            $annotations = array();
            foreach ($refObject->getProperties() as $property) {
                $annotation = $this->getPropertyAnnotation($property);
                if ($annotation) {
                    $annotations[$property->getName()] = $annotation;
                }
            }
            $this->cache->save($cacheKey, $annotations);
        }
        return $this->cache->fetch($cacheKey);
    }
404819
protected function document(Document $document = null): ?Document {
        if ($document === null) {
            return $this->document;
        }

        $this->document = $document;

        return $this->document;
    }
198140
public function get_document($record, $options = array()) {

        $context = \context_system::instance();

        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        // Include all alternate names in title.
        $array = [];
        foreach (get_all_user_name_fields(false, null, null, null, true) as $field) {
            $array[$field] = $record->$field;
        }
        $fullusername = join(' ', $array);
        // Assigning properties to our document.
        $doc->set('title', content_to_text($fullusername, false));
        $doc->set('contextid', $context->id);
        $doc->set('courseid', SITEID);
        $doc->set('itemid', $record->id);
        $doc->set('modified', $record->timemodified);
        $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
        $doc->set('content', content_to_text($record->description, $record->descriptionformat));

        // Check if this document should be considered new.
        if (isset($options['lastindexedtime']) && $options['lastindexedtime'] < $record->timecreated) {
            // If the document was created after the last index time, it must be new.
            $doc->set_is_new(true);
        }

        return $doc;
    }
438779
public function get_document($record, $options = array()) {
        global $CFG;
        require_once($CFG->dirroot . '/course/lib.php');

        // Get the context, modinfo, and section.
        try {
            $context = \context_course::instance($record->course);
        } catch (\moodle_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id .
                    ' document, not all required data is available: ' . $ex->getMessage(),
                    DEBUG_DEVELOPER);
            return false;
        }

        // Title - use default if none given.
        $title = get_section_name($record->course, $record->section);

        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        $doc->set('title', content_to_text($title, false));
        $doc->set('content', content_to_text($record->summary, $record->summaryformat));
        $doc->set('contextid', $context->id);
        $doc->set('courseid', $record->course);
        $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
        $doc->set('modified', $record->timemodified);

        return $doc;
    }
824823
public function get_document($record, $options = array()) {
        global $PAGE;

        try {
            $context = \context_course::instance($record->instanceid);
        } catch (\moodle_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document, not all required data is available: ' .
                $ex->getMessage(), DEBUG_DEVELOPER);
            return false;
        }

        $handler = course_handler::create();
        $field = $handler->get_fields()[$record->fieldid];
        $data = data_controller::create(0, $record, $field);

        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        $doc->set('title', content_to_text($field->get('name'), false));
        $doc->set('content', content_to_text($data->export_value(), FORMAT_HTML));
        $doc->set('contextid', $context->id);
        $doc->set('courseid', $context->instanceid);
        $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
        $doc->set('modified', $record->timemodified);

        // Check if this document should be considered new.
        if (isset($options['lastindexedtime']) && ($options['lastindexedtime'] < $record->timecreated)) {
            // If the document was created after the last index time, it must be new.
            $doc->set_is_new(true);
        }

        return $doc;
    }
1239589
public function get_document($record, $options = array()) {

        try {
            $cm = $this->get_cm($this->get_module_name(), $record->id, $record->course);
            $context = \context_module::instance($cm->id);
        } catch (\dml_missing_record_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document, not all required data is available: ' .
                $ex->getMessage(), DEBUG_DEVELOPER);
            return false;
        } catch (\dml_exception $ex) {
            // Notify it as we run here as admin, we should see everything.
            debugging('Error retrieving ' . $this->areaid . ' ' . $record->id . ' document: ' . $ex->getMessage(), DEBUG_DEVELOPER);
            return false;
        }

        // Prepare associative array with data from DB.
        $doc = \core_search\document_factory::instance($record->id, $this->componentname, $this->areaname);
        $doc->set('title', content_to_text($record->name, false));
        $doc->set('content', content_to_text($record->content, $record->contentformat));
        $doc->set('contextid', $context->id);
        $doc->set('courseid', $record->course);
        $doc->set('owneruserid', \core_search\manager::NO_OWNER_ID);
        $doc->set('modified', $record->timemodified);
        $doc->set('description1', content_to_text($record->intro, $record->introformat));

        return $doc;
    }
1138143
public function takeSnapshot()
    {
        if (is_array($this->originalReferencePaths)) {
            if ($this->isInitialized()) {
                foreach ($this->collection->toArray() as $document) {
                    try {
                        $this->originalReferencePaths[] = $this->dm->getUnitOfWork()->getDocumentId($document);
                    } catch (PHPCRException $e) {
                    }
                }
            } else {
                $this->originalReferencePaths = null;
            }
        }

        parent::takeSnapshot();
    }
306134
private function executeUpsert($document, array $options)
    {
        $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];
            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 = new \MongoDate($nextVersionDateTime->getTimestamp());
                $this->class->reflFields[$this->class->versionField]->setValue($document, $nextVersionDateTime);
            }
            $data['$set'][$versionMapping['name']] = $nextVersion;
        }

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

        // Do not send an empty $set modifier
        if (empty($data['$set'])) {
            unset($data['$set']);
        }

        /* 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 = array('$set' => array('_id' => $criteria['_id']));
        }

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

        $this->collection->update($criteria, array('$set' => new \stdClass), $options);
    }