Reputation: 1203
For my project, I have a workspace (kind of a user) with many projects and I am wondering if there is a way to override the default Doctrine query for when I call $workspace->getProjects()
to only fetch the active projects only (not the archived one). This way I won't have to filter my collection and it will reduce the size of the returned data from the database.
/**
* Acme\DemoBundle\Entity\Workspace
*
* @ORM\Table()
* @ORM\Entity
*/
class Workspace {
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
private $id;
/**
* @var ArrayCollection $projects
*
* @ORM\OneToMany(targetEntity="Project", mappedBy="workspace")
*/
private $projects;
/**
* Add projects
*
* @param Project $projects
* @return Workspace
*/
public function addProject( Project $projects ) {
$this->projects[] = $projects;
return $this;
}
/**
* Remove projects
*
* @param Project $projects
*/
public function removeProject( Project $projects ) {
$this->projects->removeElement( $projects );
}
/**
* Get projects
*
* @return Collection
*/
public function getProjects() {
return $this->projects;
}
Upvotes: 4
Views: 5342
Reputation: 21
To do that, you can use criteria.
Here is an exemple from the doctrine doc, to adapt to your needs
use Doctrine\Common\Collections\Criteria;
$criteria = Criteria::create()
->where(Criteria::expr()->eq("birthday", "1982-02-17"))
->orderBy(array("username" => Criteria::ASC))
->setFirstResult(0)
->setMaxResults(20)
;
$birthdayUsers = $object-getUsers()->matching($criteria);
Upvotes: 2
Reputation: 7759
I think you can put your logic inside the getter method itself
public function getProjects() {
$filtered_projects = array()
foreach($this->projects as $project)
{
// Your logic here
// e.g.
// if($project->getIsActive()){
// $filtered_projects[] = $project;
// }
}
return $filtered_projects;
}
Upvotes: 0
Reputation: 578
You will have to write your own method in the Entity Repository Class.
http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes
Upvotes: 2
Reputation: 1746
You can create some listener, and catch doctrine events: http://docs.doctrine-project.org/projects/doctrine1/en/latest/en/manual/event-listeners.html
And modify your query before execute as you wish;
Example from Doctrine docs, for custom hook on delete:
<?php
class UserListener extends Doctrine_EventListener
{
/**
* Skip the normal delete options so we can override it with our own
*
* @param Doctrine_Event $event
* @return void
*/
public function preDelete( Doctrine_Event $event )
{
$event->skipOperation();
}
/**
* Implement postDelete() hook and set the deleted flag to true
*
* @param Doctrine_Event $event
* @return void
*/
public function postDelete( Doctrine_Event $event )
{
$name = $this->_options['name'];
$event->getInvoker()->$name = true;
$event->getInvoker()->save();
}
/**
* Implement preDqlDelete() hook and modify a dql delete query so it updates the deleted flag
* instead of deleting the record
*
* @param Doctrine_Event $event
* @return void
*/
public function preDqlDelete( Doctrine_Event $event )
{
$params = $event->getParams();
$field = $params['alias'] . '.deleted';
$q = $event->getQuery();
if ( ! $q->contains( $field ) )
{
$q->from('')->update( $params['component'] . ' ' . $params['alias'] );
$q->set( $field, '?', array(false) );
$q->addWhere( $field . ' = ?', array(true) );
}
}
/**
* Implement preDqlDelete() hook and add the deleted flag to all queries for which this model
* is being used in.
*
* @param Doctrine_Event $event
* @return void
*/
public function preDqlSelect( Doctrine_Event $event )
{
$params = $event->getParams();
$field = $params['alias'] . '.deleted';
$q = $event->getQuery();
if ( ! $q->contains( $field ) )
{
$q->addWhere( $field . ' = ?', array(false) );
}
}
}
Upvotes: 0