Add Families aggregation.

@param string $filterName
@param string $field
@param int    $applicationType
@param array  $aggregationSort
@param int    $limit

@return Query
504662
public function aggregateBy(
        string $filterName,
        string $field,
        int $applicationType,
        array $aggregationSort = Aggregation::SORT_BY_COUNT_DESC,
        int $limit = Aggregation::NO_LIMIT
    ): self {
        $this->aggregations[$filterName] = Aggregation::create(
            $filterName,
            Item::getPathByField($field),
            $applicationType,
            Filter::TYPE_FIELD,
            [],
            $aggregationSort,
            $limit
        );

        return $this;
    }
595640
public function filterBy(array $criteria, array $orderBy = null, $limit = null, $offset = null, CompositeExpression $externalExpression = null)
    {
        $qb = $this->repository->createQueryBuilder('user')->distinct(true)
            ->leftJoin('user.contact', 'contact')
            ->leftJoin('contact.addresses', 'address')
            ->andWhere('address.type = :addressType')
            ->setParameter('addressType', 'main');

        if (array_key_exists('search', $criteria)) {
            $qb->andWhere('user.username like :searchLike or address.firstName like :searchLike or address.lastName like :searchLike or user.id=:search');
            $qb->setParameter('search', $criteria['search']);
            $qb->setParameter('searchLike', '%'.$criteria['search'].'%');
        }

        if (is_array($orderBy)) {
            foreach ($orderBy as $key => $value) {
                if ($key === 'id') {
                    $key = 'user.id';
                }
                $qb->orderBy($key, $value);
            }
        }

        $query = $qb->getQuery();
        $arrayResult = $query->getResult();
        $count = count($arrayResult);

        if ($offset === null) {
            $offset = 0;
        }

        if ($offset || $limit) {
            $arrayResult = array_slice($arrayResult, $offset, $limit);
        }

        $result = new FilterResult($arrayResult);
        $result->setCount($count);

        return $result;
    }
303741
protected function processOperatorFilter(Criteria $criteria, $field, $value)
    {
        if (is_array($value) && isset($value['operator']) && array_key_exists('value', $value)) {
            $operator = $value['operator'];

            if (!method_exists($criteria->expr(), $operator)) {
                throw RestException::createFilterError(['field' => $field, 'filter' => $value], 'Unknown operator.');
            }

            $criteria->andWhere(
                $criteria->expr()->$operator($field, $value['value'])
            );
        }

        return $this;
    }
733355
private function prepareAggregations(array $searchResponse, AggregationFactory $aggregationFactory)
    {
        $aggregations = [];

        if (isset($searchResponse['aggregations'])) {
            $aggregations = $searchResponse['aggregations'];
        }

        $this->aggregations = $aggregationFactory->create($aggregations);
    }
301122
public function getResult(Builder $aggregationBuilder, string $resourceClass, string $operationName = null, array $context = [])
    {
        $manager = $this->managerRegistry->getManagerForClass($resourceClass);
        if (!$manager instanceof DocumentManager) {
            throw new RuntimeException(sprintf('The manager for "%s" must be an instance of "%s".', $resourceClass, DocumentManager::class));
        }

        return new Paginator($aggregationBuilder->execute(), $manager->getUnitOfWork(), $resourceClass, $aggregationBuilder->getPipeline());
    }
409304
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        $criteria = array_merge($criteria, array("deleted" => false));

        return parent::findBy($criteria, $orderBy, $limit, $offset);
    }
340421
private function addFollowingActions($logAggregator, &$report, $idaction, $actionType, $limitBeforeGrouping, $includeLoops = false)
    {
        $data = $this->queryFollowingActions(
            $idaction, $actionType, $logAggregator, $limitBeforeGrouping, $includeLoops);

        foreach ($data as $tableName => $table) {
            $report[$tableName] = $table;
        }
    }
88147
public function Applications($Filter = '', $ApplicationName = '', $TransientKey = '') {
      $this->Permission('Garden.Settings.Manage');
      
      // Page setup
      $this->AddJsFile('addons.js');
      $this->AddJsFile('applications.js');
      $this->Title(T('Applications'));
      $this->AddSideMenu('dashboard/settings/applications');
      
      // Validate & set parameters
      $Session = Gdn::Session();
      $ApplicationName = $Session->ValidateTransientKey($TransientKey) ? $ApplicationName : '';
      if (!in_array($Filter, array('enabled', 'disabled')))
         $Filter = 'all';
      $this->Filter = $Filter;
      $AuthenticatedPostBack = $this->Form->AuthenticatedPostBack();      
      
      $ApplicationManager = new Gdn_ApplicationManager();
      $this->AvailableApplications = $ApplicationManager->AvailableVisibleApplications();
      $this->EnabledApplications = $ApplicationManager->EnabledVisibleApplications();
      
      if ($ApplicationName != '') {
         $this->EventArguments['ApplicationName'] = $ApplicationName;
         if (array_key_exists($ApplicationName, $this->EnabledApplications) === TRUE) {
            try {
               $ApplicationManager->DisableApplication($ApplicationName);
               Gdn_LibraryMap::ClearCache();
               $this->FireEvent('AfterDisableApplication');
            } catch (Exception $e) {
               $this->Form->AddError(strip_tags($e->getMessage()));
            }
         } else {
            try {
               $ApplicationManager->CheckRequirements($ApplicationName);
            } catch (Exception $e) {
               $this->Form->AddError(strip_tags($e->getMessage()));
            }
            if ($this->Form->ErrorCount() == 0) {
               $Validation = new Gdn_Validation();
               $ApplicationManager->RegisterPermissions($ApplicationName, $Validation);
               $ApplicationManager->EnableApplication($ApplicationName, $Validation);
               Gdn_LibraryMap::ClearCache();
               $this->Form->SetValidationResults($Validation->Results());
               
               $this->EventArguments['Validation'] = $Validation;
               $this->FireEvent('AfterEnableApplication');
            }
            
         }
         if ($this->Form->ErrorCount() == 0)
            Redirect('settings/applications/'.$this->Filter);
      }
      $this->Render();
   }
553384
protected function appendFilterDefinition(NodeBuilder $filterDefinition): void
    {
        $fieldDefinition = $filterDefinition
            ->scalarNode('provider')->isRequired()->end()
            ->integerNode('results_per_page')->defaultValue(15)->end()
            ->arrayNode('sortable')
                ->prototype('scalar')->end()
            ->end()
            ->arrayNode('default_sort')
                ->prototype('scalar')->defaultValue([])->end()
            ->end()
            ->variableNode('options')
                ->defaultValue([])
                ->validate()
                    ->ifTrue(function ($value) {
                        return !\is_array($value) && null !== $value;
                    })
                    ->thenInvalid('"options" configuration must be an array or left empty')
                ->end()
            ->end()
            ->arrayNode('filters')
                ->prototype('array')
                    ->children();

        $this->appendFieldDefinition($fieldDefinition);

        $fieldDefinition->end()
                ->end()
            ->end();
    }
1332563
public function addAggregation(AbstractAggregation $abstractAggregation)
    {
        if (!$this->aggregations) {
            $this->aggregations = $this->createBuilderBag();
        }

        $this->aggregations->add($abstractAggregation);
        
        return $this;
    }
1188752
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null, $indexBy = null)
    {
        $this->checkRepository();

        $data = parent::findBy($criteria, $orderBy, $limit, $offset);

        if ($data && $indexBy) {
            $data = $this->sortCollection($data, $indexBy);
        }

        return $data;
    }
94216
public function filterUniverseByDateRange(
        string $field,
        array $values,
        int $applicationType = Filter::AT_LEAST_ONE
    ): self {
        return $this->filterUniverseByRange(
            $field,
            $values,
            $applicationType,
            Filter::TYPE_DATE_RANGE
        );
    }
668904
public function getFindByQuery(array $criteria = null, array $orderBy = null, $limit = null, $offset = null)
    {
        /** @var \Doctrine\ORM\QueryBuilder $qb */
        $qb = $this->createQueryBuilder('e');

        $firstCriteria = true;
        if (!empty($criteria)) {
            foreach ($criteria as $field => $value) {
                if ($firstCriteria) {
                    if ($value === null or $value === 'null') {
                        $qb->where("e.$field IS NULL");
                    } elseif ($value === 'not null') {
                        $qb->where("e.$field IS NOT NULL");
                    } else {
                        $qb->where("e.$field = :$field");
                        $qb->setParameter($field, $value);
                    }

                    $firstCriteria = false;
                } else {
                    if ($value === null or $value === 'null') {
                        $qb->andWhere("e.$field IS NULL");
                    } elseif ($value === 'not null') {
                        $qb->andWhere("e.$field IS NOT NULL");
                    } else {
                        $qb->andWhere("e.$field = :$field");
                        $qb->setParameter($field, $value);
                    }
                }
            }
        }

        $firstOrderBy = true;
        if (!empty($orderBy)) {
            foreach ($orderBy as $field => $value) {
                if ($firstOrderBy) {
                    $qb->orderBy("e.$field", $value);
                    $firstOrderBy = false;
                } else {
                    $qb->addOrderBy("e.$field", $value);
                }
            }
        }

        if (!empty($limit)) {
            $qb->setMaxResults($limit);
        }

        if (!empty($offset)) {
            $qb->setFirstResult($offset);
        }

        return $qb->getQuery();
    }
160607
public function findByCriteria(Criteria $criteria, $order = null, $limit = null, $offset = 0)
    {
        $qb = $this->createCriteriaQueryBuilder($criteria, 'm');

        if ($order) {
            foreach ($order as $field => $dir) {
                $qb->orderBy("m.$field", $dir);
            }
        }
        if ($limit) {
            $qb->setMaxResults($limit);
        }
        if ($offset) {
            $qb->setFirstResult($offset);
        }

        return $qb->getQuery()->getResult();
    }
1249496
public function filterUniverseBy(
        string $field,
        array $values,
        int $applicationType = Filter::AT_LEAST_ONE
    ): self {
        $fieldPath = Item::getPathByField($field);
        if (!empty($values)) {
            $this->universeFilters[$field] = Filter::create(
                $fieldPath,
                $values,
                $applicationType,
                Filter::TYPE_FIELD
            );
        } else {
            unset($this->universeFilters[$field]);
        }

        return $this;
    }
1211847
public function findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)
    {
        // Check if we have to filter or sort by an encrypted field
        if ($this->filterHasEncryptedField($criteria) || $this->orderByHasEncryptedField($orderBy)) {
            return $this->filterAndSortByEncryptedField($criteria, $orderBy, $limit, $offset);
        }
        else {
            // We can use the usual repository logic
            $entities = $this->wrapped->findBy($criteria, $orderBy, $limit, $offset);
            return $entities;
        }
    }
267881
public function aggregateByRange(
        string $filterName,
        string $field,
        array $options,
        int $applicationType,
        string $rangeType = Filter::TYPE_RANGE,
        array $aggregationSort = Aggregation::SORT_BY_COUNT_DESC,
        int $limit = Aggregation::NO_LIMIT
    ): self {
        if (empty($options)) {
            return $this;
        }

        $this->aggregations[$filterName] = Aggregation::create(
            $filterName,
            Item::getPathByField($field),
            $applicationType,
            $rangeType,
            $options,
            $aggregationSort,
            $limit
        );

        return $this;
    }