Skip to content
Snippets Groups Projects
CourseCollectionDataProvider.php 3.61 KiB
<?php

declare(strict_types=1);

namespace Dbp\Relay\BaseCourseBundle\DataProvider;

use ApiPlatform\Core\DataProvider\CollectionDataProviderInterface;
use ApiPlatform\Core\DataProvider\RestrictedDataProviderInterface;
use Dbp\Relay\BaseCourseBundle\API\CourseProviderInterface;
use Dbp\Relay\BaseCourseBundle\Entity\Course;
use Dbp\Relay\CoreBundle\LocalData\LocalData;
use Dbp\Relay\CoreBundle\Pagination\Pagination;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;

final class CourseCollectionDataProvider extends AbstractController implements CollectionDataProviderInterface, RestrictedDataProviderInterface
{
    /** @var CourseProviderInterface */
    private $courseProvider;

    public function __construct(CourseProviderInterface $courseProvider)
    {
        $this->courseProvider = $courseProvider;
    }

    public function supports(string $resourceClass, string $operationName = null, array $context = []): bool
    {
        return Course::class === $resourceClass;
    }

    public function getCollection(string $resourceClass, string $operationName = null, array $context = []): iterable
    {
        $this->denyAccessUnlessGranted('IS_AUTHENTICATED_FULLY');

        $filters = $context['filters'] ?? [];
        $options = [];
        $options['lang'] = $filters['lang'] ?? 'de';

        if ($search = ($filters['search'] ?? null)) {
            $options['search'] = $search;
        }

        if ($term = ($filters['term'] ?? null)) {
            $options['term'] = $term;
        }

        if ($includeParameter = LocalData::getIncludeParameter($filters)) {
            $options[LocalData::INCLUDE_PARAMETER_NAME] = $includeParameter;
        }

        $organizationId = $filters['organization'] ?? '';
        $lecturerId = $filters['lecturer'] ?? '';

        $filterByOrganizationId = $organizationId !== '';
        $filterByLecturerId = $lecturerId !== '';

        dump($context);

        if (!($filterByOrganizationId && $filterByLecturerId)) {
            Pagination::addPaginationOptions($options, $filters);
        } // else (both filters provided) -> request paginators holding the whole set of results since we need to intersect them

        $coursePaginator = null;
        if ($filterByOrganizationId || $filterByLecturerId) {
            if ($filterByOrganizationId) {
                $coursePaginator = $this->courseProvider->getCoursesByOrganization($organizationId, $options);
            }
            if ($filterByLecturerId) {
                $coursesByPersonPaginator = $this->courseProvider->getCoursesByLecturer($lecturerId, $options);

                if (!$filterByOrganizationId) {
                    $coursePaginator = $coursesByPersonPaginator;
                } else {
                    $intersection = array_uintersect($coursePaginator->getItems(), $coursesByPersonPaginator->getItems(),
                        'Dbp\Relay\BaseCourseBundle\DataProvider\CourseCollectionDataProvider::compareCourses');
                    $courses = array_values($intersection);
                    Pagination::addPaginationOptions($options, $filters);
                    $coursePaginator = Pagination::createWholeResultPaginator($courses, $options);
                }
            }
        } else {
            $coursePaginator = $this->courseProvider->getCourses($options);
        }

        return $coursePaginator ?? [];
    }

    public static function compareCourses(Course $a, Course $b): int
    {
        if ($a->getIdentifier() > $b->getIdentifier()) {
            return 1;
        } elseif ($a->getIdentifier() === $b->getIdentifier()) {
            return 0;
        } else {
            return -1;
        }
    }
}