Adds document/s to the add queue of the group.

@param \Mongator\Document\AbstractDocument|array $documents One or more documents.

@api
187017
public function add($documents)
    {

        $pendingRemove = $this->getRemove();
        if ($this->getRemove()) {
            if ($this->all()) {
                throw new \RuntimeException('Adding to group with pending remove is not permitted');
            } else {
                $this->clearAdd();
                $this->clearRemove();
                $this->saved = array();
            }
        }
        if (!is_array($documents)) {
            $documents = array($documents);
        }

        $add =& $this->getArchive()->getByRef('add', array());
        foreach ($documents as $document) {
            $add[] = $document;
        }
    }
434306
public function scheduleForSynchronization(object $document) : void
    {
        $class                                                                       = $this->dm->getClassMetadata(get_class($document));
        $this->scheduledForSynchronization[$class->name][spl_object_hash($document)] = $document;
    }
611579
public MutationState add(Document... documents) {
        if (documents == null || documents.length == 0) {
            throw new IllegalArgumentException("At least one Document must be provided.");
        }
        for (Document d : documents) {
            addToken(d.mutationToken());
        }
        return this;
    }
290038
public function addManyToManyCollections($collections)
    {
        if (!is_array($collections)) {
            $collections = [$collections];
        }
        $this->manyToManyCollections = array_merge($this->manyToManyCollections, $collections);

        return $this;
    }
774308
private function executeReorders($documents)
    {
        foreach ($documents as $oid => $list) {
            if (!$this->contains($oid)) {
                continue;
            }
            foreach ($list as $value) {
                list($parent, $src, $target, $before) = $value;
                $parentNode = $this->session->getNode($this->getDocumentId($parent));

                // check for src and target ...
                $dest = $target;
                if ($parentNode->hasNode($src) && $parentNode->hasNode($target)) {
                    // there is no orderAfter, so we need to find the child after target to use it in orderBefore
                    if (!$before) {
                        $dest = null;
                        $found = false;
                        foreach ($parentNode->getNodes() as $name => $child) {
                            if ($name === $target) {
                                $found = true;
                            } elseif ($found) {
                                $dest = $name;
                                break;
                            }
                        }
                    }

                    $parentNode->orderBefore($src, $dest);
                    $class = $this->dm->getClassMetadata(get_class($parent));
                    foreach ($class->childrenMappings as $fieldName) {
                        if ($parent instanceof Proxy && $parent->__isInitialized()) {
                            $children = $class->reflFields[$fieldName]->getValue($parent);
                            $children->refresh();
                        }
                    }
                }
            }
        }
    }
609561
public function insertMany($documents, $options = [])
    {
        $insertQuery = [];
        foreach ($documents as $document) {
            $this->classMetadata->getEventManager()->execute(EventManager::EVENT_PRE_INSERT, $document);
            $query = $this->hydrator->unhydrate($document);

            $idGen = $this->classMetadata->getIdGenerator();
            if ($idGen !== null) {
                if (!class_exists($idGen) || !is_subclass_of($idGen, AbstractIdGenerator::class)) {
                    throw new \Exception('Bad ID generator : class \'' . $idGen . '\' not exists or not extends JPC\MongoDB\ODM\Id\AbstractIdGenerator');
                }
                $generator = new $idGen();
                $query['_id'] = $generator->generate($this->documentManager, $document);
            }

            $insertQuery[] = $query;
        }

        $result = $this->collection->insertMany($insertQuery, $options);

        if ($result->isAcknowledged()) {
            foreach ($result->getInsertedIds() as $key => $id) {
                if ($id instanceof \stdClass) {
                    $id = (array) $id;
                }
                $insertQuery[$key]["_id"] = $id;
                $this->hydrator->hydrate($documents[$key], $insertQuery[$key]);

                $this->classMetadata->getEventManager()->execute(EventManager::EVENT_POST_INSERT, $documents[$key]);

                $this->cacheObject($documents[$key]);
            }

            return true;
        } else {
            foreach ($documents as $document) {
                $this->cacheObject($document);
                // $this->documentManager->removeObject();
            }
            return false;
        }
    }
1208567
private function executeMoves($documents)
    {
        foreach ($documents as $oid => $value) {
            if (!$this->contains($oid)) {
                continue;
            }

            list($document, $targetPath) = $value;

            $sourcePath = $this->getDocumentId($document);
            if ($sourcePath === $targetPath) {
                continue;
            }

            $class = $this->dm->getClassMetadata(get_class($document));
            if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::preMove)) {
                $this->eventListenersInvoker->invoke(
                    $class,
                    Event::preMove,
                    $document,
                    new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath),
                    $invoke
                );
            }

            $parentNode = $this->session->getNode(PathHelper::getParentPath($targetPath));
            $this->validateChildClass($parentNode, $class);

            $this->session->move($sourcePath, $targetPath);

            // update fields nodename, parentMapping and depth if they exist in this type
            $node = $this->session->getNode($targetPath); // get node from session, document class might not map it
            if ($class->nodename) {
                $class->setFieldValue($document, $class->nodename, $node->getName());
            }

            if ($class->parentMapping) {
                $class->setFieldValue($document, $class->parentMapping, $this->getOrCreateProxyFromNode($node->getParent(), $this->getCurrentLocale($document, $class)));
            }

            if ($class->depthMapping) {
                $class->setFieldValue($document, $class->depthMapping, $node->getDepth());
            }

            // update all cached children of the document to reflect the move (path id changes)
            foreach ($this->documentIds as $childOid => $id) {
                if (0 !== strpos($id, $sourcePath)) {
                    continue;
                }

                $newId = $targetPath.substr($id, strlen($sourcePath));
                $this->documentIds[$childOid] = $newId;

                $child = $this->getDocumentById($id);
                if (!$child) {
                    continue;
                }

                unset($this->identityMap[$id]);
                $this->identityMap[$newId] = $child;

                $childClass = $this->dm->getClassMetadata(get_class($child));
                if ($childClass->identifier) {
                    $childClass->setIdentifierValue($child, $newId);
                    if (!$child instanceof Proxy || $child->__isInitialized()) {
                        $this->originalData[$childOid][$childClass->identifier] = $newId;
                    }
                }
            }

            if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postMove)) {
                $this->eventListenersInvoker->invoke(
                    $class,
                    Event::postMove,
                    $document,
                    new MoveEventArgs($document, $this->dm, $sourcePath, $targetPath),
                    $invoke
                );
            }
        }
    }
519667
public function createDocumentTermCount($documents)
    {
        $termCount = new TermCount($this->getSearchDbHandle(), $documents, $this->filters, $this->storage);
        $termCount->execute();
    }
1342979
public function insert($document)
    {
        $class     = $this->dm->getClassMetadata(get_class($document));
        $changeset = $this->uow->getDocumentChangeSet($document);
        $qb        = $this->dm->createQueryBuilder($this->class->name);

        foreach ($class->propertyMetadata as $mapping) {
            $new = isset($changeset[$mapping->name][1]) ? $changeset[$mapping->name][1] : null;

            if (($new === null && !$mapping->nullable) || $mapping->isInverseSide) {
                continue;
            }

            if ($mapping->isMany()) {
                if ($mapping->strategy === PropertyMetadata::STORAGE_STRATEGY_ADD_TO_SET || $new->isEmpty()) {
                    continue;
                }

                $this->uow->unscheduleCollectionDeletion($new);
                $this->uow->unscheduleCollectionUpdate($new);
            }

            $qb->attr($mapping->name)->put($new);
        }

        //add a conditional preventing the resulting PutItem from overwriting
        //an existing record with the same primary key
        $class->createIdentifier($document)->addNotExistsToQueryCondition($qb->expr);

        $qb->getQuery()->execute();
    }
169478
public void addAll(Iterable<? extends DOCUMENT> documents) {
      if (documents != null) {
         for (DOCUMENT doc : documents) {
            add(doc);
         }
      }
   }
1253642
public function bulkInsert($namespace, $documents)
    {
        $bulk = new BulkWrite();

        foreach ($documents as $document) {
            $bulk->insert($document);
        }

        return $this->bulkWrite($namespace, $bulk)->getInsertedCount();
    }
196601
public function addDocumentToDocumentPool(Document $document)
    {
        $documentId = (string) $document->getId();

        if (!isset($this->documentPool[$documentId])) {
            $this->documentPool[$documentId] = $document;
        } else {
            // merging because document after
            // load and before getting in second place may be changed
            // and this changes must be preserved:
            //
            // 1. Document loads and modifies in current session
            // 2. Document loads modified in another session
            // 3. Document loads once again in current session. Changes from stage 2 merges as unmodified

            $this->documentPool[$documentId]->mergeUnmodified($document->toArray());
        }

        return $this;
    }
1114613
public function remove($documents)
    {
        if (!is_array($documents)) {
            $documents = array($documents);
        }

        $remove =& $this->getArchive()->getByRef('remove', array());
        foreach ($documents as $document) {
            $remove[] = $document;
        }
    }
1100495
public function addAll(array $elements)
    {
        if (is_array($elements)) {
            foreach ($elements as $element) {
                $this->add($element);
            }
        }
    }
434162
private function executeInserts($documents)
    {
        // sort the documents to insert parents first but maintain child order
        $oids = [];
        foreach ($documents as $oid => $document) {
            if (!$this->contains($oid)) {
                continue;
            }

            $oids[$oid] = $this->getDocumentId($document);
        }

        $order = array_flip(array_values($oids));
        uasort($oids, function ($a, $b) use ($order) {
            // compute the node depths
            $aCount = substr_count($a, '/');
            $bCount = substr_count($b, '/');

            // ensure that the original order is maintained for nodes with the same depth
            if ($aCount === $bCount) {
                return ($order[$a] < $order[$b]) ? -1 : 1;
            }

            return ($aCount < $bCount) ? -1 : 1;
        }
        );

        $associationChangesets = $associationUpdates = [];

        foreach ($oids as $oid => $id) {
            $document = $documents[$oid];
            /** @var ClassMetadata $class */
            $class = $this->dm->getClassMetadata(get_class($document));

            // 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
            foreach ($class->fieldMappings as $fieldName) {
                if (!isset($this->documentChangesets[$oid]['fields'][$fieldName]) // empty string is ok
                    && !$class->isNullable($fieldName)
                    && !$this->isAutocreatedProperty($class, $fieldName)
                ) {
                    throw new PHPCRException(sprintf('Field "%s" of class "%s" is not nullable', $fieldName, $class->name));
                }
            }

            $parentNode = $this->session->getNode(PathHelper::getParentPath($id));
            $this->validateChildClass($parentNode, $class);

            $nodename = PathHelper::getNodeName($id);
            $node = $parentNode->addNode($nodename, $class->nodeType);
            if ($class->node) {
                $this->originalData[$oid][$class->node] = $node;
            }
            if ($class->nodename) {
                $this->originalData[$oid][$class->nodename] = $nodename;
            }

            try {
                $node->addMixin('phpcr:managed');
            } catch (NoSuchNodeTypeException $e) {
                throw new PHPCRException('Register phpcr:managed node type first. See https://github.com/doctrine/phpcr-odm/wiki/Custom-node-type-phpcr:managed');
            }

            foreach ($class->mixins as $mixin) {
                $node->addMixin($mixin);
            }

            if ($class->identifier) {
                $class->setIdentifierValue($document, $id);
            }
            if ($class->node) {
                $class->reflFields[$class->node]->setValue($document, $node);
            }
            if ($class->nodename) {
                // make sure this reflects the id generator strategy generated id
                $class->reflFields[$class->nodename]->setValue($document, $node->getName());
            }
            // make sure this reflects the id generator strategy generated id
            if ($class->parentMapping && !$class->reflFields[$class->parentMapping]->getValue($document)) {
                $class->reflFields[$class->parentMapping]->setValue($document, $this->getOrCreateProxyFromNode($parentNode, $this->getCurrentLocale($document, $class)));
            }

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

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

            $fields = $this->documentChangesets[$oid]['fields'] ?? [];
            foreach ($fields as $fieldName => $fieldValue) {
                // Ignore translatable fields (they will be persisted by the translation strategy)
                if (in_array($fieldName, $class->translatableFields)) {
                    continue;
                }

                if (in_array($fieldName, $class->fieldMappings)) {
                    $mapping = $class->mappings[$fieldName];
                    $type = PropertyType::valueFromName($mapping['type']);
                    if (null === $fieldValue) {
                        continue;
                    }

                    if ($mapping['multivalue'] && $fieldValue) {
                        $fieldValue = (array) $fieldValue;
                        if (isset($mapping['assoc'])) {
                            $fieldValue = $this->processAssoc($node, $mapping, $fieldValue);
                        }
                    }

                    $node->setProperty($mapping['property'], $fieldValue, $type);
                } elseif (in_array($fieldName, $class->referenceMappings) || in_array($fieldName, $class->referrersMappings)) {
                    $associationUpdates[$oid] = $document;

                    //populate $associationChangesets to force executeUpdates($associationUpdates)
                    //to only update association fields
                    $data = $associationChangesets[$oid]['fields'] ?? [];
                    $data[$fieldName] = [null, $fieldValue];
                    $associationChangesets[$oid] = ['fields' => $data];
                }
            }

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

            if ($invoke = $this->eventListenersInvoker->getSubscribedSystems($class, Event::postPersist)) {
                $this->eventListenersInvoker->invoke(
                    $class,
                    Event::postPersist,
                    $document,
                    new LifecycleEventArgs($document, $this->dm),
                    $invoke
                );
            }
        }

        $this->documentChangesets = array_merge($this->documentChangesets, $associationChangesets);

        $this->executeUpdates($associationUpdates, false);
    }
615079
public function remove($documents)
    {
        if (!is_array($documents)) {
            $documents = array($documents);
        }

        $remove =& Archive::getByRef($this, 'remove', array());
        foreach ($documents as $document) {
            $remove[] = $document;
        }
    }
366985
public function setDocument($document)
	{
		if (is_string($document)) {
			$this->document = $document;
		} else if (is_resource($document)) {
			$this->addMultipart("document", $document);
			$this->document = "attach://document";
		} else if ($document instanceof InputFile) {
			$this->addMultipart("document", $document->getFile());
			$this->document = "attach://document";
		}
	}