IndexController.php 19.9 KB
Newer Older
Julien Jorry committed
1 2 3 4
<?php

namespace App\Controller;

5 6
use App\Entity\Adherent;
use App\Entity\Cotisation;
Julien Jorry committed
7
use App\Entity\Comptoir;
8
use App\Entity\Faq;
9
use App\Entity\Geoloc;
Julien Jorry committed
10 11
use App\Entity\Groupe;
use App\Entity\GlobalParameter;
12
use App\Entity\Page;
Julien Jorry committed
13
use App\Entity\Prestataire;
14
use App\Entity\Siege;
15
use App\Entity\User;
16
use App\Entity\Usergroup;
17
use App\Enum\MoyenEnum;
18
use App\Form\Type\AdhererFormType;
19
use App\Form\Type\ContactFormType;
20
use App\Form\Type\InstallFormType;
21
use App\Form\Type\TransactionAdherentPrestataireFormType;
22
use App\Security\LoginAuthenticator;
23
use Doctrine\ORM\EntityManagerInterface;
24 25 26 27 28
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\Model\UserInterface;
29
use FOS\UserBundle\Model\UserManagerInterface;
30 31 32 33
use Geocoder\Provider\Nominatim\Nominatim;
use Geocoder\Query\GeocodeQuery;
use Nelmio\ApiDocBundle\Annotation\Model;
use Nelmio\ApiDocBundle\Annotation\Security;
34
use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;
Julien Jorry committed
35
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
36
use Swagger\Annotations as SWG;
Julien Jorry committed
37
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
38 39
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\Form\FormEvent;
40
use Symfony\Component\HttpFoundation\JsonResponse;
41
use Symfony\Component\HttpFoundation\RedirectResponse;
42
use Symfony\Component\HttpFoundation\Request;
Julien Jorry committed
43 44
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
Julien Jorry committed
45
use Symfony\Component\Routing\Annotation\Route;
46
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
47 48 49
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security as Secur;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
50
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
51
use Symfony\Component\Templating\EngineInterface;
Julien Jorry committed
52 53 54

class IndexController extends AbstractController
{
55
    private $eventDispatcher;
56
    private $em;
57
    private $userManager;
58
    private $tokenManager;
59
    private $guard;
60
    private $authenticator;
Julien Jorry committed
61
    private $session;
62 63
    private $mailer;
    private $templating;
64

65
    public function __construct(EventDispatcherInterface $eventDispatcher, EntityManagerInterface $em, UserManagerInterface $userManager, CsrfTokenManagerInterface $tokenManager = null, GuardAuthenticatorHandler $guard, SessionInterface $session, \Swift_Mailer $mailer, EngineInterface $templating, LoginAuthenticator $authenticator)
66
    {
67
        $this->eventDispatcher = $eventDispatcher;
68
        $this->em = $em;
69
        $this->userManager = $userManager;
70
        $this->tokenManager = $tokenManager;
71
        $this->guard = $guard;
72
        $this->authenticator = $authenticator;
Julien Jorry committed
73
        $this->session = $session;
74 75
        $this->mailer = $mailer;
        $this->templating = $templating;
76 77
    }

Julien Jorry committed
78
    /**
Julien Jorry committed
79
     * @Route("/", name="index")
Julien Jorry committed
80 81
     */
    // public function index(TranslatorInterface $translator)
82
    public function index(Request $request)
Julien Jorry committed
83 84 85 86 87 88 89 90 91
    {
        // Exemple pour la traduction :
        // $translated = $translator->trans('Symfony is great');
        // $translator->transChoice(
        //     'Hurry up %name%! There is one apple left.|There are %count% apples left.',
        //     10,
        //     // no need to include %count% here; Symfony does that for you
        //     array('%name%' => $user->getName())
        // );
92

93 94 95 96 97
        /* Pour la première installation */
        $siege = $this->em->getRepository(Siege::class)->findAll();
        if ($siege == null || empty($siege)) {
            return $this->redirectToRoute('installation');
        }
98 99 100 101 102 103 104 105 106
        /* Pour la modale de login => SecurityController loginAction */
        $session = $request->getSession();
        $lastUsernameKey = Secur::LAST_USERNAME;
        // last username entered by the user
        $lastUsername = (null === $session) ? '' : $session->get($lastUsernameKey);
        $csrfToken = $this->tokenManager
            ? $this->tokenManager->getToken('authenticate')->getValue()
            : null;

107 108 109 110 111 112 113
        $isWordpress = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::USE_WORDPRESS) != 'false';

        $template = 'index.html.twig';
        if ($isWordpress) {
            $template = 'index_wordpress.html.twig';
        }
        return $this->render($template, [
114
            'news' => array(),
115 116
            'last_username' => $lastUsername,
            'csrf_token' => $csrfToken
117 118
        ]);
    }
119

120 121 122 123 124 125
    /**
     * @Route("/installation", name="installation")
     */
    public function installationAction(Request $request)
    {
        $siege = $this->em->getRepository(Siege::class)->findOneById(1);
126 127 128 129
        // if (!empty($siege)) {
        //     // Installation déjà effectuée !
        //     return $this->redirectToRoute('index');
        // }
130 131
        $repogroup = $this->em->getRepository(Usergroup::class);
        $group = $repogroup->findOneBy(array('name' => 'Super Admin'));
Julien Jorry committed
132 133 134 135
        if (empty($group)) {
            return new Response('ERREUR !<br><br>Avant de pouvoir installer le kohinos, il faut charger les fixtures : <br>Soit charger les fixtures standards :<br><em>php bin/console hautelook:fixtures:load --purge-with-truncate</em><br/><br/>Soit charger les fixtures de dev (pour tester le kohinos avec des données/comptes factices):<br/><em>php bin/console hautelook:fixtures:load --purge-with-truncate --env=test</em>', 200);
        }
        $user = $this->userManager->createUser();
136
        $user->setEnabled(true);
137
        $user->addPossiblegroup($group);
138 139 140 141 142 143 144
        $user->addGroup($group);
        $form = $this->createForm(InstallFormType::class, ['user' => $user]);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $siege = $form['siege']->getData();
            $user = $form['user']->getData();
Julien Jorry committed
145 146 147 148 149 150 151 152 153 154 155 156 157 158
            $groupe = $form['groupe']->getData();
            $comptoir = $form['comptoir']->getData();
            $configs = $form['config']->getData();
            $groupe->setSiege($siege);
            $comptoir->setGroupe($groupe);
            
            //Création du prestataire recevant les cotisations
            $presta = new Prestataire();
            $presta->setMlc(true);
            $presta->setRaison('Monnaie locale');
            $presta->setDescription('Association gérant la monnaie locale et recevant les cotisations');
            $presta->setEnabled(true);
            $presta->setIban(' ');
            $presta->setSiret(' ');
Julien Jorry committed
159
            $groupePresta = $repogroup->findOneBy(array('name' => 'Prestataire'));
160
            $user->addPossiblegroup($groupePresta);
Julien Jorry committed
161 162 163
            $presta->addUser($user);
            $presta->setGroupe($groupe);

164
            $this->em->persist($siege);
Julien Jorry committed
165 166
            $this->em->persist($groupe);
            $this->em->persist($comptoir);
167
            $this->userManager->updateUser($user);
Julien Jorry committed
168 169 170 171
            $this->em->persist($presta);
            foreach ($configs as $config) {
                $this->em->persist($config);
            }
172
            $this->em->flush();
173 174 175 176
            // Création de l'utilisateur avec ROLE_API pour le plugin Wordpress ou les applis tierces !
            $userAPI = $this->userManager->createUser();
            $userAPI->setEnabled(true);
            $userAPI->setUsername('userapi');
177 178
            $userAPI->setPassword(md5(random_bytes(10)));
            $userAPI->setEmail('userapi@kohinos.fr');
179
            $userAPI->addRole('ROLE_API');
180
            $this->userManager->updateUser($userAPI);
181
            
Julien Jorry committed
182
            $this->em->flush();
183 184
            $this->addFlash(
                'success',
185
                "BRAVO ! Vous venez de configurer le Kohinos. Vous pouvez maintenant accéder à l'interface d'administration."
186
            );
Julien Jorry committed
187

188 189
            $url = $this->generateUrl('fos_user_registration_confirmed');
            $response = new RedirectResponse($url);
190

191
            // @TODO : send mail with this event catch !
192
            $this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
193
            return new RedirectResponse($this->generateUrl('sonata_admin_dashboard'));
194 195 196 197 198 199
        }
        return $this->render('installation.html.twig', array(
            'form' => $form->createView()
        ));
    }

200 201 202 203 204 205 206
    /**
     * @Route("/adherer", name="adherer")
     */
    public function adhererAction(Request $request)
    {
        // @TODO : formulaire d'adhésion sans cotisation ? à valider après ?

207
        $adherent = new Adherent();
208
        $user = $this->userManager->createUser();
209
        $groupe = $this->em->getRepository(Usergroup::class)->findOneByName('Adherent');
210
        $user->setEnabled(false);
211
        $user->addPossiblegroup($groupe);
212 213 214 215 216
        $user->addGroup($groupe);
        $user->addRole('ROLE_ADHERENT');
        $adherent->setEcompte('0');
        $user->setAdherent($adherent);
        $adherent->setUser($user);
217 218 219 220 221 222 223 224 225 226 227
        // @TODO : ajouter le moyen de payer sa cotisation en CB directement
        // if (count($adherent->getUser()->getCotisations()) <= 0) {
        //     $cotisation = new Cotisation();
        //     $cotisation->setMontant(floatval($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::COTISATION_ADHERENT)));
        //     $cotisation->setOperateur($adherent->getUser());
        //     $cotisation->setExpediteur($adherent);
        //     $cotisation->setMoyen(MoyenEnum::MOYEN_AUTRE);
        //     $cotisation->setDebut(new \DateTime());
        //     $cotisation->setFin(new \DateTime('+ 1 year'));
        //     $adherent->getUser()->addCotisation($cotisation);
        // }
228 229 230 231
        if ($adherent->getGeoloc() == null) {
            $adherent->setGeoloc(new Geoloc());
        }
        $form = $this->createForm(AdhererFormType::class, $adherent);
232 233
        $form->handleRequest($request);

234 235
        if ($form->isSubmitted()) {
            if ($form->isValid()) {
236
                $adherentNew = $form->getData();
237 238 239 240 241 242 243 244
                // @TODO : redirect to paiement page

                // $this->em->persist($adherentNew);
                // $this->em->flush();
                // $this->addFlash(
                //     'success',
                //     'Adhésion bien pris en compte, vous recevrez un email très bientôt !'
                // );
245 246 247 248
                return $this->redirectToRoute('index');
            } else {
                $this->addFlash(
                    'error',
249
                    'Problème avec l\'adhésion, veuillez vérifier les informations du formulaire !'
250 251
                );
            }
252 253 254 255 256 257 258
        }

        return $this->render('adherent/adherer.html.twig', array(
            'form' => $form->createView()
        ));
    }

259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298
    /**
    * @Route("/geoloc", name="geolocAdresse")
    */
    public function geoLocAction(Request $request)
    {
        $referer = $request->headers->get('referer');
        if ($referer && !$request->isXmlHttpRequest()) {
            return $this->redirect($referer);
        } elseif (!$request->isXmlHttpRequest()) {
            return new Response('', Response::HTTP_BAD_REQUEST);
        }
        $status = 'success';
        $return = null;
        if (!empty($request->get('cpostal')) && !empty($request->get('ville'))) {
            try {
                // GEOCODING ADDRESS :
                $httpClient = new \Http\Adapter\Guzzle6\Client();
                $provider = Nominatim::withOpenStreetMapServer($httpClient, 'Mozilla/5.0');
                $geocoder = new \Geocoder\StatefulGeocoder($provider, 'fr');
                // Query geocoding from complete address
                $result = $geocoder->geocodeQuery(GeocodeQuery::create($request->get('adresse').' '.$request->get('cpostal').' '.$request->get('ville')));
                if (count($result) > 0) {
                    $coords = $result->first()->getCoordinates();
                    $return = ['lat' => $coords->getLatitude(), 'lon' => $coords->getLongitude()];
                } else {
                    $result = $geocoder->geocodeQuery(GeocodeQuery::create($request->get('cpostal').' '.$request->get('ville')));
                    if (count($result) > 0) {
                        $coords = $result->first()->getCoordinates();
                        $return = ['lat' => $coords->getLatitude(), 'lon' => $coords->getLongitude()];
                    }
                }
            } catch (\Exception $e) {
                $status = 'error';
            }
        } else {
            $status = 'error';
        }
        return new JsonResponse(array('status' => $status, 'data' => $return));
    }

Julien Jorry committed
299 300 301 302 303 304 305 306 307 308 309 310 311 312
    private function removeOldSessionParams()
    {
        $this->session->remove('_choixGroup');
        $this->session->remove('_groupId');
        $this->session->remove('_groupegere');
        $this->session->remove('_comptoirgere');
        $this->session->remove('_prestagere');
    }

    /**
     * Choix du groupe local géré
     * @Route("/login/groupe/choice/{usergrpid}/{grpid}", name="groupe_choice")
     * @ParamConverter("group", class="App:Usergroup", options={"mapping": {"usergrpid": "id"}})
     * @ParamConverter("groupe", class="App:Groupe", options={"mapping": {"grpid": "id"}})
313 314
     * IsGranted({"ROLE_GESTION_GROUPE", "ROLE_CONTACT", "ROLE_TRESORIER"})
     * @IsGranted("ROLE_USER")
Julien Jorry committed
315 316 317
     */
    public function groupeChoiceAction(Usergroup $group, Groupe $groupe, Request $request)
    {
318 319 320 321 322 323 324
        if (!(($this->getUser()->getPossiblegroups()->contains('ROLE_GESTION_GROUPE') or $this->getUser()->getPossiblegroups()->contains('ROLE_CONTACT') or $this->getUser()->getPossiblegroups()->contains('ROLE_TRESORIER')) and $this->getUser()->getGroupesgeres()->contains($groupe))) {
            $this->addFlash(
                'error',
                "Accès impossible !"
            );
            return $this->redirectToRoute('index');
        }
Julien Jorry committed
325
        $this->removeOldSessionParams();
326
        // On enregistre le groupe local choisit en session
Julien Jorry committed
327
        $this->session->set('_groupegere', $groupe);
328 329 330 331 332 333 334 335 336 337 338
        $this->getUser()->setGroups([$group]);
        $this->em->persist($this->getUser());
        $this->em->flush();
        $this->guard->authenticateUserAndHandleSuccess(
            $this->getUser(),
            $request,
            $this->authenticator,
            'main'
        );
   
        return $this->redirectToRoute('sonata_admin_dashboard');
Julien Jorry committed
339 340 341 342 343 344 345
    }

    /**
     * Choix du comptoir géré
     * @Route("/login/comptoir/choice/{usergrpid}/{cptid}", name="comptoir_choice")
     * @ParamConverter("group", class="App:Usergroup", options={"mapping": {"usergrpid": "id"}})
     * @ParamConverter("comptoir", class="App:Comptoir", options={"mapping": {"cptid": "id"}})
346
     * @IsGranted("ROLE_USER")
Julien Jorry committed
347 348 349
     */
    public function comptoirChoiceAction(Usergroup $group, Comptoir $comptoir, Request $request)
    {
350 351 352 353 354 355 356 357 358
        if (!($this->getUser()->getPossiblegroups()->exists(function ($key, $value) {
            return in_array('ROLE_COMPTOIR', $value->getRoles());
        }) and $this->getUser()->getComptoirsgeres()->contains($comptoir))) {
            $this->addFlash(
                'error',
                "Accès impossible !"
            );
            return $this->redirectToRoute('index');
        }
Julien Jorry committed
359
        $this->removeOldSessionParams();
360
        // On enregistre le comptoir choisit en session
Julien Jorry committed
361
        $this->session->set('_comptoirgere', $comptoir);
362 363 364 365 366 367 368 369 370 371 372
        $this->getUser()->setGroups([$group]);
        $this->em->persist($this->getUser());
        $this->em->flush();
        $this->guard->authenticateUserAndHandleSuccess(
            $this->getUser(),
            $request,
            $this->authenticator,
            'main'
        );

        return $this->redirectToRoute('sonata_admin_dashboard');
Julien Jorry committed
373 374 375 376 377 378 379
    }

    /**
     * Choix du presta géré
     * @Route("/login/presta/choice/{usergrpid}/{prestaid}", name="presta_choice")
     * @ParamConverter("group", class="App:Usergroup", options={"mapping": {"usergrpid": "id"}})
     * @ParamConverter("prestataire", class="App:Prestataire", options={"mapping": {"prestaid": "id"}})
380
     * @IsGranted("ROLE_USER")
Julien Jorry committed
381 382 383
     */
    public function prestaChoiceAction(Usergroup $group, Prestataire $prestataire, Request $request)
    {
384 385 386 387 388 389 390 391 392
        if (!($this->getUser()->getPossiblegroups()->exists(function ($key, $value) {
            return in_array('ROLE_PRESTATAIRE', $value->getRoles());
        }) and $this->getUser()->getPrestataires()->contains($prestataire))) {
            $this->addFlash(
                'error',
                "Accès impossible !"
            );
            return $this->redirectToRoute('index');
        }
Julien Jorry committed
393
        $this->removeOldSessionParams();
394
        // On enregistre le presta choisit en session
Julien Jorry committed
395
        $this->session->set('_prestagere', $prestataire);
396 397 398 399 400 401 402 403 404
        $this->getUser()->setGroups([$group]);
        $this->em->persist($this->getUser());
        $this->em->flush();
        $this->guard->authenticateUserAndHandleSuccess(
            $this->getUser(),
            $request,
            $this->authenticator,
            'main'
        );
Julien Jorry committed
405 406 407 408

        return $this->redirectToRoute('index');
    }

409
    /**
Julien Jorry committed
410
     * @Route("/login/group/choice/{id}", name="usergroup_choice")
411
     * @IsGranted("ROLE_USER")
412 413 414
     */
    public function groupChoiceAction(Usergroup $group, Request $request)
    {
415 416 417 418 419 420 421
        if (!$this->getUser()->getPossiblegroups()->contains($group)) {
            $this->addFlash(
                'error',
                "Accès impossible !"
            );
            return $this->redirectToRoute('index');
        }
Julien Jorry committed
422
        $this->removeOldSessionParams();
423 424 425 426 427 428 429 430 431
        $this->getUser()->setGroups([$group]);
        $this->em->persist($this->getUser());
        $this->em->flush();
        $this->guard->authenticateUserAndHandleSuccess(
            $this->getUser(),
            $request,
            $this->authenticator,
            'main'
        );
432 433

        // @TODO : On redirige sur l'index (ou en fonction du rôle?)
434 435 436 437 438 439
        $referer = $request->headers->get('referer');
        if ($referer && !$request->isXmlHttpRequest()) {
            return $this->redirect($referer);
        } elseif (!$request->isXmlHttpRequest()) {
            return $this->redirectToRoute('index');
        }
440 441
    }

442 443 444
    /**
     * @Route("/contact", name="contact")
     */
445
    public function contactAction(Request $request)
446
    {
447 448 449 450
        $form = $this->createForm(ContactFormType::class);
        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
451
            $name = $form['nom']->getData();
452 453
            $emailFrom = $form['email']->getData();
            $message = $form['message']->getData();
454 455 456

            $this->sendMail($name, $emailFrom, $message);

457 458 459 460 461 462 463 464 465 466 467 468 469 470
            $this->addFlash(
                'success',
                'Merci ! Le message a bien été envoyé !'
            );
            $referer = $request->headers->get('referer');
            if ($referer && !$request->isXmlHttpRequest()) {
                return $this->redirect($referer);
            } elseif (!$request->isXmlHttpRequest()) {
                return new Response('', Response::HTTP_BAD_REQUEST);
            }
        }
        return $this->render('contact.html.twig', array(
            'form' => $form->createView()
        ));
471
    }
472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492

    private function sendMail($name, $from, $message)
    {
        $subject = $this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_NAME_SMALL).' : Contact';
        $mail = (new \Swift_Message($subject))
            ->setFrom($from)
            ->setTo($this->em->getRepository(GlobalParameter::class)->val(GlobalParameter::MLC_CONTACT_EMAIL))
            ->setBody(
                $this->templating->render(
                    'email/contact.html.twig',
                    array(
                        'subject' => $subject,
                        'from' => $from,
                        'name' => $name,
                        'message' => $message,
                    )
                ),
                'text/html'
            );
        $this->mailer->send($mail);
    }
Julien Jorry committed
493
}