在ArrayCollection

时间:2016-09-15 09:33:24

标签: symfony

对不起标题,我不知道怎么说。

我有两个实体:在管上有一个OneToMany关系的Strain,以及一个cascade = {“persist”,“remove”}属性。 对于两次实体,我使用PrePersist回调动态定义其名称。但是,它只适用于Tube实体,在Strain实体上我遇到了问题,因为它的名字是在第一个管名上定义的。我认为PrePersist用于Tubes之前的Strain。然后,如果Tubes没有名称,Strain的名称为空。

如果我在控制器中做一个foreach,在坚持应变之前逐个坚持每个管,它可以正常工作。但我真的不喜欢它。我们可以在某处配置它,比如PrePersist的优先顺序吗?

我的实体:

class Tube
{
  /**
   * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Strain", inversedBy="tubes")
   */
  private $gmoStrain;

  ...


  // SETTERS & GETTERS

  public function setStrain(Strain $strain)
  {
    $this->strain = $strain;

    return $this;
  }

  public function getStrain()
  {
    return $this->strain;
  }

  ...

  //LifecycleCallback

/**
 * Before persist.
 *
 * @ORM\PrePersist()
 */
public function prePersist()
{
    // Give a name to the tube
    // The name is composed like this:
    // ProjectPrefix_BoxLetter_xxxType

    // ProjectPrefix (The prefix of the first Tube)
    $projectPrefix = $this->getBox()->getProject()->getPrefix();

    // BoxLetter (idem, the first tube)
    $boxLetter = $this->getBox()->getBoxLetter();

    // In array the first cell is 0, in real box, it's 1
    $cell = $this->cell + 1;

    // Adapt the boxCell like: 1 => 001, 10 => 010, 100 => 100, never more than 999
    if ($cell < 10) {
        $boxCell = '00'.$cell;
    } elseif ($cell > 99) {
        $boxCell = $cell;
    } else {
        $boxCell = '0'.$cell;
    }

    // Type Letter
    $lastLetter = $this->getStrain()->getType()->getLetter();

    // Generate the tube name
    $this->name = $projectPrefix.'_'.$boxLetter.$boxCell.$lastLetter;
}
}

毒株:

class Strain
{
    /**
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\Tube", mappedBy="strain", cascade={"persist", "remove"})
 */
  private $tubes;

  ...

  //SETTERS & GETTERS

  public function addTube(Tube $tube)
  {
      if (!$this->tubes->contains($tube)) {
          $tube->setGmoStrain($this);
          $this->tubes->add($tube);
      }
  }

  public function removeTube(Tube $tube)
  {
      if ($this->tubes->contains($tube)) {
          $this->tubes->removeElement($tube);
      }
  }

  public function getTubes()
  {
      return $this->tubes;
  }

  ...

  //LifecycleCallback

/**
 * Before persist.
 *
 * @ORM\PrePersist()
 */
public function postPersist()
{
    // The automatic name of the strain is the name of the first tube
    // when the strain is registred the first time
    $this->systematicName = $this->getTubes()->first()->getName();
}
}

1 个答案:

答案 0 :(得分:0)

如果您需要设置prePersist事件的优先级,可以使用Event Listeners and Subscribers服务代替@ORM\PrePersist注释来完成此操作。

首先,为prePresist事件创建Tube监听器类:

// src/AppBundle/EventListener/TubeListener.php
namespace AppBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Tube;

class TubeListener
{
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if (!$entity instanceof Tube) {
            return;
        }

        $em = $args->getEntityManager();
        // do something with the Tube
    }
}

接下来,注册监听器,默认情况下,如果没有提供优先级标签属性,那么它的分区为0

services:
    app.event_listener.tube:
        class: AppBundle\EventListener\TubeListener
        tags:
            - { name: doctrine.event_listener, event: prePersist }

稍后,为同一Strain事件创建第二个prePresist侦听器类:

// src/AppBundle/EventListener/StrainListener.php
namespace AppBundle\EventListener;

use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Strain;

class StrainListener
{
    public function prePersist(LifecycleEventArgs $args)
    {
        $entity = $args->getEntity();

        if (!$entity instanceof Strain) {
            return;
        }

        $em = $args->getEntityManager();
        // do something with the Strain (at this moment pre-persist Tube already called)
    }
}

现在,注册此侦听器的优先级低于TubeListener

services:
    app.event_listener.strain:
        class: AppBundle\EventListener\StrainListener
        tags:
            - { name: doctrine.event_listener, event: prePersist, priority: -5 }

从而确保第一个prePersist事件(具有优先级0)已在第二个事件之前执行(优先级-5)。这也可以使用订阅者进行存档。