I love what you are doing here, and I think your separation of concerns is good. We are experimenting with taking this one step further using custom repositories. For example, if a standard service model / method might look like this:
public function findAll($sort = null) { if (!$sort) $sort = array('name' => 'asc'); return $this->getEm()->getRepository('Application\Entity\PartType') ->findAll($sort); }
... we add things that require DQL to the repository to leave all the DQLs from the models, for example:
public function findAllProducts($sort = null) { if (!$sort) $sort = array('name' => 'asc'); return $this->getEm()->getRepository('Application\Entity\PartType') ->findAllProducts($sort); }
In the above model, the repository class is as follows:
<?php namespace Application\Repository; use Application\Entity\PartType; use Doctrine\ORM\EntityRepository; class PartTypeRepository extends EntityRepository { public function findAllProducts($order=NULL) { return $this->_em->createQuery( "SELECT p FROM Application\Entity\PartType p WHERE p.productGroup IS NOT NULL ORDER BY p.name" )->getResult(); } }
Note that we simply extended Doctrine \ ORM \ EntityRepository, which means that we donβt need to redefine all the standard Doctrine repository methods, but we can redefine them if necessary, and we can add our own ones.
Thus, with regard to access control, this gives us the opportunity to add restrictions based on identification or other conditions of the recording level at a very low level by accessing the business logic in your services from the repository. By doing this this way, services are not aware of the implementation. As long as we strictly talk about not putting DQL in other parts of the application, we can achieve business restrictions at the record level for any class that accesses the database through the repository. (Beware of custom DQL at higher levels of the application).
Example:
public function findAll($order=NULL) { // assumes PHP 5.4 for trait to reduce boilerplate locator code use authService; if($this->hasIdentity()) { return $this->_em->createQuery( "SELECT p FROM Application\Entity\PartType p JOIN p.assignments a WHERE a.id = " . $this->getIdentity()->getId() )->getResult(); } else { return NULL; } }
source share