Create custom querys with doctrine is a daily normal task, however usually there are querys that needs to be used more than once and occupy more than 4 lines of code.
A normal, sane developer would not want to write that every time he needs that query ! That is the reason why we will create custom methods because in addition to saving unnecessary lines of code, make our code much more maintainable and is a good practice.
1. Create a folder for the custom methods in the bundle.
We are going to create a folder that will contain our classes with custom methods for the repositories, is recommendable to create it in the root folder of your bundle (next to controller,entity,form folders). This folder will have the name Repository.
2. Create a class with the custom methods
Now we need to create the class with custom methods for our repository, it must have the following structure :
<?php
namespace myapp\myBundle\Repository; // Declare the namespace with your bundle path and "/Repository" in the end
use Doctrine\ORM\EntityRepository; // We need the Entity Repository
/**
* RegisterRepository
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class mynameRepository extends EntityRepository // Give a name to your class
{
// A simple count method that we will call in the controller like this : $total = $em->getRepository('mybundle:Something')->countSomething();
public function countSomething()
{
return $this->getEntityManager()
->createQuery('SELECT COUNT(a) FROM myBundle:Something a')
->getSingleScalarResult();
}
}
3. Activate the repositories according to your mapping style
As we all know , There is more than one method to create entities in symfony 2 with doctrine. Depending on your preferred method you will need to activate the classes this way :
- A) Annotation method
We will add the following code into our entity file (to which we are creating the custom methods) :
// The entity should be in : src/myapp/myBundle/Entity/Something.php
/**
* @ORM\Entity(repositoryClass="myapp\myBundle\Repository\mynameRepository") //Here goes the namespace of our custom methods class with the name of the class in the end (check step 2 namespace)
*/
class Something
{
// ..
}
- B) No annotation methods
Locate the orm mapped file (usually in myBundle/resources/config/doctrine/myfile.orm.yml) and add the repositoryClass line
myapp\myBundle\Entity\Something: # This already exist
type: entity # This already exist
table: something # This already exist
repositoryClass: myapp\myBundle\Repository\mynameRepository # Add the custom repository class path to the orm.yml file
4) Rebuild the entities
Simply run the generate:entites command of doctrine to your bundle
php app/console doctrine:generate:entities myBundle
if you did everything correctly you will be able to call your custom methods from your repository. If you're using a custom repository class, you still have access to the default finder methods such as find()
and findAll()
without problems.