0

I am editing an entity, and upon some manual validation error I want to write a log message to the DB, but when I flush that message, the entity under editing is also flushed to DB. I have tried entityManager->clear() but that throws errors about entity configuration (seems like I need additional cascade configuration on my entities in order to use that).

Is there no simple way of just reversing the entityManager->persist()?

What I want is to be able to NOT persist some of the entities previously called ->persist() on (or fetched from the DB thus automatically being persisted).

Edit function:

public function editAction(Request $request, price $price)
{
    $deleteForm = $this->createDeleteForm($price);
    $editForm = $this->createForm(\App\Form\priceType::class, $price);
    $editForm->handleRequest($request);

    if ($editForm->isSubmitted() && $editForm->isValid()) {
        
        //check start before stop
        if ( $price->getDateFrom() >= $price->getDateTo()) {
            //$this->em->clear(); //not working
            $this->helper->flash('fail','Du kan inte sätta prisavtalets startdatum till efter eller samma som dess slutdatum, då skulle det inte tillämpas på någon extraöppning.',$price->getACRGroup());
            return $this->render('price/edit.html.twig', array(
                'price' => $price,
                'edit_form' => $editForm->createView(),
                'delete_form' => $deleteForm->createView(),
            ));
        }

And the logging function:

 public function flash($type,$message,$unit=null)
 {        

        //REMEMBER when using this logger - use it AFTER your entity work is done (either flushed or $em->clear()

        // currently $type can be 'success', 'fail' or 'warning'.

        //find out (from services.yaml) if this install is set up to store every message (fails and warnings also) or just success (success means something was changed so always store a log on that)
        if (
            ($type == 'fail' && $this->globalParameters->get('systemlog_save_errors') == 0)
            ||
            ($type == 'warning' && $this->globalParameters->get('systemlog_save_warnings') == 0)
            ) {
            return false;
        }
        
        if ($type == 'fail') {
            $type = 'error';
        }

        //This is important as the flush() below will otherwise flush ANY ENTITY IN EDIT unless that was explicitly removed from entityManager ( $em->clear() ). DANGER! You will easily and inadvertently save unverified data.
        /*
        if ($type == 'error') {
            $this->em->clear(); //not working
        }
        */

        //create log entry
        $em = $this->em;
        $now = new \DateTime("now");
        
        $entity  = new Systemlog();
        $entity->setACRGroup($unit);
        $entity->setemail($this->security->getUser()->getEmail());
        $entity->setTime($now);
        $entity->setEventType($type);
        $entity->setEventMessage($message);
        
        $em->persist($entity);
        $em->flush();
    }
Matt Welander
  • 8,234
  • 24
  • 88
  • 138
  • Consider making a second entity manager just for logging and avoid the entire problem. Assuming $unit is not an entity because you can't associate entities across entity managers. – Cerad Jan 29 '23 at 19:06
  • You should also consider why you are first interacting with a database (not yet saved), and then running validation. – Leroy Jan 29 '23 at 22:12
  • EntityManager>remove($entity) only notify the UnitOfWork to perform these operations during flush. So you can use it. – Bhavin Nakrani Jan 30 '23 at 06:22
  • Leroy the way I understand it, this is the preferred way of doing edit forms - the entity is picked up from the DB and modified according to the form input. Then I do some checks on it and decide whether it's valid for saving, depending on whether it conflicts with other saved data. Until the form is applied to the entity I don't know what was submitted. And at that point, the entityManager is involved already. – Matt Welander Jan 30 '23 at 10:47

0 Answers0