Ejemplo n.º 1
0
 /**
  *
  * @return \Zend\View\Model\JsonModel Exception : if query param 'return' is true, redirect to route application.
  */
 public function saveAction()
 {
     $messages = array();
     $event = null;
     $events = array();
     $sendEvents = array();
     $return = $this->params()->fromQuery('return', null);
     if ($this->zfcUserAuthentication()->hasIdentity()) {
         if ($this->getRequest()->isPost()) {
             $post = array_merge_recursive($this->getRequest()->getPost()->toArray(), $this->getRequest()->getFiles()->toArray());
             $id = $post['id'] ? $post['id'] : null;
             $objectManager = $this->getServiceLocator()->get('Doctrine\\ORM\\EntityManager');
             $deleteStatus = $objectManager->getRepository('Application\\Entity\\Status')->find('5');
             $credentials = false;
             if ($id) {
                 // modification
                 $event = $objectManager->getRepository('Application\\Entity\\Event')->find($id);
                 if ($event) {
                     if ($this->isGranted('events.write') || $event->getAuthor()->getId() === $this->zfcUserAuthentication()->getIdentity()->getId()) {
                         $credentials = true;
                         // si utilisateur n'a pas les droits events.status, le champ est désactivé et aucune valeur n'est envoyée
                         if (!isset($post['status'])) {
                             $post['status'] = $event->getStatus()->getId();
                         }
                     }
                 }
             } else {
                 // création
                 if ($this->isGranted('events.create')) {
                     $event = new Event();
                     $event->setAuthor($this->zfcUserAuthentication()->getIdentity());
                     $event->setOrganisation($this->zfcUserAuthentication()->getIdentity()->getOrganisation());
                     // si utilisateur n'a pas les droits events.status, le champ est désactivé et aucune valeur n'est envoyée
                     if (!isset($post['status'])) {
                         $post['status'] = 1;
                     }
                     $credentials = true;
                 }
             }
             if ($credentials) {
                 //préparation de certains champs
                 $startdate = new \DateTime($post['startdate']);
                 $offset = $startdate->getTimezone()->getOffset($startdate);
                 $startdate->setTimezone(new \DateTimeZone("UTC"));
                 $startdate->add(new \DateInterval("PT" . $offset . "S"));
                 $enddate = null;
                 if (isset($post['enddate']) && !empty($post['enddate'])) {
                     $enddate = new \DateTime($post['enddate']);
                     $offset = $enddate->getTimezone()->getOffset($enddate);
                     $enddate->setTimezone(new \DateTimeZone("UTC"));
                     $enddate->add(new \DateInterval("PT" . $offset . "S"));
                 }
                 $diff = 0;
                 if ($enddate !== null) {
                     $diff = $startdate->diff($enddate);
                 }
                 $now = new \DateTime('now');
                 $now->setTimezone(new \DateTimeZone('UTC'));
                 $modrecurrence = false;
                 $recurrence = null;
                 if (isset($post['recurrencepattern']) && !empty($post['recurrencepattern'])) {
                     if ($id) {
                         //récurrence existante
                         $recurrence = $event->getRecurrence();
                         if ($recurrence === null) {
                             //en cas de modification d'un évènement seul et ajout d'une recurrence
                             $recurrence = new Recurrence($startdate, "");
                             $event->setStatus($deleteStatus);
                             $this->closeEvent($event);
                         }
                         if (isset($post['exclude']) && $post['exclude'] == "true") {
                             $recurrence->exclude($event);
                             $event->setRecurrence(null);
                             $status = $objectManager->getRepository('Application\\Entity\\Status')->find($post['status']);
                             $event->setStatus($status);
                             if ($enddate !== null) {
                                 $event->setDates($startdate, $enddate);
                             }
                             $this->changeEndDate($event, $enddate);
                             $this->changeStartDate($event, $startdate);
                             $events[] = $event;
                         } else {
                             //si la règle de récurrence a changé, on exclut les évènements passés
                             //on supprime les évènements restants
                             //et on crée une nouvelle récurrence
                             $test = $recurrence->getStartdate() == $startdate;
                             //changement de récurrence si
                             //* le pattern a changé ou
                             //* la date de début de l'évènement a changé
                             if (strcmp($recurrence->getRecurrencePattern(), $post['recurrencepattern']) !== 0 || !($event->getStartdate() == $startdate)) {
                                 $recurrentEvents = $recurrence->getEvents();
                                 foreach ($recurrentEvents as $e) {
                                     if ($e->isPast($now)) {
                                         $e->setRecurrence(null);
                                     } else {
                                         $e->setStatus($deleteStatus);
                                     }
                                     $objectManager->persist($e);
                                     $sendEvents[] = $e;
                                 }
                                 //si le statut est positionné à "Supprimé"
                                 //on ne crée pas de nouveaux évènements
                                 if ($post['status'] != 5) {
                                     //$objectManager->remove($recurrence);
                                     $recurrence = new Recurrence($startdate, $post['recurrencepattern']);
                                     $objectManager->persist($recurrence);
                                     foreach ($recurrence->getRSet() as $occurrence) {
                                         $e = new Event();
                                         $e->setRecurrence($recurrence);
                                         $e->setAuthor($this->zfcUserAuthentication()->getIdentity());
                                         $e->setOrganisation($this->zfcUserAuthentication()->getIdentity()->getOrganisation());
                                         $status = $objectManager->getRepository('Application\\Entity\\Status')->find(1);
                                         $e->setStatus($status);
                                         $e->setStartdate($occurrence);
                                         if ($enddate !== null) {
                                             $end = clone $occurrence;
                                             $end->add($diff);
                                             $e->setEnddate($end);
                                         }
                                         $modrecurrence = true;
                                         $events[] = $e;
                                     }
                                 }
                             } else {
                                 //sinon on exclut simplement les evts passés
                                 //mise à jour des évènements futurs en fonction des champs modifiés
                                 $recurrentEvents = $recurrence->getEvents();
                                 foreach ($recurrentEvents as $e) {
                                     if ($e->isPast($now)) {
                                         $recurrence->exclude($e);
                                         $e->setRecurrence(null);
                                         $objectManager->persist($e);
                                         $sendEvents[] = $e;
                                     } else {
                                         $events[] = $e;
                                         //exception pour la suppression : appliqué à tous les évènements futurs
                                         if ($post['status'] == 5) {
                                             $e->setStatus($deleteStatus);
                                         }
                                     }
                                 }
                                 //on mets à jour date de fin et statut de l'évènement sélectionné
                                 $status = $objectManager->getRepository('Application\\Entity\\Status')->find($post['status']);
                                 $event->setStatus($status);
                                 if ($enddate !== null) {
                                     $event->setDates($startdate, $enddate);
                                 }
                                 $this->changeEndDate($event, $enddate);
                                 $this->changeStartDate($event, $startdate);
                             }
                         }
                     } else {
                         //nouvelle récurrence
                         $pattern = $post['recurrencepattern'];
                         $recurrence = new Recurrence($startdate, $pattern);
                         $objectManager->persist($recurrence);
                         $rset = $recurrence->getRSet();
                         foreach ($rset as $occurrence) {
                             $e = new Event();
                             $e->setRecurrence($recurrence);
                             $status = $objectManager->getRepository('Application\\Entity\\Status')->find(1);
                             $e->setStatus($status);
                             $e->setStartdate($occurrence);
                             $e->setAuthor($this->zfcUserAuthentication()->getIdentity());
                             $e->setOrganisation($this->zfcUserAuthentication()->getIdentity()->getOrganisation());
                             if ($enddate !== null) {
                                 $end = clone $occurrence;
                                 $end->add($diff);
                                 $e->setEnddate($end);
                             }
                             $events[] = $e;
                         }
                     }
                 } else {
                     //un seul évènement
                     $status = $objectManager->getRepository('Application\\Entity\\Status')->find($post['status']);
                     $event->setStatus($status);
                     if ($enddate !== null) {
                         $event->setDates($startdate, $enddate);
                     }
                     $this->changeEndDate($event, $enddate);
                     $this->changeStartDate($event, $startdate);
                     $events[] = $event;
                 }
                 foreach ($events as $e) {
                     //statut et date de fin sont gérés au dessus
                     //car les traitements sont spécifiques à chaque cas
                     //impact
                     $impact = $objectManager->getRepository('Application\\Entity\\Impact')->find($post['impact']);
                     $e->setImpact($impact);
                     //catégorie
                     $e->setCategory($objectManager->getRepository('Application\\Entity\\Category')->find($post['category']));
                     //champs horaires : ponctuel, programmé
                     $e->setPunctual($post['punctual']);
                     $e->setScheduled($post['scheduled']);
                     //cohérence horaires, statut
                     // si statut terminé, non ponctuel et pas d'heure de fin
                     // alors l'heure de fin est mise auto à l'heure actuelle
                     // sauf si heure de début future (cas improbable)
                     if (!$e->isPunctual() && $e->getStatus()->getId() == 3 && $e->getEnddate() == null) {
                         if ($e->getStartdate() < $now && $e->setEnddate($now)) {
                             $this->changeEndDate($e, $now);
                         } else {
                             // dans le cas contraire, retour au statut confirmé
                             $confirm = $objectManager->getRepository('Application\\Entity\\Status')->find(2);
                             $e->setStatus($confirm);
                             $messages['error'][] = "Impossible de passer l'évènement au statut terminé.";
                         }
                     }
                     // si annulé, non ponctuel et pas d'heure de fin
                     // alors on met l'heure de fin à heure de début +90min
                     if (!$e->isPunctual() && $e->getStatus()->getId() == 4 && $e->getEnddate() == null) {
                         if ($e->getStartdate() < $now) {
                             $this->changeEndDate($e, $now);
                         } else {
                             $enddate = clone $e->getStartdate();
                             $enddate->add(new \DateInterval("PT90M"));
                             $this->changeEndDate($e, $enddate);
                         }
                     }
                     //custom fields
                     if (isset($post['custom_fields'])) {
                         foreach ($post['custom_fields'] as $key => $value) {
                             // génération des customvalues si un customfield dont le nom est $key est trouvé
                             $customfield = $objectManager->getRepository('Application\\Entity\\CustomField')->findOneBy(array('id' => $key));
                             if ($customfield) {
                                 if (is_array($value)) {
                                     $temp = "";
                                     foreach ($value as $v) {
                                         $temp .= (string) $v . "\r";
                                     }
                                     $value = trim($temp);
                                 }
                                 $customvalue = $objectManager->getRepository('Application\\Entity\\CustomFieldValue')->findOneBy(array('customfield' => $customfield->getId(), 'event' => $e->getId()));
                                 if (!$customvalue) {
                                     $customvalue = new CustomFieldValue();
                                     $customvalue->setEvent($e);
                                     $customvalue->setCustomField($customfield);
                                     $e->addCustomFieldValue($customvalue);
                                 }
                                 $customvalue->setValue($value);
                             }
                         }
                     }
                     //une fois les évènements fils positionnés, on vérifie si il faut clore l'évènement
                     if ($e->getStatus()->getId() == 3 || $e->getStatus()->getId() == 4 || $e->getStatus()->getId() == 5) {
                         // passage au statut supprimé
                         $this->closeEvent($e);
                     }
                     // create associated actions (only relevant if creation from a model)
                     //en cas d'évènements récurrents, seuls les nouveaux évènements doivent être impactés
                     if (isset($post['modelid'])) {
                         $parentID = $post['modelid'];
                         // get actions
                         foreach ($objectManager->getRepository('Application\\Entity\\PredefinedEvent')->findBy(array('parent' => $parentID), array('place' => 'ASC')) as $action) {
                             if ($action->getCategory() instanceof ActionCategory) {
                                 $child = new Event();
                                 $child->setAuthor($e->getAuthor());
                                 $child->setParent($e);
                                 $child->setOrganisation($e->getOrganisation());
                                 $child->createFromPredefinedEvent($action);
                                 $child->setStatus($objectManager->getRepository('Application\\Entity\\Status')->findOneBy(array('defaut' => true, 'open' => true)));
                                 // customfields
                                 foreach ($action->getCustomFieldsValues() as $customvalue) {
                                     $newcustomvalue = new CustomFieldValue();
                                     $newcustomvalue->setEvent($child);
                                     $newcustomvalue->setCustomField($customvalue->getCustomField());
                                     $newcustomvalue->setValue($customvalue->getValue());
                                     $objectManager->persist($newcustomvalue);
                                 }
                                 $e->addChild($child);
                                 $objectManager->persist($child);
                             }
                         }
                     }
                     //en cas de mod de récurrence, les actions et fichiers ne sont as inclus dans le formulaire
                     //on les reprend de l'évènement modifié
                     if ($modrecurrence) {
                         //actions et alarmes
                         foreach ($event->getChildren() as $child) {
                             $newchild = new Event();
                             $newchild->createFromEvent($child);
                             $newchild->setParent($e);
                             $newchild->setStatus($objectManager->getRepository('Application\\Entity\\Status')->findOneBy(array('defaut' => true, 'open' => true)));
                             foreach ($child->getCustomFieldsValues() as $value) {
                                 $newcustomvalue = new CustomFieldValue();
                                 $newcustomvalue->setEvent($newchild);
                                 $newcustomvalue->setCustomField($value->getCustomField());
                                 $newcustomvalue->setValue($value->getValue());
                                 $objectManager->persist($newcustomvalue);
                             }
                             if ($child->getCategory() instanceof AlarmCategory) {
                                 $start = clone $e->getStartdate();
                                 $diff = $event->getStartdate()->diff($child->getStartdate());
                                 $start->add($diff);
                                 $newchild->setStartdate($start);
                             }
                             $e->addChild($newchild);
                             $objectManager->persist($newchild);
                         }
                         //fichiers
                         foreach ($event->getFiles() as $f) {
                             $f->addEvent($e);
                             $objectManager->persist($f);
                         }
                     }
                     // associated actions to be copied
                     if (isset($post['fromeventid'])) {
                         $parentID = $post['fromeventid'];
                         foreach ($objectManager->getRepository('Application\\Entity\\Event')->findBy(array('parent' => $parentID), array('place' => 'DESC')) as $action) {
                             if ($action->getCategory() instanceof \Application\Entity\ActionCategory) {
                                 $child = new Event();
                                 $child->setAuthor($e->getAuthor());
                                 $child->setParent($e);
                                 $child->setOrganisation($event->getOrganisation());
                                 $child->setCategory($action->getCategory());
                                 $child->setImpact($action->getImpact());
                                 $child->setPunctual($action->isPunctual());
                                 $child->setStatus($objectManager->getRepository('Application\\Entity\\Status')->findOneBy(array('defaut' => true, 'open' => true)));
                                 foreach ($action->getCustomFieldsValues() as $customvalue) {
                                     $newcustomvalue = new CustomFieldValue();
                                     $newcustomvalue->setEvent($child);
                                     $newcustomvalue->setCustomField($customvalue->getCustomField());
                                     $newcustomvalue->setValue($customvalue->getValue());
                                     $child->addCustomFieldValue($newcustomvalue);
                                     //$objectManager->persist($newcustomvalue);
                                 }
                                 $e->addChild($child);
                                 //$objectManager->persist($child);
                             }
                         }
                     }
                     // fichiers
                     if (isset($post['fichiers']) && is_array($post['fichiers'])) {
                         foreach ($post['fichiers'] as $key => $f) {
                             $file = $objectManager->getRepository('Application\\Entity\\File')->find($key);
                             if ($file) {
                                 $file->addEvent($e);
                                 // $e->addFile($file);
                                 //$objectManager->persist($file);
                             }
                         }
                     }
                     // alertes
                     if (isset($post['alarm']) && is_array($post['alarm'])) {
                         foreach ($post['alarm'] as $key => $alarmpost) {
                             // les modifications d'alarmes existantes sont faites en direct
                             // et ne passent pas par le formulaire
                             // voir AlarmController.php
                             $alarm = new Event();
                             $alarm->setCategory($objectManager->getRepository('Application\\Entity\\AlarmCategory')->findAll()[0]);
                             $alarm->setAuthor($this->zfcUserAuthentication()->getIdentity());
                             $alarm->setOrganisation($e->getOrganisation());
                             $alarm->setParent($e);
                             $alarm->setStatus($objectManager->getRepository('Application\\Entity\\Status')->findOneBy(array('open' => true, 'defaut' => true)));
                             $startdate = new \DateTime($alarmpost['date']);
                             $offset = $startdate->getTimezone()->getOffset($startdate);
                             $startdate->setTimezone(new \DateTimeZone("UTC"));
                             $startdate->add(new \DateInterval("PT" . $offset . "S"));
                             $alarm->setStartdate($startdate);
                             $alarm->setPunctual(true);
                             $alarm->setImpact($objectManager->getRepository('Application\\Entity\\Impact')->find(5));
                             $name = new CustomFieldValue();
                             $name->setCustomField($alarm->getCategory()->getNamefield());
                             $name->setValue($alarmpost['name']);
                             $name->setEvent($alarm);
                             $alarm->addCustomFieldValue($name);
                             $comment = new CustomFieldValue();
                             $comment->setCustomField($alarm->getCategory()->getTextfield());
                             $comment->setValue($alarmpost['comment']);
                             $comment->setEvent($alarm);
                             $alarm->addCustomFieldValue($comment);
                             $deltabegin = new CustomFieldValue();
                             $deltabegin->setCustomField($alarm->getCategory()->getDeltaBeginField());
                             $deltabegin->setValue($alarmpost['deltabegin']);
                             $deltabegin->setEvent($alarm);
                             $alarm->addCustomFieldValue($deltabegin);
                             $deltaend = new CustomFieldValue();
                             $deltaend->setCustomField($alarm->getCategory()->getDeltaEndField());
                             $deltaend->setValue($alarmpost['deltaend']);
                             $deltaend->setEvent($alarm);
                             $alarm->addCustomFieldValue($deltaend);
                             $e->addChild($alarm);
                             //$objectManager->persist($name);
                             //$objectManager->persist($comment);
                             //$objectManager->persist($deltabegin);
                             //$objectManager->persist($deltaend);
                             $objectManager->persist($alarm);
                         }
                     }
                     //certains évènements induisent des évènements fils
                     //il faut les créer à ce moment
                     if (!$id) {
                         //uniquement lors d'une création d'évènement
                         if ($e->getCategory() instanceof AntennaCategory) {
                             $frequencies = $e->getCustomFieldValue($e->getCategory()->getFrequenciesField());
                             $antennaState = $e->getCustomFieldValue($e->getCategory()->getStatefield())->getValue();
                             $antennaId = $e->getCustomFieldValue($e->getCategory()->getAntennafield())->getValue();
                             $antenna = $objectManager->getRepository('Application\\Entity\\Antenna')->find($antennaId);
                             $freqs = array();
                             if ($frequencies) {
                                 $freqids = explode("\r", $frequencies->getValue());
                                 foreach ($freqids as $freqid) {
                                     $freq = $objectManager->getRepository('Application\\Entity\\Frequency')->find($freqid);
                                     if ($freq) {
                                         $freqs[] = $freq;
                                     }
                                 }
                             }
                             if (!$frequencies || count($freqs) == 0) {
                                 //pas d'info sur les fréquences impactées : toutes les fréquences de l'antenne sont en panne
                                 foreach ($antenna->getMainfrequencies() as $freq) {
                                     $freqs[] = $freq;
                                 }
                                 foreach ($antenna->getMainfrequenciesclimax() as $freq) {
                                     $freqs[] = $freq;
                                 }
                             }
                             if ($antenna && $antennaState == 1) {
                                 //antenne indisponible : il faut créer les changements de couverture
                                 //pour les fréquences impactées
                                 foreach ($freqs as $freq) {
                                     if ($freq->hasMainAntenna($antenna) || $freq->hasMainClimaxAntenna($antenna)) {
                                         $objectManager->getRepository('Application\\Entity\\Event')->addChangeFrequencyCovEvent($freq, 1, 0, "Antenne principale indisponible", $e->getStartdate(), $e->getEnddate(), $this->zfcUserAuthentication()->getIdentity(), $e, $messages);
                                     }
                                 }
                             }
                         }
                     }
                     //mises en cohérence des alarmes
                     $e->updateAlarms();
                     $objectManager->persist($e);
                 }
                 try {
                     if ($recurrence !== null) {
                         $objectManager->persist($recurrence);
                         $messages['success'][] = "Récurrence correctement enregistrée.";
                     }
                     $objectManager->flush();
                     $messages['success'][] = $id ? "Evènement modifié" : "Évènement enregistré";
                 } catch (\Exception $e) {
                     $messages['error'][] = "Impossible d'enregistrer l'évènement.";
                     $messages['error'][] = $e->getMessage();
                     $events = array();
                 }
             } else {
                 $messages['error'][] = "Création ou modification impossible, droits insuffisants.";
             }
         } else {
             $messages['error'][] = "Requête illégale.";
         }
     } else {
         $messages['error'][] = "Utilisateur non authentifié, action impossible.";
     }
     if ($return) {
         foreach ($messages['success'] as $message) {
             $this->flashMessenger()->addSuccessMessage($message);
         }
         foreach ($messages['error'] as $message) {
             $this->flashMessenger()->addErrorMessage($message);
         }
         return $this->redirect()->toRoute('application');
     } else {
         $json = array();
         $json['messages'] = $messages;
         $jsonevents = array();
         foreach ($events as $e) {
             $jsonevents[$e->getId()] = $this->getEventJson($e);
         }
         foreach ($sendEvents as $e) {
             $jsonevents[$e->getId()] = $this->getEventJson($e);
         }
         if (count($jsonevents) > 0) {
             $json['events'] = $jsonevents;
         }
         return new JsonModel($json);
     }
 }