<?php namespace App\Controller; use App\Entity\Adherent; use App\Entity\Comptoir; use App\Entity\Cotisation; use App\Entity\Geoloc; 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\Enum\MoyenEnum; use App\Form\Type\ImportFormType; use DateTime; use Doctrine\ORM\EntityManagerInterface; use FOS\UserBundle\Model\UserManagerInterface; 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; class ImportController extends CRUDController { protected $siege; protected $header; protected $warnings; protected $errors; protected $success; protected $lineErrors; protected $em; protected $file; protected $security; protected $userManager; protected $translator; public function __construct(EntityManagerInterface $em, Security $security, UserManagerInterface $userManager, TranslatorInterface $translator) { $this->header = null; $this->warnings = array(); $this->errors = array(); $this->lineErrors = array(); $this->em = $em; $this->security = $security; $this->userManager = $userManager; $this->translator = $translator; $this->siege = null; } public function listAction() { $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(); // 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($media); if (empty($this->errors)) { $import = $this->em->getRepository(Import::class)->findOneById($idimport); $import->setEnabled(true); $this->em->persist($import); $this->em->flush(); $this->addFlash( 'success', 'Import effectué avec succès !' ); } } 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($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])); // dump($csvRows); // dump($header); // exit(); $config = $this->getParameter('app.import.header'); if ($this->header == $config['adherent']['header']) { $result = $this->importAdherent($csvRows); } else if ($this->header == $config['prestataire']['header']) { $result = $this->importPrestataire($csvRows); } else if ($this->header == $config['groupe']['header']) { $result = $this->importGroupe($csvRows); } else if ($this->header == $config['comptoir']['header']) { $result = $this->importComptoir($csvRows); } else { $this->errors['error'] = $this->translator->trans('CSV invalide'); } return $result; } private function importComptoir($csvRows) { // Iterate over the reader and write each row to the database // groupe;name;content;phone;mobile;adresse;cpostal;ville;compte $line = 0; foreach ($csvRows as $row) { if ($line == 0) { $line++; continue; } $groupe = $row['groupe']; $name = $row['name']; $content = $row['content']; $phone = $row['phone']; $adresse = $row['adresse']; $cpostal = $row['cpostal']; $ville = $row['ville']; $compte = $row['compte']; if (empty($groupe) && empty($name)) { $this->addError($row, $line, 'email & groupe', $this->translator->trans("L'email et le groupe sont obligatoires !")); $line++; continue; } $comptoir = $this->em->getRepository(Comptoir::class)->findOneBy(array('name' => $name, 'groupe' => $groupe)); if (empty($comptoir)) { $comptoir = new Comptoir(); 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); } $comptoir->setGroupe($groupeFound); } if (!empty($name)) { $comptoir->setName($name); } else { $this->addWarning($row, $line, 'name', 'empty'); } if (!empty($content)) { $comptoir->setContent($content); } else { $this->addWarning($row, $line, 'content', 'empty'); } if (!empty($phone)) { $comptoir->setTel($phone); } else { $this->addWarning($row, $line, 'phone', '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); $comptoir->setGeoloc($geolocFound); } $this->addSuccess($row, $line, 'comptoir', $this->translator->trans('Comptoir ajouté : ').$name); $this->em->persist($comptoir); $this->em->flush(); $this->em->clear(); } else { $this->addError($row, $line, 'name', $this->translator->trans("Le comptoir avec ce nom '".$name."' existe déjà !")); } $line++; } ksort($this->errors); ksort($this->warnings); } private function importGroupe($csvRows) { // Iterate over the reader and write each row to the database // name;content;compte $line = 0; foreach ($csvRows as $row) { if ($line == 0) { $line++; continue; } $name = $row['name']; $content = $row['content']; $compte = $row['compte']; $groupe = $this->em->getRepository(Groupe::class)->findOneBy(array('name' => $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'); } $this->addSuccess($row, $line, 'groupe', $this->translator->trans('Groupe ajouté : ').$name); $this->em->persist($groupe); $this->em->flush(); $this->em->clear(); } else { $this->addError($row, $line, 'name', $this->translator->trans("Le groupe avec ce nom '".$name."' existe déjà !")); } $line++; } ksort($this->errors); ksort($this->warnings); } private function importPrestataire($csvRows) { // Iterate over the reader and write each row to the database // groupe;adresse;cpostal;ville;raison;metier;statut;responsable;iban;siret;web;compte;horaires;description;firstname;lastname;email;phone;mobile;rubriques $line = 0; foreach ($csvRows as $row) { $hasError = false; if ($line == 0) { $line++; continue; } $groupe = $row['groupe']; $adresse = $row['adresse']; $cpostal = $row['cpostal']; $ville = $row['ville']; $raison = $row['raison']; $metier = $row['metier']; $statut = $row['statut']; $responsable = $row['responsable']; $iban = $row['iban']; $siret = $row['siret']; $web = $row['web']; $compte = $row['compte']; $horaires = $row['horaires']; $description = $row['description']; $firstname = $row['firstname']; $lastname = $row['lastname']; $email = $row['email']; $phone = $row['phone']; $mobile = $row['mobile']; $rubriques = $row['rubriques']; $prestataire = new Prestataire(); $user = $this->userManager->createUser(); $user->setEnabled(true); $user->setPassword(md5(random_bytes(10))); $user->addRole('ROLE_PRESTATAIRE'); $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Prestataire'); $user->addGroup($usergroupe); $user->setPrestataire($prestataire); $prestataire->setUser($user); if (!empty($raison)) { $prestataire->setRaison($raison); } else { $this->addWarning($row, $line, 'raison', 'empty'); } if (!empty($metier)) { $prestataire->setMetier($metier); } else { $this->addWarning($row, $line, 'metier', 'empty'); } if (!empty($statut)) { $prestataire->setStatut($statut); } else { $this->addWarning($row, $line, 'statut', 'empty'); } if (!empty($responsable)) { $prestataire->setResponsable($responsable); } else { $this->addWarning($row, $line, 'responsable', 'empty'); } if (!empty($iban)) { $prestataire->setIban($iban); } else { $this->addWarning($row, $line, 'iban', 'empty'); } if (!empty($siret)) { $prestataire->setSiret($siret); } else { $this->addWarning($row, $line, 'siret', 'empty'); } if (!empty($web)) { $prestataire->setWeb($web); } else { $this->addWarning($row, $line, 'web', 'empty'); } if (!empty($horaires)) { $prestataire->setHoraires($horaires); } else { $this->addWarning($row, $line, 'horaires', 'empty'); } if (!empty($description)) { $prestataire->setDescription($description); } else { $this->addWarning($row, $line, 'description', 'empty'); } 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++; 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($compte)) { $prestataire->setCompte($this->tofloat($compte)); } else { $this->addWarning($row, $line, 'compte', '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); } $prestataire->setGroupe($groupeFound); } else { $this->addWarning($row, $line, 'groupe', 'empty'); } if (!empty($rubriques)) { $rubriquesArray = explode(',', $rubriques); foreach ($rubriquesArray as $rubrique) { $rubriquesFound = $this->em->getRepository(Rubrique::class)->findOneBy(array('name' => $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); } } } else { $this->addWarning($row, $line, 'rubriques', 'empty'); } if (!empty($adresse) || !empty($cpostal) || !empty($ville)) { $geolocFound = new Geoloc(); $geolocFound->setAdresse($adresse); $geolocFound->setCpostal(intval($cpostal)); $geolocFound->setVille($ville); $prestataire->setGeoloc($geolocFound); } if (!$hasError) { $this->addSuccess($row, $line, 'user', $this->translator->trans('Prestataire bien ajouté : ').$user->__toString()); $this->userManager->updateUser($user); $this->em->persist($user); $this->em->flush(); $this->em->clear(); } $line++; } ksort($this->errors); ksort($this->warnings); } private function importAdherent($csvRows) { // Iterate over the reader and write each row to the database // groupe;firstname;lastname;email;phone;mobile;adresse;cpostal;ville;ecompte $line = 0; foreach ($csvRows as $row) { $hasError = false; if ($line == 0) { $line++; continue; } $groupe = $row['groupe']; $firstname = $row['firstname']; $lastname = $row['lastname']; $email = $row['email']; $phone = $row['phone']; $mobile = $row['mobile']; $adresse = $row['adresse']; $cpostal = $row['cpostal']; $ville = $row['ville']; $ecompte = $row['ecompte']; $cotisations = $row['cotisations']; $adherent = new Adherent(); $user = $this->userManager->createUser(); $user->setEnabled(true); $user->setPassword(md5(random_bytes(10))); $user->addRole('ROLE_ADHERENT'); $usergroupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent'); $user->addGroup($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++; 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 Cotisation(); $now = new DateTime(); $cotisation->setReference('Import du '.$now->format('d/m/Y H:i')); $cotisation->setOperateur($user); $cotisation->setExpediteur($adherent); $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE); $cotisationDetailsArray = explode(':', $cotisationDetails); if (count($cotisationDetailsArray) == 1) { $cotisation->setMontant(intval($cotisationDetails)); $cotisation->setDebut($now); $cotisation->setFin(new DateTime('+ 1 year')); } else { $cotisation->setMontant(intval($cotisationDetailsArray[0])); $cotisation->setAnnee(intval($cotisationDetailsArray[1])); $cotisation->setDebut(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'0101')); $cotisation->setFin(DateTime::createFromFormat('Ymd', intval($cotisationDetailsArray[1]).'1231')); } $user->addCotisation($cotisation); // $this->em->persist($cotisation); } } } 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->userManager->updateUser($user); $this->em->persist($user); $this->em->flush(); $this->em->clear(); } $line++; } ksort($this->errors); ksort($this->warnings); } private function parseCSV($filePath, $fileName, $ignoreFirstLine = false) { // $finder = new Finder(); // $finder->files() // ->in($filePath) // ->name($fileName) // ; // foreach ($finder as $file) { // $csv = $file; // } $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 !")); continue; } $rows[] = array_combine(array_values($firstline), array_values($data)); } } fclose($handle); } return $rows; } private function addSuccess($row, $line, $key, $message = '') { $csvline = implode(';', array_values($row)); $this->success[$line][$key][$csvline] = $message; } private function addError($row, $line, $key, $err = '') { $this->lineErrors[$line] = implode(';', array_values($row)); $this->errors[$line][$key][$this->lineErrors[$line]] = '"'.(array_key_exists($key, $row)?$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][$csvline] ='['.$errString.' ]'; } else if ($err == 'invalid') { $errString = $this->translator->trans('Valeur invalide !'); $this->warnings[$line][$key][$csvline] = '"'.(array_key_exists($key, $row)?$row[$key]:'').'" ['.$errString.']'; } else if ($err != '') { $this->warnings[$line][$key][$csvline] = '"'.(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))) ); } }