Symfony3:在表单提交时保持并刷新集合的有效部分,并显示错误

时间:2017-04-18 16:41:35

标签: forms symfony collections doctrine symfony-forms

我在下面有以下实体和抽象类型。

由于我的任务与包含文件的实体有多对多的关系,当其中一个文件的Assert失败时,表单无法重新填充所选文件而我不知道如何然后处理错误。

是否有办法保留PieceJointe集合中有效的部分,然后让用户仅在她再次发送表单之前编辑无效条目?

更新:也许是这样的?虽然我尝试过,但持久性PieceJointe未与Mission相关联。

if ($form->isSubmitted()) {
    if ($form->isValid()) {
         $em->persist($etapeMission);
         $em->flush();
    } else {
        foreach ($form->get('mission')->get('pieces_jointes') as $pj) {
            if ($pj->isValid()) {
                $em->persist($pj);
                $em->flush($pj);
            }
        }
    }
}

重点

  • 第一次提交表单时,已附加集合的Mission实体已存在
  • EtapeMission实体在这里并不真正相关,因为它在关系中没有作用。虽然,我把它放在这里,因为这是我提交的表单的实体(我从Mission表单上传EtapeMission的文件属于所谓的Mission

感谢您的帮助。任何建议,想法等都是受欢迎的。

Mission.php:

class Mission
{
// ...

/**
 * @var \AppBundle\Entity\EtapeMission
 *
 * @ORM\OneToOne(targetEntity="AppBundle\Entity\EtapeMission", inversedBy="missionAsPreCadrage")
 * @ORM\JoinColumn(name="pre_cadrage_etape_mission_id", referencedColumnName="id")
 */
private $preCadrageEtapeMission;

/**
 * @var \AppBundle\Entity\EtapeMission
 *
 * @ORM\OneToOne(targetEntity="AppBundle\Entity\EtapeMission", inversedBy="missionAsCadrage")
 * @ORM\JoinColumn(name="cadrage_etape_mission_id", referencedColumnName="id")
 */
private $cadrageEtapeMission;

/**
 * @var \AppBundle\Entity\EtapeMission
 *
 * @ORM\OneToOne(targetEntity="AppBundle\Entity\EtapeMission", inversedBy="missionAsValidation")
 * @ORM\JoinColumn(name="validation_etape_mission_id", referencedColumnName="id")
 */
private $validationEtapeMission;

/**
 * @var Collection<PieceJointe>
 *
 * @ORM\ManyToMany(targetEntity="\AppBundle\Entity\PieceJointe", cascade={"persist"}, orphanRemoval=true)
 * @ORM\JoinTable(name="missions_pieces_jointes",
 *     joinColumns={@ORM\JoinColumn(name="mission_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="piece_jointe_id", referencedColumnName="id", unique=true)}
 *     )
 */
private $piecesJointes;

// ...
}

EtapeMission.php:

class EtapeMission
{
// ...

/**
 * @var Mission
 * @ORM\OneToOne(targetEntity="Mission", mappedBy="preCadrageEtapeMission", cascade={"persist"})
 */
private $missionAsPreCadrage;

/**
 * @var Mission
 * @ORM\OneToOne(targetEntity="Mission", mappedBy="cadrageEtapeMission", cascade={"persist"})
 */
private $missionAsCadrage;

/**
 * @var Mission
 * @ORM\OneToOne(targetEntity="Mission", mappedBy="validationEtapeMission", cascade={"persist"})
 */
private $missionAsValidation;

// ...
}

PieceJointe.php

class PieceJointe
{
// ...

/**
 * @var UploadedFile
 *
 * @Assert\File(
 *     maxSize = "4096k"
 * )
 */
private $file;

/**
 * @var Collection<Mission>
 *
 * @ORM\ManyToMany(targetEntity="Mission", mappedBy="piecesJointes")
 */
private $missions;

// ...
}

这是我的抽象类型:

EtapeMissionType.php:

class EtapeMissionType extends AbstractType
{
/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        // ...
        ->add('mission', PiecesJointesCollectionType::class);
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => EtapeMission::class,
    ]);
}
}

PiecesJointesCollectionType.php:

class PiecesJointesCollectionType extends AbstractType
{
/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('pieces_jointes', CollectionType::class, [
            'entry_type' => PieceJointeType::class,
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => true,
            'constraints' => [
                new Valid(),
            ],
        ]);
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => Mission::class,
    ]);
}
}

PieceJointeType:

class PieceJointeType extends AbstractType
{
/**
 * {@inheritdoc}
 */
public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('file', FileType::class, [
            'label' => false,
        ]);
}

/**
 * {@inheritdoc}
 */
public function configureOptions(OptionsResolver $resolver)
{
    $resolver->setDefaults([
        'data_class' => PieceJointe::class,
    ]);
}
}

0 个答案:

没有答案