Sylius — внедрение сервисов в репозитории ресурсов

#symfony #dependency-injection #sylius

#symfony #внедрение зависимостей #sylius

Вопрос:

Я хочу добавить функцию AdminUser , чтобы администратор мог видеть только продукты / заказы и т. Д., Которые доступны в определенных каналах. Цель состоит в том, чтобы иметь интерфейс администратора и использовать sylius в качестве платформы с несколькими магазинами для разных клиентов с разными магазинами.

Что я сделал до сих пор:

  • Я создал пользовательский репозиторий ресурсов для продуктов, который переопределяет createListQueryBuilder метод (и, конечно, зарегистрировал его _sylius.yaml ).

  • Поскольку мне нужна служба безопасности symfonys, а автозапуск, похоже, не работает для дополнительных параметров в конструкторе репозитория, я создал CompilerPass , который добавляет вызов метода для установки службы безопасности (код ниже).

Проблема:

Служба устанавливается в репозитории, но когда createListQueryBuilder метод вызывается, он null снова запускается, поэтому нет способа отфильтровать пользователя.

Похоже, что во время вызова используется другой экземпляр класса репозитория (spl_object_hash возвращает разные значения при setSecurity вызове, чем при createListQueryBuilder вызове).

Я чего-то не хватает или есть какой-либо другой более простой способ добавить эту функцию?

Версия Sylius 1.8.0

Код:

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)]);
        }
    }
}
  

Пользовательское местоположение продукта

 

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

        ...
    }
}
  

Комментарии:

1. Вы следовали этому руководству: docs.sylius.com/en/latest/customization/repository.html ?

Ответ №1:


Или вы можете удалить зависимость от безопасности на уровне репозитория и создать уровень безопасности над репозиторием.

Комментарии:

1. Это не ответ. Пожалуйста, подумайте о том, чтобы оставить комментарий вместо этого.