<repo_name>guillaume-haerinck/lolimac<file_sep>/front/src/app/shared/components/event-card-notification/event-card-notification.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';

import { Event } from 'app/shared/models/event';

@Component({
  selector: 'app-event-card-notification',
  templateUrl: './event-card-notification.component.html',
  styleUrls: ['./event-card-notification.component.scss']
})
export class EventCardNotificationComponent implements OnInit {
  @Input() event: Event;

  constructor(private m_router: Router) { }

  ngOnInit() {
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }
}
<file_sep>/back/api/controllers/NotificationCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \models\Notification;
use \models\NotificationManager;
use \models\User;
use \models\UserManager;
use \models\Event;
use \models\EventManager;
use \controllers\scans\TokenAccess;


class NotificationCRUD {

  public function add($data) {
      $notificationManager = new NotificationManager();
      foreach ($data as $key => $value) {
          if ($key == 'id') continue;
          $notification = new Notification([
              "id_event" => $data['id'],
              'type_edit' => $key
          ]);
          $notificationManager->add($notification);
      }
  }

  public function read() {
      $token = new TokenAccess();
      $id_user = $token->getId();
      $userManager = new UserManager();
      $user = $userManager->readById($id_user);
      $notificationManager = new NotificationManager();
      $notifications = $notificationManager->readAll($id_user);
      if ($notifications) {
          $eventManager = new EventManager();
          foreach ($notifications as $key => $notification) {
              $notifications[$key] = $notification->toArray();
              $event = $eventManager->readById_noException($notification->getId_event());
              //var_dump($event);
              if ($event) {
                  $event = new Event($event);
                  $notifications[$key]["title"] = $event->getTitle();
                  $notifications[$key]["photo_url"] = $event->getPhoto_url();
              }
              else {
                  unset($notifications[$key]);
              }
          }
          $userManager->updateNotificationDate($id_user);
          $notifications = \array_values($notifications);
          echo json_encode([
              "events" => $notifications
          ]);
      }
      else {
          json_encode(['message'=>"Il n'y a pas de notifications"]);
      }
  }

  public function count() {
      $token = new TokenAccess();
      $id_user = $token->getId();
      $userManager = new UserManager();
      $user = $userManager->readById($id_user);
      $notificationManager = new NotificationManager();
      $notifications = $notificationManager->countNotifications($id_user);
      echo json_encode(["notifications" => $notifications]);
  }
}
<file_sep>/front/src/app/modules/events/event.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';
import { environment } from 'environments/environment';
import { removeEmptyProperties } from 'app/shared/utility/change-objects';

@Injectable({
  providedIn: 'root'
})
export class EventService {

  constructor(private m_http: HttpClient) {}

  createEvent(form: Object): Observable<any> {
    form = removeEmptyProperties(form);
    const URL = `${environment.backend.serverUrl}events`;
    return this.m_http.post<any>(URL, JSON.stringify(form));
  }

  getEventById(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${id}`;
    return this.m_http.get<any>(URL);
  }

  getEventList(from: number, limit: number): Observable<any[]> {
    const URL = `${environment.backend.serverUrl}events?from=${from}&limit=${limit}`;
    return this.m_http.get<any>(URL);
  }

  getIcsLink(id: number) {
    const URL = `${environment.backend.serverUrl}events/export/${id}`;
    return this.m_http.get<any>(URL);
  }

  search(terms: string): Observable<any[]> {
    const URL = `${environment.backend.serverUrl}events/search/?q=${terms}`;
    return this.m_http.get<any>(URL);
  }

  update(id: number, form: Object): Observable<any> {
    form = removeEmptyProperties(form);
    const URL = `${environment.backend.serverUrl}events/${id}`;
    return this.m_http.patch<any>(URL, JSON.stringify(form));
  }

  join(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${id}/join`;
    return this.m_http.post<any>(URL, undefined);
  }

  leave(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${id}/leave`;
    return this.m_http.delete<any>(URL, undefined);
  }

  delete(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${id}`;
    return this.m_http.delete<any>(URL);
  }
}
<file_sep>/back/api/controllers/IcsCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\parser\IcsParser;
use \controllers\EventCRUD;
use \controllers\Link_events_placesCRUD;
use \models\Event;
use \models\Link_events_places;
use \models\Place;
use \models\EventManager;
use \models\UserManager;

class IcsCRUD {
    public function readOne($dataIn) {
        $encryptionMethod = "AES-256-CBC";
        $secretHash = "25c6c7ff35b9979b151f<PASSWORD>cd13b0ff";
        $iv = "6546445734219402";
        $token = openssl_decrypt($dataIn, $encryptionMethod, $secretHash, $options=0, $iv);
        $data = \explode('/', $token);
        $data['id_user'] = $data[0];
        $data['id_event'] = $data[1];
        $eventCRUD = new EventCRUD();
        $event = $eventCRUD->readOBJ(['id' => $data['id_event']]);
        $IcsParser = new IcsParser();
        if ($event && $event->getDate_start() && $event->getDate_end()) {
            $IcsParser->openEvent();
            $IcsParser->setSUMMARY($event->getTitle());
            $IcsParser->setUID($event->getId());
            $IcsParser->setStatus();
            $IcsParser->setDate_start($event->getDate_start());
            $IcsParser->setDate_end($event->getDate_end());
            $IcsParser->setDate_timeStamp();
            $link_events_placesCRUD = new Link_events_placesCRUD();
            $place = $link_events_placesCRUD->readPlace_OBJ(['id_event' => $event->getId()]);
            if ($place) {
                $IcsParser->setLocation($place);
            }
            $IcsParser->closeEvent();
            $IcsParser->closeCalendar();

            $filename = urlencode($event->getTitle());

            header('Content-type: text/calendar; charset=utf-8');
            header("Content-Disposition: inline; filename=lolimac-{$filename}.ics");
            echo $IcsParser->ics;
            exit;
        }
        else {
            throw new \Exception("Impossible d'accéder à l'événement", 401);

        }
    }

    public function readAll($dataIn) {
        $scanDataIn = new ScanDataIn();
        $encryptionMethod = "AES-256-CBC";
        $secretHash = "<PASSWORD>ff<PASSWORD>";
        $iv = "6546445734219402";
        $token = openssl_decrypt($dataIn, $encryptionMethod, $secretHash, $options=0, $iv);
        $data['pseudo'] = $token;
        $data = $scanDataIn->failleXSS($data);
        $userManager = new UserManager();
        $user = $userManager->readByPseudo($data['pseudo']);
        if (!$user) {
            throw new \Exception("Accès refusé", 401);
        }

        $eventManager = new EventManager();
        $events = $eventManager->readAllValid();
        $IcsParser = new IcsParser();
        if ($events) {
            $link_events_placesCRUD = new Link_events_placesCRUD();
            foreach ($events as $key => $event) {
                $IcsParser->openEvent();
                $IcsParser->setSUMMARY($event->getTitle());
                $IcsParser->setUID($event->getId());
                $IcsParser->setStatus();
                $IcsParser->setDate_start($event->getDate_start());
                $IcsParser->setDate_end($event->getDate_end());
                $IcsParser->setDate_timeStamp();
                $place = $link_events_placesCRUD->readPlace_OBJ(['id_event' => $event->getId()]);
                if ($place) {
                    $IcsParser->setLocation($place);
                }
                $IcsParser->closeEvent();
            }
            $IcsParser->closeCalendar();

            header('Content-type: text/calendar; charset=utf-8');
            header('Content-Disposition: inline; filename=lolimac-calendar.ics');
            echo $IcsParser->ics;
            exit;

        }
    }
}
<file_sep>/back/api/models/CommentManager.php
<?php

namespace models;

class CommentManager extends DBAccess {

	public function add(Comment $comment) {
		$q = $this->db->prepare("INSERT INTO comments
      (`content`, `date_created`, `date_edited`, `id_user`, `id_post`)
      VALUES (:content, NOW(), NOW(), :id_user, :id_post);");

    $q->bindValue(':content', $comment->getContent());
    $q->bindValue(':id_user', $comment->getId_user());
    $q->bindValue(':id_post', $comment->getId_post());

	  $q->execute();

    $comment->hydrate(['id' => $this->db->lastInsertId()]);
    return $comment;
  }

  public function count() {
    return $this->db->query("SELECT COUNT(*) FROM comments;")->fetchColumn();
  }

  public function readById($id) {
      $q = $this->db->query("SELECT * FROM comments WHERE id = {$id}");
      $comment = $q->fetch(\PDO::FETCH_ASSOC);
      $commentObject = new Comment($comment);
      if($commentObject) {
        return $commentObject;
      } else {
        throw new \Exception("Le commentaire n'existe pas.", 400);
      }
  }

  public function readByPost($id_post) {
    $allComment = [];

    $q = $this->db->query("SELECT * FROM comments
      WHERE id_post = {$id_post};");
    for($i = 0;$data = $q->fetch(\PDO::FETCH_ASSOC); $i++) {
     $allComments[$i] = new Comment($data);
    }
    if(!empty($allComments)) {
      return $allComments;
    }

  }

  public function update(Comment $comment) {
    $q = $this->db->prepare('UPDATE comments SET content = :content, date_edited = NOW(), id_user = :id_user , id_post = :id_post WHERE id = :id');

    $q->bindValue(':id', $comment->getId());
    $q->bindValue(':content', $comment->getContent());
    $q->bindValue(':id_user', $comment->getId_user());
    $q->bindValue(':id_post', $comment->getId_post());

    $q->execute();

    return $comment;
  }

  public function deleteById($id) {
    $this->db->exec('DELETE FROM comments WHERE id = '.$id.';');
    return TRUE;
  }

  public function deleteByIdPost($id_post) {
    $this->db->exec('DELETE FROM comments WHERE id_post = '.$id_post.';');
    return TRUE;
  }
}
<file_sep>/back/api/controllers/Link_events_eventtypesCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \controllers\EventTypeCRUD;
use \models\Link_events_eventtypes;
use \models\Link_events_eventtypesManager;

class Link_events_eventtypesCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id_event", "id_type"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $link = new Link_events_eventtypes($data);
    $linkManager = new Link_events_eventtypesManager();
    if ($linkManager->readById_event_type($link->getId_event(), $link->getId_type()) === FALSE) {
      $linkManager->add($link);
    } else {
      throw new \Exception('Lien déjà existant.');
    }
    return TRUE;
  }

  public function readType_ARRAY($dataIn) {
      $scanDataIn = new ScanDataIn();
      $scanDataIn->exists($dataIn, ["id_event"]);
      $data = $scanDataIn->failleXSS($dataIn);
      $linkManager = new Link_events_eventtypesManager();
      $link_events_eventTypes = $linkManager->readById_event($data["id_event"]);
      if ($link_events_eventTypes) {
          $eventTypeCRUD = new EventTypeCRUD();
          $eventType = $eventTypeCRUD->read_OBJ(["id" => $link_events_eventTypes->getId_type()]);
          return $eventType->toArray();
      }
  }

  /*
  public function updateByIdEvent($dataIn) {
      $scanDataIn = new ScanDataIn();
      $data = $scanDataIn->failleXSS($dataIn);
      $scanDataIn->exists($data, ['id_event', 'id_type']);
      $linkManager = new Link_events_eventtypesManager();
      $link_events_eventTypes = $linkManager->readById_event($data["id_event"]);
      $link_events_eventTypes = $linkManager->updateType($data["id_event"]);
  }
  */

  public function readByIdEvent_OBJ($dataIn) {
      $scanDataIn = new ScanDataIn();
      $data = $scanDataIn->failleXSS($dataIn);
      $scanDataIn->exists($data, ["id_event"]);
      $linkManager = new Link_events_eventtypesManager();
      $link_events_eventTypes = $linkManager->readById_event($data["id_event"]);
      if($link_events_eventTypes) {
          return $link_events_eventTypes;
      } else {
          throw new Exception("Le type n'existe pas.");
      }

  }

  public function addIfNotExist($dataIn) {
    $scanDataIn = new ScanDataIn();
    $data = $scanDataIn->failleXSS($dataIn);
    $scanDataIn->exists($data, ['id_event', 'id_type']);
    $linkManager = new Link_events_eventtypesManager();
    $link_events_eventTypes = $linkManager->readById_event($data["id_event"]);
    if ($link_events_eventTypes) {
        $linkManager->updateType($link_events_eventTypes, $data['id_type']);
    }
    else {
        $link_events_eventTypes = new Link_events_eventtypes(['id_event' => $data['id_event'], 'id_type' => $data['id_type']]);
        $linkManager->add($link_events_eventTypes);
    }
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id_event", "id_type"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $linkManager = new Link_events_eventtypesManager();
    $linkManager->deleteById($data["id_event"], $data["id_type"]);
    return TRUE;
  }

  public function deleteByIdEvent($dataIn) {
      $scanDataIn = new ScanDataIn();
      $scanDataIn->exists($dataIn, ["id_event"]);
      $data = $scanDataIn->failleXSS($dataIn);
      $token = new TokenAccess();
      $linkManager = new Link_events_eventtypesManager();
      $linkManager->deleteByIdEvent($data["id_event"]);
      return TRUE;
  }
}
<file_sep>/front/src/app/modules/search/search.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';

import { Observable, Subject } from 'rxjs';
import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators';

import { Event } from 'app/shared/models/event';
import { EventService } from '../events/event.service';

@Component({
  selector: 'app-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
  searchResults$: Observable<Event[]>;
  searchForm: FormGroup;

  private m_searchTerms = new Subject<string>();

  constructor(private m_eventService: EventService,
    private m_formBuilder: FormBuilder) {
    this.searchForm = this.m_formBuilder.group({
      terms: ['']
    });
  }

  ngOnInit() {
    this.searchResults$ = this.m_searchTerms.pipe(
      // wait 300ms after each keystroke before considering the term
      debounceTime(300),
      // ignore new term if same as previous term
      distinctUntilChanged(),
      // switch to new search observable each time the term changes
      switchMap((term: string) => this.m_eventService.search(term))
    );
  }

  // Push a search term into the observable stream.
  search(terms: string): void {
    this.m_searchTerms.next(terms);
  }

}
<file_sep>/back/api/models/Place.php
<?php

namespace models;

class Place {

	protected $id,
	$postcode = NULL,
	$street = NULL,
	$number = NULL,
	$city = NULL,
	$name = NULL;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

  //Gère la récupération de données des attributs lorsqu'elle proviennent de la bdd
	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
      $array = [
          "id_place" => $this->getId(),
          "postcode" => $this->getPostcode(),
          "street" => $this->getStreet(),
          "number" => $this->getNumber(),
          "city" => $this->getCity(),
          "name" => $this->getName()
      ];
      return $array;
  }

  // Getters
  public function getId() {
    return $this->id;
  }

  public function getPostcode() {
    return $this->postcode;
  }

  public function getStreet() {
    return $this->street;
  }

  public function getNumber() {
    return $this->number;
  }

  public function getCity() {
  	return $this->city;
  }

  public function getName() {
    return $this->name;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId($id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }

  public function setPostcode($postcode) {
    $postcode = (int) $postcode;
    $this->postcode = $postcode;
  }

  public function setStreet($street) {
    if (is_string($street) && strlen($street) <= 255) {
    $this->street = $street;
    }
  }

 	public function setNumber($number) {
  	$number = (int) $number;
 		$this->number = $number;
  }

 	public function setCity($city) {
  	if (is_string($city) && strlen($city) <= 63 ) {
 		 $this->city = $city;
 	  }
  }

  public function setName($name) {
    if (is_string($name) && strlen($name) < 63 ) {
     $this->name = $name;
    }
  }

}
<file_sep>/front/src/app/modules/visitor/visitor.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { LoginComponent } from './login/login.component';
import { VisitorRoutingModule } from './visitor-routing.module';
import { SharedModule } from 'app/shared/shared.module';
import { InvitationComponent } from './invitation/invitation.component';
import { InscriptionComponent } from './inscription/inscription.component';
import { ForgotComponent } from './forgot/forgot.component';
import { UserService } from './user.service';

@NgModule({
  declarations: [
    LoginComponent,
    InvitationComponent,
    InscriptionComponent,
    ForgotComponent
  ],
  imports: [
    CommonModule,

    VisitorRoutingModule,
    SharedModule
  ],
  providers: [
    UserService
  ]
})
export class VisitorModule { }
<file_sep>/front/src/app/shared/components/event-card-small/event-card-small.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';

import { Event } from 'app/shared/models/event';

@Component({
  selector: 'app-event-card-small',
  templateUrl: './event-card-small.component.html',
  styleUrls: ['./event-card-small.component.scss']
})
export class EventCardSmallComponent implements OnInit {
  @Input() event: Event;

  constructor(private m_router: Router) { }

  ngOnInit() {
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }
}
<file_sep>/back/api/Root.php
<?php

    use \controllers\UserCRUD;
    use \controllers\PlaceCRUD;
    use \controllers\EventCRUD;
    use \controllers\PostCRUD;
    use \controllers\IcsCRUD;
    use \controllers\CommentCRUD;
    use \controllers\ModuleCRUD;
    use \controllers\Link_events_users_modulesCRUD;
    use \controllers\NotificationCRUD;
    use \controllers\Link_events_placesCRUD;
    use \controllers\scans\ScanDataIn;
    use \controllers\scans\CutURL;


class Root {

    protected $root;

    function __construct() {
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Allow-Methods: POST, GET, DELETE, PUT, PATCH, OPTIONS, HEAD');
        header('Access-Control-Allow-Headers: Content-Type, Origin, Accept, Authorization, Content-Length, X-Requested-With');
        header('Content-Type: application/json; charset=UTF-8');

        $CutURL = new CutURL($_SERVER["REQUEST_URI"]);
        $this->root = $CutURL->getURL_cut();
        $key = $this->root[0];
        if (!$key) {
            // Called if the user access /api without any other argument
            echo json_encode(
                [
                    "status" => "running",
                    "commit" => trim(shell_exec("git rev-parse HEAD"), "\n")
                ]
        );
        }
        else {
            $this->$key();
        }
    }

    public function login() {
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
            $_POST = json_decode(file_get_contents("php://input"), TRUE);
            $userCRUD = new UserCRUD();
            $userCRUD->auth($_POST);
        }
    }

    public function users() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $userCRUD = new UserCRUD();
                $userCRUD->read($this->root);
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $userCRUD = new UserCRUD();
                $userCRUD->add($_POST);
                break;

            case 'PATCH':
                $_PATCH = json_decode(file_get_contents("php://input"), TRUE);
                $userCRUD = new UserCRUD();
                $userCRUD->update($_PATCH);
                break;

            case 'DELETE':
                $userCRUD = new UserCRUD();
                $_DELETE['id'] = $this->root[1];
                $userCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }

    public function me() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                if (isset($this->root[1]) && $this->root[1] == "notifications") {
                    $notificationsCRUD = new NotificationCRUD();
                    if (isset($this->root[2]) && $this->root[2] == "count") {
                        $notificationsCRUD->count();
                    }
                    else {
                        $notificationsCRUD->read();
                    }
                }
                break;
        }
    }

    public function ics() {
        if ($_SERVER['REQUEST_METHOD'] == 'GET') {
            if (isset($this->root[1])) {
                $icsCRUD = new IcsCRUD();
                if ($this->root[1] == "all") {
                    if (isset($this->root[2])) {
                        $icsCRUD->readAll($this->root[2]);
                    }
                }
                else {
                    $icsCRUD->readOne($this->root[1]);
                }
            }
        }
    }

    public function events() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $eventCRUD = new EventCRUD();
                $_GET;
                //print_r($this->root);
                if (isset($this->root[1])) {
                    if ($this->root[1] == "export") {
                        if (isset($this->root[2])) {
                            $eventCRUD->generateSingleEventICS($this->root[2]);
                        } else {
                            $eventCRUD->generateAllEventICS();
                        }
                    }
                    elseif ($this->root[1] == "search") {
                        $_GET['query'] = $_GET['q'];
                        $eventCRUD->search($_GET);
                    }
                     else if (empty($this->root[2])) {
                        $_GET["id"] = $this->root[1];
                        // We read one specific event
                        $eventCRUD->read($_GET);
                    }
                }
                else {
                    $eventCRUD->readMultiple($_GET);
                    //$eventCRUD->readOffsetLimit($_GET);
                }
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                if(isset($this->root[2])) {
                    if($this->root[2] == "posts") {
                        if(isset($this->root[4])) {
                            if($this->root[4] == "comments") {
                                $commentCRUD = new CommentCRUD();
                                $_POST["id_post"] = $this->root[3];
                                $commentCRUD->add($_POST, $this->root[1]);
                            }
                        } else {
                            $postCRUD = new PostCRUD();
                            $_POST["id_event"] = $this->root[1];
                            $postCRUD->add($_POST);
                        }
                    } else if ($this->root[2] == "join") {
                        $linkCRUD = new Link_events_users_modulesCRUD();
                        $linkCRUD->add($this->root[1], 2);
                    }
                } else {
                    $eventCRUD = new EventCRUD();
                    $eventCRUD->add($_POST);
                }


                break;

            case 'PATCH':
                $_PUT = json_decode(file_get_contents("php://input"), TRUE);
                if(isset($this->root[2])) {
                    if($this->root[2] == "posts" && isset($this->root[3])) {
                        if(isset($this->root[4])) {
                            if($this->root[4] == "comments" && isset($this->root[5])) {
                                $commentCRUD = new CommentCRUD();
                                $_PUT["id"] = $this->root[5];
                                $commentCRUD->update($_PUT);
                            }
                        } else {
                            $postCRUD = new PostCRUD();
                            $_PUT['id'] = $this->root[3];
                            $postCRUD->update($_PUT);
                        }
                    }
                } else {
                    $idEvent = $this->root[1];
                    $_PUT["id"] = $idEvent;
                    $eventCRUD = new EventCRUD();
                    $eventCRUD->update($_PUT);
                }
                break;

            case 'DELETE':
                if(isset($this->root[2])) {
                    if(isset($this->root[2])) {
                        if ($this->root[2] == "leave") {
                            $linkCRUD = new Link_events_users_modulesCRUD();
                            $linkCRUD->delete($this->root[1]);
                        } else if ($this->root[2] == "posts" && isset($this->root[3])) {
                            if(isset($this->root[4])) {
                                if ($this->root[4] == "comments" && isset($this->root[5])) {
                                    $commentCRUD = new CommentCRUD();
                                    $_DELETE['id'] = $this->root[5];
                                    $commentCRUD->delete($_DELETE);
                                }
                            } else {
                                $postCRUD = new PostCRUD();
                                $_DELETE['id'] = $this->root[3];
                                $postCRUD->delete($_DELETE);
                            }
                        }
                    }
                } else {
                    $idEvent = $this->root[1];
                    $_DELETE["id"] = $idEvent;
                    $eventCRUD = new EventCRUD();
                    $eventCRUD->delete($_DELETE);
                }
                break;

            default:
                break;
        }
    }

    public function place() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $placeCRUD = new PlaceCRUD();
                $placeCRUD->read($this->root);
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $placeCRUD = new PlaceCRUD();
                $placeCRUD->add($_POST);
                break;

            case 'PUT':
                $_PUT = json_decode(file_get_contents("php://input"), TRUE);
                $placeCRUD = new PlaceCRUD();
                $placeCRUD->update($_PUT);
                break;

            case 'DELETE':
                $_DELETE = json_decode(file_get_contents("php://input"), TRUE);
                $placeCRUD = new PlaceCRUD();
                $placeCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }

    public function post() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $postCRUD = new PostCRUD();
                $postCRUD->read($this->root);
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $postCRUD = new PostCRUD();
                $postCRUD->add($_POST);
                break;

            case 'PUT':
                $_PUT = json_decode(file_get_contents("php://input"), TRUE);
                $postCRUD = new PostCRUD();
                $postCRUD->update($_PUT);
                break;

            case 'DELETE':
                $_DELETE = json_decode(file_get_contents("php://input"), TRUE);
                $postCRUD = new PostCRUD();
                $postCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }

    public function comment() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $commentCRUD = new CommentCRUD();
                $commentCRUD->read($this->root);
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $commentCRUD = new CommentCRUD();
                $commentCRUD->add($_POST);
                break;

            case 'PUT':
                $_PUT = json_decode(file_get_contents("php://input"), TRUE);
                $commentCRUD = new CommentCRUD();
                $commentCRUD->update($_PUT);
                break;

            case 'DELETE':
                $_DELETE = json_decode(file_get_contents("php://input"), TRUE);
                $commentCRUD = new CommentCRUD();
                $commentCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }

    public function module() {
        switch ($_SERVER['REQUEST_METHOD']) {
            case 'GET':
                $moduleCRUD = new ink_events_users_modulesCRUD();
                $moduleCRUD->read($this->root);
                break;

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $moduleCRUD = new ModuleCRUD();
                $moduleCRUD->add($_POST);
                break;

            case 'PUT':
                $_PUT = json_decode(file_get_contents("php://input"), TRUE);
                $moduleCRUD = new ModuleCRUD();
                $moduleCRUD->update($_PUT);
                break;

            case 'DELETE':
                $_DELETE = json_decode(file_get_contents("php://input"), TRUE);
                $moduleCRUD = new ModuleCRUD();
                $moduleCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }

    public function linkEUM() {
        switch ($_SERVER['REQUEST_METHOD']) {

            case 'POST':
                $_POST = json_decode(file_get_contents("php://input"), TRUE);
                $linkCRUD = new Link_events_users_modulesCRUD();
                $linkCRUD->add($_POST);
                break;


            case 'DELETE':
                $_DELETE = json_decode(file_get_contents("php://input"), TRUE);
                $linkCRUD = new Link_events_users_modulesCRUD();
                $linkCRUD->delete($_DELETE);
                break;

            default:
                break;
        }
    }
}
<file_sep>/back/api/Config.php
<?php

class Config {

    protected $jwtKey,
    $serverName;

    public function __construct() {
    	include "configVar.php";
		$this->jwtKey = $secretKey;
		$this->serverName = $ip;
    }

  	public function getJwtKey() {
    	return $this->jwtKey;
  	}

  	public function getServerName() {
    	return $this->serverName;
  	}
}<file_sep>/back/api/models/User.php
<?php

namespace models;
use \controllers\scans\ScanDataIn;

class User {

	protected $id,
  $firstname,
  $lastname,
	$pseudo,
	$pwd_hash,
  $mail,
	$phone,
  $photo_url,
  $status,
  $year_promotion,
  $date_notification_check;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

  //Gère la récupération de données des attributs lorsqu'elle proviennent de la bdd
	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
    $array = [
      "id" => $this->getId(),
      "firstmane" => $this->getFirstname(),
      "lastname" => $this->getLastname(),
      "pseudo" => $this->getPseudo(),
      "photo_url" => $this->getPhoto_url(),
      "status" => $this->getStatus()
    ];
    return $array;
  }

  // Getters
  public function getId() {
    return $this->id;
  }

  public function getFirstname() {
    return $this->firstname;
  }

  public function getLastname() {
    return $this->lastname;
  }

  public function getPseudo() {
    return $this->pseudo;
  }

  public function getPwd_hash() {
  	return $this->pwd_hash;
  }

  public function getMail() {
    return $this->mail;
  }

  public function getPhone() {
    return $this->phone;
  }

  public function getPhoto_url() {
    return $this->photo_url;
  }

  public function getStatus() {
    return $this->status;
  }

  public function getYear_promotion() {
    return $this->year_promotion;
  }

  public function getDate_notification_check() {
    return $this->date_notification_check;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId($id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }

  public function setFirstname($firstname) {
    if (is_string($firstname) && strlen($firstname) <= 22) {
    $this->firstname = $firstname;
    }
  }

  public function setLastname($lastname) {
    if (is_string($lastname) && strlen($lastname) <= 22) {
    $this->lastname = $lastname;
    }
  }

 	public function setPseudo($pseudo) {
  	if (is_string($pseudo) && strlen($pseudo) <= 25) {
 		$this->pseudo = $pseudo;
 	  }
  }

 	public function setPwd_hash($pwd_hash) {
  	if (is_string($pwd_hash)) {
 		 $this->pwd_hash = $pwd_hash;
 	  }
  }

  public function setMail($mail) {
    $mail = filter_var($mail, FILTER_VALIDATE_EMAIL);
    if ($mail == TRUE) {
     $this->mail = $mail;
    }
	else {
		throw new \Exception("L'adresse email est invalide.");
	}
  }

  public function setPhone($phone) {
    if (is_string($phone) && preg_match('#^(\d\d\s){4}(\d\d)$#', $phone)) {
     $this->phone = $phone;
    }
  }

  public function setPhoto_url($photo_url) {
    if (is_string($photo_url) && strlen($photo_url) <= 255) {
     $this->photo_url = $photo_url;
    }
  }

 	public function setStatus($status) {
  	$status = (int) $status;
 		$this->status = $status;
 	}

  public function setYear_promotion($year_promotion) {
    $year_promotion = (int) $year_promotion;
    if ($year_promotion > 0) {
     $this->year_promotion = $year_promotion;
    }
  }

  public function setDate_notification_check($date_notification) {
		$scanDataIn = new ScanDataIn();
		if (\is_null($date_notification) || $scanDataIn->validateDate($date_notification)) {
			$this->date_notification_check = $date_notification;
		}
		else {
			throw new \Exception("Veuilliez entrer une date de vérification de notifications valide.");
		}
  }
}
<file_sep>/front/src/app/modules/events/edit-event/edit-event.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router, ActivatedRoute } from '@angular/router';

import { ResponsiveService } from 'app/core/services/responsive.service';
import { EventService } from '../event.service';
import { fillUndefinedProperties, removeEmptyProperties, removeUnchangedProperties, isEmpty } from 'app/shared/utility/change-objects';
import { MatDialog } from '@angular/material';
import { DialogComponent } from 'app/shared/components/dialog/dialog.component';

@Component({
  selector: 'app-edit-event',
  templateUrl: './edit-event.component.html',
  styleUrls: ['./edit-event.component.scss']
})
export class EditEventComponent implements OnInit {
  bMobile: boolean;
  eventId: number;
  eventForm: FormGroup;
  oldEventData: Object;
  minDate = new Date();
  bEndDetail = false;
  bEndDetailControl = true;

  constructor(responsiveService: ResponsiveService,
    private m_router: Router,
    private m_formBuilder: FormBuilder,
    route: ActivatedRoute,
    private m_eventService: EventService,
    private m_dialog: MatDialog) {
    this.eventId = Number(route.snapshot.paramMap.get('id'));

    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
        this.bMobile = false;
      } else {
        this.bMobile = true;
      }
    });

    this.eventForm = this.m_formBuilder.group({
      title: ['', Validators.required],
      photo_url: ['https://images.unsplash.com/photo-1541532713592-79a0317b6b77?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80', Validators.required],
      description: '',
      date_start: '',
      date_start_hour: '0',
      date_start_minute: '0',
      date_end: '',
      date_end_offset: '0',
      date_end_hour: '0',
      place: this.m_formBuilder.group({
        name: '',
        street: '',
        number: '',
        city: ''
      })
    });
  }

  ngOnInit() {
    this.m_eventService.getEventById(this.eventId).subscribe((result) => {
      // TODO store result as oldform, and remove matching terms

      result = fillUndefinedProperties(result);
      this.oldEventData = result;
      if (result.date_start != '') {
        const dateStart = new Date(result.date_start);
        this.eventForm.patchValue({
          date_start: dateStart,
          date_start_hour: dateStart.getHours().toString(),
          date_start_minute: dateStart.getMinutes().toString(),
        });
      }

      if (result.date_end != '') {
        this.bEndDetail = true;
        this.bEndDetailControl = false;
        const dateEnd = new Date(result.date_end);
        this.eventForm.patchValue({
          date_end: dateEnd,
          date_end_hour: dateEnd.getHours().toString(),
        });
      }
      
      this.eventForm.patchValue({
        title: result.title,
        photo_url: result.photo_url,
        description: result.description,
        place: result.place
      });
    }, error => {

    });
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }

  submitForm(): void {
    let form = this.eventForm.value;
    if (form.date_start_hour && form.date_start_minute) {
      if (form.date_start instanceof Date) {
        form.date_start.setHours(form.date_start_hour, form.date_start_minute); 
      }
    }
    if (!this.bEndDetail) {
      form.date_end = new Date(form.date_start);
      if (form.date_end_offset === 24) {
        form.date_end.setHours(23);
      } else {
        form.date_end.setHours(form.date_end.getHours() + Number(form.date_end_offset), 0);
      }
    } else {
      if (form.date_end instanceof Date && form.date_end_hour instanceof Date) {
        form.date_end.setHours(form.date_end_hour);
      }
    }

    delete form.date_start_hour;
    delete form.date_start_minute;
    delete form.date_end_hour;
    delete form.date_end_offset;

    form = removeEmptyProperties(form);
    form = removeUnchangedProperties(this.oldEventData, form);

    if (!isEmpty(form)) {
      this.m_eventService.update(this.eventId, form).subscribe(result => {
        this.m_router.navigate(['/evenements/detail/' + this.eventId]);
      }, error => {
  
      });
    } else {
      this.m_router.navigate(['/evenements/detail/' + this.eventId]);
    }
  }

  deleteEvent(): void {
    const dialogRef = this.m_dialog.open(DialogComponent, {
      width: "500px",
      data: {title: `Suppression d'un évènement`, text: `En êtes-vous bien sûr ?`, bValBtn: true}
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result.validated) {
        this.m_eventService.delete(this.eventId).subscribe(result => {
          this.m_router.navigate(['/tableau-de-bord']);
        }, error => {
    
        });
      }
    });
  }

  onDateEndDropChange(event: any): void {
    if (event === 'more') {
      this.bEndDetail = true;
      this.eventForm.patchValue({
        date_end: this.eventForm.value.date_start,
        date_end_hour: (this.eventForm.value.date_start.getHours() + 2 ).toString()
      });
    } else {
      this.bEndDetail = false;
    }
  }
}
<file_sep>/back/api/controllers/Link_events_users_modulesCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \models\Link_events_users_modules;
use \models\Link_events_users_modulesManager;
use \models\UserManager;


class Link_events_users_modulesCRUD {

  public function add($id_event, $id_module) {
    $token = new TokenAccess();
    $id_user = $token->getId();
    $data["id_event"] = $id_event;
    $data["id_module"] = $id_module;
    $data["id_user"] = $id_user;
    $link = new Link_events_users_modules($data);
    $linkManager = new Link_events_users_modulesManager();
    if ($linkManager->readById_event_user_module($link->getId_event(), $link->getId_user(), $link->getId_module()) === FALSE) {
      $linkManager->add($link);
    } else {
      throw new \Exception('Lien déjà existant.');
    }
    echo \json_encode([
        'message' => 'Event joined.'
    ]);
    return TRUE;
  }

  public function readParticipation($id_event) {
    $token = new TokenAccess();
    $id_user = $token->getId();
    $linkManager = new Link_events_users_modulesManager();
    $link = $linkManager->readById_user_event($id_user, $id_event);
    if ($link != NULL) {
      return $link->getId_module();
    } else {
      return 0;
    }
  }

  public function readParticipants($id_event) {
    $linkManager = new Link_events_users_modulesManager();
    $listParticipants = $linkManager->readById_event($id_event);
    if ($listParticipants != NULL) {
      foreach ($listParticipants as $key => $value) {
        $userManager = new UserManager();
        $user = $userManager->readById($key);
        if ($user) {
            $participant = $user->toArray();
            $listParticipants[$key] = $participant;
            $listParticipants[$key]['participation'] = $value;
        }
        else {
            unset($listParticipants[$key]);
        }
      }
      return array_values($listParticipants);
    }
  }

  public function delete($id_event) {
    $token = new TokenAccess();
    $id_user = $token->getId();
    $linkManager = new Link_events_users_modulesManager();
    $linkManager->deleteById($id_event, $id_user);
    echo \json_encode([
        'message' => 'Event leaved.'
    ]);
    return TRUE;
  }
}
<file_sep>/front/src/app/shared/components/comment-list/comment-list.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { Comment } from 'app/shared/models/comment';
import { PostService } from 'app/modules/events/post.service';
import { AuthService } from 'app/core/services/auth.service';
import { Router } from '@angular/router';
import { UserService } from 'app/modules/visitor/user.service';
import { MatDialog } from '@angular/material';
import { DialogComponent } from '../dialog/dialog.component';

@Component({
  selector: 'app-comment-list',
  templateUrl: './comment-list.component.html',
  styleUrls: ['./comment-list.component.scss']
})
export class CommentListComponent implements OnInit {
  @Input() comments: Comment[];
  @Input() eventId: number;
  @Input() postId: number;
  @Output() updated = new EventEmitter<any>();

  commentForm: FormGroup;
  bEdit = false;
  userId: number;
  userPhotoUrl: string;
  commentIdToUpdate: number;

  constructor(private m_postService: PostService,
    private m_formBuilder: FormBuilder,
    authService: AuthService,
    private m_router: Router,
    private m_userService: UserService,
    private m_dialog: MatDialog) { 
    this.commentForm = this.m_formBuilder.group({
      content: ['', Validators.required]
    });

    this.userId = authService.getUserId();
  }

  ngOnInit() {
    this.m_userService.get(this.userId).subscribe(result => {
      this.userPhotoUrl = result.photo_url;
    });
  }

  submitCreateForm(): void {
    this.m_postService.createComment(this.eventId, this.postId, this.commentForm.value).subscribe(result => {
      this.updated.emit(undefined);
    }, error => {

    });
  }

  submitEditForm(): void {
    this.m_postService.updateComment(this.eventId, this.postId, this.commentIdToUpdate, this.commentForm.value).subscribe(result => {
      this.bEdit = false;
      this.commentIdToUpdate = undefined;
      this.updated.emit(undefined);
    }, error => {

    });
  }

  deleteComment(): void {
    const dialogRef = this.m_dialog.open(DialogComponent, {
      width: "500px",
      data: {title: `Suppression d'un commentaire`, text: `En êtes-vous bien sûr ?`, bValBtn: true}
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result.validated) {
        this.m_postService.deleteComment(this.eventId, this.postId, this.commentIdToUpdate).subscribe(result => {
          this.bEdit = false;
          this.commentIdToUpdate = undefined;
          this.updated.emit(undefined);
        }, error => {

        });
      }
    });
  }

  patchForm(comment: Comment | undefined): void {
    if (comment == undefined) {
      this.commentForm.patchValue({
        content: ''
      });
    } else {
      this.commentForm.patchValue({
        content: comment.content
      });
    }
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }

}
<file_sep>/front/src/app/modules/visitor/user.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';

import { Observable } from 'rxjs';

import { environment } from 'environments/environment';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  constructor(private m_http: HttpClient) { }

  create(form: JSON): Observable<any> {
    const URL = `${environment.backend.serverUrl}users`;
    return this.m_http.post<any>(URL, JSON.stringify(form));
  }

  get(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}users/${id}`;
    return this.m_http.get<any>(URL);
  }

  update(id: number, form: JSON): Observable<any> {
    const URL = `${environment.backend.serverUrl}users/${id}`;
    return this.m_http.patch<any>(URL, JSON.stringify(form));
  }

  delete(id: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}users/${id}`;
    return this.m_http.delete<any>(URL);
  }
}
<file_sep>/front/src/app/shared/models/comment.ts
import { User } from './user';

export interface Comment {
    id?: number;
    content?: string;
    date_created?: Date;
    date_edited?: Date;
    id_user?: number;
    id_post?: number;
    user?: User;
}<file_sep>/front/src/app/core/services/snack-bar.service.ts
import { Injectable } from '@angular/core';
import { MatSnackBar } from '@angular/material';

@Injectable({
  providedIn: 'root'
})
export class SnackBarService {
  constructor(private m_snackBar: MatSnackBar) { }

  open(message: string, action = "ok", timeout = 5000): void {
    this.m_snackBar.open(message, action, {
      duration: timeout
    });
  }
}
<file_sep>/back/api/controllers/EventTypeCRUD.php
<?php

	namespace controllers;

  use \controllers\scans\ScanDataIn;
  use \models\EventType;
  use \models\EventTypeManager;


class EventTypeCRUD {

	public function add($dataIn) {
		$scanDataIn = new ScanDataIn();
        $data = $scanDataIn->failleXSS($dataIn);
		$scanDataIn->exists($dataIn, ['name']);
		$eventType = new EventType($data);

		$eventTypeManager = new EventTypeManager();
		$eventType = $eventTypeManager->add($eventType);
		return $eventType;
	}

	public function update($dataIn) {
		$scanDataIn = new ScanDataIn();
        $data = $scanDataIn->failleXSS($dataIn);
        $scanDataIn->exists($data, ["id_event"]);
		$eventTypeManager = new EventTypeManager();
		$eventType = $eventTypeManager->readById($data["id_event"]);
			$eventType->hydrate($data);
			$eventType = $eventTypeManager->update($eventType);
			return $eventType;
	}

	public function read($dataIn) {
		$scanDataIn = new ScanDataIn();
		$data = $scanDataIn->failleXSS($dataIn);
        $scanDataIn->exists($data, ["id"]);
		$eventTypeManager = new EventTypeManager();
		$eventType = $eventTypeManager->readById($data["id"]);
		echo json_encode(array("name" => $eventType->GetName()));
	}

	public function read_OBJ($dataIn) {
		$scanDataIn = new ScanDataIn();
		$data = $scanDataIn->failleXSS($dataIn);
        $scanDataIn->exists($data, ["id"]);
		$eventTypeManager = new EventTypeManager();
		$eventType = $eventTypeManager->readById($data["id"]);
		return $eventType;
	}

	public function delete($dataIn) {
		$scanDataIn = new ScanDataIn();
        $scanDataIn->exists($dataIn, ["id"]);
        $data = $scanDataIn->failleXSS($dataIn);
		$eventTypeManager = new EventTypeManager();
		$eventTypeManager->deleteById($data["id"]);
		return TRUE;
	}
}
<file_sep>/front/src/app/shared/components/event-card/event-card.component.ts
import { Component, OnInit, Input } from '@angular/core';
import { Router } from '@angular/router';

import { Event } from 'app/shared/models/event';
import { EventService } from 'app/modules/events/event.service';

@Component({
  selector: 'app-event-card',
  templateUrl: './event-card.component.html',
  styleUrls: ['./event-card.component.scss']
})
export class EventCardComponent implements OnInit {
  @Input() event: Event;

  constructor(private m_router: Router,
    private m_eventService: EventService) { }

  ngOnInit() {
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }

  joinEvent(id: number) {
    this.m_eventService.join(id).subscribe(result => {
    }, error => {
    })
  }

  leaveEvent(id: number) {
    this.m_eventService.leave(id).subscribe(result => {
    }, error => {
    })
  }
}
<file_sep>/back/api/models/PlaceManager.php
<?php

namespace models;

class PlaceManager extends DBAccess {
	public function add(Place $place) {
		$q = $this->db->prepare("INSERT INTO places
      (`postcode`, `street`, `number`, `city`, `name`)
      VALUES (:postcode, :street, :number, :city, :name);");

	  $q->bindValue(':postcode', $place->getPostcode());
	  $q->bindValue(':street', $place->getStreet());
	  $q->bindValue(':number', $place->getNumber());
	  $q->bindValue(':city', $place->getCity());
	  $q->bindValue(':name', $place->getName());

	  $q->execute();

    $place->hydrate(['id' => $this->db->lastInsertId()]);
    return $place;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM places;')->fetchColumn();
  }

  public function readById($id) {
      $q = $this->db->prepare("SELECT * FROM places WHERE id = :id;");
	  $q->bindValue(':id', $id);
	  $q->execute();
      $place = $q->fetch(\PDO::FETCH_ASSOC);
      if($place) {
        return new Place($place);
      } else {
        throw new \Exception("Le lieu de l'évenement n'existe pas.", 400);
      }
  }

  public function readByName($name) {
      $q = $this->db->prepare("SELECT * FROM places WHERE name = :name");
	  $q->bindValue(':name', $name);
      //$q->execute([':name' => $name]);
      $place = $q->fetch(\PDO::FETCH_ASSOC);
      return ($place) ? new Place($place) : false;
  }

  public function readAll() {
    $allPlaces = [];

    $q = $this->db->query("SELECT * FROM places");
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allPlaces[$data['id']] = new Place($data);
    }
    return $allPlaces;
  }

  public function update(Place $place) {
    $q = $this->db->prepare('UPDATE places SET postcode = :postcode, street = :street, number = :number, city = :city, name = :name WHERE id = :id');

    $q->bindValue(':id', $place->getId());
    $q->bindValue(':postcode', $place->getPostcode());
    $q->bindValue(':street', $place->getStreet());
    $q->bindValue(':number', $place->getNumber());
    $q->bindValue(':city', $place->getCity());
    $q->bindValue(':name', $place->getName());

    $q->execute();

    return $place;
  }

  public function deleteById(int $id) {
    $q = $this->db->prepare("DELETE FROM places WHERE id = :id;");
    $q->bindValue(':id', $id);
    return $q->execute();
  }
}
<file_sep>/front/src/app/app-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { IsSignedInGuard } from './core/guards/is-signed-in.guard';

const routes: Routes = [
  {
    path: '',
    redirectTo: 'tableau-de-bord',
    pathMatch: 'full'
  },
  {
    path: 'tableau-de-bord',
    loadChildren: './modules/dashboard/dashboard.module#DashboardModule',
    canActivate: [IsSignedInGuard]
  },
  {
    path: 'notifications',
    loadChildren: './modules/notifications/notifications.module#NotificationsModule',
    canActivate: [IsSignedInGuard]
  },
  {
    path: 'evenements',
    loadChildren: './modules/events/events.module#EventsModule',
    canActivate: [IsSignedInGuard]
  },
  {
    path: 'profil',
    loadChildren: './modules/profile/profile.module#ProfileModule',
    canActivate: [IsSignedInGuard]
  },
  {
    path: 'recherche',
    loadChildren: './modules/search/search.module#SearchModule',
    canActivate: [IsSignedInGuard]
  },
  {
    path: 'visiteur',
    loadChildren: './modules/visitor/visitor.module#VisitorModule'
  },
  {
    path: 'mentions-legales',
    loadChildren: './modules/legals/legals.module#LegalsModule'
  },
  {
    path: '404',
    loadChildren: './modules/page-not-found/page-not-found.module#PageNotFoundModule'
  },
  {
    path: '**',
    redirectTo: '404',
    pathMatch: 'full'
  },
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
<file_sep>/back/api/controllers/scans/ScanDataIn.php
<?php

	namespace controllers\scans;

// Ensemble de méthode visant à effectuer des vérification sur des données entrantes dans l'api.



class ScanDataIn {

    public function exists(array $dataIn, array $champs) {
    	foreach ($champs as $champ) {
        if(!isset($dataIn[$champ])) {
          throw new \Exception('Champ ' . $champ . ' non inexistant.', 400);
        }
      }
    }

	function validateDate($date, $format = 'Y-m-d H:i:s')
	{
		$d = \DateTime::createFromFormat($format, $date);
		return $d && $d->format($format) === $date;
	}

    public function orgenize(array $dataIn, $numberIn, array $keys) {
        $data = [];
        for ($i=0; $i < $numberIn; $i++) {
            if(!isset($dataIn[$i])) {
                throw new \Exception('Champ ' . $keys[$i] . ' manquant pour satisfaire la requête.', 400);
            }
            $data[$keys[$i]] = $dataIn[$i];
        }
            return $data;
    }

	public function explodeSearchQuery($query) {
		$keywords = [
			'full'=>[],
			'words'=>[]
		];
		\preg_match_all('/"([^"]+)"/', $query, $matches);
		$keywords['full'] = $matches[1];
		$splits = \preg_split('/"([^"]+)"/', $query);
		foreach ($splits as $key => $split) {
			$sp = preg_split('/[\s,]+/', $split);
			foreach ($sp as $key => $value) {
				if ($value) {
					\array_push($keywords['words'], $value);
				}
			}
		}
		return $keywords;
	}


	public function failleXSS(array $dataIn) {
    	foreach ($dataIn as $data) {
    		if(is_string($data)) {
    			$data = htmlspecialchars($data);
    		}
    	}
    	return $dataIn;
	}
}
<file_sep>/back/api/models/EventManager.php
<?php

namespace models;

class EventManager extends DBAccess {
	public function add(Event $event) {
		$q = $this->db->prepare("INSERT INTO events (`title`, `photo_url`, `description`, `date_start`, `date_end`, `date_created`) VALUES (:title, :photo_url, :description, :date_start, :date_end, NOW());");

			$q->bindValue(':title', $event->getTitle());
			$q->bindValue(':photo_url', $event->getPhoto_url());
			$q->bindValue(':description', $event->getDescription());
			$q->bindValue(':date_start', $event->getDate_start());
			$q->bindValue(':date_end', $event->getDate_end());

			$q->execute();

			$event->hydrate(['id' => $this->db->lastInsertId()]);
			return $event;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM events;')->fetchColumn();
  }

  public function readById_noException($id) {
      $q = $this->db->prepare("SELECT * FROM events WHERE id = :id");
	  $q->bindValue(':id', $id);
	  $q->execute();
      $event = $q->fetch(\PDO::FETCH_ASSOC);
	  return $event;
  }

  public function readById($id) {
      $q = $this->db->prepare("SELECT * FROM events WHERE id = :id");
	  $q->bindValue(':id', $id);
	  $q->execute();
      $event = $q->fetch(\PDO::FETCH_ASSOC);
	  if ($event) {
		  return new Event($event);
	  }
	  else {
	  	throw new \Exception("Aucun événement ne correspond à l'id $id", 400);
	  }
  }

  public function readOffsetLimit(int $offset, int $limit) {
    $allEvents = [];

    $q = $this->db->prepare("SELECT * FROM events WHERE date_start >= DATE_SUB(NOW(), INTERVAL 1 MONTH) OR date_start IS NULL ORDER BY CASE WHEN date_start IS NULL THEN 1 ELSE 0 END, date_start LIMIT :limit OFFSET :offset");
    $q->bindValue(":limit", (int) $limit, \PDO::PARAM_INT);
    $q->bindValue(':offset', (int) $offset, \PDO::PARAM_INT);
	$q->execute();
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allEvents[$data['id']] = new Event($data);
    }
    return $allEvents;
  }

  public function readAll() {
    $allEvents = [];

    $q = $this->db->query("SELECT * FROM events WHERE date_start IS NOT NULL AND date_start >= NOW() ORDER BY date_start ASC LIMIT 10;");
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allEvents[$data['id']] = new Event($data);
    }
    return $allEvents;
  }

  public function search($keywords) {
	  $allEvents = [];

	  $query = "SELECT * FROM events";
	  $i = 0;
	  foreach ($keywords as $key => $keyword) {
		  if ($i != 0) $query .= " AND";
		  else $query .= " WHERE";
		  $query .= " title LIKE '%$keyword%'";
		  $i++;
	  }
	  $query .= ";";
	  $q = $this->db->query($query);
	  while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
	   $allEvents[$data['id']] = new Event($data);
	  }
	  return $allEvents;
  }

  public function readAllValid() {
    $allEvents = [];

    $q = $this->db->query("SELECT * FROM events WHERE date_start < date_end;");
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allEvents[$data['id']] = new Event($data);
    }
    return $allEvents;
  }

  public function update(Event $event) {
    $q = $this->db->prepare('UPDATE events SET title = :title, photo_url = :photo_url, description = :description, date_start = :date_start, date_end = :date_end, date_created = :date_created WHERE id = :id');

    $q->bindValue(':id', $event->getId());
    $q->bindValue(':title', $event->getTitle());
    $q->bindValue(':photo_url', $event->getPhoto_url());
    $q->bindValue(':description', $event->getDescription());
    $q->bindValue(':date_start', $event->getDate_start());
    $q->bindValue(':date_end', $event->getDate_end());
    $q->bindValue(':date_created', $event->getDate_created());
    $q->execute();

    return $event;
  }

  public function deleteById(int $id) {
    $this->db->exec("DELETE FROM events WHERE id = {$id};");
    return TRUE;
  }
}
<file_sep>/front/src/app/modules/visitor/inscription/inscription.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { Router } from '@angular/router';

import { PasswordMatch } from 'app/shared/validators/password-match';
import { UserService } from '../user.service';
import { HttpErrorResponse } from '@angular/common/http';
import { ImageUrl } from 'app/shared/validators/image-url';
import { ResponsiveService } from 'app/core/services/responsive.service';

@Component({
  selector: 'app-inscription',
  templateUrl: './inscription.component.html',
  styleUrls: ['./inscription.component.scss']
})
export class InscriptionComponent implements OnInit {
  inscriptionForm: FormGroup;
  bInscriptionDone = false;
  bMobile = true;

  constructor(private m_formBuilder: FormBuilder,
    private m_userService: UserService,
    private m_router: Router,
    responsiveService: ResponsiveService) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.inscriptionForm = this.m_formBuilder.group({
      page1: this.m_formBuilder.group({
        pseudo: ['', Validators.required],
        mail: ['', Validators.compose([
          Validators.required,
          Validators.pattern(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/)
        ])],
        year_promotion: ['', Validators.required]
      }),
      page2: this.m_formBuilder.group({
        phone: '',
        firstname: ['', Validators.required],
        lastname: ['', Validators.required],
        photo_url: ['https://i2.wp.com/rouelibrenmaine.fr/wp-content/uploads/2018/10/empty-avatar.png', Validators.required]
      }, {
        validators: ImageUrl('photo_url')
      }),
      page3: this.m_formBuilder.group({
        pwd: ['', Validators.compose([
          Validators.required,
          Validators.minLength(4)
        ])],
        confirm_pwd: ['', Validators.compose([
          Validators.required,
          Validators.minLength(4)
        ])]
      }, {
        validators: PasswordMatch('pwd','<PASSWORD>')
      })
    });
  }

  ngOnInit() {}

  submitForm(): void {
    // Prepare form
    const form = Object.assign({}, this.inscriptionForm.value.page1, this.inscriptionForm.value.page2, this.inscriptionForm.value.page3);
    delete form.confirm_pwd;

    // Send form
    this.m_userService.create(form).subscribe(response => {
      this.bInscriptionDone = true;

      setTimeout(() => {
        this.m_router.navigate(['/visiteur/login]']);
      }, 2500);
    }, (error: HttpErrorResponse) => {
      // TODO handles error
    });
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }
}
<file_sep>/back/api/controllers/scans/TokenCreater.php
<?php

	namespace controllers\scans;

	use \Config;
	use \vendor\jwt\src\JWT;

class TokenCreater {

	public function createToken($id) {
			$config = new Config();

			/* NOTE: mcrypt_create_iv function was DEPRECATED in PHP 7.1.0, and REMOVED in PHP 7.2.0.
	        $tokenId = base64_encode(mcrypt_create_iv(32));*/
	        $tokenId = base64_encode(random_bytes(32));
	        $issuedAt = time();
	        $notBefore = $issuedAt + 10;
	        $expire = $notBefore + 10800;
	        $serverName = $config->getServerName();

	        $data = [
	        'iat'  => $issuedAt,
	        'jti'  => $tokenId,
	        'iss'  => $serverName,
	        'nbf'  => $notBefore,
	        'exp'  => $expire,
	        'data' => [
	            'userId'   => $id
	            ]
	        ];
	        $jwt = JWT::encode($data, $config->getJwtKey(),'HS512');
			$unencodedArray = [
				'jwt' => $jwt,
				'id_user'   => $id
			];
	        echo json_encode($unencodedArray);
	    }
}
<file_sep>/back/api/models/EventTypeManager.php
<?php

namespace models;

class EventTypeManager extends DBAccess {
	public function add(EventType $eventType) {
		$q = $this->db->prepare("INSERT INTO eventtypes
      (`name`)
      VALUES (:name);");

	  $q->bindValue(':name', $eventType->getName());

	  $q->execute();

    $eventType->hydrate(['id' => $this->db->lastInsertId()]);
    return $eventType;
  }

  public function readById($id) {
      $q = $this->db->prepare("SELECT * FROM eventtypes WHERE id = :id;");
	  $q->bindValue(':id', $id);
	  $q->execute();
      $eventType = $q->fetch(\PDO::FETCH_ASSOC);
	  //\var_dump($place);
      $eventTypeObj = new EventType($eventType);
      if($eventTypeObj) {
        return $eventTypeObj;
      } else {
        throw new \Exception("Le type n'existe pas.", 400);
      }
  }

  public function readByName($name) {
      $q = $this->db->prepare("SELECT * FROM eventtypes WHERE name = :name");
	  $q->bindValue(':name', $name);
      //$q->execute([':name' => $name]);
      $eventType = $q->fetch(\PDO::FETCH_ASSOC);
      return ($eventType) ? new EventType($eventType) : false;
  }

  public function readAll() {
    $allEventTypes = [];

    $q = $this->db->query("SELECT * FROM eventtypes");
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allEventTypes[$data['id']] = new EventType($data);
    }
    return $allEventTypes;
  }

  public function update(EventType $eventType) {
    $q = $this->db->prepare('UPDATE eventtypes SET name = :name WHERE id = :id');

    $q->bindValue(':name', $eventType->getName());

    $q->execute();

    return $eventType;
  }

  public function deleteById(int $id) {
    $q = $this->db->prepare("DELETE FROM eventtypes WHERE id = :id;");
    $q->bindValue(':id', $id);
    return $q->execute();
  }
}
<file_sep>/front/documentation/js/menu-wc.js
'use strict';


customElements.define('compodoc-menu', class extends HTMLElement {
    constructor() {
        super();
        this.isNormalMode = this.getAttribute('mode') === 'normal';
    }

    connectedCallback() {
        this.render(this.isNormalMode);
    }

    render(isNormalMode) {
        let tp = lithtml.html(`
        <nav>
            <ul class="list">
                <li class="title">
                    <a href="index.html" data-type="index-link">imac-resoi-front documentation</a>
                </li>

                <li class="divider"></li>
                ${ isNormalMode ? `<div id="book-search-input" role="search"><input type="text" placeholder="Type to search"></div>` : '' }
                <li class="chapter">
                    <a data-type="chapter-link" href="index.html"><span class="icon ion-ios-home"></span>Getting started</a>
                    <ul class="links">
                        <li class="link">
                            <a href="overview.html" data-type="chapter-link">
                                <span class="icon ion-ios-keypad"></span>Overview
                            </a>
                        </li>
                        <li class="link">
                            <a href="index.html" data-type="chapter-link">
                                <span class="icon ion-ios-paper"></span>README
                            </a>
                        </li>
                        <li class="link">
                            <a href="license.html"  data-type="chapter-link">
                                <span class="icon ion-ios-paper"></span>LICENSE
                            </a>
                        </li>
                        <li class="link">
                            <a href="dependencies.html" data-type="chapter-link">
                                <span class="icon ion-ios-list"></span>Dependencies
                            </a>
                        </li>
                    </ul>
                </li>
                    <li class="chapter modules">
                        <a data-type="chapter-link" href="modules.html">
                            <div class="menu-toggler linked" data-toggle="collapse" ${ isNormalMode ?
                                'data-target="#modules-links"' : 'data-target="#xs-modules-links"' }>
                                <span class="icon ion-ios-archive"></span>
                                <span class="link-name">Modules</span>
                                <span class="icon ion-ios-arrow-down"></span>
                            </div>
                        </a>
                        <ul class="links collapse" ${ isNormalMode ? 'id="modules-links"' : 'id="xs-modules-links"' }>
                            <li class="link">
                                <a href="modules/AppModule.html" data-type="entity-link">AppModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-AppModule-1baba09bc7b7a38c6798e3b55ffefd74"' : 'data-target="#xs-components-links-module-AppModule-1baba09bc7b7a38c6798e3b55ffefd74"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-AppModule-1baba09bc7b7a38c6798e3b55ffefd74"' :
                                            'id="xs-components-links-module-AppModule-1baba09bc7b7a38c6798e3b55ffefd74"' }>
                                            <li class="link">
                                                <a href="components/AppComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">AppComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/AppRoutingModule.html" data-type="entity-link">AppRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/AppServerModule.html" data-type="entity-link">AppServerModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-AppServerModule-6f845fdce6d80526e11ce4cddb70e623"' : 'data-target="#xs-components-links-module-AppServerModule-6f845fdce6d80526e11ce4cddb70e623"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-AppServerModule-6f845fdce6d80526e11ce4cddb70e623"' :
                                            'id="xs-components-links-module-AppServerModule-6f845fdce6d80526e11ce4cddb70e623"' }>
                                            <li class="link">
                                                <a href="components/AppComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">AppComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/CoreMaterialModule.html" data-type="entity-link">CoreMaterialModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/CoreModule.html" data-type="entity-link">CoreModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' : 'data-target="#xs-components-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' :
                                            'id="xs-components-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' }>
                                            <li class="link">
                                                <a href="components/BottomNavigationComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">BottomNavigationComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/TopNavigationComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">TopNavigationComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                                <li class="chapter inner">
                                    <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                        'data-target="#injectables-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' : 'data-target="#xs-injectables-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' }>
                                        <span class="icon ion-md-arrow-round-down"></span>
                                        <span>Injectables</span>
                                        <span class="icon ion-ios-arrow-down"></span>
                                    </div>
                                    <ul class="links collapse" ${ isNormalMode ? 'id="injectables-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' :
                                        'id="xs-injectables-links-module-CoreModule-019fda25406c3d315c97aa9cf0a552fe"' }>
                                        <li class="link">
                                            <a href="injectables/AuthService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>AuthService</a>
                                        </li>
                                        <li class="link">
                                            <a href="injectables/ResponsiveService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>ResponsiveService</a>
                                        </li>
                                    </ul>
                                </li>
                            </li>
                            <li class="link">
                                <a href="modules/CreateEventModule.html" data-type="entity-link">CreateEventModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-CreateEventModule-1dc31bbf58b03dbe752879b28960acc3"' : 'data-target="#xs-components-links-module-CreateEventModule-1dc31bbf58b03dbe752879b28960acc3"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-CreateEventModule-1dc31bbf58b03dbe752879b28960acc3"' :
                                            'id="xs-components-links-module-CreateEventModule-1dc31bbf58b03dbe752879b28960acc3"' }>
                                            <li class="link">
                                                <a href="components/CreateEventComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">CreateEventComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/CreateEventRoutingModule.html" data-type="entity-link">CreateEventRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/DashboardModule.html" data-type="entity-link">DashboardModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-DashboardModule-eee20dbd623b64326757842e12126d70"' : 'data-target="#xs-components-links-module-DashboardModule-eee20dbd623b64326757842e12126d70"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-DashboardModule-eee20dbd623b64326757842e12126d70"' :
                                            'id="xs-components-links-module-DashboardModule-eee20dbd623b64326757842e12126d70"' }>
                                            <li class="link">
                                                <a href="components/DashboardComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">DashboardComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/DashboardRoutingModule.html" data-type="entity-link">DashboardRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/EditEventModule.html" data-type="entity-link">EditEventModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-EditEventModule-6b834132e3de09ab0c237f559d6bb3db"' : 'data-target="#xs-components-links-module-EditEventModule-6b834132e3de09ab0c237f559d6bb3db"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-EditEventModule-6b834132e3de09ab0c237f559d6bb3db"' :
                                            'id="xs-components-links-module-EditEventModule-6b834132e3de09ab0c237f559d6bb3db"' }>
                                            <li class="link">
                                                <a href="components/EditEventComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">EditEventComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/EditEventRoutingModule.html" data-type="entity-link">EditEventRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/EventDetailModule.html" data-type="entity-link">EventDetailModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-EventDetailModule-494bd5a76125960439a258868cb76a69"' : 'data-target="#xs-components-links-module-EventDetailModule-494bd5a76125960439a258868cb76a69"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-EventDetailModule-494bd5a76125960439a258868cb76a69"' :
                                            'id="xs-components-links-module-EventDetailModule-494bd5a76125960439a258868cb76a69"' }>
                                            <li class="link">
                                                <a href="components/EventDetailComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">EventDetailComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/EventDetailRoutingModule.html" data-type="entity-link">EventDetailRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/EventsModule.html" data-type="entity-link">EventsModule</a>
                                <li class="chapter inner">
                                    <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                        'data-target="#injectables-links-module-EventsModule-b1488a9ad3d6042e16afdec85bc68306"' : 'data-target="#xs-injectables-links-module-EventsModule-b1488a9ad3d6042e16afdec85bc68306"' }>
                                        <span class="icon ion-md-arrow-round-down"></span>
                                        <span>Injectables</span>
                                        <span class="icon ion-ios-arrow-down"></span>
                                    </div>
                                    <ul class="links collapse" ${ isNormalMode ? 'id="injectables-links-module-EventsModule-b1488a9ad3d6042e16afdec85bc68306"' :
                                        'id="xs-injectables-links-module-EventsModule-b1488a9ad3d6042e16afdec85bc68306"' }>
                                        <li class="link">
                                            <a href="injectables/EventService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>EventService</a>
                                        </li>
                                        <li class="link">
                                            <a href="injectables/PostService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>PostService</a>
                                        </li>
                                    </ul>
                                </li>
                            </li>
                            <li class="link">
                                <a href="modules/EventsRoutingModule.html" data-type="entity-link">EventsRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/LegalsModule.html" data-type="entity-link">LegalsModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-LegalsModule-3a7232d3d4fd893148edc73ce1c0b8ac"' : 'data-target="#xs-components-links-module-LegalsModule-3a7232d3d4fd893148edc73ce1c0b8ac"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-LegalsModule-3a7232d3d4fd893148edc73ce1c0b8ac"' :
                                            'id="xs-components-links-module-LegalsModule-3a7232d3d4fd893148edc73ce1c0b8ac"' }>
                                            <li class="link">
                                                <a href="components/LegalsComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">LegalsComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/LegalsRoutingModule.html" data-type="entity-link">LegalsRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/NotificationsModule.html" data-type="entity-link">NotificationsModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' : 'data-target="#xs-components-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' :
                                            'id="xs-components-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' }>
                                            <li class="link">
                                                <a href="components/NotificationsComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">NotificationsComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                                <li class="chapter inner">
                                    <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                        'data-target="#injectables-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' : 'data-target="#xs-injectables-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' }>
                                        <span class="icon ion-md-arrow-round-down"></span>
                                        <span>Injectables</span>
                                        <span class="icon ion-ios-arrow-down"></span>
                                    </div>
                                    <ul class="links collapse" ${ isNormalMode ? 'id="injectables-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' :
                                        'id="xs-injectables-links-module-NotificationsModule-080eb549465e4180c88c86e652079db6"' }>
                                        <li class="link">
                                            <a href="injectables/NotificationsService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>NotificationsService</a>
                                        </li>
                                    </ul>
                                </li>
                            </li>
                            <li class="link">
                                <a href="modules/NotificationsRoutingModule.html" data-type="entity-link">NotificationsRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/PageNotFoundModule.html" data-type="entity-link">PageNotFoundModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-PageNotFoundModule-0bc830147d4044f6d50a71f02bb3e477"' : 'data-target="#xs-components-links-module-PageNotFoundModule-0bc830147d4044f6d50a71f02bb3e477"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-PageNotFoundModule-0bc830147d4044f6d50a71f02bb3e477"' :
                                            'id="xs-components-links-module-PageNotFoundModule-0bc830147d4044f6d50a71f02bb3e477"' }>
                                            <li class="link">
                                                <a href="components/PageNotFoundComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">PageNotFoundComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/PageNotFoundRoutingModule.html" data-type="entity-link">PageNotFoundRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/ProfileModule.html" data-type="entity-link">ProfileModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-ProfileModule-3a43e8cd5888c0a8cc903ffad7e09556"' : 'data-target="#xs-components-links-module-ProfileModule-3a43e8cd5888c0a8cc903ffad7e09556"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-ProfileModule-3a43e8cd5888c0a8cc903ffad7e09556"' :
                                            'id="xs-components-links-module-ProfileModule-3a43e8cd5888c0a8cc903ffad7e09556"' }>
                                            <li class="link">
                                                <a href="components/ChangePasswordComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">ChangePasswordComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/EditProfileComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">EditProfileComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/ProfileComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">ProfileComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/ProfileRoutingModule.html" data-type="entity-link">ProfileRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/SearchModule.html" data-type="entity-link">SearchModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-SearchModule-f91f897b9a44ee7da0d12eae88e59247"' : 'data-target="#xs-components-links-module-SearchModule-f91f897b9a44ee7da0d12eae88e59247"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-SearchModule-f91f897b9a44ee7da0d12eae88e59247"' :
                                            'id="xs-components-links-module-SearchModule-f91f897b9a44ee7da0d12eae88e59247"' }>
                                            <li class="link">
                                                <a href="components/SearchComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">SearchComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/SearchRoutingModule.html" data-type="entity-link">SearchRoutingModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/SharedMaterialModule.html" data-type="entity-link">SharedMaterialModule</a>
                            </li>
                            <li class="link">
                                <a href="modules/SharedModule.html" data-type="entity-link">SharedModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-SharedModule-d4a7898cfced2451f209e2a9c9529e5b"' : 'data-target="#xs-components-links-module-SharedModule-d4a7898cfced2451f209e2a9c9529e5b"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-SharedModule-d4a7898cfced2451f209e2a9c9529e5b"' :
                                            'id="xs-components-links-module-SharedModule-d4a7898cfced2451f209e2a9c9529e5b"' }>
                                            <li class="link">
                                                <a href="components/CommentListComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">CommentListComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/EventCardComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">EventCardComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/PostListComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">PostListComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/TopAppBarComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">TopAppBarComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                            </li>
                            <li class="link">
                                <a href="modules/VisitorModule.html" data-type="entity-link">VisitorModule</a>
                                    <li class="chapter inner">
                                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                            'data-target="#components-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' : 'data-target="#xs-components-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' }>
                                            <span class="icon ion-md-cog"></span>
                                            <span>Components</span>
                                            <span class="icon ion-ios-arrow-down"></span>
                                        </div>
                                        <ul class="links collapse" ${ isNormalMode ? 'id="components-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' :
                                            'id="xs-components-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' }>
                                            <li class="link">
                                                <a href="components/ForgotComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">ForgotComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/InscriptionComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">InscriptionComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/InvitationComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">InvitationComponent</a>
                                            </li>
                                            <li class="link">
                                                <a href="components/LoginComponent.html"
                                                    data-type="entity-link" data-context="sub-entity" data-context-id="modules">LoginComponent</a>
                                            </li>
                                        </ul>
                                    </li>
                                <li class="chapter inner">
                                    <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ?
                                        'data-target="#injectables-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' : 'data-target="#xs-injectables-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' }>
                                        <span class="icon ion-md-arrow-round-down"></span>
                                        <span>Injectables</span>
                                        <span class="icon ion-ios-arrow-down"></span>
                                    </div>
                                    <ul class="links collapse" ${ isNormalMode ? 'id="injectables-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' :
                                        'id="xs-injectables-links-module-VisitorModule-44b744e02433e4a304802c512af792b7"' }>
                                        <li class="link">
                                            <a href="injectables/UserService.html"
                                                data-type="entity-link" data-context="sub-entity" data-context-id="modules" }>UserService</a>
                                        </li>
                                    </ul>
                                </li>
                            </li>
                            <li class="link">
                                <a href="modules/VisitorRoutingModule.html" data-type="entity-link">VisitorRoutingModule</a>
                            </li>
                </ul>
                </li>
                        <li class="chapter">
                            <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ? 'data-target="#injectables-links"' :
                                'data-target="#xs-injectables-links"' }>
                                <span class="icon ion-md-arrow-round-down"></span>
                                <span>Injectables</span>
                                <span class="icon ion-ios-arrow-down"></span>
                            </div>
                            <ul class="links collapse" ${ isNormalMode ? 'id="injectables-links"' : 'id="xs-injectables-links"' }>
                                <li class="link">
                                    <a href="injectables/AuthService.html" data-type="entity-link">AuthService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/EventService.html" data-type="entity-link">EventService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/NotificationsService.html" data-type="entity-link">NotificationsService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/NotificationsService-1.html" data-type="entity-link">NotificationsService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/PostService.html" data-type="entity-link">PostService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/ResponsiveService.html" data-type="entity-link">ResponsiveService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/SnackBarService.html" data-type="entity-link">SnackBarService</a>
                                </li>
                                <li class="link">
                                    <a href="injectables/UserService.html" data-type="entity-link">UserService</a>
                                </li>
                            </ul>
                        </li>
                    <li class="chapter">
                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ? 'data-target="#interceptors-links"' :
                            'data-target="#xs-interceptors-links"' }>
                            <span class="icon ion-ios-swap"></span>
                            <span>Interceptors</span>
                            <span class="icon ion-ios-arrow-down"></span>
                        </div>
                        <ul class="links collapse" ${ isNormalMode ? 'id="interceptors-links"' : 'id="xs-interceptors-links"' }>
                            <li class="link">
                                <a href="interceptors/AuthInterceptor.html" data-type="entity-link">AuthInterceptor</a>
                            </li>
                            <li class="link">
                                <a href="interceptors/ErrorInterceptor.html" data-type="entity-link">ErrorInterceptor</a>
                            </li>
                        </ul>
                    </li>
                    <li class="chapter">
                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ? 'data-target="#guards-links"' :
                            'data-target="#xs-guards-links"' }>
                            <span class="icon ion-ios-lock"></span>
                            <span>Guards</span>
                            <span class="icon ion-ios-arrow-down"></span>
                        </div>
                        <ul class="links collapse" ${ isNormalMode ? 'id="guards-links"' : 'id="xs-guards-links"' }>
                            <li class="link">
                                <a href="guards/IsSignedInGuard.html" data-type="entity-link">IsSignedInGuard</a>
                            </li>
                        </ul>
                    </li>
                    <li class="chapter">
                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ? 'data-target="#interfaces-links"' :
                            'data-target="#xs-interfaces-links"' }>
                            <span class="icon ion-md-information-circle-outline"></span>
                            <span>Interfaces</span>
                            <span class="icon ion-ios-arrow-down"></span>
                        </div>
                        <ul class="links collapse" ${ isNormalMode ? ' id="interfaces-links"' : 'id="xs-interfaces-links"' }>
                            <li class="link">
                                <a href="interfaces/Comment.html" data-type="entity-link">Comment</a>
                            </li>
                            <li class="link">
                                <a href="interfaces/Event.html" data-type="entity-link">Event</a>
                            </li>
                            <li class="link">
                                <a href="interfaces/Notification.html" data-type="entity-link">Notification</a>
                            </li>
                            <li class="link">
                                <a href="interfaces/Place.html" data-type="entity-link">Place</a>
                            </li>
                            <li class="link">
                                <a href="interfaces/Post.html" data-type="entity-link">Post</a>
                            </li>
                            <li class="link">
                                <a href="interfaces/User.html" data-type="entity-link">User</a>
                            </li>
                        </ul>
                    </li>
                    <li class="chapter">
                        <div class="simple menu-toggler" data-toggle="collapse" ${ isNormalMode ? 'data-target="#miscellaneous-links"'
                            : 'data-target="#xs-miscellaneous-links"' }>
                            <span class="icon ion-ios-cube"></span>
                            <span>Miscellaneous</span>
                            <span class="icon ion-ios-arrow-down"></span>
                        </div>
                        <ul class="links collapse" ${ isNormalMode ? 'id="miscellaneous-links"' : 'id="xs-miscellaneous-links"' }>
                            <li class="link">
                                <a href="miscellaneous/enumerations.html" data-type="entity-link">Enums</a>
                            </li>
                            <li class="link">
                                <a href="miscellaneous/functions.html" data-type="entity-link">Functions</a>
                            </li>
                            <li class="link">
                                <a href="miscellaneous/variables.html" data-type="entity-link">Variables</a>
                            </li>
                        </ul>
                    </li>
                    <li class="chapter">
                        <a data-type="chapter-link" href="coverage.html"><span class="icon ion-ios-stats"></span>Documentation coverage</a>
                    </li>
                    <li class="divider"></li>
                    <li class="copyright">
                        Documentation generated using <a href="https://compodoc.app/" target="_blank">
                            <img data-src="images/compodoc-vectorise.png" class="img-responsive" data-type="compodoc-logo">
                        </a>
                    </li>
            </ul>
        </nav>
        `);
        this.innerHTML = tp.strings;
    }
});<file_sep>/back/api/controllers/UserCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \models\User;
use \models\UserManager;


class UserCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["firstname", "lastname", "pseudo", "pwd", "mail", "photo_url", "year_promotion"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $data["pwd_hash"] = password_hash($data["pwd"], PASSWORD_DEFAULT);
    $user = new User($data);
    $userManager = new UserManager();
    if ($userManager->readByPseudo($user->getPseudo()) === FALSE) {
      $userManager->add($user);
    } else {
      throw new \Exception('Pseudo déjà existant.', 400);
    }
    echo json_encode([
            "message" => "User added.",
    ]);;
  }

  public function update($dataIn) {
    // TODO: vérifier les droits
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $token->acompteAccess($data["id"]);
    $userManager = new UserManager();
    if (isset($data['pwd'])) {
        $data['pwd_hash'] = password_hash($data["pwd"], PASSWORD_DEFAULT);
        unset($data['pwd']);
    }

    $user = $userManager->readById($data["id"]);
      if($user) {
                $user->hydrate($data);
        $userManager->update($user);
      } else {
        throw new Exception("L'utilisateur n'existe pas.", 400);
      }
    echo json_encode([
            "message" => "User updated.",
    ]);;
    }

  public function read($dataIn) {
    $scanDataIn = new ScanDataIn();
    $data = $scanDataIn->failleXSS($dataIn);
    $data = $scanDataIn->orgenize($data, 2, ["type", "id"]);
    $userManager = new UserManager();
    $user = $userManager->readById($data["id"]);
    if($user) {
        echo json_encode([
            "firstname" => $user->GetFirstname(),
            "lastname" => $user->GetLastname(),
            "pseudo" => $user->GetPseudo(),
            "photo_url" => $user->GetPhoto_url(),
            "status" => $user->GetStatus(),
            "phone" => $user->GetPhone(),
            "mail" => $user->GetMail(),
            "year_promotion" => $user->getYear_promotion()
        ]);
    } else {
      throw new Exception("L'utilisateur n'existe pas.", 400);
    }
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    if($token->acompteAccess($data["id"]) OR $token->adminAccess(1)) {
        $userManager = new UserManager();
        $userManager->deleteById($data["id"]);
        echo json_encode([
            "message" => "User deleted.",
        ]);;
    }
  }

  public function auth($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["pseudo", "pwd"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $userManager = new UserManager();
    $user = $userManager->readByPseudo($data["pseudo"]);
    if ($user == FALSE) {
        throw new \Exception("Le nom d'utilisateur est incorrect.", 401);
    } else {
        if(password_verify($data["pwd"], $user->getPwd_hash())) {
            $tokenCreater = new TokenCreater();
            $tokenCreater->createToken($user->GetId());
        } else {
          throw new \Exception("Le mot de passe est incorrect.", 401);
        }
    }
  }
}
<file_sep>/front/src/app/modules/events/event-detail/event-detail.component.ts
import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';

import { Event } from 'app/shared/models/event';
import { EventService } from '../event.service';
import { ResponsiveService } from 'app/core/services/responsive.service';
import { MatDialog } from '@angular/material';
import { DialogComponent } from 'app/shared/components/dialog/dialog.component';

@Component({
  selector: 'app-event-detail',
  templateUrl: './event-detail.component.html',
  styleUrls: ['./event-detail.component.scss']
})
export class EventDetailComponent implements OnInit {
  @ViewChild('place') place: ElementRef;
  event: Event;
  bMobile = true;
  bNoHour = true;
  eventId: number;

  constructor(private m_eventService: EventService,
    route: ActivatedRoute,
    private m_router: Router,
    responsiveService: ResponsiveService,
    private m_dialog: MatDialog) {
    this.eventId = Number(route.snapshot.paramMap.get('id'));

    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
        this.bMobile = false;
      } else {
        this.bMobile = true;
      }
    });
  }

  ngOnInit() {
    this.m_eventService.getEventById(this.eventId).subscribe(result => {
      this.event = result;
      if (result.date_start != '') {
        const date = new Date(result.date_start);
        if (date.getHours() != 0) {
          this.bNoHour = false;
        };
      }
    }, error => {

    });
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }

  joinEvent() {
    this.m_eventService.join(this.eventId).subscribe(result => {
    }, error => {
    })
  }

  leaveEvent() {
    this.m_eventService.leave(this.eventId).subscribe(result => {
    }, error => {
    })
  }

  reloadPosts(): void {
    this.m_eventService.getEventById(this.eventId).subscribe(result => {
      this.event.posts = result.posts;
    }, error => {

    });
  }

  getIcsLink(): void {
    this.m_eventService.getIcsLink(this.eventId).subscribe(result => {
      const dialogRef = this.m_dialog.open(DialogComponent, {
        width: "500px",
        data: {title: `Export de l'évènement`, text: `Copiez ce lien dans votre application de calendrier: ${result.url} `}
      });
    }, error => {

    });
  }

  scrollToPlace(): void {
    const target = this.place.nativeElement;
    target.scrollIntoView({behavior: 'smooth'});
  }

  log(text: string): void {
    console.log(text);
  }
}
<file_sep>/front/src/app/modules/profile/change-password/change-password.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';

import { AuthService } from 'app/core/services/auth.service';
import { UserService } from 'app/modules/visitor/user.service';
import { PasswordMatch } from 'app/shared/validators/password-match';
import { ResponsiveService } from 'app/core/services/responsive.service';

@Component({
  selector: 'app-change-password',
  templateUrl: './change-password.component.html',
  styleUrls: ['./change-password.component.scss']
})
export class ChangePasswordComponent implements OnInit {
  userForm: FormGroup;
  bUpdated = false;
  bMobile: boolean;

  constructor(private m_router: Router,
    private m_formBuilder: FormBuilder,
    private m_userService: UserService,
    private m_authService: AuthService,
    responsiveService: ResponsiveService) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.userForm = this.m_formBuilder.group({
      pwd: ['', Validators.compose([
        Validators.required,
        Validators.minLength(4)
      ])],
      confirm_pwd: ['', Validators.compose([
        Validators.required,
        Validators.minLength(4)
      ])]
    }, {
      validators: PasswordMatch('pwd','confirm_pwd')
    });
  }

  ngOnInit() {

  }

  submitForm(): void {
    let form = this.userForm.value;
    form.id = this.m_authService.getUserId();
    delete form.confirm_pwd;
    this.m_userService.update(this.m_authService.getUserId(), form).subscribe(result => {
      this.m_router.navigate(['/profil']);
    }, error => {

    });
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }

}
<file_sep>/front/src/app/shared/directives/defer-load.directive.ts
import { Directive, ElementRef, EventEmitter, Output } from '@angular/core';

@Directive({
  selector: '[appDeferLoad]'
})
export class DeferLoadDirective {
  @Output() public discovered: EventEmitter<any> = new EventEmitter();

  private m_intersectionObserver?: IntersectionObserver;

  constructor(private m_element: ElementRef) { }

  ngAfterViewInit() {
    this.m_intersectionObserver = new IntersectionObserver(entries => {
      this.checkForIntersection(entries);
    }, {});
    this.m_intersectionObserver.observe(<Element>(this.m_element.nativeElement));
  }

  private checkForIntersection = (entries: Array<IntersectionObserverEntry>) => {
    entries.forEach((entry: IntersectionObserverEntry) => {
      if (this.checkIfIntersecting(entry)) {
        this.discovered.emit();
        this.m_intersectionObserver.unobserve(<Element>(this.m_element.nativeElement));
        this.m_intersectionObserver.disconnect();
      }
    });
  }

  private checkIfIntersecting(entry: IntersectionObserverEntry) {
    return (<any>entry).isIntersecting && entry.target === this.m_element.nativeElement;
  }
}
<file_sep>/back/api/controllers/PlaceCRUD.php
<?php

	namespace controllers;

  use \controllers\scans\ScanDataIn;
  use \models\Place;
  use \models\PlaceManager;


class PlaceCRUD {

	public function add($dataIn) {
		$scanDataIn = new ScanDataIn();
        //$scanDataIn->exists($dataIn, ["postcode", "street", "number", "city", "name"]);
        $data = $scanDataIn->failleXSS($dataIn);
		$place = new Place($data);

		$placeManager = new PlaceManager();
		$place = $placeManager->add($place);
		return $place;
	}

	public function update($dataIn) {
		$scanDataIn = new ScanDataIn();
        $data = $scanDataIn->failleXSS($dataIn);
		$placeManager = new PlaceManager();
		$place = $placeManager->readById($data["id"]);
		$place->hydrate($data);
		$place = $placeManager->update($place);
		return $place;
	}

	public function read($dataIn) {
		$scanDataIn = new ScanDataIn();
		$data = $scanDataIn->failleXSS($dataIn);
        $scanDataIn->exists($data, ["id"]);
		$placeManager = new PlaceManager();
		$place = $placeManager->readById($data["id"]);
		echo json_encode(array("name" => $place->GetName(), "postcode" => $place->GetPostcode(), "street" => $place->GetStreet(), "number" => $place->GetNumber(), "city" => $place->GetCity()));

	}

	public function read_OBJ($dataIn) {
		$scanDataIn = new ScanDataIn();
		$data = $scanDataIn->failleXSS($dataIn);
        $scanDataIn->exists($data, ["id"]);
		$placeManager = new PlaceManager();
		$place = $placeManager->readById($data["id"]);
		return $place;
	}

	public function delete($dataIn) {
		$scanDataIn = new ScanDataIn();
        $scanDataIn->exists($dataIn, ["id"]);
        $data = $scanDataIn->failleXSS($dataIn);
		$placeManager = new PlaceManager();
		$placeManager->deleteById($data["id"]);
		return TRUE;
	}
}
<file_sep>/front/src/app/modules/visitor/invitation/invitation.component.ts
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';
import { ResponsiveService } from 'app/core/services/responsive.service';
import { Router } from '@angular/router';

@Component({
  selector: 'app-invitation',
  templateUrl: './invitation.component.html',
  styleUrls: ['./invitation.component.scss']
})
export class InvitationComponent implements OnInit {
  invitationForm: FormGroup;
  bMobile: boolean;

  constructor(private m_formBuilder: FormBuilder,
    private m_router: Router,
    responsiveService: ResponsiveService) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.invitationForm = this.m_formBuilder.group({
      email: ['', Validators.compose([
        Validators.required,
        Validators.email
      ])],
      name: ['', Validators.compose([
        Validators.required,
        Validators.minLength(4)
      ])],
      promotion: ['', Validators.required],
      message: ['']
    });
  }

  ngOnInit() {
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }
}
<file_sep>/back/api/models/Comment.php
<?php

namespace models;

class Comment {

	protected $id,
  $content,
  $date_created,
  $date_edited,
  $id_user,
  $id_post;

public function __construct(array $data) {
    $this->hydrate($data);
  }
  
  public function hydrate(array $data) {
    foreach ($data as $key => $value) {
      $method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
    $array = [
      "id" => $this->getId(),
      "content" => $this->getContent(),
      "date_created" => $this->getDate_created(),
      "date_edited" => $this->getDate_edited(),
      "id_user" => $this->getId_user(),
      "id_post" => $this->getId_post()
    ];
    return $array;
  }



  public function getId() {
    return $this->id;
  }

  public function getContent() {
    return $this->content;
  }

  public function getDate_created() {
    return $this->date_created;
  }

  public function getDate_edited() {
    return $this->date_edited;
  }

  public function getId_user() {
    return $this->id_user;
  }

  public function getId_post() {
    return $this->id_post;
  }

  public function setId($id) {
    $id = (int) $id;
    if ($id > 0) {
     $this->id = $id;
    }
  }

  public function setContent($content) {
    if (is_string($content) && strlen($content) <= 5000) {
    $this->content = $content;
    }
  }

  public function setDate_created($date_created) {
    if (is_string($date_created)) {
     $this->date_created = $date_created;
    }
  }

  public function setDate_edited($date_edited) {
    if (is_string($date_edited)) {
     $this->date_edited = $date_edited;
    }
  }

  public function setId_user($id_user) {
    $id_user = (int) $id_user;
    if ($id_user > 0) {
     $this->id_user = $id_user;
    }
  }

  public function setId_post($id_post) {
    $id_post = (int) $id_post;
    if ($id_post > 0) {
     $this->id_post = $id_post;
    }
  }
}<file_sep>/front/src/app/modules/profile/edit-profile/edit-profile.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { Router } from '@angular/router';

import { ResponsiveService } from 'app/core/services/responsive.service';
import { UserService } from 'app/modules/visitor/user.service';
import { ImageUrl } from 'app/shared/validators/image-url';
import { AuthService } from 'app/core/services/auth.service';
import { fillUndefinedProperties } from 'app/shared/utility/change-objects';
import { MatDialog } from '@angular/material';
import { DialogComponent } from 'app/shared/components/dialog/dialog.component';

@Component({
  selector: 'app-edit-profile',
  templateUrl: './edit-profile.component.html',
  styleUrls: ['./edit-profile.component.scss']
})
export class EditProfileComponent implements OnInit {
  bMobile: boolean;
  userForm: FormGroup;
  bUserDeleted = false;

  constructor(responsiveService: ResponsiveService,
    private m_router: Router,
    private m_formBuilder: FormBuilder,
    private m_userService: UserService,
    private m_authService: AuthService,
    private m_dialog: MatDialog) {
      responsiveService.isMobile().subscribe(result => {
        if (result.matches) {
          this.bMobile = false;
        } else {
          this.bMobile = true;
        }
      });

      this.userForm = this.m_formBuilder.group({
        pseudo: ['', Validators.required],
        mail: ['', Validators.compose([
          Validators.required,
          Validators.pattern(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/)
        ])],
        year_promotion: ['', Validators.required],
        phone: '',
        firstname: ['', Validators.required],
        lastname: ['', Validators.required],
        photo_url: ['', Validators.required]
      }, {
        validators: ImageUrl('photo_url')
      });
    }

  ngOnInit() {
    this.m_userService.get(this.m_authService.getUserId()).subscribe(result => {
      result = fillUndefinedProperties(result);
      this.userForm.patchValue({
        pseudo: result.pseudo,
        mail: result.mail,
        year_promotion: result.year_promotion.toString(),
        phone: result.phone,
        firstname: result.firstname,
        lastname: result.lastname,
        photo_url: result.photo_url
      });
    }, error => {

    });
  }

  submitForm(): void {
    let form = this.userForm.value;
    form.id = this.m_authService.getUserId();
    this.m_userService.update(this.m_authService.getUserId(), form).subscribe(result => {
      this.m_router.navigate(['/profil']);
    }, error => {

    });
  }

  deleteUser(): void {
    const dialogRef = this.m_dialog.open(DialogComponent, {
      width: "500px",
      data: {title: `Suppression de votre compte`, text: `On est triste de vous voir partir ! En êtes-vous sûr de sûr ?`, bValBtn: true}
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result.validated) {
        this.m_userService.delete(this.m_authService.getUserId()).subscribe(result => {
          this.bUserDeleted = true;
          this.m_authService.logout();
          this.m_router.navigate(['/visiteur/login]']);
        }, error => {

        });
      }
    });
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }

}
<file_sep>/front/src/app/modules/visitor/login/login.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { FormGroup, FormBuilder, Validators } from '@angular/forms';

// custom
import { AuthService } from 'app/core/services/auth.service';
import { HttpErrorResponse } from '@angular/common/http';

@Component({
  selector: 'app-login',
  templateUrl: './login.component.html',
  styleUrls: ['./login.component.scss']
})
export class LoginComponent implements OnInit {
  loginForm: FormGroup;
  bInvalid = false;

  constructor(private m_formBuilder: FormBuilder,
    private m_authService: AuthService,
    private m_router: Router) 
  {
    this.loginForm = this.m_formBuilder.group({
      username: ['', Validators.required],
      password: ['', Validators.required]
    });
  }

  ngOnInit() {
    if (this.m_authService.isLoggedIn()) {
      this.m_router.navigate(['/tableau-de-bord']);
    }
  }

  login(username: string, password: string): void {
    this.m_authService.login(username, password)
      .subscribe(response => {
        this.m_router.navigate([this.m_authService.redirectUrl]);
      }, (error: HttpErrorResponse) => {
        // TODO display error with the form field
        
      });
  }

}
<file_sep>/back/api/models/Notification.php
<?php

namespace models;
use \controllers\scans\ScanDataIn;

class Notification {

	protected $id,
  $id_event,
  $date_edit,
  $type_edit;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

  //Gère la récupération de données des attributs lorsqu'elle proviennent de la bdd
	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
	  $array = [
				  "id_event" => $this->getId_event(),
				  "date_edit" => $this->getDate_edit(),
				  "type_edit" => $this->getType_edit()
			  ];
			  return $array;
  }

  // Getters
  public function getId() {
    return $this->id;
  }

  public function getId_event() {
    return $this->id_event;
  }

  public function getDate_edit() {
    return $this->date_edit;
  }

  public function getType_edit() {
    return $this->type_edit;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId($id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }

  public function setId_event($id) {
	  $id = (int) $id;
	  if ($id > 0) {
		  $this->id_event = $id;
	  }
  }

  public function setType_edit($type) {
    if (is_string($type) && strlen($type) <= 255) {
    $this->type_edit = $type;
    }
  }

  public function setDate_edit($date_edit) {
		$scanDataIn = new ScanDataIn();
		if (\is_null($date_edit) || $scanDataIn->validateDate($date_edit)) {
			$this->date_edit = $date_edit;
		}
		else {
			throw new \Exception("Date de modification invalide.", 400);
		}
  }
}
<file_sep>/front/src/app/modules/events/post.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';

import { environment } from 'environments/environment';

@Injectable({
  providedIn: 'root'
})
export class PostService {

  constructor(private m_http: HttpClient) { }

  // POSTS

  createPost(eventId: number, form: Object): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts`;
    return this.m_http.post<any>(URL, JSON.stringify(form));
  }

  updatePost(eventId: number, postId: number, form: Object): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts/${postId}`;
    return this.m_http.patch<any>(URL, JSON.stringify(form));
  }

  deletePost(eventId: number, postId: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts/${postId}`;
    return this.m_http.delete<any>(URL);
  }

  // COMMENTS

  createComment(eventId: number, postId: number, form: Object): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts/${postId}/comments`;
    return this.m_http.post<any>(URL, JSON.stringify(form));
  }

  updateComment(eventId: number, postId: number, commentId: number, form: Object): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts/${postId}/comments/${commentId}`;
    return this.m_http.patch<any>(URL, JSON.stringify(form));
  }

  deleteComment(eventId: number, postId: number, commentId: number): Observable<any> {
    const URL = `${environment.backend.serverUrl}events/${eventId}/posts/${postId}/comments/${commentId}`;
    return this.m_http.delete<any>(URL);
  }
}
<file_sep>/front/src/app/shared/models/notification.ts
import { Event } from './event';

export interface Notification {
    event?: Event[];
}
<file_sep>/back/bdd/structure/lolimac.sql
-- phpMyAdmin SQL Dump
-- version 4.8.4
-- https://www.phpmyadmin.net/
--
-- Hôte : 127.0.0.1:3306
-- Généré le :  Dim 19 mai 2019 à 11:27
-- Version du serveur :  10.3.9-MariaDB
-- Version de PHP :  7.0.33

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Base de données :  `lolimac`
--

-- --------------------------------------------------------

--
-- Structure de la table `comments`
--

DROP TABLE IF EXISTS `comments`;
CREATE TABLE IF NOT EXISTS `comments` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` text NOT NULL,
  `date_created` date NOT NULL,
  `date_edited` date NOT NULL,
  `id_post` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `events`
--

DROP TABLE IF EXISTS `events`;
CREATE TABLE IF NOT EXISTS `events` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `photo_url` text NOT NULL,
  `description` text DEFAULT NULL,
  `date_start` datetime DEFAULT NULL,
  `date_end` datetime DEFAULT NULL,
  `date_created` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `eventtypes`
--

DROP TABLE IF EXISTS `eventtypes`;
CREATE TABLE IF NOT EXISTS `eventtypes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `link_events_eventtypes`
--

DROP TABLE IF EXISTS `link_events_eventtypes`;
CREATE TABLE IF NOT EXISTS `link_events_eventtypes` (
  `id_event` int(11) NOT NULL,
  `id_type` int(11) NOT NULL,
  PRIMARY KEY (`id_event`,`id_type`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `link_events_places`
--

DROP TABLE IF EXISTS `link_events_places`;
CREATE TABLE IF NOT EXISTS `link_events_places` (
  `id_event` int(11) NOT NULL,
  `id_place` int(11) NOT NULL,
  PRIMARY KEY (`id_event`,`id_place`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `link_events_users_modules`
--

DROP TABLE IF EXISTS `link_events_users_modules`;
CREATE TABLE IF NOT EXISTS `link_events_users_modules` (
  `id_event` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  `id_module` int(11) NOT NULL,
  PRIMARY KEY (`id_event`,`id_user`,`id_module`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `modules`
--

DROP TABLE IF EXISTS `modules`;
CREATE TABLE IF NOT EXISTS `modules` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `notification_events`
--

DROP TABLE IF EXISTS `notification_events`;
CREATE TABLE IF NOT EXISTS `notification_events` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `id_event` int(11) NOT NULL,
  `date_edit` datetime NOT NULL,
  `type_edit` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `places`
--

DROP TABLE IF EXISTS `places`;
CREATE TABLE IF NOT EXISTS `places` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `postcode` int(11) DEFAULT NULL,
  `street` varchar(255) DEFAULT NULL,
  `number` int(11) DEFAULT NULL,
  `city` varchar(255) DEFAULT NULL,
  `name` varchar(255) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `posts`
--

DROP TABLE IF EXISTS `posts`;
CREATE TABLE IF NOT EXISTS `posts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `date_created` date NOT NULL,
  `date_edited` date NOT NULL,
  `id_event` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `promotions`
--

DROP TABLE IF EXISTS `promotions`;
CREATE TABLE IF NOT EXISTS `promotions` (
  `end_year` int(11) NOT NULL,
  `nickname` varchar(100) NOT NULL,
  PRIMARY KEY (`end_year`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Structure de la table `users`
--

DROP TABLE IF EXISTS `users`;
CREATE TABLE IF NOT EXISTS `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `firstname` varchar(22) NOT NULL,
  `lastname` varchar(22) NOT NULL,
  `pseudo` varchar(25) NOT NULL,
  `mail` varchar(100) NOT NULL,
  `phone` varchar(14) DEFAULT NULL,
  `pwd_hash` varchar(255) NOT NULL,
  `photo_url` varchar(255) NOT NULL,
  `status` int(1) NOT NULL,
  `year_promotion` int(11) NOT NULL,
  `date_notification_check` datetime NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (`id`),
  UNIQUE KEY `pseudo` (`pseudo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
<file_sep>/back/api/models/Link_events_eventtypesManager.php
<?php

namespace models;

class Link_events_eventtypesManager extends DBAccess {

  public function add(Link_events_eventtypes $link) {
      $q = $this->db->prepare("INSERT INTO link_events_eventtypes
          (`id_event`, `id_type`)
          VALUES (:id_event, :id_type);");

          $q->bindValue(':id_event', $link->getId_event());
          $q->bindValue(':id_type', $link->getId_type());

	  $q->execute();

    $link->hydrate(['id' => $this->db->lastInsertId()]);
    return $link;
  }

  public function count() {
    return $this->db->query("SELECT COUNT(*) FROM link_events_eventtypes;")->fetchColumn();
  }

  public function updateType(Link_events_eventtypes $link_events_eventtypes, int $new_id_type) {
    $q = $this->db->prepare("UPDATE link_events_eventtypes SET id_event = :id_event, id_type = :new_id_type WHERE id_event = :id_event AND id_type = :id_type");

    $q->bindValue(':id_event', $link_events_eventtypes->getId_event());
    $q->bindValue(':id_type', $link_events_eventtypes->getId_type());
    $q->bindValue(':new_id_type', $new_id_type);

    $q->execute();

    return $link_events_eventtypes;
  }

  public function readById_event($id_event) {
      $q = $this->db->prepare("SELECT * FROM link_events_eventtypes WHERE id_event = :id_event LIMIT 1;");
      $q->bindValue(':id_event', $id_event);
      $q->execute();
      $link = $q->fetch(\PDO::FETCH_ASSOC);
      if ($link) {
          return new Link_events_eventtypes($link);
      }
      else {
          return NULL;
      }
  }

  public function readById_type($id_type) {
      $q = $this->db->query("SELECT * FROM link_events_eventtypes WHERE id_type = :id_type");
	  $q->bindValue(':id_type', $id_type);
      $link = $q->fetch(\PDO::FETCH_ASSOC);
	  if ($link) {
		  return new Link_events_eventtypes($link);
	  }
	  else {
		  return NULL;
	  }
  }

  public function readById_event_type($id_event, $id_type) {
      $q = $this->db->prepare('SELECT * FROM link_events_eventtypes WHERE id_event = :id_event AND id_type = :id_type;');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_type', $id_type);
      $q->execute();

      $link = $q->fetch(\PDO::FETCH_ASSOC);

      return $link ? True : False;
  }


  public function readAll() {
    $allLink = [];

    $q = $this->db->query('SELECT * FROM link_events_eventtypes');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allLink[$data['id']] = new Link_events_eventtypes($data);
    }
    return $allLink;
  }

  public function deleteById($id_event, $id_type) {
     $q = $this->db->prepare('DELETE FROM link_events_eventtypes WHERE id_event = :id_event AND id_type = :id_type;');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_type', $id_type);
      $q->execute();
      return TRUE;
  }

  public function deleteByIdEvent($id_event) {
       $q = $this->db->prepare('DELETE FROM link_events_eventtypes WHERE id_event = :id_event;');
        $q->bindValue(':id_event', $id_event);
        $q->execute();
        return TRUE;
    }
}
<file_sep>/front/src/app/shared/models/post.ts
import { Comment } from './comment';
import { User } from './user';

export interface Post {
    id?: number;
    title?: string;
    content?: string;
    date_created?: Date;
    date_edited?: Date;
    id_user?: number;
    id_event?: number;
    comments?: Comment[];
    user?: User;
}<file_sep>/back/api/Autoloader.php
<?php 
// Ce fichier gère la récupération des fichiers de class en fonction des besoins de la requète et en prenant en compte les namespaces (devant correspondre à l'architecture de fichier).

class Autoloader {
	
	function __construct()
	{
		$this->autoload();
	}

	public function autoload() {
		spl_autoload_register(function ($class_name) {
        		include_once  str_replace("\\", "/", $class_name) . '.php';
    	});
	}

}<file_sep>/front/src/app/shared/models/place.ts
export interface Place {
    id_place?: number;
    street?: string;
    number?: number;
    city?: number;
    name?: string;
}<file_sep>/front/src/app/shared/models/event.ts
import { Place } from './place';
import { Post } from './post';
import { User } from './user';

export interface Event {
    id_event?: number;
    title?: string;
    description?: string;
    date_start?: Date;
    date_end?: Date;
    date_created?: Date;
    photo_url?: string;
    participation: number;
    place?: Place;
    posts?: Post[];
    participants?: User[];
    type_edit?: string;
}<file_sep>/front/src/app/core/interceptors/error.interceptor.ts
import { Injectable } from '@angular/core';
import { HttpRequest, HttpHandler, HttpEvent, HttpInterceptor } from '@angular/common/http';
import { Router } from '@angular/router';

// 3rd party
import { Observable, throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';

// custom
import { AuthService } from '../services/auth.service';
import { SnackBarService } from '../services/snack-bar.service';

@Injectable({
    providedIn: 'root',
})
export class ErrorInterceptor implements HttpInterceptor {
    constructor(private m_authService: AuthService, private m_router: Router, private m_snackbar: SnackBarService) { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        return next.handle(request).pipe(catchError(err => {
          console.error(err);
          switch(err.status) {
              case 0:
                this.m_snackbar.open('[Erreur] Le serveur est déconnecté !', 'Oh, zut alors', 10000);
                break;

              case 400:
                if (err.error.message) {
                  this.m_snackbar.open('[Erreur] ' + err.error.message, 'Oh, zut alors', 10000);
                } else {
                  this.m_snackbar.open('[Erreur] La requête envoyée au serveur est invalide !', 'Oh, zut alors', 10000);
                }
                break;

              case 401:
                  // logout if token expired
                  //this.m_authService.redirectUrl = location.origin; // FIXME wrong route ?
                  if (this.m_authService.isLoggedIn()) {
                    this.m_snackbar.open('Votre connexion a expirée', 'Très bien', 10000);
                    this.m_authService.logout();
                    this.m_router.navigate(['/visiteur/login']);
                  } else {
                    this.m_snackbar.open('Mot de passe ou pseudo incorrect !', 'Je retente', 10000);
                  }
                  break;

              case 500:
                this.m_snackbar.open('[Erreur] Problème interne coté serveur !', 'Oh, zut alors', 10000);
                break;

              case 504:
                this.m_snackbar.open('[Erreur] Le serveur a mit trop de temps à répondre, veuillez réessayer plus tard !', 'Oh, zut alors', 10000);
                break;
            
              default:
                if (err.message.search("Http failure during parsing") == 0) {
                  this.m_snackbar.open('[Erreur] La réponse formulée par le serveur est incorrecte !', 'Oh, zut alors', 10000);
                }
                break;
            }
          return throwError(err);
        }));
    }
}
<file_sep>/back/api/models/NotificationManager.php
<?php

namespace models;

class NotificationManager extends DBAccess {

  public function readAll($id_user) {
	 $q = $this->db->prepare("SELECT MAX(notification_events.id) AS id, notification_events.id_event, MAX(notification_events.date_edit) AS date_edit, notification_events.type_edit FROM notification_events INNER JOIN link_events_users_modules ON link_events_users_modules.id_event = notification_events.id_event INNER JOIN users ON users.id = link_events_users_modules.id_user WHERE link_events_users_modules.id_user = :id_user AND notification_events.date_edit >= users.date_notification_check GROUP BY notification_events.id_event, notification_events.type_edit ;");
	 $q->bindValue(':id_user', $id_user);

	 $q->execute();
	 while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
		 $allNotifications[$data['id']] = new Notification($data);
	 }
	if(isset($allNotifications)) {
	 		 return $allNotifications;
	} else {
		return NULL;
	}
 }
 public function add(Notification $notification){
	 $q = $this->db->prepare('INSERT INTO notification_events (id_event, type_edit, date_edit) VALUES (:id_event, :type_edit, NOW());');

	 $q->bindValue(':id_event', $notification->getId_event());
	 $q->bindValue(':type_edit', $notification->getType_edit());

	 $q->execute();
 }

 public function countNotifications($id_user) {
	$q = $this->db->prepare("SELECT COUNT(DISTINCT notification_events.type_edit ) AS Count FROM notification_events INNER JOIN link_events_users_modules ON link_events_users_modules.id_event = notification_events.id_event  INNER JOIN users ON users.id = link_events_users_modules.id_user  WHERE link_events_users_modules.id_user = :id_user  AND notification_events.date_edit >= users.date_notification_check;");

	$q->bindValue(':id_user', $id_user);
	$q->execute();

 	return $q->fetch(\PDO::FETCH_ASSOC)['Count'];
}
}
<file_sep>/front/src/app/modules/notifications/notifications.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
 
import { Observable } from 'rxjs';

import { environment } from 'environments/environment';

@Injectable({
  providedIn: 'root'
})
export class NotificationsService {

  constructor(private m_http: HttpClient) {}

  getAll(): Observable<any> {
    const URL = `${environment.backend.serverUrl}me/notifications`;
    return this.m_http.get<any>(URL);
  }

  getCount(): Observable<any> {
    const URL = `${environment.backend.serverUrl}me/notifications/count`;
    return this.m_http.get<any>(URL);
  }
}
<file_sep>/front/src/environments/environment.prod.ts
export const environment = {
  production: true,

  backend: {
    serverUrl: 'https://www.lolimac.fr/api/'
  }
};
<file_sep>/front/src/app/app.component.ts
import { Component } from '@angular/core';
import { SwUpdate, SwPush } from '@angular/service-worker';
import { Router, RouterEvent, NavigationEnd } from '@angular/router';

import { AuthService } from './core/services/auth.service';
import { ResponsiveService } from './core/services/responsive.service';
import { NotificationsService } from './modules/notifications/notifications.service';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent {
    bMobile = true;
    bVisitor = true;
    notificationCount = 0;

    constructor(updates: SwUpdate, push: SwPush,
        authService: AuthService,
        responsiveService: ResponsiveService,
        router: Router,
        notificationsService: NotificationsService) 
    {
        push.messages.subscribe(message => {
            console.info("New push message recieved !");
            console.log(message);
        });

        responsiveService.isMobile().subscribe(result => {
            if (result.matches) {
                this.bMobile = false;
            } else {
                this.bMobile = true;
            }
        });

        router.events.subscribe((event: RouterEvent) => {
            if (event instanceof NavigationEnd) {
                if (event.url.search("visiteur") != -1 || event.url.search("404") != -1) {
                    this.bVisitor = true;
                } else {
                    this.bVisitor = false;
                    notificationsService.getCount().subscribe(result => {
                        this.notificationCount = Number(result.notifications);
                    });
                }

                if (event.url.search("notifications") != -1) {
                    this.notificationCount = 0;
                }
            }
        });
    }
}
<file_sep>/back/api/controllers/EventCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \models\Event;
use \models\EventManager;
use \models\Link_events_places;
use \models\Link_events_eventtypes;
use \models\Place;
use \controllers\EventTypeCRUD;
use \controllers\NotificationCRUD;
use \controllers\Link_events_placesCRUD;
use \controllers\Link_events_eventtypesCRUD;
use \controllers\Link_events_users_modulesCRUD;
use \models\Link_events_users_modules;
use \models\Link_events_users_modulesManager;
use \models\User;
use \models\UserManager;

class EventCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["title", "photo_url"]);
    $data = $scanDataIn->failleXSS($dataIn);
    unset($data['date_created']);
    $event = new Event($data);
    $eventManager = new EventManager();
    $event = $eventManager->add($event);
    $token = new TokenAccess();

    $link = new Link_events_users_modules([
        'id_event'=>$event->getId(),
        'id_module'=>1,
        'id_user'=>$token->getId()
    ]);
    $linkManager = new Link_events_users_modulesManager();
    $linkManager->add($link);

    if (isset($data["place"])) {
        $placeCRUD = new PlaceCRUD();
        if(\is_array($data["place"])) {
            $place = $placeCRUD->add($data["place"]);
        }
        else {
            $place = $placeCRUD->read_OBJ(['id' => $data['place']]);
        }
        $link_events_placesCRUD = new Link_events_placesCRUD();
        $link_events_placesCRUD->add(["id_event"=>$event->getId(), "id_place" => $place->getId()]);
    }

    if (isset($data['type'])) {
        $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
        $eventTypeCRUD = new EventTypeCRUD();
        if (is_numeric($data['type'])) {
            $eventType = $eventTypeCRUD->read_OBJ(['id' => $data['type']]);
            $link_events_eventtypesCRUD->add(["id_event"=>$event->getId(), "id_type" => $eventType->getId()]);
        }
        else {
            $eventType = $eventTypeCRUD->add($data['type']);
            $link_events_eventtypesCRUD->add(["id_event"=>$event->getId(), "id_type" => $eventType->getId()]);
        }
    }

    echo \json_encode([
        'message' => 'New event added.',
        'id_user' => $token->getId(),
        'id_event' => $event->getId()
    ]);
    return TRUE;
  }

  public function update($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    unset($data['date_created']); // NOTE: prevents user from modifying creation date
    $eventManager = new EventManager();
    $event = $eventManager->readById($data["id"]);
    $event->hydrate($data);
    $eventManager->update($event);

    $NotificationCRUD = new NotificationCRUD();
    $NotificationCRUD->add($data);
    if (isset($data["place"])) {
        $placeCRUD = new PlaceCRUD();
        if(\is_array($data["place"])) { // NOTE: On ajoute un nouvel endroit
            $place = $placeCRUD->add($data["place"]);
        }
        else { // On lie à un autre endroit déjà existant
            $place = $placeCRUD->read_OBJ(['id' => $data['place']]);
        }
        $link_events_placesCRUD = new Link_events_placesCRUD();
        $link_events_places = $link_events_placesCRUD->deleteByIdEvent(['id_event'=>$event->getId()]);
        $link_events_placesCRUD->add(["id_event"=>$event->getId(), "id_place" => $place->getId()]);

    }
    if (isset($data['type'])) {
        $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
        $eventTypeCRUD = new EventTypeCRUD();
        if (is_numeric($data['type'])) {
            $eventType = $eventTypeCRUD->read_OBJ(['id' => $data['type']]);
            $link_events_eventtypesCRUD->addIfNotExist(["id_event"=>$event->getId(), "id_type" => $eventType->getId()]);
        }
        else {
            $eventType = $eventTypeCRUD->add($data['type']);
            $link_events_eventtypesCRUD->addIfNotExist(["id_event"=>$event->getId(), "id_type" => $eventType->getId()]);
        }
    }
       echo \json_encode([
        'message' => 'Event updated.',
    ]);
}

  public function readMultiple($dataIn) {
      $scanDataIn = new ScanDataIn();
      $data = $scanDataIn->failleXSS($dataIn);
      $eventManager = new EventManager();
      if (isset($data["limit"])) {
          if (empty($data["from"])) {
              $data["from"] = "0";
          }
          $events = $eventManager->readOffsetLimit($data["from"], $data["limit"]);
      }
      else {
          $events = $eventManager->readAll();
      }
      if($events) {
          $participantManager = new Link_events_users_modulesCRUD();
          $link_events_placesCRUD = new Link_events_placesCRUD();
          $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
          foreach ($events as $key => $event) {
              $events[$key] = $event->toArray();
              $participation = $participantManager->readParticipation($event->getId());
              $events[$key]['participation'] = $participation;
              $place = $link_events_placesCRUD->readPlace_ARRAY(['id_event' => $events[$key]["id_event"]]);
              $events[$key]['place'] = $place;
              $type = $link_events_eventtypesCRUD->readType_ARRAY(['id_event' => $events[$key]["id_event"]]);
              $events[$key]['type'] = $type;
          }
          echo json_encode(array_values($events));
      } else {
          echo \json_encode([]);
      }
  }

  public function search($dataIn) {
      $scanDataIn = new ScanDataIn();
      $data = $scanDataIn->failleXSS($dataIn);
      $scanDataIn->exists($dataIn, ["query"]);
      $full = [];
      $parts = [];
      $eventManager = new EventManager();
      $keywords = $scanDataIn->explodeSearchQuery($data['query']);
      $keywords = array_merge($keywords['full'], $keywords['words']);
      if (!empty($keywords)) {
          $events = $eventManager->search($keywords);
      }
      else $events = [];
      if($events) {
          $participantManager = new Link_events_users_modulesCRUD();
          $link_events_placesCRUD = new Link_events_placesCRUD();
          $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
          foreach ($events as $key => $event) {
              $events[$key] = $event->toArray();
              $participation = $participantManager->readParticipation($event->getId());
              $events[$key]['participation'] = $participation;
              $place = $link_events_placesCRUD->readPlace_ARRAY(['id_event' => $events[$key]["id_event"]]);
              $events[$key]['place'] = $place;
              $type = $link_events_eventtypesCRUD->readType_ARRAY(['id_event' => $events[$key]["id_event"]]);
              $events[$key]['type'] = $type;
          }
          echo json_encode(array_values($events));
      } else {
          echo \json_encode([]);
      }

  }

  public function generateSingleEventICS($id_event) {
      $token = new TokenAccess();
      $scanDataIn = new ScanDataIn();
      $data = $scanDataIn->failleXSS(['id_event'=>$id_event]);
      $eventManager = new EventManager();
      $event = $eventManager->readById($data['id_event']);
      if ($event) {
          if ($event->getDate_start() && $event->getDate_end()) {
              $encryptionMethod = "AES-256-CBC";
              $secretHash = "<KEY>";
              $iv = "6546445734219402";
              $token = "{$token->getId()}/{$data['id_event']}";
              $encrypted = openssl_encrypt($token, $encryptionMethod, $secretHash, $options=0, $iv);
              $url = "https://www.lolimac.fr/";
              echo \json_encode([
                 'url'=> "{$url}api/ics/{$encrypted}"
             ], $options = JSON_UNESCAPED_SLASHES);
          }
          else {
              throw new \Exception("Impossible de générer le lien iCalendar, l'événement n'est pas totalement prêt", 400);
          }
      }
      else {
          throw new \Exception("Evenement non existant", 400);
      }
  }

  public function generateAllEventICS() {
      $token = new TokenAccess();
      $scanDataIn = new ScanDataIn();
      $eventManager = new EventManager();
      $encryptionMethod = "AES-256-CBC";
      $secretHash = "2<PASSWORD>";
      $userManager = new UserManager();
      $user = $userManager->readById($token->getId());
      $iv = "6546445734219402";
      $token = "{$user->getPseudo()}";
      $encrypted = openssl_encrypt($token, $encryptionMethod, $secretHash, $options=0, $iv);
      $url = "https://www.lolimac.fr/";
      echo \json_encode([
          'url'=>"{$url}lolimac-back/api/ics/all/{$encrypted}"
      ], $options = JSON_UNESCAPED_SLASHES);
  }

  public function read($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $eventManager = new EventManager();
    $event = $eventManager->readById($data["id"]);
    $event = $event->toArray();
    $participantManager = new Link_events_users_modulesCRUD();
    $participation = $participantManager->readParticipation($event["id_event"]);
    $event['participation'] = $participation;
    $listParticipants = $participantManager->readParticipants($event["id_event"]);
    $event['participants'] = $listParticipants;
    $link_events_placesCRUD = new Link_events_placesCRUD();
    $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
    $place = $link_events_placesCRUD->readPlace_ARRAY(['id_event' => $event["id_event"]]);
    $event['place'] = $place;
    $type = $link_events_eventtypesCRUD->readType_ARRAY(['id_event' => $event["id_event"]]);
    $event['type'] = $type;
    $postCRUD = new PostCRUD();
    $posts = $postCRUD->read($data["id"]);
    $event['posts'] = $posts;
    echo json_encode($event);
  }

  public function readOBJ($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $eventManager = new EventManager();
    $event = $eventManager->readById($data["id"]);
    return $event;
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $eventManager = new EventManager();
    $event = $eventManager->readById($data["id"]);
    $link_events_placesCRUD = new Link_events_placesCRUD();
    $link_events_eventtypesCRUD = new Link_events_eventtypesCRUD();
    $link_events_placesCRUD->deleteByIdEvent(['id_event'=>$event->getId()]);
    $link_events_placesCRUD->deleteByIdEvent(['id_event'=>$event->getId()]);
    $eventManager->deleteById($event->getId());
    echo json_encode(["message" => "Event deleted"]);
  }
}
<file_sep>/back/api/index.php
<?php

	require_once('Root.php');
	require_once("Autoloader.php");
	new Autoloader();


try {
	$index = new Root();
}

catch(Exception $e) {
	http_response_code($e->getCode());
	echo json_encode([
				"code" => $e->getCode(),
				"message" => $e->getMessage()
				] );
}
<file_sep>/front/documentation/components/InscriptionComponent.html
<!doctype html>
<html class="no-js" lang="">
    <head>
        <meta charset="utf-8">
        <meta http-equiv="x-ua-compatible" content="ie=edge">
        <title>imac-resoi-front documentation</title>
        <meta name="description" content="">
        <meta name="viewport" content="width=device-width, initial-scale=1">

        <link rel="icon" type="image/x-icon" href="../images/favicon.ico">
	      <link rel="stylesheet" href="../styles/style.css">
    </head>
    <body>

        <div class="navbar navbar-default navbar-fixed-top visible-xs">
            <a href="../" class="navbar-brand">imac-resoi-front documentation</a>
            <button type="button" class="btn btn-default btn-menu ion-ios-menu" id="btn-menu"></button>
        </div>

        <div class="xs-menu menu" id="mobile-menu">
                <div id="book-search-input" role="search"><input type="text" placeholder="Type to search"></div>            <compodoc-menu></compodoc-menu>
        </div>

        <div class="container-fluid main">
           <div class="row main">
               <div class="hidden-xs menu">
                   <compodoc-menu mode="normal"></compodoc-menu>
               </div>
               <!-- START CONTENT -->
               <div class="content component">
                   <div class="content-data">




<ol class="breadcrumb">
  <li>Components</li>
  <li>InscriptionComponent</li>
</ol>

<ul class="nav nav-tabs" role="tablist">
        <li class="active">
            <a href="#info" role="tab" id="info-tab" data-toggle="tab" data-link="info">Info</a>
        </li>
        <li >
            <a href="#source" role="tab" id="source-tab" data-toggle="tab" data-link="source">Source</a>
        </li>
        <li >
            <a href="#templateData" role="tab" id="templateData-tab" data-toggle="tab" data-link="template">Template</a>
        </li>
        <li >
            <a href="#styleData" role="tab" id="styleData-tab" data-toggle="tab" data-link="style">Styles</a>
        </li>
        <li >
            <a href="#tree" role="tab" id="tree-tab" data-toggle="tab" data-link="dom-tree">DOM Tree</a>
        </li>
</ul>

<div class="tab-content">
    <div class="tab-pane fade active in" id="c-info"><p class="comment">
    <h3>File</h3>
</p>
<p class="comment">
    <code>src/app/modules/visitor/inscription/inscription.component.ts</code>
</p>



    <p class="comment">
        <h3>Implements</h3>
    </p>
    <p class="comment">
                    <code><a href="https://angular.io/api/core/OnInit" target="_blank" >OnInit</a></code>
    </p>


<section>
    <h3>Metadata</h3>
    <table class="table table-sm table-hover">
        <tbody>











            <tr>
                <td class="col-md-3">selector</td>
                <td class="col-md-9"><code>app-inscription</code></td>
            </tr>

            <tr>
                <td class="col-md-3">styleUrls</td>
                <td class="col-md-9"><code>./inscription.component.scss</code></td>
            </tr>



            <tr>
                <td class="col-md-3">templateUrl</td>
                <td class="col-md-9"><code>./inscription.component.html</code></td>
            </tr>








        </tbody>
    </table>
</section>

    <section>
    <h3 id="index">Index</h3>
    <table class="table table-sm table-bordered index-table">
        <tbody>
                <tr>
                    <td class="col-md-4">
                        <h6><b>Properties</b></h6>
                    </td>
                </tr>
                <tr>
                    <td class="col-md-4">
                        <ul class="index-list">
                            <li>
                                <a href="#bInscriptionDone">bInscriptionDone</a>
                            </li>
                            <li>
                                <a href="#bMobile">bMobile</a>
                            </li>
                            <li>
                                <a href="#inscriptionForm">inscriptionForm</a>
                            </li>
                        </ul>
                    </td>
                </tr>

                <tr>
                    <td class="col-md-4">
                        <h6><b>Methods</b></h6>
                    </td>
                </tr>
                <tr>
                    <td class="col-md-4">
                        <ul class="index-list">
                            <li>
                                <a href="#goTo">goTo</a>
                            </li>
                            <li>
                                <a href="#ngOnInit">ngOnInit</a>
                            </li>
                            <li>
                                <a href="#submitForm">submitForm</a>
                            </li>
                        </ul>
                    </td>
                </tr>





        </tbody>
    </table>
</section>

    <section>
    <h3 id="constructor">Constructor</h3>
        <table class="table table-sm table-bordered">
            <tbody>
                <tr>
                    <td class="col-md-4">
<code>constructor(m_formBuilder: <a href="https://angular.io/api/forms/FormBuilder" target="_blank">FormBuilder</a>, m_userService: <a href="../injectables/UserService.html">UserService</a>, m_router: <a href="https://angular.io/api/router/Router" target="_blank">Router</a>, responsiveService: <a href="../injectables/ResponsiveService.html">ResponsiveService</a>)</code>
                    </td>
                </tr>
                        <tr>
                            <td class="col-md-4">
                                <div class="io-line">Defined in <a href="" data-line="19" class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:19</a></div>
                            </td>
                        </tr>

                <tr>
                    <td class="col-md-4">
                            <div>
                                    <b>Parameters :</b>
                                    <table class="params">
                                        <thead>
                                            <tr>
                                                <td>Name</td>
                                                    <td>Type</td>
                                                <td>Optional</td>
                                            </tr>
                                        </thead>
                                        <tbody>
                                                <tr>
                                                        <td>m_formBuilder</td>
                                                  
                                                        <td>
                                                                        <code><a href="https://angular.io/api/forms/FormBuilder" target="_blank" >FormBuilder</a></code>
                                                        </td>
                                                  
                                                    <td>
                                                            No
                                                    </td>
                                                    
                                                </tr>
                                                <tr>
                                                        <td>m_userService</td>
                                                  
                                                        <td>
                                                                        <code><a href="../injectables/UserService.html" target="_self" >UserService</a></code>
                                                        </td>
                                                  
                                                    <td>
                                                            No
                                                    </td>
                                                    
                                                </tr>
                                                <tr>
                                                        <td>m_router</td>
                                                  
                                                        <td>
                                                                        <code><a href="https://angular.io/api/router/Router" target="_blank" >Router</a></code>
                                                        </td>
                                                  
                                                    <td>
                                                            No
                                                    </td>
                                                    
                                                </tr>
                                                <tr>
                                                        <td>responsiveService</td>
                                                  
                                                        <td>
                                                                        <code><a href="../injectables/ResponsiveService.html" target="_self" >ResponsiveService</a></code>
                                                        </td>
                                                  
                                                    <td>
                                                            No
                                                    </td>
                                                    
                                                </tr>
                                        </tbody>
                                    </table>
                            </div>
                    </td>
                </tr>
            </tbody>
        </table>
</section>





    <section>
    
    <h3 id="methods">
        Methods
    </h3>
    <table class="table table-sm table-bordered">
        <tbody>
            <tr>
                <td class="col-md-4">
                    <a name="goTo"></a>
                    <span class="name">
                        <b>
                            goTo
                        </b>
                        <a href="#goTo"><span class="icon ion-ios-link"></span></a>
                    </span>
                </td>
            </tr>
            <tr>
                <td class="col-md-4">
<code>goTo(url: <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string" target="_blank">string</a>)</code>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">
                    <div class="io-line">Defined in <a href="" data-line="84"
                            class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:84</a></div>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">

                    <div class="io-description">
                        <b>Parameters :</b>
                        <table class="params">
                            <thead>
                                <tr>
                                    <td>Name</td>
                                    <td>Type</td>
                                    <td>Optional</td>
                                </tr>
                            </thead>
                            <tbody>
                                <tr>
                                    <td>url</td>
                                    <td>
                                                <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/string" target="_blank" >string</a></code>
                                    </td>

                                    <td>
                                        No
                                    </td>


                                </tr>
                            </tbody>
                        </table>
                    </div>
                    <div>
                    </div>
                    <div class="io-description">
                        <b>Returns : </b>        <code><a href="https://www.typescriptlang.org/docs/handbook/basic-types.html" target="_blank" >void</a></code>

                    </div>
                    <div class="io-description">
                        
                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    <table class="table table-sm table-bordered">
        <tbody>
            <tr>
                <td class="col-md-4">
                    <a name="ngOnInit"></a>
                    <span class="name">
                        <b>
                            ngOnInit
                        </b>
                        <a href="#ngOnInit"><span class="icon ion-ios-link"></span></a>
                    </span>
                </td>
            </tr>
            <tr>
                <td class="col-md-4">
<code>ngOnInit()</code>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">
                    <div class="io-line">Defined in <a href="" data-line="65"
                            class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:65</a></div>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">

                    <div class="io-description">
                        <b>Returns : </b>        <code><a href="https://www.typescriptlang.org/docs/handbook/basic-types.html" target="_blank" >void</a></code>

                    </div>
                </td>
            </tr>
        </tbody>
    </table>
    <table class="table table-sm table-bordered">
        <tbody>
            <tr>
                <td class="col-md-4">
                    <a name="submitForm"></a>
                    <span class="name">
                        <b>
                            submitForm
                        </b>
                        <a href="#submitForm"><span class="icon ion-ios-link"></span></a>
                    </span>
                </td>
            </tr>
            <tr>
                <td class="col-md-4">
<code>submitForm()</code>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">
                    <div class="io-line">Defined in <a href="" data-line="67"
                            class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:67</a></div>
                </td>
            </tr>


            <tr>
                <td class="col-md-4">

                    <div class="io-description">
                        <b>Returns : </b>        <code><a href="https://www.typescriptlang.org/docs/handbook/basic-types.html" target="_blank" >void</a></code>

                    </div>
                </td>
            </tr>
        </tbody>
    </table>
</section>
    <section>
    
        <h3 id="inputs">
            Properties
        </h3>
        <table class="table table-sm table-bordered">
            <tbody>
                <tr>
                    <td class="col-md-4">
                        <a name="bInscriptionDone"></a>
                        <span class="name">
                            <b>
                            bInscriptionDone</b>
                            <a href="#bInscriptionDone"><span class="icon ion-ios-link"></span></a>
                        </span>
                    </td>
                </tr>
                    <tr>
                        <td class="col-md-4">
                            <i>Default value : </i><code>false</code>
                        </td>
                    </tr>
                        <tr>
                            <td class="col-md-4">
                                    <div class="io-line">Defined in <a href="" data-line="18" class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:18</a></div>
                            </td>
                        </tr>


            </tbody>
        </table>
        <table class="table table-sm table-bordered">
            <tbody>
                <tr>
                    <td class="col-md-4">
                        <a name="bMobile"></a>
                        <span class="name">
                            <b>
                            bMobile</b>
                            <a href="#bMobile"><span class="icon ion-ios-link"></span></a>
                        </span>
                    </td>
                </tr>
                    <tr>
                        <td class="col-md-4">
                            <i>Default value : </i><code>true</code>
                        </td>
                    </tr>
                        <tr>
                            <td class="col-md-4">
                                    <div class="io-line">Defined in <a href="" data-line="19" class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:19</a></div>
                            </td>
                        </tr>


            </tbody>
        </table>
        <table class="table table-sm table-bordered">
            <tbody>
                <tr>
                    <td class="col-md-4">
                        <a name="inscriptionForm"></a>
                        <span class="name">
                            <b>
                            inscriptionForm</b>
                            <a href="#inscriptionForm"><span class="icon ion-ios-link"></span></a>
                        </span>
                    </td>
                </tr>
                    <tr>
                        <td class="col-md-4">
                            <i>Type : </i>        <code><a href="https://angular.io/api/forms/FormGroup" target="_blank" >FormGroup</a></code>

                        </td>
                    </tr>
                        <tr>
                            <td class="col-md-4">
                                    <div class="io-line">Defined in <a href="" data-line="17" class="link-to-prism">src/app/modules/visitor/inscription/inscription.component.ts:17</a></div>
                            </td>
                        </tr>


            </tbody>
        </table>
</section>

</div>


    <div class="tab-pane fade  tab-source-code" id="c-source">
        <pre class="line-numbers compodoc-sourcecode"><code class="language-typescript">import { Component, OnInit } from &#x27;@angular/core&#x27;;
import { FormGroup, FormBuilder, Validators } from &#x27;@angular/forms&#x27;;
import { Router } from &#x27;@angular/router&#x27;;

import { PasswordMatch } from &#x27;app/shared/validators/password-match&#x27;;
import { UserService } from &#x27;../user.service&#x27;;
import { HttpErrorResponse } from &#x27;@angular/common/http&#x27;;
import { ImageUrl } from &#x27;app/shared/validators/image-url&#x27;;
import { ResponsiveService } from &#x27;app/core/services/responsive.service&#x27;;

@Component({
  selector: &#x27;app-inscription&#x27;,
  templateUrl: &#x27;./inscription.component.html&#x27;,
  styleUrls: [&#x27;./inscription.component.scss&#x27;]
})
export class InscriptionComponent implements OnInit {
  inscriptionForm: FormGroup;
  bInscriptionDone &#x3D; false;
  bMobile &#x3D; true;

  constructor(private m_formBuilder: FormBuilder,
    private m_userService: UserService,
    private m_router: Router,
    responsiveService: ResponsiveService) {
    responsiveService.isMobile().subscribe(result &#x3D;&gt; {
      if (result.matches) {
          this.bMobile &#x3D; false;
      } else {
          this.bMobile &#x3D; true;
      }
    });

    this.inscriptionForm &#x3D; this.m_formBuilder.group({
      page1: this.m_formBuilder.group({
        pseudo: [&#x27;&#x27;, Validators.required],
        mail: [&#x27;&#x27;, Validators.compose([
          Validators.required,
          Validators.pattern(/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/)
        ])],
        year_promotion: [&#x27;&#x27;, Validators.required]
      }),
      page2: this.m_formBuilder.group({
        phone: &#x27;&#x27;,
        firstname: [&#x27;&#x27;, Validators.required],
        lastname: [&#x27;&#x27;, Validators.required],
        photo_url: [&#x27;https://i2.wp.com/rouelibrenmaine.fr/wp-content/uploads/2018/10/empty-avatar.png&#x27;, Validators.required]
      }, {
        validators: ImageUrl(&#x27;photo_url&#x27;)
      }),
      page3: this.m_formBuilder.group({
        pwd: [&#x27;&#x27;, Validators.compose([
          Validators.required,
          Validators.minLength(4)
        ])],
        confirm_pwd: [&#x27;&#x27;, Validators.compose([
          Validators.required,
          Validators.minLength(4)
        ])]
      }, {
        validators: PasswordMatch(&#x27;pwd&#x27;,&#x27;confirm_pwd&#x27;)
      })
    });
  }

  ngOnInit() {}

  submitForm(): void {
    // Prepare form
    const form &#x3D; Object.assign({}, this.inscriptionForm.value.page1, this.inscriptionForm.value.page2, this.inscriptionForm.value.page3);
    delete form.confirm_pwd;

    // Send form
    this.m_userService.create(form).subscribe(response &#x3D;&gt; {
      this.bInscriptionDone &#x3D; true;

      setTimeout(() &#x3D;&gt; {
        this.m_router.navigate([&#x27;/visiteur/login]&#x27;]);
      }, 2500);
    }, (error: HttpErrorResponse) &#x3D;&gt; {
      // TODO handles error
    });
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }
}
</code></pre>
    </div>

    <div class="tab-pane fade " id="c-templateData">
        <pre class="line-numbers"><code class="language-html">&lt;app-top-app-bar *ngIf&#x3D;&quot;bMobile&quot; [title]&#x3D;&quot;&#x27;Inscription&#x27;&quot; [bReturn]&#x3D;&quot;true&quot; (return)&#x3D;&quot;goTo(&#x27;/visiteur/login&#x27;)&quot;&gt;
&lt;/app-top-app-bar&gt;

&lt;div id&#x3D;&quot;inscription-page&quot; class&#x3D;&quot;full-page&quot;&gt;
  &lt;h2 *ngIf&#x3D;&quot;!bMobile&quot;&gt;Inscription sur Lolimac&lt;/h2&gt;

  &lt;mat-horizontal-stepper  [linear]&#x3D;&quot;true&quot; *ngIf&#x3D;&quot;!bInscriptionDone; else success&quot;&gt;
    &lt;mat-step label&#x3D;&quot;Identifiants&quot; [stepControl]&#x3D;&quot;inscriptionForm.get(&#x27;page1&#x27;)&quot;&gt;
      &lt;form [formGroup]&#x3D;&quot;inscriptionForm.get(&#x27;page1&#x27;)&quot;&gt;
        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Pseudo&lt;/mat-label&gt;
          &lt;input matInput placeholder&#x3D;&quot;CrousMan&quot; formControlName&#x3D;&quot;pseudo&quot; required&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Email&lt;/mat-label&gt;
          &lt;input matInput placeholder&#x3D;&quot;<EMAIL>&quot; type&#x3D;&quot;email&quot; formControlName&#x3D;&quot;mail&quot; required&gt;
          &lt;mat-error&gt;Email invalide !&lt;/mat-error&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Promotion&lt;/mat-label&gt;
          &lt;mat-select placeholder&#x3D;&quot;Promotion&quot; formControlName&#x3D;&quot;year_promotion&quot; required&gt;
            &lt;mat-option value&#x3D;&quot;2021&quot;&gt;2021&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;2020&quot;&gt;2020&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;2019&quot;&gt;2019&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;2018&quot;&gt;2018&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;2017&quot;&gt;2017&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;2016&quot;&gt;2016&lt;/mat-option&gt;
            &lt;mat-option value&#x3D;&quot;autre&quot;&gt;Autre&lt;/mat-option&gt;
          &lt;/mat-select&gt;
          &lt;mat-error&gt;Veuillez indiquer votre promotion&lt;/mat-error&gt;
        &lt;/mat-form-field&gt;

        &lt;button mat-button matStepperNext [disabled]&#x3D;&quot;!inscriptionForm.get(&#x27;page1&#x27;).valid&quot;&gt;Suite&lt;/button&gt;
      &lt;/form&gt;
    &lt;/mat-step&gt;

    &lt;mat-step label&#x3D;&quot;Identité&quot;&gt;
      &lt;form [formGroup]&#x3D;&quot;inscriptionForm.get(&#x27;page2&#x27;)&quot;&gt;
        &lt;div class&#x3D;&quot;avatar&quot;&gt;
          &lt;img src&#x3D;&quot;{{ inscriptionForm.get(&#x27;page2&#x27;).value.photo_url }}&quot;&gt;          
        &lt;/div&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Avatar&lt;/mat-label&gt;
          &lt;input matInput type&#x3D;&quot;url&quot; formControlName&#x3D;&quot;photo_url&quot;&gt;
          &lt;mat-error&gt;Vous devez spécifier une url d&#x27;image&lt;/mat-error&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Prénom&lt;/mat-label&gt;
          &lt;input matInput placeholder&#x3D;&quot;George&quot; formControlName&#x3D;&quot;lastname&quot; required&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Nom&lt;/mat-label&gt;
          &lt;input matInput placeholder&#x3D;&quot;Brassens&quot; formControlName&#x3D;&quot;firstname&quot; required&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Téléphone (Optionnel) &lt;/mat-label&gt;
          &lt;input matInput type&#x3D;&quot;tel&quot; formControlName&#x3D;&quot;phone&quot;&gt;
        &lt;/mat-form-field&gt;
  
        &lt;button mat-button matStepperNext [disabled]&#x3D;&quot;!inscriptionForm.get(&#x27;page2&#x27;).valid&quot;&gt;Suite&lt;/button&gt;
      &lt;/form&gt;
    &lt;/mat-step&gt;

    &lt;mat-step label&#x3D;&quot;Validation&quot;&gt;
      &lt;form [formGroup]&#x3D;&quot;inscriptionForm.get(&#x27;page3&#x27;)&quot;&gt;
        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Mot de passe&lt;/mat-label&gt;
          &lt;input matInput type&#x3D;&quot;password&quot; formControlName&#x3D;&quot;pwd&quot; required&gt;
        &lt;/mat-form-field&gt;

        &lt;mat-form-field appearance&#x3D;&quot;fill&quot;&gt;
          &lt;mat-label&gt;Confirmation du mot de passe&lt;/mat-label&gt;
          &lt;input matInput type&#x3D;&quot;password&quot; formControlName&#x3D;&quot;confirm_pwd&quot; required&gt;
          &lt;mat-error&gt;Les mots de passe ne sont pas équivalents&lt;/mat-error&gt;  
        &lt;/mat-form-field&gt;

        &lt;button mat-raised-button color&#x3D;&quot;accent&quot;
          aria-label&#x3D;&quot;S&#x27;inscrire sur lolimac&quot;
          (click)&#x3D;&quot;submitForm()&quot;
          [disabled]&#x3D;&quot;!inscriptionForm.valid&quot;&gt;
          S&#x27;inscrire
        &lt;/button&gt;
      &lt;/form&gt;
    &lt;/mat-step&gt;
  &lt;/mat-horizontal-stepper&gt;

  &lt;ng-template #success&gt;
    &lt;div class&#x3D;&quot;success&quot;&gt;
      &lt;mat-icon class&#x3D;&quot;success-icon&quot;&gt;done&lt;/mat-icon&gt;
      &lt;h3&gt;Inscription validée !&lt;/h3&gt;
      &lt;p&gt;Vous allez être redirigé à la page de login pour vous authentifier&lt;/p&gt;
    &lt;/div&gt;
  &lt;/ng-template&gt;

  &lt;a id&#x3D;&quot;subscribe&quot; routerLink&#x3D;&quot;/visiteur/login&quot; *ngIf&#x3D;&quot;!bMobile&quot;&gt;Changement d&#x27;avis ? Retour à la page login&lt;/a&gt;
&lt;/div&gt;
</code></pre>
    </div>

    <div class="tab-pane fade " id="c-styleData">
                <p class="comment">
                    <code>./inscription.component.scss</code>
                </p>
                <pre class="line-numbers"><code class="language-scss">
#inscription-page {
    align-content: stretch;
    grid-gap: 10px;

    mat-horizontal-stepper, .success {
        border-radius: var(--border-radius);
        align-self: center;
        overflow: hidden;
        background-color: unset;
    }

    .success {
        display: grid;
        padding: 24px;
        grid-auto-flow: row;
        justify-items: center;
        text-align: center;
        background-color: var(--color-primary-lighter);

        .success-icon {
            font-size: 55px;
            background-color: var(--color-accent);
            border-radius: 50px; 
            height: 70px;
            width: 70px;
            line-height: 70px;
            display: flex;
            justify-content: center;
        }
    }

    form {
        display: grid;
        grid-auto-flow: row;
        grid-gap: 5px;

        button {
            margin-top: 5px; 
        }
    }

    a {
        text-align: center;
    }
}
</code></pre>
    </div>

    <div class="tab-pane fade " id="c-tree">
        <div id="tree-container"></div>
        <div class="tree-legend">
            <div class="title">
                <b>Legend</b>
            </div>
            <div>
                <div class="color htmlelement"></div><span>Html element</span>
            </div>
            <div>
                <div class="color component"></div><span>Component</span>
            </div>
            <div>
                <div class="color directive"></div><span>Html element with directive</span>
            </div>
        </div>
    </div>

    
</div>

<script src="../js/libs/vis.min.js"></script>
<script src="../js/libs/htmlparser.js"></script>
<script src="../js/libs/deep-iterator.js"></script>
<script>
        var COMPONENT_TEMPLATE = '<div><app-top-app-bar *ngIf="bMobile" [title]="\'Inscription\'" [bReturn]="true" (return)="goTo(\'/visiteur/login\')"></app-top-app-bar><div id="inscription-page" class="full-page">  <h2 *ngIf="!bMobile">Inscription sur Lolimac</h2>  <mat-horizontal-stepper  [linear]="true" *ngIf="!bInscriptionDone; else success">    <mat-step label="Identifiants" [stepControl]="inscriptionForm.get(\'page1\')">      <form [formGroup]="inscriptionForm.get(\'page1\')">        <mat-form-field appearance="fill">          <mat-label>Pseudo</mat-label>          <input matInput placeholder="CrousMan" formControlName="pseudo" required>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Email</mat-label>          <input matInput placeholder="<EMAIL>" type="email" formControlName="mail" required>          <mat-error>Email invalide !</mat-error>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Promotion</mat-label>          <mat-select placeholder="Promotion" formControlName="year_promotion" required>            <mat-option value="2021">2021</mat-option>            <mat-option value="2020">2020</mat-option>            <mat-option value="2019">2019</mat-option>            <mat-option value="2018">2018</mat-option>            <mat-option value="2017">2017</mat-option>            <mat-option value="2016">2016</mat-option>            <mat-option value="autre">Autre</mat-option>          </mat-select>          <mat-error>Veuillez indiquer votre promotion</mat-error>        </mat-form-field>        <button mat-button matStepperNext [disabled]="!inscriptionForm.get(\'page1\').valid">Suite</button>      </form>    </mat-step>    <mat-step label="Identité">      <form [formGroup]="inscriptionForm.get(\'page2\')">        <div class="avatar">          <img src="{{ inscriptionForm.get(\'page2\').value.photo_url }}">                  </div>        <mat-form-field appearance="fill">          <mat-label>Avatar</mat-label>          <input matInput type="url" formControlName="photo_url">          <mat-error>Vous devez spécifier une url d\'image</mat-error>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Prénom</mat-label>          <input matInput placeholder="George" formControlName="lastname" required>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Nom</mat-label>          <input matInput placeholder="Brassens" formControlName="firstname" required>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Téléphone (Optionnel) </mat-label>          <input matInput type="tel" formControlName="phone">        </mat-form-field>          <button mat-button matStepperNext [disabled]="!inscriptionForm.get(\'page2\').valid">Suite</button>      </form>    </mat-step>    <mat-step label="Validation">      <form [formGroup]="inscriptionForm.get(\'page3\')">        <mat-form-field appearance="fill">          <mat-label>Mot de passe</mat-label>          <input matInput type="password" formControlName="pwd" required>        </mat-form-field>        <mat-form-field appearance="fill">          <mat-label>Confirmation du mot de passe</mat-label>          <input matInput type="password" formControlName="confirm_pwd" required>          <mat-error>Les mots de passe ne sont pas équivalents</mat-error>          </mat-form-field>        <button mat-raised-button color="accent"          aria-label="S\'inscrire sur lolimac"          (click)="submitForm()"          [disabled]="!inscriptionForm.valid">          S\'inscrire        </button>      </form>    </mat-step>  </mat-horizontal-stepper>  <ng-template #success>    <div class="success">      <mat-icon class="success-icon">done</mat-icon>      <h3>Inscription validée !</h3>      <p>Vous allez être redirigé à la page de login pour vous authentifier</p>    </div>  </ng-template>  <a id="subscribe" routerLink="/visiteur/login" *ngIf="!bMobile">Changement d\'avis ? Retour à la page login</a></div></div>'
    var COMPONENTS = [{'name': 'AppComponent', 'selector': 'app-root'},{'name': 'BottomNavigationComponent', 'selector': 'app-bottom-navigation'},{'name': 'ChangePasswordComponent', 'selector': 'app-change-password'},{'name': 'CommentListComponent', 'selector': 'app-comment-list'},{'name': 'CreateEventComponent', 'selector': 'app-create-event'},{'name': 'DashboardComponent', 'selector': 'app-dashboard'},{'name': 'EditEventComponent', 'selector': 'app-edit-event'},{'name': 'EditProfileComponent', 'selector': 'app-edit-profile'},{'name': 'EventCardComponent', 'selector': 'app-event-card'},{'name': 'EventDetailComponent', 'selector': 'app-event-detail'},{'name': 'ForgotComponent', 'selector': 'app-forgot'},{'name': 'InscriptionComponent', 'selector': 'app-inscription'},{'name': 'InvitationComponent', 'selector': 'app-invitation'},{'name': 'LegalsComponent', 'selector': 'app-legals'},{'name': 'LoginComponent', 'selector': 'app-login'},{'name': 'NotificationsComponent', 'selector': 'app-notifications'},{'name': 'PageNotFoundComponent', 'selector': 'app-page-not-found'},{'name': 'PostListComponent', 'selector': 'app-post-list'},{'name': 'ProfileComponent', 'selector': 'app-profile'},{'name': 'SearchComponent', 'selector': 'app-search'},{'name': 'TopAppBarComponent', 'selector': 'app-top-app-bar'},{'name': 'TopNavigationComponent', 'selector': 'app-top-navigation'}];
    var DIRECTIVES = [];
    var ACTUAL_COMPONENT = {'name': 'InscriptionComponent'};
</script>
<script src="../js/tree.js"></script>














                   </div><div class="search-results">
    <div class="has-results">
        <h1 class="search-results-title"><span class='search-results-count'></span> result-matching "<span class='search-query'></span>"</h1>
        <ul class="search-results-list"></ul>
    </div>
    <div class="no-results">
        <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
    </div>
</div>
</div>
               <!-- END CONTENT -->
           </div>
       </div>

       <script>
            var COMPODOC_CURRENT_PAGE_DEPTH = 1;
            var COMPODOC_CURRENT_PAGE_CONTEXT = 'component';
            var COMPODOC_CURRENT_PAGE_URL = 'InscriptionComponent.html';
       </script>

       <script src="../js/libs/custom-elements.min.js"></script>
       <script src="../js/libs/lit-html.js"></script>
       <!-- Required to polyfill modern browsers as code is ES5 for IE... -->
       <script src="../js/libs/custom-elements-es5-adapter.js" charset="utf-8" defer></script>
       <script src="../js/menu-wc.js" defer></script>

       <script src="../js/libs/bootstrap-native.js"></script>

       <script src="../js/libs/es6-shim.min.js"></script>
       <script src="../js/libs/EventDispatcher.js"></script>
       <script src="../js/libs/promise.min.js"></script>
       <script src="../js/libs/zepto.min.js"></script>

       <script src="../js/compodoc.js"></script>

       <script src="../js/tabs.js"></script>
       <script src="../js/menu.js"></script>
       <script src="../js/libs/clipboard.min.js"></script>
       <script src="../js/libs/prism.js"></script>
       <script src="../js/sourceCode.js"></script>
          <script src="../js/search/search.js"></script>
          <script src="../js/search/lunr.min.js"></script>
          <script src="../js/search/search-lunr.js"></script>
          <script src="../js/search/search_index.js"></script>
       <script src="../js/lazy-load-graphs.js"></script>


    </body>
</html>
<file_sep>/back/api/models/Post.php
<?php

namespace models;

class Post {

	protected $id,
  	$title,
  	$content,
	  $date_created,
	  $date_edited,
    $id_user,
  	$id_event;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

  //Gère la récupération de données des attributs lorsqu'elle proviennent de la bdd
	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
    $array = [
      "id" => $this->getId(),
      "title" => $this->getTitle(),
      "content" => $this->getContent(),
      "date_created" => $this->getDate_created(),
      "date_edited" => $this->getDate_edited(),
      "id_user" => $this->getId_user(),
      "id_event" => $this->getId_event()
    ];
    return $array;
  }


  // Getters 
  public function getId() {
    return $this->id;
  }

  public function getTitle() {
    return $this->title;
  }

  public function getContent() {
    return $this->content;
  }

  public function getDate_created() {
    return $this->date_created;
  }

  public function getDate_edited() {
  	return $this->date_edited;
  }

  public function getId_user() {
    return $this->id_user;
  }

  public function getId_event() {
    return $this->id_event;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId($id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }

  public function setTitle($title) {
    if (is_string($title) && strlen($title) <= 255) {
    $this->title = $title;
    }
  }

  public function setContent($content) {
    if (is_string($content) && strlen($content) <= 5000) {
    $this->content = $content;
    }
  }

 	public function setDate_created($date_created) {
  	if (is_string($date_created)) {
 		 $this->date_created = $date_created;
 	  }
  }

  public function setDate_edited($date_edited) {
    if (is_string($date_edited)) {
     $this->date_edited = $date_edited;
    }
  }

  public function setId_user($id_user) {
    $id_user = (int) $id_user;
    if ($id_user > 0) {
     $this->id_user = $id_user;
    }
  }

  public function setId_event($id_event) {
    $id_event = (int) $id_event;
    if ($id_event > 0) {
     $this->id_event = $id_event;
    }
  }
}<file_sep>/front/src/app/modules/dashboard/dashboard.component.ts
import { Component, OnInit } from '@angular/core';
import { ResponsiveService } from 'app/core/services/responsive.service';

import { Event } from 'app/shared/models/event';
import { EventService } from '../events/event.service';
import { AuthService } from 'app/core/services/auth.service';
import { isEmpty } from 'app/shared/utility/change-objects';

enum DashBoardState {
  Error,
  Empty,
  Done,
  Loading,
  NoMore
}

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.scss']
})
export class DashboardComponent implements OnInit {
  events: Event[] = [];
  bMobile = true;
  dashBoardState = DashBoardState;
  currentState = DashBoardState.Loading;
  private m_offset = 0;
  private m_sizeToGet = 5;

  constructor(responsiveService: ResponsiveService, private m_eventService: EventService, private m_authService: AuthService) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
        this.bMobile = false;
      } else {
        this.bMobile = true;
      }
    });

    if (!this.bMobile) {
      this.m_sizeToGet = 15;
    }
  }

  ngOnInit() {
    this.m_eventService.getEventList(this.m_offset, this.m_sizeToGet).subscribe(result => {
      this.currentState = DashBoardState.Done;
      this.events = result;
      this.m_offset += this.m_sizeToGet;
    }, error => {
      this.currentState = DashBoardState.Error;
    });

  }

  increaseEventList() {
    this.currentState = DashBoardState.Loading;
    this.m_eventService.getEventList(this.m_offset, this.m_sizeToGet).subscribe(result => {
      if (isEmpty(result)) {
        this.currentState = DashBoardState.NoMore;
      } else {
        this.events = this.events.concat(result);
        this.m_offset += this.m_sizeToGet;
        this.currentState = DashBoardState.Done;
      }
    }, error => {
      this.currentState = DashBoardState.Error;
    });
  }

}
<file_sep>/front/src/app/shared/utility/change-objects.ts
export function removeEmptyProperties(obj: Object, parent?: Object, key?: string): Object {
    Object.keys(obj).forEach(key => {
        if (obj[key] instanceof Date) {
            obj[key] = dateToPhp(obj[key]);
        }
        
        if (obj[key] && typeof obj[key] === 'object') {
            removeEmptyProperties(obj[key], obj, key);
        } else if (obj[key] === '' || obj[key] === undefined || obj[key] === null) {
            delete obj[key];
        }
    });
    if (isEmpty(obj)) {
        delete parent[key];
    } else {
        return obj;
    }
}

export function fillUndefinedProperties(obj: Object): Object {
    Object.keys(obj).forEach(key => {
        if (obj[key] && typeof obj[key] === 'object') {
            fillUndefinedProperties(obj[key]);
        } else if (obj[key] === null || obj[key] === undefined) {
            obj[key] = '';
        }
    });
    return obj;
}

export function removeUnchangedProperties(objOld: Object, objNew: Object): Object {
    Object.keys(objNew).forEach(key => {
        if (objOld[key] != undefined) {
          if (objOld[key] === objNew[key]) {
            delete objNew[key];
          }
        }
    });
    return objNew;
}

export function isEmpty(obj: Object): boolean {
    if (obj instanceof Date) {
        return false;
    } else {
        for (let key in obj) {
            if (obj.hasOwnProperty(key)) {
                return false;
            }
        }
    }
    return true;
}

function dateToPhp(date: Date): string {
    if (!isNaN(date.getTime())) {
        let month = date.getMonth() + 1;
        return `${date.getFullYear()}-${month.toLocaleString(undefined, {minimumIntegerDigits: 2})}-${date.getDate().toLocaleString(undefined, {minimumIntegerDigits: 2})} ${date.getHours().toLocaleString(undefined, {minimumIntegerDigits: 2})}:${date.getMinutes().toLocaleString(undefined, {minimumIntegerDigits: 2})}:${date.getSeconds().toLocaleString(undefined, {minimumIntegerDigits: 2})}`;
    } else {
        return '';
    }
}
<file_sep>/front/src/app/modules/notifications/notifications.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { Observable } from 'rxjs';

import { Notification } from 'app/shared/models/notification';
import { ResponsiveService } from 'app/core/services/responsive.service';
import { NotificationsService } from './notifications.service';


@Component({
  selector: 'app-notifications',
  templateUrl: './notifications.component.html',
  styleUrls: ['./notifications.component.scss']
})
export class NotificationsComponent implements OnInit {
  bMobile = true;
  notification$: Observable<Notification>;

  constructor(responsiveService: ResponsiveService,
    private m_notificationService: NotificationsService,
    private m_router: Router) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.notification$ = this.m_notificationService.getAll();
  }

  ngOnInit() {
  }

  goTo(url: string) {
    this.m_router.navigateByUrl(url);
  }

}
<file_sep>/front/src/app/core/services/auth.service.ts
import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { HttpClient } from '@angular/common/http';

// 3rd party
import { Observable } from 'rxjs';
import { tap } from 'rxjs/operators';

// Custom
import { environment } from 'environments/environment';
import { isPlatformBrowser } from '@angular/common';

@Injectable({
  providedIn: 'root'
})
export class AuthService {
  redirectUrl = '/tableau-de-bord';
  private m_bLoggedIn = false;

  constructor(private m_http: HttpClient, @Inject(PLATFORM_ID) private m_platformId: Object) {
    if (isPlatformBrowser(this.m_platformId)) {
      if (localStorage.getItem('jwt')) {
        this.m_bLoggedIn = true;
        // TODO test token and renew it
      }
    }
  }

  login(username: string, password: string): Observable<any> {
    const URL = `${environment.backend.serverUrl}login`;
    return this.m_http.post<any>(URL, {"pseudo": username, "pwd": <PASSWORD>})
      .pipe(
        tap(
          data => { // logged-in
            if ((data.jwt) && (data.id_user)) {
              if (isPlatformBrowser(this.m_platformId)) {
                localStorage.setItem('jwt', data.jwt);
                localStorage.setItem('userId', data.id_user);
                this.m_bLoggedIn = true;
              } else {
                console.error('[Login] Impossible de stocker token coté serveur');
              }
            } else {
              console.error('[Login] Mauvaise structure de la réponse');
            }
          },
          error => { // bad credentials or internal error
            console.error(error);
          }
        )
      );
  }

  logout(): void {
    localStorage.removeItem('jwt');
    localStorage.removeItem('userId');
    this.m_bLoggedIn = false;
  }

  isLoggedIn(): boolean {
    return this.m_bLoggedIn;
  }

  getToken(): string {
    return localStorage.getItem('jwt');
  }

  getUserId(): number {
    return Number(localStorage.getItem('userId'));
  }
}
<file_sep>/front/src/app/shared/shared.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { ReactiveFormsModule } from '@angular/forms';

import { LazyLoadImageModule } from 'ng-lazyload-image';

import { SharedMaterialModule } from './modules/shared-material.module';
import { TopAppBarComponent } from './components/top-app-bar/top-app-bar.component';
import { EventCardComponent } from './components/event-card/event-card.component';
import { PostListComponent } from './components/post-list/post-list.component';
import { CommentListComponent } from './components/comment-list/comment-list.component';
import { DialogComponent } from './components/dialog/dialog.component';
import { EventCardSmallComponent } from './components/event-card-small/event-card-small.component';
import { EventCardNotificationComponent } from './components/event-card-notification/event-card-notification.component';
import { DeferLoadDirective } from './directives/defer-load.directive';

@NgModule({
  declarations: [
    TopAppBarComponent,
    EventCardComponent,
    PostListComponent,
    CommentListComponent,
    DialogComponent,
    EventCardSmallComponent,
    EventCardNotificationComponent,
    DeferLoadDirective
  ],
  imports: [
    CommonModule,
    SharedMaterialModule,
    ReactiveFormsModule,
    LazyLoadImageModule
  ],
  entryComponents: [DialogComponent],
  exports: [
    SharedMaterialModule,
    ReactiveFormsModule,
    LazyLoadImageModule,
    TopAppBarComponent,
    EventCardComponent,
    PostListComponent,
    CommentListComponent,
    DialogComponent,
    EventCardSmallComponent,
    EventCardNotificationComponent,
    DeferLoadDirective
  ]
})
export class SharedModule { }
<file_sep>/front/src/app/shared/validators/image-url.ts
import { FormGroup } from '@angular/forms';

export function ImageUrl(controlName: string) {
    return (formGroup: FormGroup) => {
        const url = formGroup.controls[controlName].value;

        if (formGroup.controls[controlName].errors && !formGroup.controls[controlName].errors.invalidImg) {
            // return if another validator has already found an error
            return;
        }

        if (!url.match(/\.(jpeg|jpg|gif|png)$/)) {
            formGroup.controls[controlName].setErrors({ invalidImg: true });
        } else {
            formGroup.controls[controlName].setErrors(null);
        }
    }
}
<file_sep>/front/src/app/core/core.module.ts
import { NgModule, Optional, SkipSelf } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { RouterModule } from '@angular/router';
import { MAT_DATE_LOCALE } from '@angular/material/core';
import { registerLocaleData } from '@angular/common';
import { LOCALE_ID } from '@angular/core';
import localeFr from '@angular/common/locales/fr';

import { BottomNavigationComponent } from './components/bottom-navigation/bottom-navigation.component';
import { TopNavigationComponent } from './components/top-navigation/top-navigation.component';
import { AuthService } from './services/auth.service';
import { AuthInterceptor } from './interceptors/auth.interceptor';
import { ErrorInterceptor } from './interceptors/error.interceptor';
import { CoreMaterialModule } from './modules/core-material.module';
import { ResponsiveService } from './services/responsive.service';

registerLocaleData(localeFr, 'fr');

@NgModule({
  declarations: [
    BottomNavigationComponent,
    TopNavigationComponent
  ],
  imports: [
    CommonModule,
    RouterModule,
    CoreMaterialModule
  ],
  providers: [
    HttpClientModule,

    // Custom
    AuthService,
    ResponsiveService,
    {
      provide: HTTP_INTERCEPTORS,
      useClass: AuthInterceptor,
      multi: true
    },
    {
      provide: HTTP_INTERCEPTORS,
      useClass: ErrorInterceptor,
      multi: true
    },
    {
      provide: MAT_DATE_LOCALE,
      useValue: 'fr-FR'
    },
    {
      provide: LOCALE_ID,
      useValue: 'fr-FR'
    }
  ],
  exports: [
    HttpClientModule,
    BottomNavigationComponent,
    TopNavigationComponent,
    CoreMaterialModule
  ]
})
export class CoreModule {
  constructor(@Optional() @SkipSelf() parentModule: CoreModule) {
    if (parentModule) {
      throw new Error('CoreModule is already loaded. Import only in AppModule');
    }
  }
}
<file_sep>/back/api/controllers/parser/IcsParser.php
<?php

	namespace controllers\parser;
	use \models\Place;


class IcsParser {

    protected $proid = "Lolimac Events//Lolimac//FR";
	public $ics;

    public function __construct() {
		$this->ics = "BEGIN:VCALENDAR\r
METHOD:REQUEST\r
VERSION:2.0\r
PRODID:-//{$this->proid}\r\n";
    }

    public function openEvent() {
		$this->ics .= "BEGIN:VEVENT\r\n";
    }
    public function closeEvent() {
		$this->ics .= "END:VEVENT\r\n";
    }

	public function setDate_timeStamp() {
		$date = new \DateTime("now");
		$this->ics .= "DTSTAMP:{$date->format('Ymd\THis\Z')}\r\n";
	}
	public function setDate_start($date) {
		$date = new \DateTime($date);
		$this->ics .= "DTSTART:{$date->format('Ymd\THis\Z')}\r\n";
	}


	public function setDate_end($date) {
		$date = new \DateTime($date);
		$this->ics .= "DTEND:{$date->format('Ymd\THis\Z')}\r\n";
	}
	public function setStatus() {
		$this->ics .= "STATUS:CONFIRMED\r\n";
	}

	public function setLocation(Place $place) {
		if ($place->getName()) {
			$this->ics .= "LOCATION:{$place->getName()}";

			if ($place->getCity()) {
				$this->ics .= " {$place->getCity()}";
			}
			if ($place->getPostcode()) {
				$this->ics .= " {$place->getPostcode()}";
			}
			if ($place->getNumber()) {
				$this->ics .= " n°{$place->getNumber()}";
			}
			if ($place->getStreet()) {
				$this->ics .= " {$place->getStreet()}";
			}

			$this->ics .= "\r\n";
		}
	}

	public function setUID($id) {
		$id = md5($id);
		$this->ics .= "UID:$id\r\n";
	}

	public function setSUMMARY($name) {
		$this->ics .= "SUMMARY:$name\r\n";
	}

	public function closeCalendar() {
		$this->ics .= "END:VCALENDAR\r\n";
	}

}
<file_sep>/back/api/models/Link_events_users_modulesManager.php
<?php

namespace models;

class Link_events_users_modulesManager extends DBAccess {
	
  public function add(Link_events_users_modules $link) {
		$q = $this->db->prepare("INSERT INTO link_events_users_modules 
      (`id_event`, `id_user`, `id_module`) 
      VALUES (:id_event, :id_user, :id_module);");

		$q->bindValue(':id_event', $link->getId_event());
    $q->bindValue(':id_user', $link->getId_user());
    $q->bindValue(':id_module', $link->getId_module());

	  $q->execute();

    $link->hydrate(['id' => $this->db->lastInsertId()]);
    return $link;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM link_events_users_modules;')->fetchColumn();
  }

  public function readById_event($id_event) {
      $q = $this->db->query('SELECT * FROM link_events_users_modules WHERE id_event = '.$id_event);
      for($i = 0; $data = $q->fetch(\PDO::FETCH_ASSOC); $i++) {
          $allParticipants[$data["id_user"]] = $data["id_module"];
      }
      if(isset($allParticipants)) {
        return $allParticipants;
      } else {
        return NULL;
      }
    
  }

  public function readById_user_event($id_user, $id_event) {
      $q = $this->db->query('SELECT * FROM link_events_users_modules WHERE id_user = '. $id_user .' AND id_event = '. $id_event);
      $link = $q->fetch(\PDO::FETCH_ASSOC);
      if ($link != NULL) {
        return new Link_events_users_modules($link);
      } else {
        return NULL;
      }  
  }

  public function readById_user_module($id_user, $id_module) {
      $q = $this->db->query('SELECT * FROM link_events_users_modules WHERE id_user = '. $id_user .' AND id_module = '. $id_module);
      $link = $q->fetch(\PDO::FETCH_ASSOC);
      return new Link_events_users_modules($link);
  }

  public function readById_event_user_module($id_event, $id_user, $id_module) {
      $q = $this->db->prepare('SELECT * FROM link_events_users_modules WHERE id_event = :id_event AND id_user = :id_user AND id_module = :id_module;');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_user', $id_user);
      $q->bindValue(':id_module', $id_module);
      $q->execute();

      $link = $q->fetch(\PDO::FETCH_ASSOC);

      return $link ? True : False;
  }


  public function readAll() {
    $allLink = [];
    
    $q = $this->db->query('SELECT * FROM link_events_users_modules');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allLink[$data['id']] = new Link_events_users_modules($data);
    }
    return $allLink;
  }

  public function deleteById($id_event, $id_user) {
     $q = $this->db->prepare('DELETE FROM link_events_users_modules WHERE id_event = :id_event AND id_user = :id_user');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_user', $id_user);
      $q->execute();
      return TRUE;
  }
}<file_sep>/front/src/app/shared/components/post-list/post-list.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { Post } from 'app/shared/models/post';
import { PostService } from 'app/modules/events/post.service';
import { AuthService } from 'app/core/services/auth.service';
import { MatDialog } from '@angular/material';
import { DialogComponent } from '../dialog/dialog.component';

enum PostState {
  Read,
  Create,
  Update
}

@Component({
  selector: 'app-post-list',
  templateUrl: './post-list.component.html',
  styleUrls: ['./post-list.component.scss']
})
export class PostListComponent implements OnInit {
  @Input() posts: Post[];
  @Input() eventId: number;
  @Output() updated = new EventEmitter<any>();
  
  postForm: FormGroup;
  postState = PostState;
  currentState = PostState.Read;
  userId: number;
  postIdToUpdate: number;

  constructor(private m_postService: PostService,
    private m_formBuilder: FormBuilder,
    authService: AuthService,
    private m_dialog: MatDialog) {
    this.postForm = this.m_formBuilder.group({
      title: ['', Validators.required],
      content: ['', Validators.required]
    });

    this.userId = authService.getUserId();
  }

  ngOnInit() {
  }

  submitCreateForm(): void {
    this.m_postService.createPost(this.eventId, this.postForm.value).subscribe(result => {
      this.currentState = PostState.Read;
      this.updated.emit(undefined);
    }, error => {

    });
  }

  submitEditForm(): void {
    this.m_postService.updatePost(this.eventId, this.postIdToUpdate, this.postForm.value).subscribe(result => {
      this.currentState = PostState.Read;
      this.postIdToUpdate = undefined;
      this.patchForm(undefined);
      this.updated.emit(undefined);
    }, error => {

    });
  }

  deletePost(): void {
    const dialogRef = this.m_dialog.open(DialogComponent, {
      width: "500px",
      data: {title: `Suppression d'un post`, text: `En êtes-vous bien sûr ?`, bValBtn: true}
    });

    dialogRef.afterClosed().subscribe(result => {
      if (result.validated) {
        this.m_postService.deletePost(this.eventId, this.postIdToUpdate).subscribe(result => {
          this.currentState = PostState.Read;
          this.postIdToUpdate = undefined;
          this.updated.emit(undefined);
        }, error => {

        });
      }
    });
  }

  reloadComments(): void {
    this.updated.emit(undefined);
  }

  patchForm(post: Post | undefined): void {
    if (post == undefined) {
      this.postForm.patchValue({
        title: '',
        content: ''
      });
    } else {
      this.postForm.patchValue({
        title: post.title,
        content: post.content
      });
    }
  }
}
<file_sep>/back/api/models/UserManager.php
<?php

namespace models;

class UserManager extends DBAccess {
	public function add(User $user) {
		$q = $this->db->prepare("INSERT INTO users
      (`firstname`, `lastname`, `pseudo`, `mail`, `phone`, `pwd_hash`, `photo_url`, `status`, `year_promotion`)
      VALUES (:firstname, :lastname, :pseudo, :mail, :phone, :pwd_hash, :photo_url, 3, :year_promotion);");

		$q->bindValue(':firstname', $user->getFirstname());
    $q->bindValue(':lastname', $user->getLastname());
    $q->bindValue(':pseudo', $user->getPseudo());
    $q->bindValue(':phone', $user->getPhone());
    $q->bindValue(':mail', $user->getMail());
    $q->bindValue(':pwd_hash', $user->getPwd_hash());
    $q->bindValue(':photo_url', $user->getPhoto_url());
    $q->bindValue(':year_promotion', $user->getYear_promotion());

	  $q->execute();

    $user->hydrate(['id' => $this->db->lastInsertId()]);
    return $user;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM users;')->fetchColumn();
  }

  public function readById($id) {
      $q = $this->db->query('SELECT * FROM users WHERE id = '.$id);
      $user = $q->fetch(\PDO::FETCH_ASSOC);
	  if ($user) {
		  return new User($user);
	  }
	  return NULL;
  }

  public function readByPseudo($pseudo) {
      $q = $this->db->prepare('SELECT * FROM users WHERE pseudo = :pseudo');
      $q->execute([':pseudo' => $pseudo]);
      $user = $q->fetch(\PDO::FETCH_ASSOC);
      return ($user) ? new User($user) : false;
  }

  public function readAll() {
    $allUsers = [];

    $q = $this->db->query('SELECT * FROM users');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allUsers[$data['id']] = new User($data);
    }
    return $allUsers;
  }

  public function update(User $user) {
    $q = $this->db->prepare('UPDATE users SET firstname = :firstname, lastname = :lastname, pseudo = :pseudo, mail = :mail, phone = :phone, pwd_hash = :pwd_hash, photo_url = :photo_url, status = :status, year_promotion = :year_promotion WHERE id = :id');

    $q->bindValue(':id', $user->getId());
    $q->bindValue(':firstname', $user->getFirstname());
    $q->bindValue(':lastname', $user->getLastname());
    $q->bindValue(':pseudo', $user->getPseudo());
    $q->bindValue(':mail', $user->getMail());
    $q->bindValue(':phone', $user->getPhone());
    $q->bindValue(':pwd_hash', $user->getPwd_hash());
    $q->bindValue(':photo_url', $user->getPhoto_url());
    $q->bindValue(':status', $user->getStatus());
    $q->bindValue(':year_promotion', $user->getYear_promotion());

    $q->execute();

    return $user;
  }

  public function updateNotificationDate($id_user) {
	  $q = $this->db->prepare('UPDATE users SET date_notification_check = NOW() WHERE id = :id_user;');
	  $q->bindValue(':id_user', $id_user);
	  $q->execute();
  }

  public function deleteById($id) {
    $this->db->exec("DELETE FROM users WHERE id = $id;");
    return TRUE;
  }
}
<file_sep>/back/api/vendor/jwt/src/BeforeValidException.php
<?php
namespace vendor\jwt\src;


class BeforeValidException extends \UnexpectedValueException
{

}
<file_sep>/back/api/controllers/CommentCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \models\Comment;
use \models\CommentManager;
use \models\PostManager;
use \controllers\scans\TokenAccess;
use \controllers\Link_events_users_modulesCRUD;

class CommentCRUD {

  public function add($dataIn, $id_event) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["content", "id_post"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $data['id_user'] = $token->getId();
    $postManager = new PostManager();
    $postManager->readById($data["id_post"]);
    $participantManager = new Link_events_users_modulesCRUD();
    $participation = $participantManager->readParticipation($id_event);
    if($participation != 0) {
      $comment = new Comment($data);
      $commentManager = new CommentManager();
      $commentManager->add($comment);
    } else {
      throw new \Exception('Vous n\'etes pas autorisé à publier sur cette event.', 400);
    }
    echo \json_encode([
        'message' => 'Comment added.'
    ]);
    return TRUE;
  }

  public function update($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $commentManager = new CommentManager();
    $comment = $commentManager->readById($data["id"]);
    $comment->hydrate($data);
    $token = new TokenAccess();
    $token->acompteAccess($comment->getId_user());
    $commentManager->update($comment);
    echo \json_encode([
        'message' => 'Comment updated.'
    ]);
  }

   public function read($dataIn) {
    $scanDataIn = new ScanDataIn();
    $data = $scanDataIn->failleXSS($dataIn);
    $data = $scanDataIn->orgenize($data, 2 ,["user", "id"]);
    $commentManager = new CommentManager();
    $comment = $commentManager->readById($data["id"]);
    echo json_encode(array("content" => $comment->GetContent(), "id_post" => $comment->GetId_post(), "id_user" => $comment->GetId_user(), "date_created" => $comment->GetDate_created(), "date_edited" => $comment->GetDate_edited()));
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $commentManager = new CommentManager();
    $comment = $commentManager->readById($data["id"]);
    $comment->hydrate($data);
    $token = new TokenAccess();
    $token->acompteAccess($comment->getId_user());
    $commentManager->deleteById($data["id"]);
    return TRUE;
  }
}<file_sep>/back/README.md
# IMAC site d'organisation de soirée - BackEnd

Actuellement, sont fixés comme limite de taille pour les différents contenus du site : 
- contenu commentaires : 1000
- contenu posts : 10 000
- titre evenements/posts : 255
- description evenement : 5000
- nom et prénom des utilisateurs : 22
- pseudo : 25
- mail : 50

## Getting started

Besoin de définir 2 fichiers PHP (à mettre à jour en production):

`configVar.php` dans `api`
```
<?php 
$secretKey = "<KEY>
$ip = "127.0.0.1";
```

`dbID.php` dans `api/models`
```
<?php 
$dbHost = "localhost";
$dbTableName ="lolimac";
$dbUsername = "root";
$dbPassword = "<PASSWORD>";
```

Il faut aussi vérifier que `Mcrpyt` (déprécié) est bien installé

## Inspirations

- [REST errors](https://blog.restcase.com/rest-api-error-codes-101/) - Best practices gestion erreurs api rest
- [Open Api errors](https://github.com/OAI/OpenAPI-Specification/issues/1392) - Proposition d'erreurs standardisés OpenAPI
- [Best practices](https://medium.com/studioarmix/learn-restful-api-design-ideals-c5ec915a430f) - Conseils quant à la création des endpoints
- [Microsoft guidelines](https://docs.microsoft.com/fr-fr/azure/architecture/best-practices/api-design) - Autre conseils d'organisations REST

## Dépendences

- [JWT](https://jwt.io/) - Json Web Tokens
<file_sep>/back/api/models/Link_events_users_modules.php
<?php

namespace models;

class Link_events_users_modules {

	protected $id_event,
  $id_user,
  $id_module;


	public function __construct(array $data) {
		$this->hydrate($data);
	}

	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function getId_event() {
    return $this->id_event;
  }

  public function getId_user() {
    return $this->id_user;
  }

  public function getId_module() {
    return $this->id_module;
  }

  public function setId_event($id_event) {
    $id_event = (int) $id_event;
    if ($id_event > 0) {
     $this->id_event = $id_event;
    }
  }

  public function setId_user($id_user) {
    $id_user = (int) $id_user;
    if ($id_user > 0) {
     $this->id_user = $id_user;
    }
  }

  public function setId_module($id_module) {
    $id_module = (int) $id_module;
    if ($id_module >= 0) {
     $this->id_module = $id_module;
    }
  }
}<file_sep>/back/api/vendor/jwt/src/SignatureInvalidException.php
<?php
namespace vendor\jwt\src;


class SignatureInvalidException extends \UnexpectedValueException
{

}
<file_sep>/README.md
# Lolimac

Event creation website made in Angular (front folder). It interacts with a REST api made in PHP (back folder).
<file_sep>/front/src/app/modules/events/event-detail/event-detail.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { EventDetailComponent } from './event-detail.component';
import { SharedModule } from 'app/shared/shared.module';
import { EventDetailRoutingModule } from './event-detail-routing.module';

@NgModule({
  declarations: [EventDetailComponent],
  imports: [
    CommonModule,
    SharedModule,
    EventDetailRoutingModule
  ]
})
export class EventDetailModule { }
<file_sep>/front/src/app/shared/components/top-app-bar/top-app-bar.component.ts
import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'app-top-app-bar',
  templateUrl: './top-app-bar.component.html',
  styleUrls: ['./top-app-bar.component.scss']
})
export class TopAppBarComponent implements OnInit {
  @Input() title: String;
  @Input() bReturn: Boolean;

  @Output() return = new EventEmitter<any>()

  constructor() { }

  ngOnInit() {
  }

  onReturn(event: any): void {
    this.return.emit(undefined);
  }

}
<file_sep>/back/api/controllers/scans/TokenAccess.php
<?php

	namespace controllers\scans;

    use \Config;
    use \vendor\jwt\src\JWT;
    use \models\UserManager;
    use \models\Link_events_users_modulesManager;

class TokenAccess {

    protected $token;

    public function __construct() {
        $config = new Config();

        $headers = getallheaders();
        if($headers['Authorization']) {
        list($jwt) = sscanf($headers['Authorization'], 'Bearer %s');
            if ($jwt) {
                $this->token = JWT::decode($jwt, $config->getJwtKey(), array('HS512'));
            } else {
                throw new \Exception('Absense d\'autorization', 401);
            }
        }
    }

    public function getId() {
        return $this->token->data->userId;
    }

    public function adminAccess($level) {
        $userManager = new UserManager();
        $user = $userManager->readById($this->token->data->userId);
        if($user->getStatus() <= $level) {
            return TRUE;
        } else {
            throw new \Exception('Droits utilisateur insuffisants', 400);
        }
    }

    public function acompteAccess($id) {
        $userManager = new UserManager();
        $user = $userManager->readById($this->token->data->userId);
        if($user->getId() == $id OR $this->adminAccess(1)) {
            return TRUE;
        } else {
            throw new \Exception('Droits d\'accès au compte restrint', 400);
        }
    }

    public function moduleAccess($event_id, $module_id) {
        $userManager = new UserManager();
        $user = $userManager->readById($this->token->data->userId);
        $linkManager = new Link_events_users_modulesManager();
        if($linkManager->readById_event_user_module($event_id, $user->getId(), $module_id)) {
            return TRUE;
        } else {
            return FALSE;
        }
    }
}
<file_sep>/back/api/controllers/ModuleCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \models\Module;
use \models\ModuleManager;


class ModuleCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["name"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    if($token->adminAccess(1)) {
      $module = new Module($data);
      $moduleManager = new ModuleManager();
      if ($moduleManager->readByName($module->getName()) === FALSE) {
        $moduleManager->add($module);
      } else {
        throw new \Exception('Nom de module déjà existant.');
      }
      return TRUE;
    }
  }

  public function update($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $token->adminAccess(1);
    $moduleManager = new ModuleManager();
    $module = $moduleManager->readById($data["id"]);
    $module->hydrate($data);
    $moduleManager->update($module);
  }

  public function read($dataIn) {
    $scanDataIn = new ScanDataIn();
    $data = $scanDataIn->failleXSS($dataIn);
    $data = $scanDataIn->orgenize($data, 2, ["type", "id"]);
    $moduleManager = new ModuleManager();
    $module = $moduleManager->readById($data["id"]);
    echo json_encode(array("name" => $module->GetName()));
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $token->adminAccess(1);
    $moduleManager = new ModuleManager();
    $moduleManager->deleteById($data["id"]);
  }
}<file_sep>/back/api/controllers/Link_events_placesCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \controllers\scans\TokenAccess;
use \controllers\scans\TokenCreater;
use \controllers\PlaceCRUD;
use \models\Link_events_places;
use \models\Link_events_placesManager;

class Link_events_placesCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id_event", "id_place"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $link = new Link_events_places($data);
    $linkManager = new Link_events_placesManager();
    if ($linkManager->readById_event_place($link->getId_event(), $link->getId_place()) === FALSE) {

      $linkManager->add($link);
    } else {
      throw new \Exception('Lien déjà existant.');
    }
    return TRUE;
  }

  public function readPlace_ARRAY($dataIn) {
      $scanDataIn = new ScanDataIn();
      $scanDataIn->exists($dataIn, ["id_event"]);
      $data = $scanDataIn->failleXSS($dataIn);
      $linkManager = new Link_events_placesManager();
      $link_events_places = $linkManager->readById_event($data["id_event"]);
      if ($link_events_places) {
          $placeCRUD = new PlaceCRUD();
          $place = $placeCRUD->read_OBJ(["id" => $link_events_places->getId_place()]);
          return $place->toArray();
      }
  }

  public function readPlace_OBJ($dataIn) {
        $scanDataIn = new ScanDataIn();
        $scanDataIn->exists($dataIn, ["id_event"]);
        $data = $scanDataIn->failleXSS($dataIn);
        $linkManager = new Link_events_placesManager();
        $link_events_places = $linkManager->readById_event($data["id_event"]);
        if ($link_events_places) {
            $placeCRUD = new PlaceCRUD();
            $place = $placeCRUD->read_OBJ(["id" => $link_events_places->getId_place()]);
            return $place;
        }
    }

  public function update($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id_event", "id_place"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $linkManager = new Link_events_placesManager();
    $link = $linkManager->readById_event($data["id_event"]);
    if ($link) {
        $linkManager->updatePlace($link, $data["id_place"]);
    }
    else {
        self::add($dataIn);
    }
    return TRUE;
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id_event", "id_place"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $linkManager = new Link_events_placesManager();
    $linkManager->deleteById($data["id_event"], $data["id_place"]);
    return TRUE;
  }

  public function deleteByIdEvent($dataIn) {
      $scanDataIn = new ScanDataIn();
      $scanDataIn->exists($dataIn, ["id_event"]);
      $data = $scanDataIn->failleXSS($dataIn);
      $token = new TokenAccess();
      $linkManager = new Link_events_placesManager();
      $linkManager->deleteByIdEvent($data["id_event"]);
      return TRUE;
  }

}
<file_sep>/front/src/app/shared/models/user.ts
export interface User {
    firstname?: string;
    lastname?: string;
    pseudo?: string;
    photo_url?: string;
    mail?: string;
    phone?: string;
    year_promotion?: number;
    status?: number;
    participation?: number;
}<file_sep>/front/src/app/core/services/responsive.service.ts
import { Injectable } from '@angular/core';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class ResponsiveService {
  constructor(private m_breakpointObserver: BreakpointObserver) {}

  isMobile(): Observable<BreakpointState> {
    return this.m_breakpointObserver.observe(['(min-width: 800px)']);
  }
}
<file_sep>/back/bdd/seed/lolimac.sql
-- phpMyAdmin SQL Dump
-- version 4.8.5
-- https://www.phpmyadmin.net/
--
-- Host: localhost:3306
-- Generation Time: May 19, 2019 at 01:19 PM
-- Server version: 5.7.26-0ubuntu0.18.04.1
-- PHP Version: 7.2.17-0ubuntu0.18.04.1

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET AUTOCOMMIT = 0;
START TRANSACTION;
SET time_zone = "+00:00";


/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;

--
-- Database: `lolimac`
--

-- --------------------------------------------------------

--
-- Table structure for table `comments`
--

CREATE TABLE `comments` (
  `id` int(11) NOT NULL,
  `content` text NOT NULL,
  `date_created` date NOT NULL,
  `date_edited` date NOT NULL,
  `id_post` int(11) NOT NULL,
  `id_user` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `comments`
--

INSERT INTO `comments` (`id`, `content`, `date_created`, `date_edited`, `id_post`, `id_user`) VALUES
(1, 'Voila j\'ai changÃ© ce que je voulait dire', '2019-04-20', '2019-04-20', 2, 12),
(2, 'Voila j\'ai changÃ© ce que je voulait dire', '2019-04-20', '2019-04-20', 2, 12),
(3, 'Voila j\'ai changÃ© ce que je voulait dire', '2019-04-20', '2019-04-20', 2, 12);

-- --------------------------------------------------------

--
-- Table structure for table `events`
--

CREATE TABLE `events` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `photo_url` text NOT NULL,
  `description` text,
  `date_start` datetime DEFAULT NULL,
  `date_end` datetime DEFAULT NULL,
  `date_created` datetime NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `events`
--

INSERT INTO `events` (`id`, `title`, `photo_url`, `description`, `date_start`, `date_end`, `date_created`) VALUES
(1, 'Titre AAAAAeeAAA 1 <3', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', 'c\'est le lol', NULL, '2018-12-12 00:00:00', '2019-04-27 00:00:00'),
(2, 'euh coucou', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', 'c\'est le lol', '2019-05-23 10:10:10', '2019-12-12 10:10:10', '2019-04-27 23:42:06'),
(3, 'Titre AAAAAeeAAA 1 <3', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', 'c\'est le lol', '2019-05-20 10:00:00', '2019-05-21 00:00:00', '2019-04-27 23:44:54'),
(4, 'There we glkji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:19:07'),
(5, 'There we godfodlkji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:20:03'),
(6, 'There we godfodlkiojji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:22:23'),
(7, 'There we godfodlkuihiuiojji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:23:02'),
(8, 'There we godfodlkuihiuopiiojji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:24:01'),
(9, 'There we godfodlkuihiuopoopiiojji', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-16 15:25:35'),
(11, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:01:42'),
(12, 'Les slips en folie', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, '2019-05-24 18:22:12', '2019-05-24 23:25:12', '2019-05-17 19:08:44'),
(13, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:08:45'),
(14, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:08:46'),
(15, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:08:46'),
(16, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:08:46'),
(17, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:09:15'),
(18, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:09:34'),
(19, 'Name', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-17 19:10:35'),
(20, 'Nameeee', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-18 19:34:32'),
(21, 'Nameeee', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-18 19:35:09'),
(22, 'Nameeee', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-18 21:21:12'),
(23, 'Nameeee', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-18 21:21:14'),
(24, 'Nameeee', 'https://images.unsplash.com/photo-1504564321107-4aa3efddb5bd?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=2134&q=80', NULL, NULL, NULL, '2019-05-18 21:21:14');

-- --------------------------------------------------------

--
-- Table structure for table `eventtypes`
--

CREATE TABLE `eventtypes` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `eventtypes`
--

INSERT INTO `eventtypes` (`id`, `name`) VALUES
(1, '<NAME>'),
(2, 'salu'),
(3, '<NAME>'),
(4, 'n\'importe iugyt fr quoi'),
(5, 'n\'importe iugyt fr quoi'),
(6, 'n\'importe iugyt fr quoi'),
(7, 'n\'importe iugyt fr quoi'),
(8, 'n\'importe iugyt fr quoi');

-- --------------------------------------------------------

--
-- Table structure for table `link_events_eventtypes`
--

CREATE TABLE `link_events_eventtypes` (
  `id_event` int(11) NOT NULL,
  `id_type` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `link_events_eventtypes`
--

INSERT INTO `link_events_eventtypes` (`id_event`, `id_type`) VALUES
(1, 2),
(12, 8),
(19, 1),
(21, 3);

-- --------------------------------------------------------

--
-- Table structure for table `link_events_places`
--

CREATE TABLE `link_events_places` (
  `id_event` int(11) NOT NULL,
  `id_place` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `link_events_places`
--

INSERT INTO `link_events_places` (`id_event`, `id_place`) VALUES
(3, 10),
(12, 19);

-- --------------------------------------------------------

--
-- Table structure for table `link_events_users_modules`
--

CREATE TABLE `link_events_users_modules` (
  `id_event` int(11) NOT NULL,
  `id_user` int(11) NOT NULL,
  `id_module` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `link_events_users_modules`
--

INSERT INTO `link_events_users_modules` (`id_event`, `id_user`, `id_module`) VALUES
(1, 21, 2),
(1, 22, 2),
(12, 22, 1),
(13, 22, 1),
(14, 22, 1),
(15, 22, 1),
(16, 22, 1),
(17, 22, 1),
(18, 22, 1),
(19, 22, 1),
(21, 22, 1),
(22, 22, 1),
(23, 22, 1),
(24, 22, 1);

-- --------------------------------------------------------

--
-- Table structure for table `modules`
--

CREATE TABLE `modules` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Table structure for table `notification_events`
--

CREATE TABLE `notification_events` (
  `id` int(11) NOT NULL,
  `id_event` int(11) NOT NULL,
  `date_edit` datetime NOT NULL,
  `type_edit` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

--
-- Dumping data for table `notification_events`
--

INSERT INTO `notification_events` (`id`, `id_event`, `date_edit`, `type_edit`) VALUES
(8, 1, '2019-05-17 18:34:12', 'title'),
(9, 1, '2019-05-17 18:34:12', 'id'),
(10, 1, '2019-05-17 18:34:50', 'date_start'),
(11, 1, '2019-05-17 18:34:50', 'title'),
(12, 1, '2019-05-17 18:34:57', 'date_start'),
(13, 1, '2019-05-17 18:34:57', 'title'),
(14, 1, '2019-05-17 19:31:31', 'date_start'),
(15, 1, '2019-05-17 19:31:31', 'title'),
(16, 1, '2019-05-17 19:31:31', 'type'),
(17, 1, '2019-05-17 19:35:46', 'date_start'),
(18, 1, '2019-05-17 19:35:46', 'title'),
(19, 1, '2019-05-17 19:35:46', 'type'),
(20, 3, '2019-05-19 01:14:09', 'date_start'),
(21, 3, '2019-05-19 01:14:09', 'title'),
(22, 3, '2019-05-19 01:14:09', 'place'),
(23, 3, '2019-05-19 01:18:07', 'date_start'),
(24, 3, '2019-05-19 01:18:07', 'title'),
(25, 3, '2019-05-19 01:18:07', 'place'),
(26, 12, '2019-05-19 12:36:44', 'title'),
(27, 12, '2019-05-19 12:36:44', 'place'),
(28, 12, '2019-05-19 12:36:44', 'type'),
(29, 12, '2019-05-19 12:36:44', 'date_start'),
(30, 12, '2019-05-19 12:36:44', 'date_end'),
(31, 12, '2019-05-19 12:49:35', 'title'),
(32, 12, '2019-05-19 12:49:35', 'place'),
(33, 12, '2019-05-19 12:49:35', 'type'),
(34, 12, '2019-05-19 12:49:35', 'date_start'),
(35, 12, '2019-05-19 12:49:35', 'date_end'),
(36, 12, '2019-05-19 12:58:28', 'title'),
(37, 12, '2019-05-19 12:58:28', 'place'),
(38, 12, '2019-05-19 12:58:28', 'type'),
(39, 12, '2019-05-19 12:58:28', 'date_start'),
(40, 12, '2019-05-19 12:58:28', 'date_end'),
(41, 12, '2019-05-19 13:01:47', 'title'),
(42, 12, '2019-05-19 13:01:47', 'place'),
(43, 12, '2019-05-19 13:01:47', 'type'),
(44, 12, '2019-05-19 13:01:47', 'date_start'),
(45, 12, '2019-05-19 13:01:47', 'date_end'),
(46, 12, '2019-05-19 13:02:25', 'title'),
(47, 12, '2019-05-19 13:02:25', 'place'),
(48, 12, '2019-05-19 13:02:25', 'type'),
(49, 12, '2019-05-19 13:02:25', 'date_start'),
(50, 12, '2019-05-19 13:02:25', 'date_end'),
(51, 12, '2019-05-19 13:02:28', 'title'),
(52, 12, '2019-05-19 13:02:28', 'place'),
(53, 12, '2019-05-19 13:02:28', 'type'),
(54, 12, '2019-05-19 13:02:28', 'date_start'),
(55, 12, '2019-05-19 13:02:28', 'date_end'),
(56, 12, '2019-05-19 13:02:29', 'title'),
(57, 12, '2019-05-19 13:02:29', 'place'),
(58, 12, '2019-05-19 13:02:29', 'type'),
(59, 12, '2019-05-19 13:02:29', 'date_start'),
(60, 12, '2019-05-19 13:02:29', 'date_end'),
(61, 12, '2019-05-19 13:03:15', 'title'),
(62, 12, '2019-05-19 13:03:15', 'place'),
(63, 12, '2019-05-19 13:03:15', 'type'),
(64, 12, '2019-05-19 13:03:15', 'date_start'),
(65, 12, '2019-05-19 13:03:15', 'date_end'),
(66, 12, '2019-05-19 13:09:45', 'type_edit'),
(67, 12, '2019-05-19 13:10:00', 'type_edit'),
(68, 12, '2019-05-19 13:11:37', 'post'),
(69, 12, '2019-05-19 13:11:54', 'post'),
(70, 12, '2019-05-19 13:11:59', 'title'),
(71, 12, '2019-05-19 13:11:59', 'place'),
(72, 12, '2019-05-19 13:11:59', 'type'),
(73, 12, '2019-05-19 13:11:59', 'date_start'),
(74, 12, '2019-05-19 13:11:59', 'date_end');

-- --------------------------------------------------------

--
-- Table structure for table `places`
--

CREATE TABLE `places` (
  `id` int(11) NOT NULL,
  `postcode` int(11) DEFAULT NULL,
  `street` varchar(255) DEFAULT NULL,
  `number` int(11) DEFAULT NULL,
  `city` varchar(255) DEFAULT NULL,
  `name` varchar(255) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `places`
--

INSERT INTO `places` (`id`, `postcode`, `street`, `number`, `city`, `name`) VALUES
(1, NULL, NULL, NULL, NULL, 'lalaspokzpela'),
(2, NULL, NULL, NULL, NULL, 'lalaspookpokzpela'),
(3, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(4, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(5, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(6, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(7, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(8, NULL, NULL, NULL, NULL, 'lalaspookpoiojkzpela'),
(9, 98247, 'Groove St', 2, '<NAME>', 'C\'est lÃ '),
(10, 98247, 'Groove St', 2, '<NAME>', 'C\'est lÃ '),
(11, NULL, NULL, NULL, 'ta mÃ¨re', 'lol'),
(12, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(13, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(14, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(15, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(16, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(17, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(18, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol'),
(19, 84848, 'Lalalol', 4, 'ta mÃ¨re', 'lol');

-- --------------------------------------------------------

--
-- Table structure for table `posts`
--

CREATE TABLE `posts` (
  `id` int(11) NOT NULL,
  `title` varchar(255) NOT NULL,
  `content` text NOT NULL,
  `date_created` date NOT NULL,
  `date_edited` date NOT NULL,
  `id_event` int(11) NOT NULL,
  `id_user` int(11) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `posts`
--

INSERT INTO `posts` (`id`, `title`, `content`, `date_created`, `date_edited`, `id_event`, `id_user`) VALUES
(2, 'J\'adore ta grosse saucisse', 'Enforne moi la stp.', '2019-05-19', '2019-05-19', 12, 22),
(3, 'Coucou', 'a stp.', '2019-05-19', '2019-05-19', 12, 22),
(4, 'Coucou toa', 'a stp.', '2019-05-19', '2019-05-19', 12, 22),
(5, 'Coucou toeeea', 'a stp.', '2019-05-19', '2019-05-19', 12, 22);

-- --------------------------------------------------------

--
-- Table structure for table `promotions`
--

CREATE TABLE `promotions` (
  `end_year` int(11) NOT NULL,
  `nickname` varchar(100) NOT NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

-- --------------------------------------------------------

--
-- Table structure for table `users`
--

CREATE TABLE `users` (
  `id` int(11) NOT NULL,
  `firstname` varchar(22) NOT NULL,
  `lastname` varchar(22) NOT NULL,
  `pseudo` varchar(25) NOT NULL,
  `mail` varchar(100) NOT NULL,
  `phone` varchar(14) DEFAULT NULL,
  `pwd_hash` varchar(255) NOT NULL,
  `photo_url` varchar(255) NOT NULL,
  `status` int(1) NOT NULL,
  `year_promotion` int(11) NOT NULL,
  `date_notification_check` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

--
-- Dumping data for table `users`
--

INSERT INTO `users` (`id`, `firstname`, `lastname`, `pseudo`, `mail`, `phone`, `pwd_hash`, `photo_url`, `status`, `year_promotion`, `date_notification_check`) VALUES
(21, 'liuiyiuyl', 'lien', 'nicolnt', '<EMAIL>', '06 06 06 06 06', '$2y$10$iQs9LjUg./unNub/8xPQv.6zq2UXEdUukvigN3FH..AWCKbBAQQre', 'nom_photo.jpg', 1, 2021, '2019-05-17 14:33:49'),
(22, 'nico', 'lien', 'nicol', '<EMAIL>', '06 06 06 06 06', '$2y$10$YYYVYKgDq9iE6.zbzOp6zeAaoTmOYBcDfWAUUZgtdtiGUp7fH.S4W', 'nom_photo.jpg', 3, 2021, '2019-05-19 13:13:41'),
(23, 'nico', 'lien', 'lalal', '<EMAIL>', '06 06 06 06 06', '$2y$10$mXn.IcSl3Kk5.64zx3y7LOCAlndBrNgzreyKGT1veOyMk1FyvGT5m', 'nom_photo.jpg', 3, 2021, '2019-05-18 15:07:16'),
(24, 'nico', 'lien', 'yoyo', '<EMAIL>', NULL, '$2y$10$o8qfiU00HfqDN7GdmjdccOtuWOhOhScqJmjn2O.1tny/SXAJm.6Dm', 'nom_photo.jpg', 3, 2021, '2019-05-18 15:07:40');

--
-- Indexes for dumped tables
--

--
-- Indexes for table `comments`
--
ALTER TABLE `comments`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `events`
--
ALTER TABLE `events`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `eventtypes`
--
ALTER TABLE `eventtypes`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `link_events_eventtypes`
--
ALTER TABLE `link_events_eventtypes`
  ADD PRIMARY KEY (`id_event`,`id_type`);

--
-- Indexes for table `link_events_places`
--
ALTER TABLE `link_events_places`
  ADD PRIMARY KEY (`id_event`,`id_place`);

--
-- Indexes for table `link_events_users_modules`
--
ALTER TABLE `link_events_users_modules`
  ADD PRIMARY KEY (`id_event`,`id_user`,`id_module`);

--
-- Indexes for table `modules`
--
ALTER TABLE `modules`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `notification_events`
--
ALTER TABLE `notification_events`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `places`
--
ALTER TABLE `places`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `posts`
--
ALTER TABLE `posts`
  ADD PRIMARY KEY (`id`);

--
-- Indexes for table `promotions`
--
ALTER TABLE `promotions`
  ADD PRIMARY KEY (`end_year`);

--
-- Indexes for table `users`
--
ALTER TABLE `users`
  ADD PRIMARY KEY (`id`),
  ADD UNIQUE KEY `pseudo` (`pseudo`);

--
-- AUTO_INCREMENT for dumped tables
--

--
-- AUTO_INCREMENT for table `comments`
--
ALTER TABLE `comments`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=5;

--
-- AUTO_INCREMENT for table `events`
--
ALTER TABLE `events`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=25;

--
-- AUTO_INCREMENT for table `eventtypes`
--
ALTER TABLE `eventtypes`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=9;

--
-- AUTO_INCREMENT for table `modules`
--
ALTER TABLE `modules`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT;

--
-- AUTO_INCREMENT for table `notification_events`
--
ALTER TABLE `notification_events`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=75;

--
-- AUTO_INCREMENT for table `places`
--
ALTER TABLE `places`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=20;

--
-- AUTO_INCREMENT for table `posts`
--
ALTER TABLE `posts`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=6;

--
-- AUTO_INCREMENT for table `users`
--
ALTER TABLE `users`
  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=25;
COMMIT;

/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
<file_sep>/back/api/vendor/jwt/src/ExpiredException.php
<?php
namespace vendor\jwt\src;


class ExpiredException extends \UnexpectedValueException
{

}
<file_sep>/front/src/app/shared/directives/defer-load.directive.spec.ts
import { DeferLoadDirective } from './defer-load.directive';

describe('DeferLoadDirective', () => {
  it('should create an instance', () => {
    const directive = new DeferLoadDirective();
    expect(directive).toBeTruthy();
  });
});
<file_sep>/front/src/app/modules/events/events.module.ts
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';

import { EventsRoutingModule } from './events-routing.module';
import { EventService } from './event.service';
import { PostService } from './post.service';

@NgModule({
  declarations: [],
  imports: [
    CommonModule,

    EventsRoutingModule
  ],
  providers: [
    EventService,
    PostService
  ]
})
export class EventsModule { }
<file_sep>/back/api/models/DBAccess.php
<?php

namespace models;

// Classe mère de tous les modèles, gérant l'identification d'accès à la base de donnée.
abstract class DBAccess {

  protected $db;

  public function __construct()
  {
    include "dbID.php"; // This file must not be staged
    $db = new \PDO("mysql:host={$dbHost};dbname={$dbTableName}", $dbUsername, $dbPassword);
    $this->db = $db;
  }
}
<file_sep>/back/api/models/Module.php
<?php

namespace models;

class Module {

	protected $id,
  $name;


	public function __construct(array $data) {
		$this->hydrate($data);
	}

	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function getId() {
    return $this->id;
  }

  public function getName() {
    return $this->name;
  }

  public function setId($id) {
    $id = (int) $id;
    if ($id > 0) {
     $this->id = $id;
    }
  }

  public function setName($name) {
    if (is_string($name) && strlen($name) <= 255) {
    $this->name = $name;
    }
  }
}<file_sep>/back/api/models/EventType.php
<?php

namespace models;

class EventType {

	protected $id,
	$name = NULL;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
      $array = [
          "id_type" => $this->getId(),
          "name" => $this->getName()
      ];
      return $array;
  }

  // Getters
  public function getId() {
    return $this->id;
  }

  public function getName() {
    return $this->name;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId($id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }
  
  public function setName($name) {
    if (is_string($name) && strlen($name) < 63 ) {
     $this->name = $name;
    }
  }

}
<file_sep>/front/src/app/modules/events/create-event/create-event.component.ts
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';

import { ResponsiveService } from 'app/core/services/responsive.service';
import { EventService } from '../event.service';
import { HttpErrorResponse } from '@angular/common/http';
import { Router } from '@angular/router';

enum FormStep {
  Page1,
  Page2,
  Page3,
  Page4
};

@Component({
  selector: 'app-create-event',
  templateUrl: './create-event.component.html',
  styleUrls: ['./create-event.component.scss']
})
export class CreateEventComponent implements OnInit {
  bMobile = true;
  eventForm: FormGroup;
  currentStep = FormStep.Page1;
  formStep = FormStep;
  topBarTitle = "Création d'évènement";
  minDate = new Date();
  bEndDetail = false;

  constructor(responsiveService: ResponsiveService,
    private m_formBuilder: FormBuilder,
    private m_eventService: EventService,
    private m_router: Router)
  {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.eventForm = this.m_formBuilder.group({
      title: ['', Validators.required],
      photo_url: ['https://images.unsplash.com/photo-1541532713592-79a0317b6b77?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80', Validators.required],
      description: '',
      date_start: '',
      date_start_hour: '0',
      date_start_minute: '0',
      date_end: '',
      date_end_offset: '',
      date_end_hour: '0',
      place: this.m_formBuilder.group({
        name: '',
        street: '',
        number: '',
        city: ''
      })
    });
  }

  ngOnInit() {
  }

  submitForm(): void {
    let form = this.eventForm.value;
    if (form.date_start != '') {
      form.date_start.setHours(form.date_start_hour, form.date_start_minute);
      form.date_end = new Date(form.date_start);

      if (this.bEndDetail) {
        form.date_end.setHours(form.date_end_hour);
      } else {
        if (form.date_end_offset != '') {
          form.date_end.setHours(form.date_end.getHours() + Number(form.date_end_offset), 0);
        } else {
          form.date_end.setHours(0, 0);
        }
      }

      delete form.date_start_hour;
      delete form.date_start_minute;
      delete form.date_end_offset;
    }

    // FIXME temp fix for api that refuses a place without name
    if (form.place.street != '' || form.place.number != '' || form.place.city != '') {
      if (form.place.name === '') {
        form.place.name = ' ';
      }
    }

    this.m_eventService.createEvent(form)
      .subscribe(response => {
        if (response.id_event) {
          this.m_router.navigate([`/evenements/detail/${response.id_event}`]);
        } else {
          // this.m_router.navigate([`/tableau-de-bord`]);
          console.error("Le back n'a pas indiqué l'ID de l'event créé");
        }
      }, (error: HttpErrorResponse) => {
        console.error("error");
        // TODO display error with the form field
      });
  }

  previousStep(): void {
    if (this.currentStep > 0) {
      this.currentStep--;
    }
  }

  updateTitle(): void {
    switch(this.currentStep) {
      case FormStep.Page1:
        this.topBarTitle = "Création d'évènement";
        break;

      case FormStep.Page2:
        this.topBarTitle = "Lieu et Date";
        break;

      case FormStep.Page3:
        this.topBarTitle = "Précisions";
        break;

      case FormStep.Page4:
        this.topBarTitle = "Adresse";
        break;
    }
  }

  onDateEndDropChange(event: any): void {
    if (event === 'more') {
      this.bEndDetail = true;
      this.eventForm.patchValue({
        date_end: this.eventForm.value.date_start
      });
    } else {
      this.bEndDetail = false;
    }
  }
}
<file_sep>/front/src/app/modules/profile/profile.component.ts
import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';

import { Observable } from 'rxjs';

import { ResponsiveService } from 'app/core/services/responsive.service';
import { AuthService } from 'app/core/services/auth.service';
import { UserService } from '../visitor/user.service';
import { EventService } from '../events/event.service';
import { User } from 'app/shared/models/user';
import { Event } from 'app/shared/models/event';

@Component({
  selector: 'app-profile',
  templateUrl: './profile.component.html',
  styleUrls: ['./profile.component.scss']
})
export class ProfileComponent implements OnInit {
  bMobile = true;
  user$: Observable<User>;
  events$: Observable<Event[]>

  constructor(responsiveService: ResponsiveService,
    private m_authService: AuthService,
    private m_router: Router,
    private m_userService: UserService,
    private m_eventService: EventService) {
    responsiveService.isMobile().subscribe(result => {
      if (result.matches) {
          this.bMobile = false;
      } else {
          this.bMobile = true;
      }
    });

    this.user$ = this.m_userService.get(this.m_authService.getUserId());
    this.events$ = this.m_eventService.getEventList(0, 20);
  }

  ngOnInit() {}

  logout(): void {
    this.m_authService.logout();
    this.m_router.navigate(['/visiteur/login']);
  }

  goTo(url: string): void {
    this.m_router.navigate([url]);
  }
}
<file_sep>/back/api/models/PostManager.php
<?php

namespace models;

class PostManager extends DBAccess {
	public function add(Post $post) {
		$q = $this->db->prepare("INSERT INTO posts
      (`title`, `content`, `date_created`, `date_edited`,`id_user` ,`id_event`)
      VALUES (:title, :content, NOW(), NOW(), :id_user, :id_event);");

		$q->bindValue(':title', $post->getTitle());
    $q->bindValue(':content', $post->getContent());
    $q->bindValue(':id_user', $post->getId_user());
    $q->bindValue(':id_event', $post->getId_event());

	  $q->execute();

    $post->hydrate(['id' => $this->db->lastInsertId()]);
    return $post;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM posts;')->fetchColumn();
  }

  public function readById($id) {
      $q = $this->db->query('SELECT * FROM posts WHERE id = '.$id);
      $post = $q->fetch(\PDO::FETCH_ASSOC);
      if($post != NULL) {
        return new Post($post);
      } else {
        throw new \Exception("La publication n'existe pas.", 400);
      }
  }

  public function readByIdEvent($id_event) {
      $q = $this->db->query('SELECT * FROM posts WHERE id_event = '.$id_event);
    for($i = 0; $data = $q->fetch(\PDO::FETCH_ASSOC); $i++) {
     $allPosts[$i] = new Post($data);
    }
	if (isset($allPosts)) {
		return $allPosts;
	}
	else return NULL;
  }

  public function readByTitle($title) {
      $q = $this->db->prepare('SELECT * FROM posts WHERE title = :title');
      $q->execute([':title' => $title]);
      $title = $q->fetch(\PDO::FETCH_ASSOC);
      return ($title) ? new Post($title) : false;
  }

  public function readAll() {
    $allPosts = [];

    $q = $this->db->query('SELECT * FROM posts');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allPosts[$data['id']] = new Post($data);
    }
    return $allPosts;
  }

  public function update(Post $post) {
    $q = $this->db->prepare('UPDATE posts SET  title = :title, content = :content, date_edited = NOW(), id_user = :id_user, id_event = :id_event WHERE id = :id');

    $q->bindValue(':id', $post->getId());
    $q->bindValue(':title', $post->getTitle());
    $q->bindValue(':content', $post->getContent());
    $q->bindValue(':id_user', $post->getId_user());
    $q->bindValue(':id_event', $post->getId_event());

    $q->execute();

    return $post;
  }

  public function deleteById($id) {
    $this->db->exec('DELETE FROM posts WHERE id = '.$id.';');
    return TRUE;
  }
}
<file_sep>/back/api/controllers/PostCRUD.php
<?php

namespace controllers;

use \controllers\scans\ScanDataIn;
use \models\Post;
use \models\PostManager;
use \models\CommentManager;
use \models\UserManager;
use \controllers\scans\TokenAccess;
use \controllers\Link_events_users_modulesCRUD;
use \controllers\NotificationCRUD;



class PostCRUD {

  public function add($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["title", "content", "id_event"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $token = new TokenAccess();
    $data['id_user'] = $token->getId();
    $post = new Post($data);
    $participantManager = new Link_events_users_modulesCRUD();
    $participation = $participantManager->readParticipation($post->getId_event());
    if($participation != 0) {
        $postManager = new PostManager();
        $postManager->add($post);
    } else {
      throw new \Exception('Vous n\'etes pas autorisé à publier sur cette event.', 400);
    }

    $NotificationCRUD = new NotificationCRUD();
    $NotificationCRUD->add([
        'id' => $data['id_event'],
        'post' => 'post'
    ]);
    echo \json_encode([
        'message' => 'Post added.'
    ]);
    return TRUE;
  }

  public function update($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $postManager = new PostManager();
    $post = $postManager->readById($data["id"]);
    $post->hydrate($data);
    $token = new TokenAccess();
    $token->acompteAccess($post->getId_user());
    $postManager->update($post);
    echo \json_encode([
        'message' => 'Post updated.'
    ]);
  }

  public function read($id_event) {
    $postManager = new PostManager();
    $posts = $postManager->readByIdEvent($id_event);
    if($posts) {
        $commentManager = new CommentManager();
        $userManager = new UserManager();
        foreach ($posts as $key => $post) {
            $postArray = $post->toArray();
            $comments = $commentManager->readByPost($post->getId());
            if ($comments) {
                foreach ($comments as $key2 => $comment) {
                    $commentInfos = $comment->toArray();
                    $userComment = $userManager->readById($comment->getId_user());
                    $userCommentInfos["id"] = $userComment->getId();
                    $userCommentInfos["firstname"] = $userComment->getFirstname();
                    $userCommentInfos["lastname"] = $userComment->getLastname();
                    $userCommentInfos["photo_url"] = $userComment->getPhoto_url();
                    $commentInfos["user"] = $userCommentInfos;
                    $comments[$key2] = $commentInfos;
                }
                $user = $userManager->readById($post->getId_user());
                $userInfos["id"] = $user->getId();
                $userInfos["firstname"] = $user->getFirstname();
                $userInfos["lastname"] = $user->getLastname();
                $userInfos["photo_url"] = $user->getPhoto_url();
                $postArray["comments"] = $comments;
                $postArray["user"] = $userInfos;
            }
            $posts[$key] = $postArray;
        }
        return $posts;
    }
  }

  public function delete($dataIn) {
    $scanDataIn = new ScanDataIn();
    $scanDataIn->exists($dataIn, ["id"]);
    $data = $scanDataIn->failleXSS($dataIn);
    $postManager = new PostManager();
    $post = $postManager->readById($data["id"]);
    $post->hydrate($data);
    $token = new TokenAccess();
    $token->acompteAccess($post->getId_user());
    $commentManager = new CommentManager();
    $commentManager->deleteByIdPost($data["id"]);
    $postManager->deleteById($data["id"]);
    echo \json_encode([
        'message' => 'Post deleted.'
    ]);
    return TRUE;
  }
}
<file_sep>/back/api/controllers/scans/CutURL.php
<?php

	namespace controllers\scans;


class CutURL {

    protected $URL_cut;

    public function __construct($url) {
		$url_cutted = parse_url($url, PHP_URL_PATH); // NOTE: Focus on the actual path of the URL, preventing errors with query arguments
        $url_cutted = explode ("/" , $url_cutted);
        while ($url_cutted[0] != "api") {
            array_shift($url_cutted);
        }
		array_shift($url_cutted);
        $this->URL_cut = $url_cutted;
    }

    public function getURL_cut() {
        return $this->URL_cut;
    }


}
<file_sep>/back/api/models/Link_events_placesManager.php
<?php

namespace models;

class Link_events_placesManager extends DBAccess {

  public function add(Link_events_places $link) {
      $q = $this->db->prepare("INSERT INTO link_events_places
          (`id_event`, `id_place`)
          VALUES (:id_event, :id_place);");

          $q->bindValue(':id_event', $link->getId_event());
          $q->bindValue(':id_place', $link->getId_place());

	  $q->execute();
    
    return $link;
  }

  public function count() {
    return $this->db->query("SELECT COUNT(*) FROM link_events_places;")->fetchColumn();
  }

  public function updatePlace(Link_events_places $link_events_places, int $new_id_place) {
    $q = $this->db->prepare("UPDATE link_events_places SET id_event = :id_event, id_place = :new_id_place WHERE id_event = :id_event AND id_place = :id_place");

    $q->bindValue(':id_event', $link_events_places->getId_event());
    $q->bindValue(':id_place', $link_events_places->getId_place());
    $q->bindValue(':new_id_place', $new_id_place);

    $q->execute();

    return $link_events_places;
  }

  public function readById_event($id_event) {
      $q = $this->db->prepare("SELECT * FROM link_events_places WHERE id_event = :id_event LIMIT 1;");
      $q->bindValue(':id_event', $id_event);
      $q->execute();
      $link = $q->fetch(\PDO::FETCH_ASSOC);
      if ($link) {
          return new Link_events_places($link);
      }
      else {
          return NULL;
      }
  }

  public function readById_place($id_place) {
      $q = $this->db->query("SELECT * FROM link_events_places WHERE id_place = :id_place");
	  $q->bindValue(':id_place', $id_place);
      $link = $q->fetch(\PDO::FETCH_ASSOC);
	  if ($link) {
		  return new Link_events_places($link);
	  }
	  else {
		  return NULL;
	  }
  }

  public function readById_event_place($id_event, $id_place) {
      $q = $this->db->prepare('SELECT * FROM link_events_places WHERE id_event = :id_event AND id_place = :id_place;');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_place', $id_place);
      $q->execute();

      $link = $q->fetch(\PDO::FETCH_ASSOC);

      return $link ? True : False;
  }


  public function readAll() {
    $allLink = [];

    $q = $this->db->query('SELECT * FROM link_events_places');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allLink[$data['id']] = new Link_events_places($data);
    }
    return $allLink;
  }

  public function deleteById($id_event, $id_place) {
     $q = $this->db->prepare('DELETE FROM link_events_places WHERE id_event = :id_event AND id_place = :id_place;');

      $q->bindValue(':id_event', $id_event);
      $q->bindValue(':id_place', $id_place);
      $q->execute();
      return TRUE;
  }

  public function deleteByIdEvent($id_event) {
       $q = $this->db->prepare('DELETE FROM link_events_places WHERE id_event = :id_event;');
        $q->bindValue(':id_event', $id_event);
        $q->execute();
        return TRUE;
    }
}
<file_sep>/back/api/models/Link_events_eventtypes.php
<?php

namespace models;

class Link_events_eventtypes {

	protected $id_event,
  $id_type;


	public function __construct(array $data) {
		$this->hydrate($data);
	}

	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  public function toArray() {
      $array = [
          "id_event" => $this->getId_event(),
          "id_type" => $this->getId_place()
      ];
      return $array;
  }

  public function getId_event() {
    return $this->id_event;
  }

  public function getId_type() {
    return $this->id_type;
  }

  public function setId_event($id_event) {
    if ($id_event > 0) {
     $this->id_event = $id_event;
    }
  }

  public function setId_type($id_type) {
    if ($id_type > 0) {
     $this->id_type = $id_type;
    }
  }
}
<file_sep>/back/api/models/ModuleManager.php
<?php

namespace models;

class ModuleManager extends DBAccess {
	public function add(Module $module) {
		$q = $this->db->prepare("INSERT INTO modules 
      (`name`) 
      VALUES (:name);");

		$q->bindValue(':name', $module->getName());

	  $q->execute();

    $module->hydrate(['id' => $this->db->lastInsertId()]);
    return $module;
  }

  public function count() {
    return $this->db->query('SELECT COUNT(*) FROM modules;')->fetchColumn();
  }

  public function readById($id) {
      $q = $this->db->query('SELECT * FROM modules WHERE id = '.$id);
      $module = $q->fetch(\PDO::FETCH_ASSOC);

      $moduleObj = new Module($module);
      if($moduleObj) {
        return $moduleObj;
      } else {
        throw new \Exception("Le module n'existe pas.", 400);
      }
  }

  public function readByName($name) {
      $q = $this->db->prepare('SELECT * FROM modules WHERE name = :name');
      $q->execute([':name' => $name]);
      $module = $q->fetch(\PDO::FETCH_ASSOC); 
      return ($module) ? new Module($module) : false;
  }

  public function readAll() {
    $allModules = [];
    
    $q = $this->db->query('SELECT * FROM modules');
    while ($data = $q->fetch(\PDO::FETCH_ASSOC)) {
     $allModules[$data['id']] = new Module($data);
    }
    return $allModules;
  }

  public function update(Module $module) {
    $q = $this->db->prepare('UPDATE modules SET name = :name WHERE id = :id');

    $q->bindValue(':id', $module->getId());
    $q->bindValue(':name', $module->getName());

    $q->execute();

    return $module;
  }

  public function deleteById($id) {
    $this->db->exec('DELETE FROM modules WHERE id = '.$id.';');
    return TRUE;
  }
}
<file_sep>/back/api/models/Event.php
<?php

namespace models;
use \controllers\scans\ScanDataIn;

class Event {

	protected $id,
	$title,
	$photo_url,
	$description = NULL,
	$date_start = NULL,
	$date_end = NULL,
	$date_created;

	public function __construct(array $data) {
		$this->hydrate($data);
	}

	public function toArray() {
		$array = [
			"id_event" => $this->getId(),
			"title" => $this->getTitle(),
			"description" => $this->getDescription(),
			"date_start" => $this->getDate_start(),
			"date_end" => $this->getDate_end(),
			"date_created" => $this->getDate_created(),
			"photo_url" => $this->getPhoto_url()
		];
		return $array;
	}

	public function __isset($property) {
		return isset($this->$property);
	}

  //Gère la récupération de données des attributs lorsqu'elle proviennent de la bdd
	public function hydrate(array $data) {
    foreach ($data as $key => $value) {
     	$method = 'set'.ucfirst($key);
      if (method_exists($this, $method)) {
        $this->$method($value);
      }
    }
  }

  // Getters
  public function getId() {
    return $this->id;
  }

  public function getTitle() {
    return $this->title;
  }

  public function getPhoto_url() {
    return $this->photo_url;
  }

  public function getDescription() {
    return $this->description;
  }

  public function getDate_start() {
    return $this->date_start;
  }

  public function getDate_end() {
  	return $this->date_end;
  }

  public function getDate_created() {
    return $this->date_created;
  }

  //Assesseurs
  //Attention le nom de méthode doit obligatoirement être composé de "set" suivi du nom de l'attribut correspondant, avec une majuscule, pour que la méthode hydrate soit fonctionnelle.
	public function setId(int $id) {
 	  $id = (int) $id;
 	  if ($id > 0) {
 		 $this->id = $id;
 	  }
  }

  public function setTitle($title) {
	  if (is_null($title)) {
		  throw new \Exception("Veuilliez entrer un titre");
	  }
	  if (is_string($title) && strlen($title) <= 255) {
		  $this->title = $title;
	  }
  }

  public function setPhoto_url($photo_url) {
	  if (is_null($photo_url)) {
		  throw new \Exception("Veuilliez indiquer une photo");
	  }
	  if (filter_var($photo_url, FILTER_VALIDATE_URL) && strlen($photo_url) <= 2083) {
		  $this->photo_url = $photo_url;
	  }
  }

  public function setDescription($description) {
    if (is_string($description) && (strlen($description) <= 65535)) {
    $this->description = $description;
    }
  }

  public function setDate_start($date_start) {
	  $scanDataIn = new ScanDataIn();
	  if (\is_null($date_start) || $scanDataIn->validateDate($date_start)) {
		  $this->date_start = $date_start;
	  }
	  else {
		  throw new \Exception("Veuilliez entrer une date de début valide.", 400);
	  }
  }

 	public function setDate_end($date_end) {
		$scanDataIn = new ScanDataIn();
		if (\is_null($date_end) || $scanDataIn->validateDate($date_end)) {
			$this->date_end = $date_end;
		}
		else {
			throw new \Exception("Veuilliez entrer une date de fin valide.", 400);
		}
  }

  public function setDate_created($date_created) {
		$scanDataIn = new ScanDataIn();
		if (\is_null($date_created) || $scanDataIn->validateDate($date_created)) {
			$this->date_created = $date_created;
		}
		else {
			throw new \Exception("Veuilliez entrer une date de création valide.", 400);
		}
  }
}
<file_sep>/front/src/app/modules/events/events-routing.module.ts
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

const routes: Routes = [
    {
      path: 'creation',
      loadChildren: './create-event/create-event.module#CreateEventModule'
    },
    {
      path: 'detail/:id',
      loadChildren: './event-detail/event-detail.module#EventDetailModule'
    },
    {
      path: 'edition/:id',
      loadChildren: './edit-event/edit-event.module#EditEventModule'
    },
    {
      path: '404',
      loadChildren: '../page-not-found/page-not-found.module#PageNotFoundModule'
    },
    {
      path: '**',
      redirectTo: '404',
      pathMatch: 'full'
    }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class EventsRoutingModule { }