Sylius Stack
  • Sylius Stack Documentation
  • Getting started
  • Cookbook
    • How to customize your admin panel
      • Basic operations
      • Customizing your grids
      • Customizing the logo
      • Customizing the menu
      • Configuring the security access
      • Customizing the page titles
    • How to use in a DDD architecture
      • Architecture overview
      • Resource configuration
      • Basic operations
      • Operation using a grid
  • Admin UI
    • Getting started
  • Bootstrap Admin UI
    • Getting started
  • Resource
    • Resource Bundle documentation
      • Installation
      • Create new resource
      • Configure your resource
      • Configure your operations
      • Validation
      • Redirect
      • Resource factories
      • Providers
      • Processors
      • Responders
      • Legacy Resource Documentation
        • Configuration
        • Services
        • Routing
        • Forms
        • Getting a Single Resource
        • Getting a Collection of Resources
        • Creating Resources
        • Updating Resources
        • Deleting Resources
        • Configuring a state machine
        • Configuration Reference
  • Grid
    • Grid Bundle documentation
      • Installation
      • Creating your first grid
      • Configuring Fields
      • Field types
      • Creating a custom Field Type
      • Creating a custom Action
      • Creating a custom Bulk Action
      • Filters
      • Creating a custom Filter
      • Advanced configuration
      • Configuration Reference
  • 🍀Twig Extra
    • Getting started
  • 🌱Twig Hooks
    • Getting started
    • Passing data to your hookables
    • Making your hookables configurable
    • Autoprefixing feature
    • Composable Layouts with a predictable structure
    • Advanced
      • Ergonomic work with hooks
      • Metadata objects
      • Multiple hooks inside a single template
      • Overriding hookables
Powered by GitBook
On this page
  • Default providers
  • Custom repository method
  • Custom repository arguments
  • Custom providers
  • Disable providing data
  1. Resource
  2. Resource Bundle documentation

Providers

PreviousResource factoriesNextProcessors

Last updated 1 month ago

Providers retrieve data from your persistence layer.

Default providers

When your resource is a Doctrine entity, there's a default provider Sylius\Component\Resource\Symfony\Request\State\Provider which is already configured to your operations.

As it uses the Doctrine repository configured on your resource, some default repository methods are used.

Operation
Repository method

index

createPaginator

show

findOneBy

update

findOneBy

delete

findOneBy

bulk delete

findById

Custom repository method

You can customize the method to use.

src/Entity/Customer.php

declare(strict_types=1);

namespace App\Entity;

use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Show;
use Sylius\Resource\Model\ResourceInterface;

#[AsResource(
    operations: [
        new Show(
            repositoryMethod: 'findOneByEmail',
        ),
    ],
)
final class Customer implements ResourceInterface
{
    // [...]
}

Custom repository arguments

You can pass arguments to your repository method.

3 variables are available:

  • request: to retrieve data from the request via Symfony\Component\HttpFoundation\Request

  • token: to retrieve data from the authentication token via Symfony\Component\Security\Core\Authentication\Token\TokenInterface

  • user: to retrieve data from the logged-in user via Symfony\Component\Security\Core\User\UserInterface

src/Entity/Customer.php

declare(strict_types=1);

namespace App\Entity;

use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Show;
use Sylius\Resource\Model\ResourceInterface;

#[AsResource(
    operations: [
        new Show(
            repositoryMethod: 'findOneByEmail', 
            repositoryArguments: ['email' => "request.attributes.get('email')"],
        ),
    ],
)
final class Customer implements ResourceInterface
{
    // [...]
}

Custom providers

Custom providers are useful to customize your logic to retrieve data and for an advanced usage such as an hexagonal architecture.

As an example, let's configure a BoardGameItemProvider on a BoardGameResource which is not a Doctrine entity.

src/BoardGameBlog/Infrastructure/Sylius/State/Provider/BoardGameItemProvider.php

declare(strict_types=1);

namespace App\BoardGameBlog\Infrastructure\Sylius\State\Provider;

use Sylius\Resource\State\ProviderInterface;

final class BoardGameItemProvider implements ProviderInterface
{
    public function __construct(
        private QueryBusInterface $queryBus,
    ) {
    }

    public function provide(Operation $operation, Context $context): object|array|null
    {
        $request = $context->get(RequestOption::class)?->request();
        Assert::notNull($request);

        $id = (string) $request->attributes->get('id');

        $model = $this->queryBus->ask(new FindBoardGameQuery(new BoardGameId(Uuid::fromString($id))));

        return null !== $model ? BoardGameResource::fromModel($model) : null;
    }
}

Use this provider on your operation.

src/BoardGameBlog/Infrastructure/Sylius/Resource/BoardGameResource.php

declare(strict_types=1);

namespace App\BoardGameBlog\Infrastructure\Sylius\Resource;

use App\BoardGameBlog\Infrastructure\Sylius\State\Provider\BoardGameItemProvider;
use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Show;
use Sylius\Resource\Model\ResourceInterface;

#[AsResource(
    operations: [
        new Show(
            provider: BoardGameItemProvider::class, 
        ),
    ],
)
final class BoardGameResource implements ResourceInterface
{
    // [...]
}

Disable providing data

In some cases, you may want not to read data.

For example, in a delete operation, you can implement your custom delete processor without reading it before.

src/BoardGameBlog/Infrastructure/Sylius/Resource/BoardGameResource.php

declare(strict_types=1);

namespace App\BoardGameBlog\Infrastructure\Sylius\Resource;

use App\BoardgameBlog\Infrastructure\Sylius\State\Provider\DeleteBoardGameProcessor;
use Sylius\Resource\Metadata\AsResource;
use Sylius\Resource\Metadata\Delete;
use Sylius\Resource\Model\ResourceInterface;

#[AsResource(
    operations: [
        new Delete(
            processor: DeleteBoardGameProcessor::class,
            read: false,
        ),
    ],
)
final class BoardGameResource implements ResourceInterface
{
    // [...]
}
src/BoardGameBlog/Infrastructure/Sylius/State/Processor/DeleteBoardGameProcessor.php

namespace App\BoardGameBlog\Infrastructure\Sylius\State\Processor;

use App\BoardGameBlog\Application\Command\DeleteBoardGameCommand;
use App\BoardGameBlog\Domain\ValueObject\BoardGameId;
use App\BoardGameBlog\Infrastructure\Sylius\Resource\BoardGameResource;
use App\Shared\Application\Command\CommandBusInterface;
use Sylius\Resource\Context\Context;
use Sylius\Resource\Context\Option\RequestOption;
use Sylius\Resource\Metadata\Operation;
use Sylius\Resource\State\ProcessorInterface;
use Webmozart\Assert\Assert;

final class DeleteBoardGameProcessor implements ProcessorInterface
{
    public function __construct(
        private CommandBusInterface $commandBus,
    ) {
    }

    public function process(mixed $data, Operation $operation, Context $context): mixed
    {
        Assert::isInstanceOf($data, BoardGameResource::class);
        
        // Data is not provided in this case, so you will need to get it from the HTTP request
        $id = $context->get(RequestOption::class)?->attributes->get('id') ?? null;
        Assert::notNull($id);

        $this->commandBus->dispatch(new DeleteBoardGameCommand(new BoardGameId($id)));

        return null;
    }
}

It uses the component.

Symfony expression language
Default providers
Custom repository method
Custom repository arguments
Custom providers
Disable providing data