Persist and flush (and clear?)

@param mixed|object|array $entities       entities to persist and flush.
@param mixed|string|bool  $clearAfterPush true to clear all or class name.

@return $this
485538
public function persistAndFlush($entities, $clearAfterPush = false)
    {
        if (0 === func_num_args()) {
            throw new \LogicException('Missing arguments');
        }

        $persists = [];
        $entities = func_get_args();
        $clearAfterPush = false;

        foreach ($entities as $entity) {
            if (true === $entity || true === is_string($entity)) {
                $clearAfterPush = $entity;

                continue;
            }

            if (true === is_array($entity)) {
                $persists = array_merge($persists, $entity);
            } else {
                $persists[] = $entity;
            }
        }

        foreach ($persists as $persist) {
            $this->getDoctrineManager()->persist($persist);
        }

        $this->getDoctrineManager()->flush();

        /* Clear after push */
        if (false !== $clearAfterPush) {
            if (true === $clearAfterPush) {
                $this->getDoctrineManager()->clear();

                return $this;
            }

            $this->getDoctrineManager()->clear($clearAfterPush);
        }

        return $this;
    }
306084
public function updateNodes(array $nodes, $flush = true)
    {
        foreach ($nodes as $node) {
            $node->setSiterootId($this->siterootId);

            $this->entityManager->persist($node);
        }

        if ($flush) {
            $this->entityManager->flush();
        }

        return $this;
    }
187438
public function upsert($entities)
    {
        if($entities instanceof Entity) {
            $entities = [$entities];
        }
        $this->obj_gateway
            ->withSchema($this->obj_schema)
            ->withTransaction($this->consumeTransaction())
            ->putMulti($entities);
    }
1101753
public function commit($entity = null)
    {
        if ($this->evm->hasListeners(Events::preFlush)) {
            $this->evm->dispatchEvent(Events::preFlush, new Event\PreFlushEventArgs($this->sm));
        }

        //TODO: single/array entity commit handling
        $this->commitRemoved();
        $this->commitPersisted();

        //Force refresh of updated indexes
        if ($entity === true) {
            $client = $this->sm->getClient();
            foreach (array_unique($this->updatedIndexes) as $index) {
                $client->refreshIndex($index);
            }
        }

        $this->clear();

        if ($this->evm->hasListeners(Events::postFlush)) {
            $this->evm->dispatchEvent(Events::postFlush, new Event\PostFlushEventArgs($this->sm));
        }
    }
1354358
public function onFlush(OnFlushEventArgs $eventArgs)
    {
        $em = $eventArgs->getEntityManager();
        $uow = $em->getUnitOfWork();

        foreach ($uow->getScheduledEntityInsertions() as $entity) {
            if ($entity instanceof FileInterface){
                $this->populateMeta($em, $uow, $entity);
                $this->scheduledForCopyFiles[spl_object_hash($entity)] = $entity;
            }
        }

        foreach ($uow->getScheduledEntityUpdates() as $entity) {

            if ($entity instanceof FileInterface){

                if ($this->versionEnabled){
                    $em->lock($entity, LockMode::OPTIMISTIC, $entity->getCurrentVersion());
                }
                
                if (true === $entity->isScheduledForDeletion()){
                    $uow->scheduleForDelete($entity);
                    continue;
                }
                
                $changeSet = $uow->getEntityChangeSet($entity);

                if (isset($changeSet['name'])){
                    // remove old file
                    $clonedEntity = clone $entity;
                    $clonedEntity->setName($changeSet['name'][0]);
                    $this->scheduledForDeleteFiles[spl_object_hash($clonedEntity)] = $clonedEntity;
                    $this->scheduledForCopyFiles[spl_object_hash($entity)] = $entity;
                    $this->checksum($entity);
                } 

                if(isset($changeSet['name']) || isset($changeSet['hash'])){
                    $this->populateMeta($em, $uow, $entity);
                }                
            }
        }

        foreach ($uow->getScheduledEntityDeletions() as $entity) {
            if ($entity instanceof FileInterface){
                $this->scheduledForDeleteFiles[spl_object_hash($entity)] = $entity;
            }
        }
    }
427746
public function save($entity)
    {
        $this
            ->objectManager
            ->persist($entity);

        $this
            ->objectManager
            ->flush($entity);
    }
374962
public function onFlush($args)
    {
        if (!$this->isDirty) {
            /** @var $em \Doctrine\ORM\EntityManager */
            $em = $args->getEntityManager();

            /** @var $uow \Doctrine\ORM\UnitOfWork */
            $uow = $em->getUnitOfWork();

            $array = array(
                $uow->getScheduledEntityUpdates(),
                $uow->getScheduledEntityDeletions(),
                $uow->getScheduledEntityInsertions(),
                $uow->getScheduledCollectionUpdates(),
                $uow->getScheduledCollectionDeletions(),
                $uow->getScheduledCollectionDeletions(),
                $uow->getScheduledCollectionUpdates()
            );

            foreach ($array as $obj) {
                foreach ($obj as $element) {
                    if ($element instanceof Entity\Message
                     || $element instanceof Entity\MessageTranslation
                    ) {
                        $this->isDirty = true;
                        break 2;
                    }
                }
            }
        }

        $this->flushCache();
    }
183437
public function deleteAndFlush($entity, $entityManager = null)
    {
        $entityManager = $this->getEntityManager($entityManager);

        $entityManager->remove($entity);
        $entityManager->flush($entity);
    }
272220
protected function persist($entity)
    {
        $manager = $this->getDoctrine()->getManager();
        $manager->persist($entity);
        $manager->flush();
    }
546413
public function saveEntity($entity, $flush = true)
    {
        $this->preSaveEntity($entity);

        $this->getEntityManager()->persist($entity);

        if ($flush) {
            $this->getEntityManager()->flush($entity);
        }

        // Get updated fields, and include changes so that we have everything.
        $fields  = $entity->getUpdatedFields();
        $changes = [];
        if (method_exists($entity, 'getChanges')) {
            $changes = $entity->getChanges();

            // remove the fields that are part of changes as they were already saved via a setter
            $fields = array_diff_key($fields, $changes);
        }

        // Get Extended Fields to separate from standard Update statement.
        $extendedFields = [];
        $fieldList      = $this->getCustomFieldList('lead');
        foreach ($fields as $alias => $value) {
            if (in_array($fieldList[0][$alias]['object'], ['extendedField', 'extendedFieldSecure'])) {
                // Depends on object added by alteration in organizeFieldsByGroup.
                $extendedFields[$alias]['object'] = $fieldList[0][$alias]['object'];
                $extendedFields[$alias]['id']     = $fieldList[0][$alias]['id'];
                $extendedFields[$alias]['type']   = $fieldList[0][$alias]['type'];
                $extendedFields[$alias]['alias']  = $alias;
                $extendedFields[$alias]['value']  = $value;
                unset($fields[$alias]);
            }
        }

        $this->prepareDbalFieldsForSave($fields);

        // Save standard/core fields (same as core).
        if (!empty($fields)) {
            $table = $this->getEntityManager()->getClassMetadata($this->getClassName())->getTableName();
            $this->getEntityManager()->getConnection()->update($table, $fields, ['id' => $entity->getId()]);
        }

        // Now to update extended fields if there were any to be updated.
        if (!empty($extendedFields)) {
            $insertUpdates = $deletions = [];
            $leadId        = $entity->getId();
            /** @var \Doctrine\DBAL\Connection $connection */
            $connection = $this->getEntityManager()->getConnection();
            foreach ($extendedFields as $extendedField) {
                if (
                    !isset($changes['fields'])
                    || !isset($changes['fields'][$extendedField['alias']])
                ) {
                    // No change to this extended field detected.
                    continue;
                }
                $schema  = $this->leadFieldModel->getSchemaDefinition($extendedField['alias'], $extendedField['type']);
                $columns = [
                    'value' => $extendedField['value'],
                ];
                // Corrects boolean field values, nothing more at this point.
                $this->prepareDbalFieldsForSave($columns);
                $secure    = 'extendedFieldSecure' === $extendedField['object'] ? '_secure' : '';
                $tableName = MAUTIC_TABLE_PREFIX.'lead_fields_leads_'.$schema['type'].$secure.'_xref';

                if (
                    null !== $changes['fields'][$extendedField['alias']][0]
                    && null === $changes['fields'][$extendedField['alias']][1]
                ) {
                    // Removed an existing value.
                    $connection->delete(
                        $tableName,
                        [
                            'lead_id'       => $leadId,
                            'lead_field_id' => $extendedField['id'],
                        ]
                    );
                } else {
                    // Mark for insert/update.
                    if (!isset($insertUpdates[$tableName])) {
                        $insertUpdates[$tableName] = [];
                    }
                    if (!isset($insertUpdates[$tableName][$extendedField['id']])) {
                        $insertUpdates[$tableName][$extendedField['id']] = $columns['value'];
                    }
                }
            }
            // Handle inserts/updates in bulk by table.
            if ($insertUpdates) {
                foreach ($insertUpdates as $tableName => $leadField) {
                    $rows = $params = [];
                    foreach ($leadField as $leadFieldId => $value) {
                        $key          = $tableName.$leadFieldId;
                        $rows[]       = $leadId.', '.$leadFieldId.', :'.$key;
                        $params[$key] = $value;
                    }
                    $sql  = 'INSERT INTO '.$tableName.' (`lead_id`, `lead_field_id`, `value`) '.
                        'VALUES ('.implode('),(', $rows).') '.
                        'ON DUPLICATE KEY UPDATE `value`=VALUES(`value`);';
                    $stmt = $connection->prepare($sql);
                    $stmt->execute($params);
                }
            }
        }

        $this->postSaveEntity($entity);
    }
666570
public function flush($resetAfterwards = true)
    {
        if ($this->writer instanceof Writers\FlushableInterface) {
            return $this->writer->flush($resetAfterwards);
        } else {
            throw new \Exception('Flushing a non FlushableInterface is not possible');
        }
    }
1238351
public static function clearAfter($what)
    {
        $cache = new static;

        switch ($what) {
            case 'userDelete':
                $cache->delete('forum.latestposts');
                // no break
            case 'activate':
                $cache->delete('members.fieldlist');
                $cache->delete('forum.memberscount');
                break;
            case 'categoryDelete':
            case 'forumDelete':
            case 'threadDelete':
            case 'postDelete':
                $cache->delete('forum.threadscount');
                $cache->delete('forum.postscount');
                $cache->delete('user.threadscount');
                $cache->delete('user.postscount');
                $cache->delete('forum.latestposts');
                break;
            case 'threadMove':
            case 'postMove':
                $cache->delete('forum.threadscount');
                $cache->delete('forum.postscount');
                $cache->delete('forum.latestposts');
                break;
            case 'newThread':
                $cache->delete('forum.threadscount');
                $cache->deleteElement('user.threadscount', User::loggedId());
                // no break
            case 'newPost':
                $cache->delete('forum.postscount');
                $cache->delete('forum.latestposts');
                $cache->deleteElement('user.postscount', User::loggedId());
                break;
        }
    }
338480
public function postFlush(PostFlushEventArgs $event)
    {
        $em = $event->getEntityManager();
        $valueCount = \count($this->valuesToPersist);
        foreach ($this->valuesToPersist as $value) {
            $em->persist($value);
        }
        $this->valuesToPersist = [];
        if ($valueCount > 0) {
            $em->flush();
        }
    }
501029
public function flush()
    {
        $em = $this->entityManager;
        $em->flush();
        $em->clear();

        $this->referenceRepository = null;

        $cacheDriver = $em->getMetadataFactory()->getCacheDriver();

        if ($cacheDriver) {
            $cacheDriver->deleteAll();
        }
    }
209080
public function clear($entityName = null)
    {
        $this->unitOfWork->clear();

        $this->unitOfWork = new UnitOfWork($this);

        if ($this->eventManager->hasListeners(Events::onClear)) {
            $this->eventManager->dispatchEvent(Events::onClear, new Event\OnClearEventArgs($this));
        }
    }
479209
public function persist(Entity $entity)
    {
        $this->checkEntityType($entity);

        $this->events->invokeCallbacks(Events::EVENT_BEFORE_PERSIST, $entity);
        if ($entity->isDetached()) {
            $entity->makeAlive($this->entityFactory, $this->connection, $this->mapper);
            $this->events->invokeCallbacks(Events::EVENT_BEFORE_CREATE, $entity);
            $result = $id = $this->insertIntoDatabase($entity);
            $entity->attach($id);
            $this->events->invokeCallbacks(Events::EVENT_AFTER_CREATE, $entity);
        } else {
            if ($entity->isModified()) {
                $this->events->invokeCallbacks(Events::EVENT_BEFORE_UPDATE, $entity);
                $result = $this->updateInDatabase($entity);
                $this->events->invokeCallbacks(Events::EVENT_AFTER_UPDATE, $entity);
            }
            $this->persistHasManyChanges($entity);
            $entity->markAsUpdated();
        }
        $this->events->invokeCallbacks(Events::EVENT_AFTER_PERSIST, $entity);

        return isset($result) ? $result : null;
    }
54643
public function delete($entity, $flush = true)
    {
        $this->getEntityManager()->remove($entity);

        if ($flush) {
            $this->getEntityManager()->flush();
        }
        return $this;
    }