我有几条以 /experiment/{id}/...
开头的路由,我厌倦了重写相同的逻辑来检索登录用户的实验。我想我可以重构我的代码,但我猜 @ParamConverter
会是更好的解决方案。
我将如何重写以下代码以利用 Symfony 的 @ParamConverter功能?
/**
* Displays details about an Experiment entity, including stats.
*
* @Route("/experiment/{id}/report", requirements={"id" = "\d+"}, name="experiment_report")
* @Method("GET")
* @Template()
* @Security("has_role('ROLE_USER')")
*/
public function reportAction(Request $request, $id)
{
$em = $this->getDoctrine()->getManager();
$experiment = $em->getRepository('AppBundle:Experiment')
->findOneBy(array(
'id' => $id,
'user' => $this->getUser(),
));
if (!$experiment) {
throw $this->createNotFoundException('Unable to find Experiment entity.');
}
// ...
}
实验实体有composite primary keys如下:
class Experiment
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
*/
protected $id;
/**
* @var integer
*
* @ORM\Column(name="user_id", type="integer")
* @ORM\Id
*/
protected $userId;
/**
* @ORM\ManyToOne(targetEntity="UserBundle\Entity\User", inversedBy="experiments", cascade={"persist"})
* @ORM\JoinColumn(name="user_id", referencedColumnName="id")
*/
protected $user;
// ..
}
我想使用他们的用户 id
和路径中的实验 id
检索登录用户的实验。
最佳答案
您可以通过使用 custom ParamConverter
来实现.例如这样的事情:
namespace AppBundle\Request\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\ParamConverterInterface;
use Doctrine\ORM\EntityManager;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorage;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use AppBundle\Entity\Experiment;
class ExperimentConverter implements ParamConverterInterface
{
protected $em;
protected $user;
public function __construct(EntityManager $em, TokenStorage $tokenStorage)
{
$this->em = $em;
$this->user = $tokenStorage->getToken()->getUser();
}
public function apply(Request $request, ParamConverter $configuration)
{
$object = $this->em->getRepository(Experiment::class)->findOneBy([
'id' => $request->attributes->get('id'),
'user' => $this->user
]);
if (null === $object) {
throw new NotFoundHttpException(
sprintf('%s object not found.', $configuration->getClass())
);
}
$request->attributes->set($configuration->getName(), $object);
return true;
}
public function supports(ParamConverter $configuration)
{
return Experiment::class === $configuration->getClass();
}
}
您需要注册您的转换器服务并为其添加标签:
# app/config/config.yml
services:
experiment_converter:
class: AppBundle\Request\ParamConverter\ExperimentConverter
arguments:
- "@doctrine.orm.default_entity_manager"
- "@security.token_storage"
tags:
- { name: request.param_converter, priority: 1, converter: experiment_converter }
关于php - Symfony @ParamConverter 通过用户关系获取实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37012596/