Reputation: 4650
I have a controller which has actions for inserting in the database, updating, deleting and some others, but almost all of the actions contain in them this lines:
$em = $this->getDoctrine()->getEntityManager();
$friend = $em->getRepository('EMMyFriendsBundle:Friend')->find($id);
$user = $this->get('security.context')->getToken()->getUser();
Is this OK, or it's code duplication? I tried to make a property called $em
and to have a constructor like this:
public function __construct()
{
$this->em = $this->getDoctrine()->getEntityManager();
}
but it didn't work. As for the queries especially the one with the $id
parameter, I don't even know how to separate them in one place, so each action to be able to use them. One way is a function, but is there sense in a function like this? And if yes what should it return? An array?
Please advise me for the optimal way!
Upvotes: 2
Views: 106
Reputation: 6429
If you have that code only in a couple of controllers you can wrap that code into a protected method for both.
If you think that you can reuse that code in more parts of your application then you should start to think if you need write a validator, use a service or another kind of design
Upvotes: 1
Reputation: 11351
You can do:
private $em;
private $friend;
private $user;
private function init($id==null) {
$this->em = $this->getDoctrine()->getEntityManager();
$this->friend = $id?$this->em->getRepository('EMMyFriendsBundle:Friend')->find($id):null;
$this->user = $this->get('security.context')->getToken()->getUser();
}
Then you can call in your actions
$this->init($id);
or
$this->init();
And you will have
$this->em;
$this->friend;
$this->user;
available. Note that I allowed for the $id parameter not to be set, as I guess that in some actions you will not have it.
If you want this init function to be available in different controllers, create a base controller and extend from it, as suggested in another answer.
Upvotes: 1
Reputation: 8855
What I do, for Symfony2, in the controllers to avoid code duplication is creating a class called Controller.php
in which I put the function I often use.
For example :
<?php
namespace YourProject\Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller as BaseController;
/**
* Base Controller for xxBundle
*/
class Controller extends BaseController
{
/**
* Get repository
*
* @param string $class class
*
* @return Doctrine\ORM\EntityRepository
*/
protected function getRepository($class)
{
return $this->getDoctrine()->getEntityManager()->getRepository($class);
}
/**
* Set flash
*
* @param string $type type
* @param string $text text
*/
protected function setFlash($type, $text)
{
$this->get('session')->getFlashBag()->add($type, $text);
}
/**
* Returns the pager
*
* @param integer $page Page
* @param integer $perPage Max per page
* @param Doctrine_Query $query Query
*
* @return \Pagination
*/
public function getPager($page = 1, $perPage = 10, $query = null)
{
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$query,
$this->get('request')->query->get('page', 1),
$perPage
);
return $pagination;
}
After creating this controller, you need to make your apps controller extends
the controller you've created.
That way, you avoid duplicated code and alias for popular method.
Upvotes: 3
Reputation: 11374
The thing you are looking for probably is param converter which maps action param to object directly.
Here is description and some examples:
http://symfony.com/doc/2.0/bundles/SensioFrameworkExtraBundle/annotations/converters.html
edit:
Some more info in an interesting article:
http://www.adayinthelifeof.nl/2012/08/04/multiparamconverter-for-symfony2/
Upvotes: 1