@param PersistenceContext $context
@param Column[]           $modifiedColumns
@param array              $children

@return Row[]
@throws InvalidArgumentException
542721
final protected function bulkUpdateForeignKeys(PersistenceContext $context, array $modifiedColumns, array $children) : array
    {
        $primaryKey     = $this->mapper->getPrimaryTable()->getPrimaryKeyColumn();
        $primaryKeyName = $primaryKey->getName();

        $columnsToPersist = array_merge([$primaryKey], $modifiedColumns);

        $rowSet = new RowSet($this->mapper->getPrimaryTable()->withColumnsButIgnoringConstraints($columnsToPersist));
        $rows   = [];

        foreach ($children as $key => $childId) {
            if ($childId !== null) {
                $row = $rowSet->createRow([$primaryKeyName => $childId]);
                $rowSet->add($row);
                $rows[$key] = $row;
            }
        }

        if ($modifiedColumns) {
            if ($rowSet->count() > 0) {
                $context->bulkUpdate($rowSet);
            }
        }

        return $rows;
    }
1232064
private function load(array $entities, callable $queryBuilderCallback = null)
    {
        foreach ($entities as $key => $entity) {
            $hash = spl_object_hash($entity);

            if (!empty($queryBuilderCallback)) {
                /** @var callable|object $queryBuilderCallback */
                $hash .= spl_object_hash($queryBuilderCallback);
            }
            if (isset($this->processedHashes[$hash])) {
                unset($entities[$key]);

                continue;
            }

            $this->processedHashes[$hash] = true;

            $entityClass = ClassUtils::getClass($entity);

            if (!$this->customObjectsLoadable($entityClass)) {
                $message = sprintf(
                    'Class "%s" must be annotated with "%s" annotation in order to load custom objects.',
                    $entityClass,
                    CustomObject::class
                );

                throw new CustomObjectException($message);
            }
        }

        $customEntitiesMap = $this->buildCustomEntitiesMap($entities);

        $queriesMap = $this->buildQueriesMap($customEntitiesMap);

        $customEntities = $this->fetchCustomEntities($queriesMap, $queryBuilderCallback);

        $this->setCustomEntities($entities, $customEntities, $customEntitiesMap);
    }
641155
public function findHierarchiesByParentsAndChildren(User $user, array $parents, array $children)
    {
        if (count($parents) === 0 || count($children) === 0) {
            throw new \InvalidArgumentException('Array argument cannot be empty');
        }

        $parentIndex = 0;
        $eol = PHP_EOL;
        $parentsTest = '(';

        foreach ($parents as $parent) {
            $parentsTest .= $parentIndex > 0 ? '    OR ' : '    ';
            $parentsTest .= "p.id = {$parent}{$eol}";
            $parentIndex++;
        }
        $parentsTest .= "){$eol}";

        $childrenIndex = 0;
        $childrenTest = '(';

        foreach ($children as $child) {
            $childrenTest .= $childrenIndex > 0 ? '    OR ' : '    ';
            $childrenTest .= "t.id = {$child}{$eol}";
            $childrenIndex++;
        }
        $childrenTest .= "){$eol}";

        $dql = "
            SELECT h
            FROM Claroline\CoreBundle\Entity\Workspace\WorkspaceTagHierarchy h
            JOIN h.parent p
            JOIN h.tag t
            WHERE h.user = :user
            AND h.level > 0
            AND {$parentsTest}
            AND {$childrenTest}
        ";
        $query = $this->_em->createQuery($dql);
        $query->setParameter('user', $user);

        return $query->getResult();
    }
721107
protected function initItems(array $items)
    {
        foreach ($items as $k => $item) {
            if (!$item instanceof AbstractEntity) {
                throw new \InvalidArgumentException('Item ' . $k . ' is not an instance of ' . AbstractEntity::class);
            }
            $this->items[$item->getId()] = $item;
        }

        \uasort($this->items, function (AbstractEntity $item1, AbstractEntity $item2) {
            return $item1->get($this->sortField) <=> $item2->get($this->sortField);
        });

        foreach ($this->items as $item) {
            $id = $item->getId();
            $parentId = $item->get($this->parentField);
            $this->parentIds[$id] = $parentId;
            isset($this->childrenIds[$parentId])
                ? $this->childrenIds[$parentId][] = $id
                : $this->childrenIds[$parentId] = [$id];

            if (!$parentId) {
                $this->root[] = $item->getId();
            }
        }
    }
1334303
public function mapTree(array $nodes, array $mappedNodes = []) {
        if (!$mappedNodes) {
            return $nodes;
        }

        $tree = [];
        $pk = $this->getRepository()->getPrimaryKey();

        foreach ($nodes as $node) {
            $id = $node[$pk];

            if (isset($mappedNodes[$id])) {
                $node[$this->getConfig('treeField') ?: 'Nodes'] = $this->mapTree($mappedNodes[$id], $mappedNodes);
            }

            $tree[] = $node;
        }

        return $tree;
    }
610340
@Override
    public Set<IGroupMember> getChildren() throws GroupsException {

        final EntityIdentifier cacheKey = getUnderlyingEntityIdentifier();
        Element element = childrenCache.get(cacheKey);

        if (element == null) {
            final Set<IGroupMember> children = buildChildrenSet();
            element = new Element(cacheKey, children);
            childrenCache.put(element);
        }

        @SuppressWarnings("unchecked")
        final Set<IGroupMember> rslt = (Set<IGroupMember>) element.getObjectValue();
        return rslt;
    }
148757
protected function mapModelDataToElementCollection(ElementCollection $children)
    {
        foreach ($children->all() as $child) {
            $this->mapModelDataToElement($child);
        }
    }
304961
protected function preload_contexts(array $contextids) {
        global $DB;

        if (empty($contextids)) {
            return;
        }

        $ctxfields = \context_helper::get_preload_record_columns_sql('ctx');
        list($insql, $inparams) = $DB->get_in_or_equal($contextids, SQL_PARAMS_NAMED);
        $sql = "SELECT {$ctxfields} FROM {context} ctx WHERE ctx.id {$insql}";
        $contextlist = $DB->get_recordset_sql($sql, $inparams);
        foreach ($contextlist as $contextdata) {
            \context_helper::preload_from_record($contextdata);
        }
        $contextlist->close();

    }
993398
protected function addIndexes(&$properties, array $indexes, array $validColumns)
    {
        foreach ($indexes as $index) {
            if (!$index->hasColumns()) {
                continue;
            }

            $indexName = '';
            if ($index->hasName()) {
                $indexName = sprintf(", '%s'", $index->getName());
            }

            if ($index->hasMultipleColumns()) {
                $invalidColumns = array_diff($index->getColumns(), $validColumns);

                if (count($invalidColumns) > 0) {
                    throw new Exception('Non-Existing columns are being using an index. Invalid columns are "' . implode(',', $invalidColumns) . '"');
                }

                $columns = Helpers::wrapItems($index->getColumns());

                $indexColumn = sprintf('[%s]', implode(',', $columns));
            } else {
                $column = $index->getFirstColumn();

                if (!in_array($column, $validColumns)) {
                    throw new Exception('Non-Existing column is being using an index. Invalid columns is ' . $column);
                }
                $indexColumn = sprintf("'%s'", $column);
            }

            $properties .= sprintf('%s(%s%s)', $this->getPropertyBase($index->getType()), $indexColumn, $indexName);

            $this->addFieldPropertyClousure($properties);
        }

        return $this;
    }
784408
public function findAdminHierarchiesByParentsAndChildren(array $parents, array $children)
    {
        if (count($parents) === 0 || count($children) === 0) {
            throw new \InvalidArgumentException('Array argument cannot be empty');
        }

        $parentIndex = 0;
        $eol = PHP_EOL;
        $parentsTest = '(';

        foreach ($parents as $parent) {
            $parentsTest .= $parentIndex > 0 ? '    OR ' : '    ';
            $parentsTest .= "p.id = {$parent}{$eol}";
            $parentIndex++;
        }
        $parentsTest .= "){$eol}";

        $childrenIndex = 0;
        $childrenTest = '(';

        foreach ($children as $child) {
            $childrenTest .= $childrenIndex > 0 ? '    OR ' : '    ';
            $childrenTest .= "t.id = {$child}{$eol}";
            $childrenIndex++;
        }
        $childrenTest .= "){$eol}";

        $dql = "
            SELECT h
            FROM Claroline\CoreBundle\Entity\Workspace\WorkspaceTagHierarchy h
            JOIN h.parent p
            JOIN h.tag t
            WHERE h.user IS NULL
            AND h.level > 0
            AND {$parentsTest}
            AND {$childrenTest}
        ";
        $query = $this->_em->createQuery($dql);

        return $query->getResult();
    }
1276003
public function get_document_recordset($modifiedfrom = 0, \context $context = null) {
        global $DB;

        list ($contextjoin, $contextparams) = $this->get_course_level_context_restriction_sql($context, 'c', SQL_PARAMS_NAMED);
        if ($contextjoin === null) {
            return null;
        }

        $fields = course_handler::create()->get_fields();
        if (!$fields) {
            $fields = array();
        }
        list($fieldsql, $fieldparam) = $DB->get_in_or_equal(array_keys($fields), SQL_PARAMS_NAMED, 'fld', true, true);

        // Restrict recordset to CONTEXT_COURSE (since we are implementing it to core_course\search).
        $sql = "SELECT d.*
                  FROM {customfield_data} d
                  JOIN {course} c ON c.id = d.instanceid
                  JOIN {context} cnt ON cnt.instanceid = c.id
           $contextjoin
                 WHERE d.timemodified >= :modifiedfrom
                   AND cnt.contextlevel = :contextlevel
                   AND d.fieldid $fieldsql
              ORDER BY d.timemodified ASC";
        return $DB->get_recordset_sql($sql , array_merge($contextparams,
            ['modifiedfrom' => $modifiedfrom, 'contextlevel' => CONTEXT_COURSE], $fieldparam));
    }
171303
protected function loadGroupedOrderIndexes(PersistenceContext $context, array $rows)
    {
        /** @var Row[][] $groupedRows */
        $groupedRows        = [];
        $groupingValues     = [];
        $groupingColumnName = $this->groupingColumn->getName();

        foreach ($rows as $row) {
            $groupingValue = $row->getColumn($groupingColumnName);
            $groupHash     = $groupingValue instanceof \DateTimeInterface
                    ? $groupingValue->format('Y-m-d H:i:s')
                    : $groupingValue;

            $groupingValues[$groupHash] = $groupingValue;
            $groupedRows[$groupHash][]  = $row;
        }

        $groupingColumn = Expr::column($this->table->getName(), $this->groupingColumn);
        $select         = Select::from($this->table)
                ->addColumn('order_index', Expr::max(Expr::column($this->table->getName(), $this->orderColumn)))
                ->addColumn('group', $groupingColumn)
                ->where(Expr::in(
                        $groupingColumn,
                        Expr::tupleParams($this->groupingColumn->getType(), $groupingValues)
                ))
                ->addGroupBy($groupingColumn);

        $orderIndexes        = $context->getConnection()->load($select)->asArray();
        $indexedOrderIndexes = [];

        foreach ($orderIndexes as $orderIndexRow) {
            $groupHash = $orderIndexRow['group'] instanceof \DateTimeInterface
                    ? $orderIndexRow['group']->format('Y-m-d H:i:s')
                    : $orderIndexRow['group'];

            $indexedOrderIndexes[$groupHash] = $orderIndexRow['order_index'];
        }
        
        $orderColumn = $this->orderColumn->getName();

        foreach ($groupedRows as $groupHash => $rows) {
            $orderIndex = isset($indexedOrderIndexes[$groupHash])
                    ? $indexedOrderIndexes[$groupHash] + 1
                    : 1;

            foreach ($rows as $row) {
                $row->setColumn($orderColumn, $orderIndex);
                $orderIndex++;
            }
        }
    }
392167
public function applyLockingDataBeforeCommit(PersistenceContext $context, array $objects, array $rows)
    {
        $columnName = $this->columnName;

        foreach ($rows as $row) {
            $currentVersion = $row->getColumn($columnName);
            $row->setColumn($columnName, $currentVersion + 1);

            if ($row->hasPrimaryKey()) {
                $row->setLockingColumn($columnName, $currentVersion);
            }
        }
    }
37359
public function doSerialize(
        JsonSerializationVisitor $visitor,
        ChildrenCollection $childrenCollection,
        array $type,
        Context $context
    ) {
        $array = $childrenCollection->toArray();

        return $context->accept($array);
    }
1293920
protected function loadOrderIndexes(PersistenceContext $context, array $rows)
    {
        $select = Select::from($this->table)
                ->addColumn('order_index', Expr::max(Expr::column($this->table->getName(), $this->orderColumn)));

        $orderIndexRows = $context->getConnection()->load($select)->asArray();

        $orderIndex = isset($orderIndexRows[0]['order_index'])
                ? $orderIndexRows[0]['order_index'] + 1
                : 1;

        $orderColumn = $this->orderColumn->getName();
        foreach ($rows as $row) {
            $row->setColumn($orderColumn, $orderIndex);
            $orderIndex++;
        }
    }
1253189
protected function insertRelated(PersistenceContext $context, ParentChildrenMap $map)
    {
        $primaryKey = $map->getPrimaryKeyColumn();
        /** @var Row[] $parents */
        $parents = [];
        /** @var object[] $children */
        $children          = [];
        $childRows         = [];
        $childKeyParentMap = [];

        foreach ($map->getItems() as $key => $item) {
            $parents[$key] = $item->getParent();

            foreach ($item->getChildren() as $childKey => $child) {
                $uniqueKey                     = $key . '|' . $childKey;
                $children[$uniqueKey]          = $child;
                $childKeyParentMap[$uniqueKey] = $key;
                $childRows[$uniqueKey]         = new Row($this->childrenTable);
            }
        }

        // Since all the rows are deleted then reinserted, we have to disable lazy loading
        // for all child relations as these will have been deleted via the foreign key
        // and need to be re-inserted
        $this->disableLazyLoadingForRelations(function () use ($context, $children, $childRows) {
            $this->mapper->persistAllToRows($context, $children, $childRows);
        });

        $rowGroups = [];

        foreach ($childKeyParentMap as $rowKey => $parentKey) {
            $rowGroups[$parentKey][] = $childRows[$rowKey];
        }

        foreach ($map->getItems() as $key => $item) {
            $parentRow = $item->getParent();
            $childRows = isset($rowGroups[$key]) ? $rowGroups[$key] : [];

            if ($parentRow->hasColumn($primaryKey)) {
                $this->setForeignKey($childRows, $this->foreignKeyToParent->getName(), $parentRow->getColumn($primaryKey));
            } else {
                $parentRow->onInsertPrimaryKey(function ($id) use ($childRows) {
                    $this->setForeignKey($childRows, $this->foreignKeyToParent->getName(), $id);
                });
            }
        }
    }
1312784
public function setChildren(array $children)
    {
        if (count(array_filter($children, function($v) {
            return !$v instanceof MenuItemInterface;
        })) > 0) {
            throw new InvalidChildTypeException('Child items has to implement ' . MenuItemInterface::class);
        }

        $this->children = $children;
    }