Sylius – Inject Services into Resource Repositories

I want to add a feature to AdminUser so that an admin can only see products / orders etc. that are available in specific channels. The aim is to have an admin interface and use sylius as a multishop platform for different clients with different shops.

What I did so far:

  • I created a custom resource repository for products that overrides the createListQueryBuilder method (and registered it in _sylius.yaml of course).

  • Since I need symfonys security service and autowiring seems not to work for additional parameters in the repository constructor, I created a CompilerPass that adds a method call to set the security service (code below).

Problem:

The service gets set in the repository, but when the createListQueryBuilder method gets called it is null again – so there is not way to filter user specific.

It seems that during the call another instance of the repository class is used (spl_object_hash returns different values when setSecurity is called than when createListQueryBuilder is called).

Am I something missing or is there any other more sylius-way to add this feature?

Sylius Version 1.8.0

Code:

ProductRepositoryCompilerPass


namespace AppDependencyInjection;

use SymfonyComponentDependencyInjectionCompilerCompilerPassInterface;
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentDependencyInjectionReference;
use SymfonyComponentSecurityCoreSecurity;

/**
 * Class ProductRepositoryCompilerPass
 *
 * This class injects the security service into the product repository for filtering.
 * @package AppDependencyInjection
 */
class ProductRepositoryCompilerPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if($container->hasDefinition('sylius.repository.product')) {
            $definition = $container->getDefinition('sylius.repository.product');
            $definition->addMethodCall('setSecurity', [new Reference(Security::class)]);
        }
    }
}

Custom ProductRepository



namespace AppRepositoryProduct;


use DoctrineORMEntityManager;
use DoctrineORMEntityManagerInterface;
use DoctrineORMMapping;
use DoctrineORMQueryBuilder;
use SymfonyComponentSecurityCoreSecurity;

class ProductRepository extends SyliusBundleCoreBundleDoctrineORMProductRepository
{
    private $security;
    public function __construct(EntityManager $entityManager, MappingClassMetadata $class)
    {
        parent::__construct($entityManager, $class);
    }

    public function setSecurity(Security $security) {
       $this->security = $security; // this gets called properly
    }

    public function createListQueryBuilder(string $locale, $taxonId = null): QueryBuilder
    {
        // $this->security is null here

        ...
    }
}

Source: Symfony Questions

Was this helpful?

0 / 0

Leave a Reply 0

Your email address will not be published. Required fields are marked *