Получить пользователя внутри SQLFilter в Symfony 3 - PullRequest
0 голосов
/ 04 мая 2018

Я начинаю с Symfony и хочу создать мультитенантное приложение.

Я хочу автоматически фильтровать в моих SQL-запросах содержимое в соответствии с компанией принадлежности подключенного пользователя, каждый раз, когда таблица имеет ссылку на таблицу моей компании.

Я нашел способ создания фильтров, но не могу найти способ извлечь в этом фильтре информацию о компании подключенного пользователя.

Я использую FOSuser, я переопределяю его своим собственным классом User.

my config.yml

#app\config\config.yml

    doctrine:
        dbal:
           ...
        orm:
            auto_generate_proxy_classes: '%kernel.debug%'
            naming_strategy: doctrine.orm.naming_strategy.underscore
            auto_mapping: true
            filters:
                company:
                    class: 'Acme\CompanyBundle\Repository\Filters\CompanyFilter'
                    enabled: true

мой фильтр

<?php
#src\Acme\CompanyBundle\Repository\Filters\CompanyFilter.php

namespace Acme\CompanyBundle\Repository\Filters;

use Doctrine\ORM\Mapping\ClassMetaData;
use Doctrine\ORM\Query\Filter\SQLFilter;
use Acme\UserBundle\Entity\UserEntity;
use Acme\CompanyBundle\Entity\CompanyEntity;

class CompanyFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        if ($targetEntity->hasAssociation("company")) {

            // here how to get the connected user ???

            $company = $user->getCompany();
            $idCompany = $company->getId();
            return $targetTableAlias . ".company_id = '".$idCompany."'";


        }
        return "";
    }
}

заранее спасибо за помощь

1 Ответ

0 голосов
/ 04 мая 2018

Установите прослушиватель onKernelRequest, передайте ему службу хранения токенов, чтобы он определял вашего пользователя как параметр вашего SQLFilter.

Так в ваших services.yml добавьте:

services:
    on_request_listener:
        class: Acme\CompanyBundle\EventListener\OnRequestListener
        arguments: ["@doctrine.orm.entity_manager", "@security.token_storage"]
        tags:
            -
                name: kernel.event_listener
                event: kernel.request
                method: onKernelRequest

Создать слушателя:

class OnRequestListener
{
    protected $em;
    protected $tokenStorage;

    public function __construct($em, $tokenStorage)
    {
        $this->em = $em;
        $this->tokenStorage = $tokenStorage;
    }
    public function onKernelRequest(GetResponseEvent $event)
    {
        if($this->tokenStorage->getToken()) {
            $user = $this->tokenStorage->getToken()->getUser();
            $filter = $this->em->getFilters()->enable('company');
            $filter->setParameter('user', $user);
        }
    }
}

Тогда, наконец, ваш SQLFilter:

<?php
#src\Acme\CompanyBundle\Repository\Filters\CompanyFilter.php

namespace Acme\CompanyBundle\Repository\Filters;

use Doctrine\ORM\Mapping\ClassMetaData;
use Doctrine\ORM\Query\Filter\SQLFilter;
use Acme\UserBundle\Entity\UserEntity;
use Acme\CompanyBundle\Entity\CompanyEntity;

class CompanyFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        if ($targetEntity->hasAssociation("company") && $this->hasParameter('user')) {

            $user = $this->getParameter('user');

            $company = $user->getCompany();
            $idCompany = $company->getId();
            return $targetTableAlias . ".company_id = '".$idCompany."'";


        }
        return "";
    }
}
...