我正在构建一个应用程序,其中用户与帐户绑定(如同多个用户共享帐户),然后是其他实体 - 让我们称之为产品与帐户绑定。这些产品与帐户相关联,只有与该帐户关联的用户才能编辑产品。
不同之处在于我的情况,在同一个模型中共享了许多不同的实体。
如果它只是一个(产品)实体,那么在我的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语句吗?
答案 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并定义拦截器,拦截对您的控制器和操作(显示,删除等)的所有请求。切入点(连接到拦截器)将从上下文获取当前用户,并从实体获取所有者。然后你做检查...