Skip to content
Snippets Groups Projects
NewsPrepareResponseService.php 3.35 KiB
Newer Older
<?php

namespace App\News\Service;

use App\News\Dto\NewsDetailElementDto;
use App\News\Dto\NewsListingElementDto;
use App\News\DtoFactory\NewsCategoryDtoFactory;
use App\News\DtoFactory\NewsDetailElementDtoFactory;
use App\News\DtoFactory\NewsFilterVariantsDtoFactory;
use App\News\DtoFactory\NewsListDtoFactory;
use App\News\DtoFactory\NewsListingElementDtoFactory;
use App\Shared\Abstraction\AbstractListDto;
use App\Shared\Abstraction\ServiceInterface;
use App\Shared\DtoFactory\PaginationDtoFactory;
use App\Shared\Error\NonValidUuidError;
use App\Shared\Error\NotFoundError;
use App\Shared\Repository\NewsCategoriesRepository;
use App\Shared\Repository\NewsRepository;
use App\Shared\Service\ValidateService;

readonly class NewsPrepareResponseService implements ServiceInterface
{
    public function __construct(
        private NewsRepository $news,
        private NewsCategoriesRepository $newsCategories,
        private PaginationDtoFactory $paginationFactory,
        private NewsListingElementDtoFactory $listFactory,
        private NewsFilterVariantsDtoFactory $filterFactory,
        private NewsListDtoFactory $listingFactory,
        private NewsCategoryDtoFactory $categoryFactory,
        private ValidateService $validate,
        private NewsDetailElementDtoFactory $detailElementFactory
    ) {
    }

    /**
     * @param int $page
     * @param int $limit
     * @param array<string>|null ...$filters
     * @return AbstractListDto
     */
    public function bornListDto(
        int $page,
        int $limit,
        ?array $filters
    ): AbstractListDto {
        $filters['news_category'] = $filters[0];
        if (!$this->validate->isValidUuid($filters['news_category'])) {
            $filters['news_category'] = null;
        }

        $this->validate->correctPagination($page, $limit);

        $countOfNews = $this->news->getCountWithFilters(
            $filters['news_category']
        );

        $pagination = $this->paginationFactory->create(
            $page,
            $limit,
            $countOfNews
        );

        $offset = min(
                $pagination->pageSize,
                $countOfNews
            ) * ($pagination->currentPage - 1);

        $list = $this->listFactory->createCollection(
            $this->news->getWithFilters(
                $filters['news_category'],
                $limit,
                $offset
            )
        );

        $filters = $this->filterFactory->create(
            $this->categoryFactory->createCollection(
                $this->newsCategories->getAll()
            )
        );

        return $this->listingFactory->create(
            $pagination,
            $list,
            $filters
        );
    }

    public function bornMainNews(): NewsListingElementDto
    {
        return $this->listFactory->create($this->news->getMainNews());
    }

    public function bornDetailMainNews(): NewsDetailElementDto
    {
        return $this->detailElementFactory->create($this->news->getMainNews());
    }

    public function bornDetailElement(string $detailId): NewsDetailElementDto
    {
        if (!$this->validate->isValidUuid($detailId)) {
            throw new NonValidUuidError();
        }

        $news = $this->news->find($detailId);

        if ($news === null) {
            throw new NotFoundError('News not found');
        }

        return $this->detailElementFactory->create($news);
    }
}