Symfony2应用程序架构 - 如何在所有控制器中提供功能?

时间:2013-02-19 13:14:36

标签: symfony architecture doctrine-orm

我正在构建一个应用程序,其中用户与帐户绑定(如同多个用户共享帐户),然后是其他实体 - 让我们称之为产品与帐户绑定。这些产品与帐户相关联,只有与该帐户关联的用户才能编辑产品。

不同之处在于我的情况,在同一个模型中共享了许多不同的实体。

如果它只是一个(产品)实体,那么在我的ProductRepository中有一个方法就不会有问题,如:

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

确保产品的ID与用户的帐户绑定。

使用以下命令将account参数传递给此函数:

$this->getUser();

在控制器中。

对我来说,让其他实体可以使用此功能以防止代码重复的最佳方法是什么? (目前)只有3个其他实体,所以在每个存储库中只有它就不会是世界末日,但我只是想知道是否有办法创建'共同'或遵循良好标准的全球存储库?我很想知道它。

修改

或者我刚刚过度思考过这个?我可以在'MainBundle'中创建一个'Common'目录,定义命名空间并在我需要访问该函数的控制器的开头添加一个use语句吗?

1 个答案:

答案 0 :(得分:1)

我希望我完全理解你的问题。

解决方案一,重复,轻松:让@ParamConverter完成工作(如果不存在,则自动回复404

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

解决方案二,DRY,更难一点:使用JMSAOPBundle并定义拦截器,拦截对您的控制器和操作(显示,删除等)的所有请求。切入点(连接到拦截器)将从上下文获取当前用户,并从实体获取所有者。然后你做检查...