Sonata: Fill, save, and update multiple-entry field
Eingetragen von fayon am 02 Jul 2017 in Arbeit
I have an application which contains shipments and orderings. One shipment can have 0..N orderings. One ordering has maximum one shipment.
Within the ShipmentAdmin I configured the form fields as follows. They show all orderings without a shipment (1). If the current form already shows an existing shipment, we also need to show these shipments (2).
protected function configureFormFields(FormMapper $formMapper) { $formMapper ... ->add('orderings','entity', array( 'class' => 'Lysano\ConnectBundle\Entity\Ordering', 'query_builder' => function (\Lysano\ConnectBundle\Repository\OrderingRepository $er) { $qb = $er->createQueryBuilder('o'); $qb->where('o.shipment IS NULL'); // 1 if ($this->getSubject()->getId()) { // 2 $qb->orWhere('o.shipment = :shipm') ->setParameter('shipm', $this->getSubject()); } return $qb; }, 'multiple' => true ) ) ; }
In order to save chosen orderings, I added prePersist() and preUpdate() to ShipmentAdmin. prePersist() iterates through all chosen orderings and updates them (3). preUpdate() needs to also care about deleted orderings (4).
public function prePersist($object) { ... foreach ($object->getOrderings() as $ordering) { // 3 $ordering->setShipment($object); } } public function preUpdate($object) { ... // delete old // 4 $idArr = array(); // IDs to keep foreach ($object->getOrderings() as $ordering) { $idArr[] = $ordering->getId(); } $em = $this->getModelManager()->getEntityManager($this->getClass()); $qb = $em->createQueryBuilder(); $qb->update('LysanoConnectBundle:Ordering', 'o') ->set('o.shipment', 'null') ->where('o.shipment = ?1'); if (count($idArr) > 0) { $qb->andWhere($qb->expr()->notIn('o.id', $idArr)); } $q = $qb->setParameter(1, $object->getId()) ->getQuery(); $q->execute(); // add new: foreach ($object->getOrderings() as $ordering) { $ordering->setShipment($object); } }
Dieser Eintrag wurde eingetragen von fayon und ist abgelegt unter Arbeit.