Magento 2 Experten — Hyvä Theme, Tailwind CSS & SEO aus einer Hand ›

Filtering Collections by User

Filtering Collections by User

~14 Min. Lesezeit Zuletzt aktualisiert am August 8, 2026

Chapter 53 secured INDIVIDUAL projects – but GET /api/projects STILL shows ALL projects from ALL users. A state provider FILTERS the collection ITSELF.

Demonstrating the problem

curl -k https://localhost/api/projects -H "Authorization: Bearer $TOKEN"

Returns ALL 45 test projects, REGARDLESS of who owns them – the voter from chapters 52-53 only affects INDIVIDUAL item operations, NOT the collection query ITSELF.

Writing a custom collection provider

api/src/State/OwnProjectsCollectionProvider.php
<?php

declare(strict_types=1);

namespace App\State;

use ApiPlatform\Metadata\Operation;
use ApiPlatform\State\ProviderInterface;
use App\Entity\User;
use App\Repository\ProjectRepository;
use Symfony\Bundle\SecurityBundle\Security;

final class OwnProjectsCollectionProvider implements ProviderInterface
{
    public function __construct(
        private readonly ProjectRepository $projectRepository,
        private readonly Security $security,
    ) {
    }

    public function provide(Operation $operation, array $uriVariables = [], array $context = []): iterable
    {
        $user = $this->security->getUser();

        if (!$user instanceof User) {
            return [];
        }

        if (\in_array('ROLE_ADMIN', $user->getRoles(), true)) {
            return $this->projectRepository->findAll();
        }

        return $this->projectRepository->findBy(['owner' => $user]);
    }
}

The state provider REPLACES the DEFAULT Doctrine query ENTIRELY – UNLIKE the processor from chapter 48/54 (which WRAPS the DEFAULT flow), a fully REPLACING provider has to take over the database query ITSELF.

use App\State\OwnProjectsCollectionProvider;

new GetCollection(provider: OwnProjectsCollectionProvider::class),

Achtung: This SIMPLE provider loses the pagination/filter/sorting from block 4 – in a REAL project it would need to evaluate the query parameters ITSELF or (BETTER) use a QueryBuilder instead of findBy() and PASS IT ON to the DEFAULT provider. For THIS learning example, the simplification stays DELIBERATELY as is; block 7 covers state providers in depth.

Testing the behavior

Create TWO different users (chapter 49), have EACH create a project (chapter 54 sets owner automatically), then compare GET /api/projects with BOTH tokens – EACH user sees ONLY THEIR OWN projects.

Tipp: ROLE_ADMIN STILL sees ALL projects – EXACTLY the same pattern as in the voter from chapter 52, applied CONSISTENTLY at both the collection AND item level.