<?php namespace App\Controller; use App\Entity\Adherent; use App\Entity\ContactComptoir; use App\Entity\ContactPrestataire; use App\Entity\Comptoir; use App\Entity\CotisationAdherent; use App\Entity\CotisationPrestataire; use App\Entity\EtatPrestataire; use App\Entity\Geoloc; use App\Entity\GeolocPrestataire; use App\Entity\Groupe; use App\Entity\Import; use App\Entity\Prestataire; use App\Entity\Rubrique; use App\Entity\Siege; use App\Entity\User; use App\Entity\Usergroup; use App\Entity\Flux; use App\Entity\TypePrestataire; use App\Enum\ImportEnum; use App\Enum\MoyenEnum; use App\Events\MLCEvents; use App\Form\Type\ImportFormType; use Gedmo\Sluggable\Util as Sluggable; use Behat\Transliterator\Transliterator; use DateTime; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\ORM\EntityManagerInterface; use FOS\UserBundle\Event\UserEvent; use FOS\UserBundle\Model\UserInterface; use FOS\UserBundle\Model\UserManagerInterface; use FOS\UserBundle\Util\TokenGeneratorInterface; use FOS\UserBundle\Util\UserManipulator; use Sonata\AdminBundle\Controller\CRUDController; use Symfony\Component\Finder\Finder; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Security; use Symfony\Component\Translation\TranslatorInterface; use Symfony\Component\EventDispatcher\EventDispatcherInterface; class ImportController extends CRUDController { protected $siege; protected $header; protected $warnings; protected $errors; protected $nberrors; protected $nbsuccess; protected $success; protected $lineErrors; protected $em; protected $file; protected $security; protected $userManager; protected $translator; protected $tokenGenerator; protected $eventDispatcher; public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator, TokenGeneratorInterface $tokenGenerator, EventDispatcherInterface $eventDispatcher) { $this->header = null; $this->warnings = array(); $this->errors = array(); $this->nberrors = 0; $this->nbsuccess = 0; $this->lineErrors = array(); $this->em = $em; $this->security = $security; $this->userManager = $userManager; $this->translator = $translator; $this->tokenGenerator = $tokenGenerator; $this->eventDispatcher = $eventDispatcher; $this->siege = null; $this->sendemail = false; } /** * @TODO: manage the case of a fatal error (so catch the exception, and display a nice message)! */ public function createAction() { $this->siege = $this->em->getRepository(Siege::class)->findOneById(1); $import = new Import(); $import->setUser($this->getUser()); $form = $this->createForm(ImportFormType::class, $import); $form->handleRequest($this->getRequest()); if ($form->isSubmitted() && $form->isValid()) { $import = $form->getData(); $media = $import->getMedia(); $type = $import->getType(); $this->sendemail = (bool)$import->getSendemail(); // Sauvegarder l'import en base de données avant l'essai d'import $this->em->persist($import); $this->em->flush(); $idimport = $import->getId(); $this->importFromCSV($type, $media); $import = $this->em->getRepository(Import::class)->findOneById($idimport); $import->setEnabled(true); $import->setSuccess(json_encode($this->success)); $import->setWarnings(json_encode($this->warnings)); $import->setErrors(json_encode($this->errors)); $import->setNbentityadded($this->nbsuccess); $import->setNbentityerror($this->nberrors); $this->em->persist($import); $this->em->flush(); if (empty($this->errors)) { $this->addFlash( 'success', 'Import effectué avec succès !' ); } else { $this->addFlash( 'error', "Il y a eu des erreurs lors de l'import !" ); } return $this->redirect($this->admin->generateUrl('show', array('id' => $import->getId()))); } return $this->renderWithExtraParams('admin/import.html.twig', array( 'action' => 'list', 'form' => $form->createView(), 'errors' => $this->errors, 'warnings' => $this->warnings, 'success' => $this->success, 'linkcsverror' => (count($this->lineErrors) > 0)?$this->generateUrl('getcsv', array('header' => $this->header, 'data' => array_values($this->lineErrors))):null, 'csvparams' => $this->getParameter('app.import.header') )); } private function importFromCSV($type, $media) { // Turning off doctrine default logs queries for saving memory $this->em->getConnection()->getConfiguration()->setSQLLogger(null); // Get file provider $provider = $this->container->get($media->getProviderName()); $csvRows = $this->parseCSV($provider->getFilesystem()->getAdapter()->getDirectory(), $provider->getReferenceImage($media)); $this->header = implode(';', array_values($csvRows[0])); $config = $this->getParameter('app.import.header'); if ($type == ImportEnum::IMPORT_ADHERENT) { $result = $this->importAdherent($csvRows); } elseif ($type == ImportEnum::IMPORT_PRESTATAIRE) { $result = $this->importPrestataire($csvRows); } elseif ($type == ImportEnum::IMPORT_GROUPE) { $result = $this->importGroupe($csvRows); } elseif ($type == ImportEnum::IMPORT_COMPTOIR) { $result = $this->importComptoir($csvRows); } else { // Ne devrait jamais arriver, mais sait-on jamais ! $this->errors['error'] = $this->translator->trans('Choisir un type de données à importer !'); } return $result; } private function slugify($string) { $string = Transliterator::transliterate($string, '-'); return Transliterator::urlize($string, '-'); } private function importComptoir($csvRows) { // Iterate over the reader and write each row to the database //groupe;nom;description;adresse;cpostal;ville;latitude;longitude;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;contact1;phone1;email1;contact2;phone2;email2 $line = 1; foreach ($csvRows as $row) { if ($line == 1) { $line++; continue; } if (!(array_key_exists("groupe", $row) && array_key_exists("nom", $row))) { $this->addError($row, $line, 'nom & groupe', $this->translator->trans("Les colonnes 'nom' et 'groupe' sont obligatoires !")); $this->nberrors++; $line++; continue; } $groupe = array_key_exists("groupe", $row) ? $row['groupe'] : ''; $nom = array_key_exists("nom", $row) ? $row['nom'] : ''; if (empty($groupe)) { $this->addError($row, $line, 'groupe', $this->translator->trans("Le 'groupe' est obligatoire !")); $this->nberrors++; $line++; continue; } if (empty($nom)) { $this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !")); $this->nberrors++; $line++; continue; } $description = array_key_exists("description", $row) ? $row['description'] : ''; $adresse = array_key_exists("adresse", $row) ? $row['adresse'] : ''; $cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : ''; $ville = array_key_exists("ville", $row) ? $row['ville'] : ''; $latitude = array_key_exists("latitude", $row) ? $row['latitude'] : ''; $longitude = array_key_exists("longitude", $row) ? $row['longitude'] : ''; $compte = array_key_exists("compte", $row) ? $row['compte'] : ''; $groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('slug' => $this->slugify($groupe))); if (empty($groupeFound)) { $groupeFound = new Groupe(); $groupeFound->setName($groupe); $groupeFound->setSiege($this->siege); $this->em->persist($groupeFound); $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$groupe); } $comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(array('slug' => $this->slugify($nom), 'groupe' => $groupeFound)); if (empty($comptoir)) { $comptoir = new Comptoir(); $comptoir->setGroupe($groupeFound); $comptoir->setName($nom); if (!empty($description)) { $comptoir->setContent($description); } else { $this->addWarning($row, $line, 'description', 'empty'); } if (!empty($compte)) { $comptoir->setCompte($this->tofloat($compte)); } else { $this->addWarning($row, $line, 'compte', 'empty'); } if (!empty($adresse) || !empty($cpostal) || !empty($ville)) { $geolocFound = new Geoloc(); $geolocFound->setAdresse($adresse); $geolocFound->setCpostal(intval($cpostal)); $geolocFound->setVille($ville); if (!empty($latitude) && !empty($longitude)) { $geolocFound->setLat((float)$latitude); $geolocFound->setLon((float)$longitude); } $comptoir->setGeoloc($geolocFound); } // Importer les contacts du comptoir s'ils existent (par défaut en public) $cptContact = 1; while (array_key_exists("contact".$cptContact, $row) && $cptContact < 10) { $contact = array_key_exists('contact'.$cptContact, $row) ? $row['contact'.$cptContact] : ''; $phone = array_key_exists('phone'.$cptContact, $row) ? $row['phone'.$cptContact] : ''; $email = array_key_exists('email'.$cptContact, $row) ? $row['email'.$cptContact] : ''; $contactC = new ContactComptoir(); $contactC->setComptoir($comptoir); $contactC->setEnabled(true); $contactC->setName($contact); $contactC->setTel($phone); $contactC->setEmail($email); $this->em->persist($contactC); ++$cptContact; } // Importer les gestionnaires de comptoir s'ils existent $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Comptoir'); $gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire); $comptoir->setGestionnaires($gestionnaires); $this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ').$nom); $this->nbsuccess++; $this->em->persist($comptoir); $this->em->flush(); $this->em->clear(); } else { $this->addError($row, $line, 'nom', $this->translator->trans("Le comptoir avec ce nom {name} existe déjà !", ['name' => $nom])); $this->nberrors++; } $line++; } ksort($this->errors); ksort($this->warnings); } private function importGroupe($csvRows) { // Iterate over the reader and write each row to the database // nom;description;compte;gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1 $line = 1; foreach ($csvRows as $row) { if ($line == 1) { $line++; continue; } $name = array_key_exists("nom", $row) ? $row['nom'] : ''; if (empty($name)) { $this->addError($row, $line, 'nom', $this->translator->trans("Le 'nom' est obligatoire !")); $this->nberrors++; $line++; continue; } $description = array_key_exists("description", $row) ? $row['description'] : ''; $compte = array_key_exists("compte", $row) ? $row['compte'] : ''; $groupe = $this->em->getRepository(Groupe::class)->findOneBy(array('slug' => $this->slugify($name))); if (empty($groupe)) { $groupe = new Groupe(); $groupe->setSiege($this->em->getRepository(Siege::class)->findOneById(1)); if (!empty($name)) { $groupe->setName($name); } else { $this->addWarning($row, $line, 'name', 'empty'); } if (!empty($content)) { $groupe->setContent($content); } else { $this->addWarning($row, $line, 'content', 'empty'); } if (!empty($compte)) { $groupe->setCompte($this->tofloat($compte)); } else { $this->addWarning($row, $line, 'compte', 'empty'); } // Importer les gestionnaires du groupe s'ils existent $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Gestionnaire de Groupe'); $gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire); $groupe->setGestionnaires($gestionnaires); $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$name); $this->em->persist($groupe); $this->nbsuccess++; $this->em->flush(); $this->em->clear(); } else { $this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '".$name."' existe déjà !")); $this->nberrors++; } $line++; } ksort($this->errors); ksort($this->warnings); } private function importPrestataire($csvRows) { $operateur = $this->getUser(); $operateur_id = $operateur->getId(); $line = 0; /** * Iterate over the reader and write each row to the database. * Each row has at least 6 required columns. * * Row format: groupe;adresse;cpostal;ville;raison;ecompte;metier;statut;responsable;iban;siret;web;horaires;... * description;rubriques;tags;tauxreconversion;cotisations;... * gestionnaire_email1;gestionnaire_nom1;gestionnaire_prenom1;gestionnaire_phone1;gestionnaire_mobile1;... * contact1;phone1;email1;contact2;phone2;email2 */ $requiredColumns = [ 'groupe', 'raison', 'siret', 'adresse', 'cpostal', 'ville', ]; $warningColumns = [ 'metier', 'statut', 'responsable', 'iban', 'web', 'horaires', 'description', 'ecompte', ]; $columns = array_fill_keys( array_merge($requiredColumns, $warningColumns, ['rubriques', 'tags', 'tauxreconversion', 'cotisations']), null ); foreach ($csvRows as $row) { $hasError = false; $line++; // The header is ignored if ($line === 1) { continue; } // Add the missing columns to the current row (with a null value). $row += $columns; /** * Check the required columns. * If one is not present or empty => add an error and go to the next line. */ foreach ($requiredColumns as $column) { if (! $row[$column]) { $this->addError($row, $line, $column, $this->translator->trans('prestataire.column_required', [$column], 'import') ); $hasError = true; } } if ($hasError) { $this->nberrors++; continue; } /** * If it doesn't exist yet, create and fill a Prestataire. * Otherwise => error! */ $prestataire = $this->em->getRepository(Prestataire::class)->findOneBy([ 'slug' => $this->slugify($row['raison']) ]); if (!$prestataire) { $prestataire = new Prestataire(); // Actually, each new Prestataire will have the 'prestataire' as TypePrestataire // @TODO: add a column 'type' in the CSV file (to choose a TypePrestataire)? $prestataire->setTypePrestataire($this->em->getRepository(TypePrestataire::class)->findOneBy([ 'slug' => 'prestataire' ])); foreach ($requiredColumns as $column) { // Special processings for these fields => so we skip them if (in_array($column, ['groupe', 'adresse', 'cpostal', 'ville'])) continue; $prestataire->{'set'.ucfirst($column)}($row[$column]); } // Special processing for the 'ecompte' field if ($e =& $row['ecompte']) { $e = $this->tofloat($e); } foreach ($warningColumns as $column) { if ($row[$column]) { $prestataire->{'set'.ucfirst($column)}($row[$column]); } else { $this->addWarning($row, $line, $column, 'empty'); } } /** * If one or many Contacts are present, we create them for the Prestataire. * If a phone or an email is defined, the associated 'contact' field must be defined too! */ for ($i = 1; $i < 10; $i++) { $name = $row["contact$i"] ?? null; $phone = $row["phone$i"] ?? null; $email = $row["email$i"] ?? null; if ($name) { $contact = new ContactPrestataire(); $contact->setPrestataire($prestataire); $contact->setEnabled(true); $contact->setName($name); $contact->setTel($row["phone$i"] ?? ''); $contact->setEmail($row["email$i"] ?? ''); $this->em->persist($contact); } elseif ($phone || $email) { $this->addError($row, $line, "contact$i", $this->translator->trans('prestataire.column_required', ["contact$i"], 'import') ); $hasError = true; } } if ($hasError) { $this->nberrors++; continue; } // Importer les gestionnaires du prestataire s'ils existent $groupeGestionnaire = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire'); $gestionnaires = $this->importGestionnaires($row, $groupeGestionnaire); $prestataire->setUsers($gestionnaires); /** * If no Groupe object exists for the 'groupe' field, we create one. * Note: at this point, the 'groupe' field is necessarily not empty (because it was required above). */ $groupe = $row['groupe']; $groupeObj = $this->em->getRepository(Groupe::class)->findOneBy(['name' => $groupe]); if (! $groupeObj) { $groupeObj = new Groupe(); $groupeObj->setName($groupe); $groupeObj->setSiege($this->siege); $this->em->persist($groupeObj); $this->addSuccess($row, $line, 'groupe', $this->translator->trans('prestataire.groupe_notfound_created', [$groupe], 'import') ); } $prestataire->setGroupe($groupeObj); if ($cotisations = $row['cotisations']) { $cotisationArray = explode(',', $cotisations); foreach ($cotisationArray as $cotisationDetails) { $cotisation = new CotisationPrestataire(); $now = new DateTime(); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setOperateur($operateur); $cotisation->setRole('ROLE_SUPER_ADMIN'); $cotisation->setExpediteur($prestataire); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisationDetailsArray = explode(':', $cotisationDetails); if (count($cotisationDetailsArray) == 1) { $cotisation->setMontant(intval($cotisationDetails[0])); $cotisation->getCotisationInfos()->setDebut($now); $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year')); } else { $cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231')); } $this->em->persist($cotisation); $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajouté : ').$groupe); } } else { $this->addWarning($row, $line, 'cotisations', 'empty'); } if ($rubriques = $row['rubriques']) { $rubriquesArray = explode(',', $rubriques); foreach ($rubriquesArray as $rubrique) { $rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('slug' => $this->slugify($rubrique))); if (empty($rubriquesFound)) { $rubriquesFound = new Rubrique(); $rubriquesFound->setName($rubrique); $this->em->persist($rubriquesFound); $this->addSuccess($row, $line, 'rubrique', $this->translator->trans('Rubrique ajoutée : ').$rubrique); } $prestataire->addRubrique($rubriquesFound); } } else { $this->addWarning($row, $line, 'rubriques', 'empty'); } if ($tags = $row['tags']) { $tagsArray = explode(',', $tags); foreach ($tagsArray as $tag) { $tagsFound = $this->em->getRepository(EtatPrestataire::class)->findOneBy(array('slug' => $this->slugify($tag))); if (empty($tagsFound)) { $tagNew = new EtatPrestataire(); $tagNew->setName($tag); $this->em->persist($tagNew); $this->addSuccess($row, $line, 'tag', $this->translator->trans('Tag ajouté : ').$tag); } } } else { $this->addWarning($row, $line, 'tags', 'empty'); } /** * Add a Geoloc for this Prestataire. * At this point, 'adresse', 'cpostal' and 'ville' fields exist and are not empty. */ $geoloc = new Geoloc(); $geoloc->setEnabled(true); $geoloc->setAdresse($row['adresse']); $geoloc->setCpostal($row['cpostal']); $geoloc->setVille($row['ville']); $geolocP = new GeolocPrestataire(); $geolocP->setName('Adresse'); $geolocP->setPrestataire($prestataire); $geolocP->setGeoloc($geoloc); $this->em->persist($geolocP); $prestataire->setGeolocs([$geolocP]); } else { $this->addError($row, $line, 'raison', $this->translator->trans('prestataire.already_exists', [$row['raison']], 'import') ); $this->nberrors++; $hasError = true; } if (!$hasError) { $this->em->persist($prestataire); $this->em->flush(); $this->em->clear(); // em is fully cleared: we need to refetch entities we get from em during process $operateur = $this->em->getRepository(User::class)->findOneById($operateur_id); $this->siege = $this->em->getRepository(Siege::class)->findOneById(1); $this->addSuccess($row, $line, 'user', $this->translator->trans('prestataire.added', [(string) $prestataire], 'import') ); $this->nbsuccess++; } } ksort($this->errors); ksort($this->warnings); } private function importAdherent($csvRows) { // Batch operations with doctrine require some workaround $operateur = $this->getUser(); $operateur_id = $operateur->getId(); // Iterate over the reader and write each row to the database // groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte $line = 1; foreach ($csvRows as $row) { $hasError = false; if ($line == 1) { $line++; continue; } $groupe = array_key_exists("groupe", $row) ? $row['groupe'] : ''; $firstname = array_key_exists("firstname", $row) ? $row['firstname'] : ''; $lastname = array_key_exists("lastname", $row) ? $row['lastname'] : ''; $email = array_key_exists("email", $row) ? $row['email'] : ''; $phone = array_key_exists("phone", $row) ? $row['phone'] : ''; $mobile = array_key_exists("mobile", $row) ? $row['mobile'] : ''; $adresse = array_key_exists("adresse", $row) ? $row['adresse'] : ''; $cpostal = array_key_exists("cpostal", $row) ? $row['cpostal'] : ''; $ville = array_key_exists("ville", $row) ? $row['ville'] : ''; $ecompte = array_key_exists("ecompte", $row) ? $row['ecompte'] : ''; $cotisations = array_key_exists("cotisations", $row) ? $row['cotisations'] : ''; if (!(array_key_exists("email", $row))) { $this->addError($row, $line, 'email', $this->translator->trans("La colonne 'email' est obligatoire !")); $line++; $this->nberrors++; continue; } $adherent = new Adherent(); $user = $this->userManager->createUser(); $user->setConfirmationToken($this->tokenGenerator->generateToken()); $user->setEnabled(true); $user->setPassword(md5(random_bytes(10))); $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent'); $user->addPossiblegroup($usergroupe); $user->setGroups([$usergroupe]); $user->setAdherent($adherent); $adherent->setUser($user); if (!empty($firstname)) { $user->setFirstname($firstname); } else { $this->addWarning($row, $line, 'firstname', 'empty'); } if (!empty($lastname)) { $user->setLastname($lastname); } else { $this->addWarning($row, $line, 'lastname', 'empty'); } if (!empty($email)) { $userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email)); if (!empty($userFound)) { $hasError = true; $this->addError($row, $line, 'email', $this->translator->trans("L'email est déjà utilisé !")); $line++; $this->nberrors++; continue; } else { $user->setEmail($email); $user->setUsername($email); } } else { $this->addWarning($row, $line, 'email', 'empty'); } if (!empty($phone)) { $user->setPhone($phone); } else { $this->addWarning($row, $line, 'phone', 'empty'); } if (!empty($mobile)) { $user->setMobile($mobile); } else { $this->addWarning($row, $line, 'mobile', 'empty'); } if (!empty($ecompte)) { $adherent->setEcompte($this->tofloat($ecompte)); } else { $this->addWarning($row, $line, 'ecompte', 'empty'); } if (!empty($groupe)) { $groupeFound = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $groupe)); if (empty($groupeFound)) { $groupeFound = new Groupe(); $groupeFound->setName($groupe); $groupeFound->setSiege($this->siege); $this->em->persist($groupeFound); $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$groupe); } $adherent->setGroupe($groupeFound); } else { $this->addWarning($row, $line, 'groupe', 'empty'); } if (!empty($cotisations)) { $cotisationArray = explode(',', $cotisations); if (count($cotisationArray) > 0) { foreach ($cotisationArray as $cotisationDetails) { $cotisation = new CotisationAdherent(); $now = new DateTime(); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setOperateur($operateur); $cotisation->setRole('ROLE_ADHERENT'); $cotisation->setExpediteur($adherent); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisationDetailsArray = explode(':', $cotisationDetails); if (count($cotisationDetailsArray) == 1) { $cotisation->setMontant(intval($cotisationDetails)); $cotisation->getCotisationInfos()->setDebut($now); $cotisation->getCotisationInfos()->setFin(new DateTime('+ 1 year')); } else { $cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->getCotisationInfos()->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->getCotisationInfos()->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->getCotisationInfos()->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231')); } $this->em->persist($cotisation); $this->addSuccess($row, $line, 'cotisations', $this->translator->trans('Cotisation ajoutée : ').$groupe); } } } else { $this->addWarning($row, $line, 'cotisations', 'empty'); } if (!empty($adresse) || !empty($cpostal) || !empty($ville)) { $geolocFound = new Geoloc(); $geolocFound->setAdresse($adresse); $geolocFound->setCpostal(intval($cpostal)); $geolocFound->setVille($ville); $adherent->setGeoloc($geolocFound); } if (!$hasError) { $this->addSuccess($row, $line, 'user', $this->translator->trans('Utilisateur bien ajouté : ').$user->__toString()); $this->nbsuccess++; $user->setPasswordRequestedAt(new \DateTime()); $this->userManager->updateUser($user); if ($this->sendemail) { $this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest())); } $this->em->flush(); $this->em->clear(); // em is fully cleared: we need to refetch entities we get from em during process $operateur = $this->em->getRepository(User::class)->findOneBy(array('id' => $operateur_id)); } $line++; } ksort($this->errors); ksort($this->warnings); } /** * Open and parse .CSV file * @param string $filePath Path of the file * @param string $fileName Name of the file * @param boolean $ignoreFirstLine If true, ignore first line * @return array Array of parsed values with array's key = firstline */ private function parseCSV($filePath, $fileName, $ignoreFirstLine = false) { $csv = new \SplFileObject($filePath.'/'.$fileName); $rows = array(); $firstline = null; if (($handle = fopen($csv->getRealPath(), "r")) !== false) { $i = 0; while (($data = fgetcsv($handle, null, ";")) !== false) { $i++; if ($i == 1) { $firstline = $data; $rows[] = $data; if ($ignoreFirstLine) { continue; } } else { if (count($firstline) != count($data)) { $this->addError($data, $i, 'Ligne entière', $this->translator->trans("La ligne ne contient pas le bon nombre d'éléments requis !")); $this->nberrors++; continue; } $rows[] = array_combine(array_values($firstline), array_values($data)); } } fclose($handle); } return $rows; } /** * Import manager of comptoir / groupe / presta * @param array $row Value of line imported * @param Usergroup $groupe Groupe add to manager imported * @return User Manager created */ private function importGestionnaires($row, Usergroup $groupe) { $cptGestionnaire = 1; $users = new ArrayCollection(); while (array_key_exists("gestionnaire_email".$cptGestionnaire, $row) && !empty($row['gestionnaire_email'.$cptGestionnaire]) && $cptGestionnaire < 10) { $email = array_key_exists('gestionnaire_email'.$cptGestionnaire, $row) ? $row['gestionnaire_email'.$cptGestionnaire] : ''; $userFound = $this->em->getRepository(User::class)->findOneBy(array('email' => $email)); if (!empty($userFound)) { $userFound->addPossiblegroup($groupe); $users[] = $userFound; $this->em->persist($userFound); } else { $nom = array_key_exists('gestionnaire_nom'.$cptGestionnaire, $row) ? $row['gestionnaire_nom'.$cptGestionnaire] : ''; $prenom = array_key_exists('gestionnaire_prenom'.$cptGestionnaire, $row) ? $row['gestionnaire_prenom'.$cptGestionnaire] : ''; $phone = array_key_exists('gestionnaire_phone'.$cptGestionnaire, $row) ? $row['gestionnaire_phone'.$cptGestionnaire] : ''; $mobile = array_key_exists('gestionnaire_mobile'.$cptGestionnaire, $row) ? $row['gestionnaire_mobile'.$cptGestionnaire] : ''; $user = $this->userManager->createUser(); $user->setConfirmationToken($this->tokenGenerator->generateToken()); $user->setEnabled(true); $user->setPassword(md5(random_bytes(10))); $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adhérent'); $user->addPossiblegroup($usergroupe); $user->addPossiblegroup($groupe); $user->setGroups([$groupe]); $user->setFirstname($prenom); $user->setLastname($nom); $user->setPhone($phone); $user->setMobile($mobile); $user->setEmail($email); $user->setUsername($user->getName()); $users[] = $user; $this->em->persist($user); } if ($this->sendemail) { $this->eventDispatcher->dispatch(MLCEvents::REGISTRATION_ADHERENT, new UserEvent($user, $this->getRequest())); } ++$cptGestionnaire; } return $users; } private function addSuccess($row, $line, $key, $message = '') { $csvline = implode(';', array_values($row)); $this->success[$line][$key] = $message; } private function addError($row, $line, $key, $err = '') { $this->lineErrors[$line] = implode(';', array_values($row)); $this->errors[$line][$key] = (array_key_exists($key, $row)?(!empty($row[$key])?'"'.$row[$key].'"':''):'').' ['.$err.']'; } private function addWarning($row, $line, $key, $err = '') { $csvline = implode(';', array_values($row)); if ($err == 'empty') { $errString = $this->translator->trans('Valeur vide !'); $this->warnings[$line][$key] ='['.$errString.' ]'; } elseif ($err == 'invalid') { $errString = $this->translator->trans('Valeur invalide !'); $this->warnings[$line][$key] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$errString.']'; } elseif ($err != '') { $this->warnings[$line][$key] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$err.']'; } } private function tofloat($num) { $dotPos = strrpos($num, '.'); $commaPos = strrpos($num, ','); $sep = (($dotPos > $commaPos) && $dotPos) ? $dotPos : ((($commaPos > $dotPos) && $commaPos) ? $commaPos : false); if (!$sep) { return floatval(preg_replace("/[^0-9]/", "", $num)); } return floatval( preg_replace("/[^0-9]/", "", substr($num, 0, $sep)) . '.' . preg_replace("/[^0-9]/", "", substr($num, $sep+1, strlen($num))) ); } }