Symfony2 - 创建一个Doctrine过滤器以选择当前用户数据

时间:2014-05-19 21:42:24

标签: php symfony doctrine-orm multi-tenant saas

我正在使用Symfony 2构建Saas / Multitenant应用程序。我创建了一个Doctrine事件订阅者来添加和更新行的所有者,创建它的用户,修改它的用户,时间戳等等

现在我需要实现某种过滤器,因此当用户登录时,他只能看到他公司的数据。我的第一个是使用Doctrine preLoad事件,但是这个事件不存在......据我所知,我必须使用Doctrine过滤器,不是吗?如果是这样,该过滤器如何访问用户数据以读取公司ID?我必须使用依赖注入注入吗?有没有标准的方法来实现我的目标?

更新 我正在寻找的是创建某种Doctrine插件/钩子,所以每次我调用从数据库中获取数据的任何函数(find,findOneBy等),我正在获取的实体实现一个特定的接口,一个额外的'AND company_id =:id'SQL序列被添加到生成的查询中,因此控制器或模型都不会从其他公司接收数据。

2 个答案:

答案 0 :(得分:5)

为此,您可以使用DoctrineFilter 来自官方文档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');
    }
}

要设置过滤器中使用的参数tenantId,您必须启用过滤器并设置参数

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

MultiTenant界面只是实体实现的东西

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

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

答案 1 :(得分:0)

在Doctrine2中过滤很简单。只需为变量分配一个过滤函数,然后通过ArrayCollection类中包含的filter()方法将该变量作为参数发送。

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

在此示例中,您必须先在list_item的类中定义一个方法belongsToSameCompanyThatEmploys($user),如果它属于用户所在的同一公司,则返回true

UPDATE您还需要指明过滤器函数应该使用局部变量用户,因为它不会因为拥有自己的范围而被使用。