Symfony2 - Create a Doctrine filter to select current user data

老子叫甜甜 提交于 2019-12-07 05:21:24

问题


I'm building a Saas / Multitenant application using Symfony 2. I've created a Doctrine event-subscriber to add and update the owner of a row, the user who created it, the user who modified it, timestamps and so.

And now I need to implement some kind of filter so when a user is logged in, he only can see data from his company. My first though was using a Doctrine preLoad event, but this event doesn't exist... As far as I know, I must use Doctrine filters, isn't it? If so, how can this filter access user data to read the company id? Must I inject it using the Dependency Injection? Is there any standard way to accomplish my goal?

UPDATE What I'm looking for is to create some kind of Doctrine plugin/hook so everytime I call any function that fetch data from the database (find, findOneBy, etc), and the entity I'm fetching implements a particular interface, an extra 'AND company_id=:id' SQL sequence is added to the generated query, so neither the controller or the model receives data from other companies.


回答1:


For this you can use a DoctrineFilter Link from official doc Doctrine2 SQL Filters

namespace Rwmt\Bundle\RwmtBundle\DoctrineFilters;

use Doctrine\ORM\Mapping\ClassMetaData,
    Doctrine\ORM\Query\Filter\SQLFilter;

class MultiTenantFilter extends SQLFilter
{
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
    {
        // Check if the entity implements the MultiTenant interface
        if (!$targetEntity->reflClass->implementsInterface('Rwmt\Bundle\RwmtBundle\Entity\MultiTenant')) {
            return "";
        }

        return $targetTableAlias.'.tenant_id = ' . $this->getParameter('tenantId');
    }
}

And to set the parameter tenantId used in the filter you must enable the filter and set the parameter

$filter = $em->getFilters()->enable('multi_tenant');
$filter->setParameter('tenantId', $tenant->getId(), 'integer');

As for the MultiTenant interface is just something for the entities to implement

namespace Rwmt\Bundle\RwmtBundle\Entity;
use Rwmt\Bundle\RwmtBundle\Entity\Tenant;

interface MultiTenant
{
    public function setTenant(Tenant $tenant);
    public function getTenant();
}



回答2:


Filtering in Doctrine2 is simple. Just assign a filter function to a variable, then send that variable as a parameter through the filter() method included in the ArrayCollection class.

$closure = function($list_item) use($user) {                                
        return $list_item->belongsToSameCompanyThatEmploys($user) === true;
};                                                         
$filtered_array_collection = $arrayYouWantToFilter->filter($closure); 

In this example, you'd have to have previously defined a method belongsToSameCompanyThatEmploys($user) in list_item's class that returns true if it belongs to the same company that the user works for.

UPDATE You need to also indicate that the filter function should use the local variable user, since it won't otherwise due to having its own scope.



来源:https://stackoverflow.com/questions/23747697/symfony2-create-a-doctrine-filter-to-select-current-user-data

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!