4

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;
    }
2

4 Answers 4

2

You will have to write your own method in the Entity Repository Class.

http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes

Sign up to request clarification or add additional context in comments.

2 Comments

And how Doctrine knows which method to use from my custom repository ?
You will have to call it yourself. Instead of using $workflog->getProjects() you use $workflowRepository->findProjectsForWorkflow($workflow);
2

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);

Comments

0

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) );
        }
    }
}

1 Comment

Your answer concerns doctrine 1.
0

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;
    }

1 Comment

He wanted to filter them in the query. Not afterwards in PHP.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.