Anonymous
Anonymous

Reputation: 6251

Symfony2 Application Architecture - how to make a function available in all controllers?

I'm building an application where users are tied to accounts (as in, multiple users all share an account), then other entities - lets call them products are tied to the accounts. The products are associated with the accounts and only users that are tied to that account can edit the products.

The difference being in my case, there are many different entities being shared in the same model.

If it was just the one (product) entity, it wouldn't be a problem to have a method in my ProductRepository like:

public function checkOwnership($id, $account)
{
    $count = $this->createQueryBuilder('s')
        ->select('count(s.id)')
        ->where('s.account = :acc')
        ->andWhere('s.id = :id')
        ->setParameters(array('id' => $id, 'acc' => $account))
        ->getQuery()
        ->getSingleScalarResult();

    if($count == 0)
        throw $this->createNotFoundException('ye..');

    return;
}

To make sure the id of the product is tied to the user's account.

The account argument is passed to this function by using:

$this->getUser();

In the controller.

What is the best way for me to make this function available to the other entities to prevent code duplication? There are (currently) only 3 other entities, so it wouldn't be the end of the world to just have it in each repository, but I'm just wondering if there were a way to create a 'common' or global repository that follows good standards? I'd sure like to know about it.

Edit:

Or have I just completely over-thought this? Can I just create a 'Common' directory in my 'MainBundle', define a namespace and add a use statement at the start of my controllers that need access to the function?

Upvotes: 0

Views: 158

Answers (1)

gremo
gremo

Reputation: 48899

I hope I fully understand your question.

Solution one, duplication, easy: let @ParamConverter do the job (automatic response to 404 if doesn't exist)

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;

/**
 * @Route("/pets/{id}")
 */
public function showAction(Pet $pet)
{
    // Current logged user
    $currentUser = $this->get('security.context')->getToken()->getUser();

    // Owner
    $ownerUser = $pet->getUser();

    if(!$currentUser->equals($ownerUser)) {
        // 401, 403 o 404 depends on you
    }
}

Solution two, DRY, a bit harder: use JMSAOPBundle and define an interceptor that intercepts all request to you controller and actions (show, delete, etc.). The pointcut (connected to the interceptor) will get the current user from the context and the owner from the entity. Then you do the check...

Upvotes: 1

Related Questions