2015-05-24 15 views
5

Uso i filtri di doctrine e di recente ho notato che i filtri non vengono applicati alle istruzioni di eliminazione. Ho cercato di analizzare la documentazione e google, ma il mistero rimane irrisolto.Doctrine2 applica i filtri per eliminare le istruzioni

Per esempio io ho il filtro che si collega all'utente di società in modo che ogni query di selezione come:

$userRepo->find(12); 

e viene modificato da

SELEZIONA .... da t0 utente in cui t0.id = 12

in

SELEZIONA .... da t0 utente in cui t0.id = 12 E (t0.company_id = '6')

fresco, che è quello che mi serve.

Ciò che mi dà fastidio è che le istruzioni di cancellazione sembrano non essere toccate. Qualcuno sa se è l'architettura predefinita di dottrina o la mia configurazione è sbagliata?

Il filtro

use Doctrine\ORM\Mapping\ClassMetaData; 
use Doctrine\ORM\Query\Filter\SQLFilter; 
use Doctrine\Common\Annotations\Reader; 

class CompanyAware extends SQLFilter 
{ 
    /** 
    * @var Reader 
    */ 
    protected $reader; 

    /** 
    * @param ClassMetaData $targetEntity 
    * @param string $targetTableAlias 
    * 
    * @return string 
    */ 
    public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias) 
    { 
     $query = ''; 
     $ann = 'Mrok\\PortalBundle\\Annotation\\CompanyAware'; 
     $isAware = $this->reader->getClassAnnotation($targetEntity->getReflectionClass(), $ann); 

     if ($isAware) { 
      $id = $this->getParameter('id'); 
      $query = sprintf('%s.company_id = %s', $targetTableAlias, $id); 
     } 

     return $query; 
    } 

    public function setAnnotationReader(Reader $reader) 
    { 
     $this->reader = $reader; 
    } 
} 
+0

Possiamo vedere il filtro di sql? – Federkun

risposta

1

Come Dottrina repository non ha una cancellazione (id) o deleteBy (criteri) come un built-in, presumo lei si riferisce a uno $ em-> rimuovere ($ entità); o DQL. Guardando il codice (vedi sotto) né Remove o cascade remove applica i filtri prima di eseguire l'SQL. La documentazione indica che i filtri devono essere applicati a DQL.

http://doctrine-orm.readthedocs.org/en/latest/reference/filters.html

/** 
* Deletes a managed entity. 
* 
* The entity to delete must be managed and have a persistent identifier. 
* The deletion happens instantaneously. 
* 
* Subclasses may override this method to customize the semantics of entity deletion. 
* 
* @param object $entity The entity to delete. 
* 
* @return void 
*/ 
public function delete($entity) 
{ 
    $class  = $this->class; 
    $em   = $this->em; 

    $identifier = $this->em->getUnitOfWork()->getEntityIdentifier($entity); 
    $tableName = $this->quoteStrategy->getTableName($class, $this->platform); 
    $idColumns = $this->quoteStrategy->getIdentifierColumnNames($class, $this->platform); 
    $id   = array_combine($idColumns, $identifier); 
    $types  = array_map(function ($identifier) use ($class, $em) { 

     if (isset($class->fieldMappings[$identifier])) { 
      return $class->fieldMappings[$identifier]['type']; 
     } 

     $targetMapping = $em->getClassMetadata($class->associationMappings[$identifier]['targetEntity']); 

     if (isset($targetMapping->fieldMappings[$targetMapping->identifier[0]])) { 
      return $targetMapping->fieldMappings[$targetMapping->identifier[0]]['type']; 
     } 

     if (isset($targetMapping->associationMappings[$targetMapping->identifier[0]])) { 
      return $targetMapping->associationMappings[$targetMapping->identifier[0]]['type']; 
     } 

     throw ORMException::unrecognizedField($targetMapping->identifier[0]); 

    }, $class->identifier); 

    $this->deleteJoinTableRecords($identifier); 
    $this->conn->delete($tableName, $id, $types); 
} 

/** 
* @todo Add check for platform if it supports foreign keys/cascading. 
* 
* @param array $identifier 
* 
* @return void 
*/ 
protected function deleteJoinTableRecords($identifier) 
{ 
    foreach ($this->class->associationMappings as $mapping) { 
     if ($mapping['type'] !== ClassMetadata::MANY_TO_MANY) { 
      continue; 
     } 

     // @Todo this only covers scenarios with no inheritance or of the same level. Is there something 
     // like self-referential relationship between different levels of an inheritance hierarchy? I hope not! 
     $selfReferential = ($mapping['targetEntity'] == $mapping['sourceEntity']); 
     $class   = $this->class; 
     $association  = $mapping; 
     $otherColumns = array(); 
     $otherKeys  = array(); 
     $keys   = array(); 

     if (! $mapping['isOwningSide']) { 
      $class  = $this->em->getClassMetadata($mapping['targetEntity']); 
      $association = $class->associationMappings[$mapping['mappedBy']]; 
     } 

     $joinColumns = $mapping['isOwningSide'] 
      ? $association['joinTable']['joinColumns'] 
      : $association['joinTable']['inverseJoinColumns']; 


     if ($selfReferential) { 
      $otherColumns = (! $mapping['isOwningSide']) 
       ? $association['joinTable']['joinColumns'] 
       : $association['joinTable']['inverseJoinColumns']; 
     } 

     foreach ($joinColumns as $joinColumn) { 
      $keys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); 
     } 

     foreach ($otherColumns as $joinColumn) { 
      $otherKeys[] = $this->quoteStrategy->getJoinColumnName($joinColumn, $class, $this->platform); 
     } 

     if (isset($mapping['isOnDeleteCascade'])) { 
      continue; 
     } 

     $joinTableName = $this->quoteStrategy->getJoinTableName($association, $this->class, $this->platform); 

     $this->conn->delete($joinTableName, array_combine($keys, $identifier)); 

     if ($selfReferential) { 
      $this->conn->delete($joinTableName, array_combine($otherKeys, $identifier)); 
     } 
    } 
} 
+0

"Presumo che ti riferisci a $ em-> remove ($ entity);" - si – mrok

Problemi correlati