forceDefault()) { $this->applyDefaultOrder($queryBuilder, $params->getOrder()); return; } $orderBy = $params->getOrderBy(); if (/*$params->forbidComplexExpressions() && */$orderBy) { if ( !is_string($orderBy) || str_contains($orderBy, '.') || str_contains($orderBy, ':') ) { throw new Forbidden("Complex expressions are forbidden in 'orderBy'."); } } if ($orderBy === null) { $orderBy = $this->metadataProvider->getDefaultOrderBy($this->entityType); } if (!$orderBy) { return; } $this->applyOrder($queryBuilder, $orderBy, $params->getOrder()); } /** * @param SearchParams::ORDER_ASC|SearchParams::ORDER_DESC|null $order * @throws Error */ private function applyDefaultOrder(QueryBuilder $queryBuilder, ?string $order): void { $orderBy = $this->metadataProvider->getDefaultOrderBy($this->entityType); if (!$orderBy) { $queryBuilder->order('id', $order); return; } if (!$order) { $order = $this->metadataProvider->getDefaultOrder($this->entityType); if ($order && strtolower($order) === 'desc') { $order = SearchParams::ORDER_DESC; } else if ($order && strtolower($order) === 'asc') { $order = SearchParams::ORDER_ASC; } else if ($order !== null) { throw new Error("Bad default order."); } } /** @var SearchParams::ORDER_ASC|SearchParams::ORDER_DESC|null $order */ $this->applyOrder($queryBuilder, $orderBy, $order); } /** * @param SearchParams::ORDER_ASC|SearchParams::ORDER_DESC|null $order * @throws Error */ private function applyOrder(QueryBuilder $queryBuilder, string $orderBy, ?string $order): void { if (!$orderBy) { throw new Error("Could not apply empty order."); } if ($order === null) { $order = SearchParams::ORDER_ASC; } $hasOrderer = $this->ordererFactory->has($this->entityType, $orderBy); if ($hasOrderer) { $orderer = $this->ordererFactory->create($this->entityType, $orderBy); $orderer->apply( $queryBuilder, OrderItem::create($orderBy, $order) ); if ($order !== 'id') { $queryBuilder->order('id', $order); } return; } $resultOrderBy = $orderBy; $type = $this->metadataProvider->getFieldType($this->entityType, $orderBy); $hasItemConverter = $this->itemConverterFactory->has($this->entityType, $orderBy); if ($hasItemConverter) { $converter = $this->itemConverterFactory->create($this->entityType, $orderBy); $resultOrderBy = $this->orderListToArray( $converter->convert( OrderItem::create($orderBy, $order) ) ); } else if (in_array($type, ['link', 'file', 'image', 'linkOne'])) { $resultOrderBy .= 'Name'; } else if ($type === 'linkParent') { $resultOrderBy .= 'Type'; } else if ( /*!str_contains($orderBy, '.') && !str_contains($orderBy, ':') &&*/ !$this->metadataProvider->hasAttribute($this->entityType, $orderBy) ) { throw new Error("Order by non-existing field '{$orderBy}'."); } $orderByAttribute = null; if (!is_array($resultOrderBy)) { $orderByAttribute = $resultOrderBy; $resultOrderBy = [ [$resultOrderBy, $order] ]; } if ( $orderBy !== 'id' && ( !$orderByAttribute || !$this->metadataProvider->isAttributeParamUniqueTrue($this->entityType, $orderByAttribute) ) && $this->metadataProvider->hasAttribute($this->entityType, 'id') ) { $resultOrderBy[] = ['id', $order]; } $queryBuilder->order($resultOrderBy); } /** * @return array */ private function orderListToArray(OrderList $orderList): array { $list = []; foreach ($orderList as $order) { $list[] = [ $order->getExpression()->getValue(), $order->getDirection(), ]; } return $list; } }