2014-05-19 9 views
5

Sto costruendo un'applicazione Saas/Multitenant usando Symfony 2. Ho creato un sottoscrittore di eventi Doctrine per aggiungere e aggiornare il proprietario di una riga, l'utente che ha creato esso, l'utente che lo ha modificato, data e ora e così via.Symfony2 - Crea un filtro Doctrine per selezionare i dati utente correnti

E ora ho bisogno di implementare un qualche tipo di filtro in modo tale che quando un utente ha effettuato il login, può solo vedere i dati dalla sua azienda. Il mio primo pensiero era l'utilizzo di un evento preLoad di Doctrine, ma questo evento non esiste ... Per quanto ne so, devo usare i filtri Doctrine, non è vero? In tal caso, in che modo questo filtro può accedere ai dati dell'utente per leggere l'ID dell'azienda? Devo iniettarlo usando l'iniezione di dipendenza? C'è un modo standard per raggiungere il mio obiettivo?

UPDATE Quello che sto cercando è quello di creare una sorta di Dottrina plugin/gancio in modo ogni volta che chiamare qualsiasi funzione che recuperare i dati dal database (trovare, findOneBy, ecc), e l'entità sono recuperando implementa un'interfaccia particolare, una sequenza 'AND company_id =: id' aggiuntiva viene aggiunta alla query generata, quindi né il controller né il modello ricevono dati da altre società.

+0

forse questa risposta può aiutarti: http://stackoverflow.com/a/15809800/3059764 – ferodss

risposta

3

Per questo si può utilizzare un DoctrineFilter link da doc ufficiale 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'); 
    } 
} 

E per impostare il tenantId parametro utilizzato nel filtro è necessario abilitare il filtro e impostare il parametro

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

Per quanto riguarda l'interfaccia MultiTenant è solo qualcosa per le entità di implementare

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

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

Il filtraggio in Doctrine2 è semplice. Basta assegnare una funzione di filtro a una variabile, quindi inviare tale variabile come parametro attraverso il metodo filter() incluso nella classe ArrayCollection.

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

In questo esempio, dovreste aver già definito un metodo belongsToSameCompanyThatEmploys($user) nella classe di list_item che restituisce true se appartiene alla stessa società che l'utente lavora.

UPDATE È inoltre necessario indicare che la funzione di filtro deve utilizzare l'utente della variabile locale, poiché altrimenti non avrà il proprio ambito.

+0

Non sono sicuro che stiamo parlando dello stesso ... Ho bisogno di un filtro che altera il comando SQL prima di inviare al server (aggiungi un semplice 'AND company_id =: id'), e collega questo filtro con symfony, quindi ad ogni richiesta il filtro usa l'utente registrato corrente company_id ... – mHouses

+0

Oh capisco. In effetti stiamo parlando di cose diverse! Stavo rispondendo come filtrare dopo aver ricevuto tutte le righe. – iamdev

+0

@iamadev: questo è esattamente ciò che voglio evitare, ricevere tutte le righe e quindi filtrarle. Voglio che vengano filtrati nel motore del database, non in PHP. – mHouses

Problemi correlati