<?php
/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);
namespace Ibexa\Bundle\OrderManagement\PageBuilder\RecentOrders;
use Ibexa\Contracts\OrderManagement\OrderServiceInterface;
use Ibexa\Contracts\OrderManagement\Value\Order\OrderQuery;
use Ibexa\Contracts\OrderManagement\Value\Order\Query\Criterion\LogicalAnd;
use Ibexa\Contracts\OrderManagement\Value\Order\Query\Criterion\StatusCriterion;
use Ibexa\Contracts\OrderManagement\Value\Order\Query\CriterionInterface;
use Ibexa\Contracts\OrderManagement\Value\Order\Query\SortClause\Created;
use Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\BlockRenderEvents;
use Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\Event\PreRenderEvent;
use Ibexa\FieldTypePage\FieldType\Page\Block\Renderer\Twig\TwigRenderRequest;
use Ibexa\OrderManagement\Pagerfanta\Adapter\OrderListAdapter;
use Pagerfanta\Pagerfanta;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
final class BlockSubscriber implements EventSubscriberInterface
{
private const PAGINATION_PAGE_PARAM_PREFIX = 'recent_orders_page_';
private const PAGINATION_DEFAULT_LIMIT = 10;
private const PAGINATION_DEFAULT_CURRENT_PAGE = 1;
private const ALL_STATUSES = 'all';
private OrderServiceInterface $orderService;
private RequestStack $requestStack;
public function __construct(
OrderServiceInterface $orderService,
RequestStack $requestStack
) {
$this->orderService = $orderService;
$this->requestStack = $requestStack;
}
public static function getSubscribedEvents(): array
{
return [
BlockRenderEvents::getBlockPreRenderEventName(RecentOrdersBlock::BLOCK_IDENTIFIER) => 'onPreRender',
];
}
public function onPreRender(PreRenderEvent $event): void
{
$request = $event->getRenderRequest();
if (!$request instanceof TwigRenderRequest) {
return;
}
$block = new RecentOrdersBlock($event->getBlockValue());
$query = $this->createQuery($block);
$pagerfanta = new Pagerfanta(new OrderListAdapter($this->orderService, $query));
$pagerfanta->setCurrentPage(
$this->getCurrentPage(self::PAGINATION_PAGE_PARAM_PREFIX . $block->getId())
);
$pagerfanta->setMaxPerPage($block->getLimit() ?? self::PAGINATION_DEFAULT_LIMIT);
$request->addParameter('orders', $pagerfanta);
}
private function createQuery(RecentOrdersBlock $block): OrderQuery
{
$query = new OrderQuery($this->createCriteria($block));
$query->setSortClauses([new Created(OrderQuery::SORT_DESC)]);
return $query;
}
private function createCriteria(RecentOrdersBlock $block): ?CriterionInterface
{
$criteria = [];
$statuses = $block->getStatuses();
if (!empty($statuses) && $statuses !== [self::ALL_STATUSES]) {
$criteria[] = new StatusCriterion($statuses);
}
return empty($criteria) ? null : new LogicalAnd(...$criteria);
}
private function getCurrentPage(string $pageParam): int
{
$request = $this->requestStack->getMainRequest();
if ($request === null) {
return self::PAGINATION_DEFAULT_CURRENT_PAGE;
}
return $request->query->getInt($pageParam, self::PAGINATION_DEFAULT_CURRENT_PAGE);
}
}