Php 如何确保加载Synfony实体以触发postLoad事件?
我是Symfony和Follow的新手。我试图使用服务侦听器和Php 如何确保加载Synfony实体以触发postLoad事件?,php,symfony,symfony-2.6,Php,Symfony,Symfony 2.6,我是Symfony和Follow的新手。我试图使用服务侦听器和postLoad将容器注入实体。其目的是用于在@ORM\PostPersist中写入缩略图。问题是某些路由上没有加载作业实体,然后不会触发postLoad。因此,@ORM\PostPersist中使用的容器不可用 根据本教程,有两条路线可以运行PostPersist: job/create job/update 我发现作业实体未加载,Job/create上未触发postLoad。路径job/update正常,容器被注入。我发布了一
postLoad
将容器注入实体。其目的是用于在@ORM\PostPersist
中写入缩略图。问题是某些路由上没有加载作业实体,然后不会触发postLoad
。因此,@ORM\PostPersist
中使用的容器不可用
根据本教程,有两条路线可以运行PostPersist
:
job/create
job/update
Job/create
上未触发postLoad
。路径job/update
正常,容器被注入。我发布了一些
- 服务.yml
- JobListener.php
- Entity\Job.php
- JobController.php
services:
ibw.jobeet.entity.job.container_aware:
class: Ibw\JobeetBundle\Doctrine\Event\Listener\JobListener
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: doctrine.event_listener, event: postLoad }
ibw.jobeet.event.mylistener:
class: Ibw\JobeetBundle\Listener\Event\MyListener
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: doctrine.event_listener, event: postLoad }
- { name: doctrine.event_listener, event: prePersist }
src/Ibw/JobeetBundle/Doctrine/Event/Listener/JobListener.php
<?php
namespace Ibw\JobeetBundle\Doctrine\Event\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
class JobListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @ORM\PostLoad
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if (method_exists($entity, 'setContainer')) {
$entity->setContainer($this->container);
}
}
}
// ....
/**
* @ORM\PostPersist
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
if ($this->getFile()->move($this->getUploadTmpRootDir(), $this->logo)) {
$this->moveAndResizeImage();
}
$this->file = null;
}
private function moveAndResizeImage($filter = 'primary')
{
$path = $this->getWebTmpPath();
$target = $this->getAbsolutePath();
if (file_exists($path)) {
$container = $this->container;
// got problem here. $container is null for /job/create
// but it is okay for /job/update
$dataManager = $container->get('liip_imagine.data.manager');
$filterManager = $container->get('liip_imagine.filter.manager');
$image = $dataManager->find($filter, $path);
$thumb = $filterManager->applyFilter($image, $filter);
file_put_contents($target, $thumb->getContent());
unlink($path); // remove the temp client original image
}
}
// ...
// ...
public function createAction(Request $request)
{
$entity = new Job();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ibw_job_preview', array(
'company' => $entity->getCompanySlug(),
'location' => $entity->getLocationSlug(),
'token' => $entity->getToken(),
'position' => $entity->getPositionSlug()
)));
}
return $this->render('IbwJobeetBundle:Job:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
// ....
<?php
namespace Ibw\JobeetBundle\Listener\Event;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Ibw\JobeetBundle\Entity\Job;
class MyListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function prePersist(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
protected function injectContainer(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof Job) {
$entity->setContainer($this->container);
}
$em = $eventArgs->getEntityManager();
$repository = $em->getRepository('IbwJobeetBundle:Job');
if ($entity instanceof Job) {
$repository->setContainer($this->container);
}
}
}
src/Ibw/JobeetBundle/Controller/JobController.php
<?php
namespace Ibw\JobeetBundle\Doctrine\Event\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
class JobListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @ORM\PostLoad
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if (method_exists($entity, 'setContainer')) {
$entity->setContainer($this->container);
}
}
}
// ....
/**
* @ORM\PostPersist
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
if ($this->getFile()->move($this->getUploadTmpRootDir(), $this->logo)) {
$this->moveAndResizeImage();
}
$this->file = null;
}
private function moveAndResizeImage($filter = 'primary')
{
$path = $this->getWebTmpPath();
$target = $this->getAbsolutePath();
if (file_exists($path)) {
$container = $this->container;
// got problem here. $container is null for /job/create
// but it is okay for /job/update
$dataManager = $container->get('liip_imagine.data.manager');
$filterManager = $container->get('liip_imagine.filter.manager');
$image = $dataManager->find($filter, $path);
$thumb = $filterManager->applyFilter($image, $filter);
file_put_contents($target, $thumb->getContent());
unlink($path); // remove the temp client original image
}
}
// ...
// ...
public function createAction(Request $request)
{
$entity = new Job();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ibw_job_preview', array(
'company' => $entity->getCompanySlug(),
'location' => $entity->getLocationSlug(),
'token' => $entity->getToken(),
'position' => $entity->getPositionSlug()
)));
}
return $this->render('IbwJobeetBundle:Job:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
// ....
<?php
namespace Ibw\JobeetBundle\Listener\Event;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Ibw\JobeetBundle\Entity\Job;
class MyListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function prePersist(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
protected function injectContainer(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof Job) {
$entity->setContainer($this->container);
}
$em = $eventArgs->getEntityManager();
$repository = $em->getRepository('IbwJobeetBundle:Job');
if ($entity instanceof Job) {
$repository->setContainer($this->container);
}
}
}
有没有办法解决这个问题?我通过在事件侦听器类中添加
prePersist
来解决这个问题,以确保容器在持久化之前可用。LiipImagineBundle服务在postPersist
上调用。我将JobListener
重命名为MyListener
。这是我的工作代码:
src/Ibw/JobeetBundle/Resources/config/services.yml
services:
ibw.jobeet.entity.job.container_aware:
class: Ibw\JobeetBundle\Doctrine\Event\Listener\JobListener
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: doctrine.event_listener, event: postLoad }
ibw.jobeet.event.mylistener:
class: Ibw\JobeetBundle\Listener\Event\MyListener
calls:
- [setContainer, ["@service_container"]]
tags:
- { name: doctrine.event_listener, event: postLoad }
- { name: doctrine.event_listener, event: prePersist }
src/Ibw/JobeetBundle/Listener/Event/MyListener.php
<?php
namespace Ibw\JobeetBundle\Doctrine\Event\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
class JobListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @ORM\PostLoad
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if (method_exists($entity, 'setContainer')) {
$entity->setContainer($this->container);
}
}
}
// ....
/**
* @ORM\PostPersist
*/
public function upload()
{
if (null === $this->getFile()) {
return;
}
if ($this->getFile()->move($this->getUploadTmpRootDir(), $this->logo)) {
$this->moveAndResizeImage();
}
$this->file = null;
}
private function moveAndResizeImage($filter = 'primary')
{
$path = $this->getWebTmpPath();
$target = $this->getAbsolutePath();
if (file_exists($path)) {
$container = $this->container;
// got problem here. $container is null for /job/create
// but it is okay for /job/update
$dataManager = $container->get('liip_imagine.data.manager');
$filterManager = $container->get('liip_imagine.filter.manager');
$image = $dataManager->find($filter, $path);
$thumb = $filterManager->applyFilter($image, $filter);
file_put_contents($target, $thumb->getContent());
unlink($path); // remove the temp client original image
}
}
// ...
// ...
public function createAction(Request $request)
{
$entity = new Job();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('ibw_job_preview', array(
'company' => $entity->getCompanySlug(),
'location' => $entity->getLocationSlug(),
'token' => $entity->getToken(),
'position' => $entity->getPositionSlug()
)));
}
return $this->render('IbwJobeetBundle:Job:new.html.twig', array(
'entity' => $entity,
'form' => $form->createView(),
));
}
// ....
<?php
namespace Ibw\JobeetBundle\Listener\Event;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Doctrine\ORM\Event\LifecycleEventArgs;
use Ibw\JobeetBundle\Entity\Job;
class MyListener
{
/** @var ContainerInterface */
protected $container;
/**
* @param ContainerInterface @container
*/
public function setContainer(ContainerInterface $container)
{
$this->container = $container;
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function postLoad(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
/**
* @param LifecycleEventArgs $eventArgs
*/
public function prePersist(LifecycleEventArgs $eventArgs)
{
$this->injectContainer($eventArgs);
}
protected function injectContainer(LifecycleEventArgs $eventArgs)
{
$entity = $eventArgs->getEntity();
if ($entity instanceof Job) {
$entity->setContainer($this->container);
}
$em = $eventArgs->getEntityManager();
$repository = $em->getRepository('IbwJobeetBundle:Job');
if ($entity instanceof Job) {
$repository->setContainer($this->container);
}
}
}