diff --git a/ensiie-project/.docker/nginx-php/Dockerfile b/ensiie-project/.docker/nginx-php/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..5c2391468b2dee52be406f0d9ea8cb5fa16276a8
--- /dev/null
+++ b/ensiie-project/.docker/nginx-php/Dockerfile
@@ -0,0 +1,11 @@
+FROM nginx:1.13-alpine
+
+COPY ./config /tmp
+RUN mv /tmp/site.conf /etc/nginx/conf.d/default.conf \
+ && mv /tmp/entrypoint.sh /root/entrypoint.sh \
+ && apk add --no-cache tzdata
+
+STOPSIGNAL SIGTERM
+
+ENTRYPOINT ["/bin/sh","/root/entrypoint.sh"]
+CMD ["nginx", "-g", "daemon off;"]
diff --git a/ensiie-project/.docker/nginx-php/config/entrypoint.sh b/ensiie-project/.docker/nginx-php/config/entrypoint.sh
new file mode 100644
index 0000000000000000000000000000000000000000..c169df8558f31e91ca4ae60b07bdd3e198a2819b
--- /dev/null
+++ b/ensiie-project/.docker/nginx-php/config/entrypoint.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+set -e
+
+if [ -z ${TZ+x} ]; then
+  echo "Warning : TimeZone is unset !";
+else
+  ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ;
+fi
+
+if [ -z ${PHP_ADDRESS+x} ]; then
+  echo "Error : PHP_ADDRESS is unset, please specify php hostname";
+  exit 1
+else
+  sed -i "s/\${PHP_ADDRESS}/${PHP_ADDRESS}/" /etc/nginx/conf.d/default.conf
+fi
+
+if [ -z ${SERVER_NAME+x} ]; then
+  echo "Error : SERVER_NAME is unset, please specify nginx hostname";
+  exit 1
+else
+  sed -i "s/\${SERVER_NAME}/${SERVER_NAME}/" /etc/nginx/conf.d/default.conf
+fi
+
+exec "$@"
diff --git a/ensiie-project/.docker/nginx-php/config/site.conf b/ensiie-project/.docker/nginx-php/config/site.conf
new file mode 100644
index 0000000000000000000000000000000000000000..11beef32f2bb27c950b8473f0b004dc3f334724a
--- /dev/null
+++ b/ensiie-project/.docker/nginx-php/config/site.conf
@@ -0,0 +1,100 @@
+server {
+    listen       80;
+    server_name  ${SERVER_NAME};
+
+    root         /usr/share/nginx/html;
+
+    gzip on;
+
+    # Enable compression both for HTTP/1.0 and HTTP/1.1.
+    gzip_http_version 1.1;
+
+    # Compression level (1-9).
+    # 5 is a perfect compromise between size and cpu usage, offering about
+    # 75% reduction for most ascii files (almost identical to level 9).
+    gzip_comp_level 6;
+
+    # Don't compress anything that's already small and unlikely to shrink much
+    # if at all (the default is 20 bytes, which is bad as that usually leads to
+    # larger files after gzipping).
+    gzip_min_length 256;
+
+    # Compress data even for clients that are connecting to us via proxies,
+    # identified by the "Via" header (required for CloudFront).
+    gzip_proxied any;
+
+    # Tell proxies to cache both the gzipped and regular version of a resource
+    # whenever the client's Accept-Encoding capabilities header varies;
+    # Avoids the issue where a non-gzip capable client (which is extremely rare
+    # today) would display gibberish if their proxy gave them the gzipped version.
+    gzip_vary on;
+
+    # Compress all output labeled with one of the following MIME-types.
+    gzip_types
+      application/atom+xml
+      application/javascript
+      application/json
+      application/rss+xml
+      application/vnd.ms-fontobject
+      application/x-font-ttf
+      application/x-web-app-manifest+json
+      application/xhtml+xml
+      application/xml
+      font/opentype
+      image/svg+xml
+      image/x-icon
+      text/css
+      text/plain
+      text/x-component;
+
+    server_tokens off;
+
+    #Large header
+    large_client_header_buffers 4 32k;
+
+    index index.php index.html index.htm index.phtml;
+
+    charset utf-8;
+    fastcgi_read_timeout 1200;
+    fastcgi_connect_timeout 1200;
+    fastcgi_send_timeout 1200;
+    fastcgi_buffers 8 16k;
+    fastcgi_buffer_size 32k;
+    include fastcgi_params;
+    client_max_body_size 32M;
+
+    location / {
+        try_files $uri $uri/ /index.php$is_args$args;
+    }
+
+    location = /favicon.ico { access_log off; log_not_found off; }
+    location = /robots.txt  { access_log off; log_not_found off; }
+
+
+    location ~* \.php$ {
+        fastcgi_split_path_info ^(.+\.php)(/.+)$;
+        fastcgi_pass ${PHP_ADDRESS}:9000;
+        fastcgi_index index.php;
+        include fastcgi_params;
+        fastcgi_param SCRIPT_FILENAME /var/www/html/public/$fastcgi_script_name;
+        fastcgi_param PATH_INFO $fastcgi_path_info;
+        fastcgi_intercept_errors on;
+    }
+
+    location ~ /\.ht {
+        deny all;
+    }
+
+    # Added cache headers for images, quick fix for cloudfront.
+    location ~* \.(png|jpg|jpeg|gif)$ {
+        expires 30d;
+        log_not_found off;
+    }
+
+    # Only 3 hours on CSS/JS to allow me to roll out fixes during
+    # early weeks.
+    location ~* \.(js|css|ico)$ {
+        expires 3h;
+        log_not_found off;
+    }
+}
diff --git a/ensiie-project/.docker/php-fpm/Dockerfile b/ensiie-project/.docker/php-fpm/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..8645b965281aa8f742bd93a61a469099c4bbcb96
--- /dev/null
+++ b/ensiie-project/.docker/php-fpm/Dockerfile
@@ -0,0 +1,37 @@
+FROM php:7.3-fpm
+
+ARG DOCKER_USER
+ARG DOCKER_USER_ID
+
+RUN apt-get update -qq \
+    && apt-get install -y --no-install-recommends \
+        gettext-base openssh-client wget git make cmake libssl-dev libssl-doc libxml2-dev libcurl3-dev sudo libpq-dev zlib1g-dev libzip-dev \
+    && pecl install xdebug \
+    && echo "zend_extension=$(find /usr/local/lib/php/extensions/ -name xdebug.so)" > /usr/local/etc/php/conf.d/xdebug.ini \
+    && echo "xdebug.remote_enable=on" >> /usr/local/etc/php/conf.d/xdebug.ini \
+    && echo "xdebug.remote_autostart=off" >> /usr/local/etc/php/conf.d/xdebug.ini \
+    && docker-php-ext-install -j$(nproc) pdo pdo_pgsql bcmath mbstring xml curl zip \
+    && curl -sS http://getcomposer.org/installer | php -- --filename=composer \
+    && chmod a+x composer \
+    && mv composer /usr/local/bin/composer \
+    && composer -q global require "hirak/prestissimo:^0.3" \
+    && composer -q global require "phing/phing:^2.16" \
+    && ln -s /root/.composer/vendor/phing/phing/bin/phing /usr/bin/phing \
+    && apt-get clean \
+    && mkdir /nginx \
+    && rm -rf /var/lib/apt/lists/* \
+    && cd -
+
+# Copy config
+COPY ./config/ /docker/
+ADD config/custom-php.ini /usr/local/etc/php/conf.d/custom-php.ini
+
+
+# Add local user
+RUN useradd --shell /bin/bash -u ${DOCKER_USER_ID} -o -c "" -m ${DOCKER_USER} \
+    && adduser ${DOCKER_USER} sudo \
+    && echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers \
+    && export HOME=/home/${DOCKER_USER}
+
+ENTRYPOINT ["/bin/bash", "/docker/entrypoint.sh"]
+CMD ["php-fpm"]
diff --git a/ensiie-project/.docker/php-fpm/config/custom-php.ini b/ensiie-project/.docker/php-fpm/config/custom-php.ini
new file mode 100644
index 0000000000000000000000000000000000000000..5e491bfe1ebd99151a7c32f9f5c34be2954ac30a
--- /dev/null
+++ b/ensiie-project/.docker/php-fpm/config/custom-php.ini
@@ -0,0 +1,4 @@
+memory_limit=1000M
+display_errors=true
+display_startup_errors=true
+error_reporting=E_ALL
\ No newline at end of file
diff --git a/ensiie-project/.docker/php-fpm/config/entrypoint.sh b/ensiie-project/.docker/php-fpm/config/entrypoint.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a06b435fb1e5ad3e64d18a9bd1aca679003274a8
--- /dev/null
+++ b/ensiie-project/.docker/php-fpm/config/entrypoint.sh
@@ -0,0 +1,21 @@
+#!/bin/sh
+# DO NOT EDIT THIS FILE, create a bash script in /docker/custom-entrypoint.sh
+
+set -e
+
+shopt -s nocasematch
+
+if [ -z ${TZ+x} ]; then
+  echo "Warning : TimeZone is unset !";
+else
+  ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone ;
+fi
+
+# Moving static files to a sharedVolume with the nginx
+rm -rf /nginx/*
+if [ -d "/var/www/html/public" ]; then
+    cp -rf /var/www/html/public /nginx
+fi
+
+exec "$@"
+
diff --git a/ensiie-project/.docker/postgres/Dockerfile b/ensiie-project/.docker/postgres/Dockerfile
new file mode 100644
index 0000000000000000000000000000000000000000..1349d0c48dd5cc7859040bbd4094c592fa4e2d9b
--- /dev/null
+++ b/ensiie-project/.docker/postgres/Dockerfile
@@ -0,0 +1 @@
+FROM postgres:alpine
\ No newline at end of file
diff --git a/ensiie-project/.env b/ensiie-project/.env
new file mode 100644
index 0000000000000000000000000000000000000000..96158aff0b9053ceee152bfa0221effe50f10cea
--- /dev/null
+++ b/ensiie-project/.env
@@ -0,0 +1,26 @@
+# $(echo id -u $USER)
+DOCKER_USER_ID=1000
+
+# Remote Hosts for Xdebug configuration
+# PUT YOUR LOCAL IP HERE
+# ip addr show
+REMOTE_HOST=localhost
+
+DOCKER_USER=ensiie
+
+# Nginx listen port on local machine
+NGINX_PORT=8080
+
+# Nginx hostname
+SERVER_NAME=php-docker.local
+
+# php-fpm listen address (php service name in docker-compose)
+PHP_ADDRESS=php
+
+# Timezone
+TIMEZONE='Europe/Paris'
+
+#DB
+DB_USER=ensiie
+DB_PASSWORD=ensiie
+DB_PORT_EXTERNAL=5431
\ No newline at end of file
diff --git a/ensiie-project/Makefile b/ensiie-project/Makefile
new file mode 100644
index 0000000000000000000000000000000000000000..8c86dfc94523eb85b10818ffde11e164c287c17e
--- /dev/null
+++ b/ensiie-project/Makefile
@@ -0,0 +1,44 @@
+bold=$(shell (tput bold))
+normal=$(shell (tput sgr0))
+.DEFAULT_GOAL=help
+DISTRIB:=$(shell lsb_release -is | tr '[:upper:]' '[:lower:]')
+VERSION:=$(shell lsb_release -cs)
+ARCHITECTURE:=$(shell dpkg --print-architecture)
+
+help:
+	@echo "${bold}install${normal}\n\t Installs the whole appplication.\n"
+	@echo "${bold}uninstall${normal}\n\t Stops and removes all containers and drops the database.\n"
+	@echo "${bold}start${normal}\n\t Starts the application.\n"
+	@echo "${bold}db.connect${normal}\n\t Connects to the database.\n"
+	@echo "${bold}phpunit.run${normal}\n\t Runs the unit tests.\n"
+
+start:
+	docker-compose up --build -d
+	sleep 3
+
+stop:
+	docker-compose down -v
+	docker-compose rm -v
+
+install: uninstall start composer.install db.install
+
+uninstall: stop
+	@sudo rm -rf postgres-data
+
+reinstall: install
+
+#Connects to the databatase
+db.connect:
+	docker-compose exec postgres /bin/bash -c 'psql -U $$POSTGRES_USER'
+
+db.install:
+	docker-compose exec postgres /bin/bash -c 'psql -U $$POSTGRES_USER -h localhost -f data/db.sql'
+
+php.connect:
+	docker-compose exec php /bin/bash
+
+phpunit.run:
+	docker-compose exec php vendor/bin/phpunit --config=phpunit.xml
+
+composer.install:
+	docker-compose exec php composer install || exit 0
diff --git a/ensiie-project/README.md b/ensiie-project/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..465f12b57c2c46ecbccf74efaaeafa93ea058e32
--- /dev/null
+++ b/ensiie-project/README.md
@@ -0,0 +1,30 @@
+# ENSIIE Web Project Skeleton
+
+## Install your application
+This tutorial will guide you through the installation procedure of the Web Project Skeleton.   
+
+The only packages you need to install right now are **docker** and **docker-compose**
+* [Install Docker](https://docs.docker.com/install/) :
+    * [(Optional: docker w/o sudo on linux)](https://docs.docker.com/install/linux/linux-postinstall/)
+* [Install Docker Compose](https://docs.docker.com/compose/install/)
+
+Then, clone the Web Project skeleton on your machine:
+* `git clone https://github.com/Kirouane/ensiie-project.git`
+* `cd ensiie-project`
+
+The next step is to set some environment variables in the `.env` file
+* Open this Skeleton on your favorite IDE : PHPStorm or VSCode.
+* Open the file .env
+    * DOCKER_USER_ID: to obtain the value of this variable you need to execute this command `$(echo id -u $USER)` on a Terminal. Copy and past the output.
+    * REMOTE_HOST: For those who want to use the PHPStorm Debugger, put your IP address. Otherwise, skip this step.
+
+Now, let's begin the installation :
+* `make install`. This command may take time.  
+* That's it! Your website is running [http:localhost:8080](http:localhost:8080)
+
+Below are some useful commands :
+* `make stop` Stop the containers
+* `make start` Start the containers
+* `make db.connect` Connect to th database
+* `make phpunit.run` Run the PHPUnit tests
+* `make install` Reinstall all containers
\ No newline at end of file
diff --git a/ensiie-project/composer.json b/ensiie-project/composer.json
new file mode 100644
index 0000000000000000000000000000000000000000..928be9d93d4b62298217112248b6a53f0df5c26e
--- /dev/null
+++ b/ensiie-project/composer.json
@@ -0,0 +1,15 @@
+{
+    "require-dev": {
+        "phpunit/phpunit": "^7.0"
+    },
+    "autoload": {
+        "psr-4": {
+            "User\\": "src/User/"
+        }
+    },
+    "autoload-dev": {
+        "psr-4": {
+            "User\\": "test/unit/User/"
+        }
+    }
+}
diff --git a/ensiie-project/data/db.sql b/ensiie-project/data/db.sql
new file mode 100644
index 0000000000000000000000000000000000000000..0b1781ee6cebc62d379282bae3f413dc0bada7ed
--- /dev/null
+++ b/ensiie-project/data/db.sql
@@ -0,0 +1,19 @@
+CREATE TABLE "user" (
+    id SERIAL PRIMARY KEY ,
+    firstname VARCHAR NOT NULL ,
+    lastname VARCHAR NOT NULL ,
+    birthday date
+);
+
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('John', 'Doe', '1967-11-22');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Yvette', 'Angel', '1932-01-24');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Amelia', 'Waters', '1981-12-01');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Manuel', 'Holloway', '1979-07-25');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Alonzo', 'Erickson', '1947-11-13');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Otis', 'Roberson', '1995-01-09');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Jaime', 'King', '1924-05-30');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Vicky', 'Pearson', '1982-12-12)');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Silvia', 'Mcguire', '1971-03-02');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Brendan', 'Pena', '1950-02-17');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Jackie', 'Cohen', '1967-01-27');
+INSERT INTO "user"(firstname, lastname, birthday) VALUES ('Delores', 'Williamson', '1961-07-19');
\ No newline at end of file
diff --git a/ensiie-project/docker-compose.yml b/ensiie-project/docker-compose.yml
new file mode 100644
index 0000000000000000000000000000000000000000..f63d6bf3475a48ff16a8a3da23044827d8ed38f3
--- /dev/null
+++ b/ensiie-project/docker-compose.yml
@@ -0,0 +1,63 @@
+version: '3'
+services:
+
+  nginx:
+    build: ./.docker/nginx-php
+    restart: "no"
+    depends_on:
+      - php
+    ports :
+      - "${NGINX_PORT}:80"
+    environment:
+      - "SERVER_NAME=${SERVER_NAME}"
+      - "PHP_ADDRESS=${PHP_ADDRESS}"
+      - "TZ=${TIMEZONE}"
+    volumes:
+      - ./public:/usr/share/nginx/html
+    networks:
+      - "ensiie"
+
+  php:
+    build:
+      context: ./.docker/php-fpm/
+      args:
+        DOCKER_USER: ${DOCKER_USER}
+        DOCKER_USER_ID: ${DOCKER_USER_ID}
+    restart: "no"
+    environment:
+      TZ: ${TIMEZONE}
+      XDEBUG_CONFIG: remote_host=${REMOTE_HOST}
+      SSH_AUTH_SOCK: /ssh-agent
+      DB_NAME: ${DB_USER}
+      DB_USER: ${DB_USER}
+      DB_PASSWORD: ${DB_PASSWORD}
+    volumes:
+      - .:/var/www/html
+      - $SSH_AUTH_SOCK:/ssh-agent
+    working_dir: /var/www/html
+    user: "${DOCKER_USER}"
+    entrypoint:
+      - ""
+    command:
+      - "php-fpm"
+    networks:
+      - "ensiie"
+
+  postgres:
+    build:
+      context: ./.docker/postgres
+    ports:
+      - ${DB_PORT_EXTERNAL}
+    environment:
+      - POSTGRES_USER=${DB_USER}
+      - POSTGRES_PASSWORD=${DB_PASSWORD}
+    volumes:
+      - ./postgres-data:/var/lib/postgresql/data
+      - .:/var/www/html
+    working_dir: /var/www/html
+    networks:
+      - "ensiie"
+
+networks:
+    ensiie:
+        driver: bridge
diff --git a/ensiie-project/document/Presentation.md b/ensiie-project/document/Presentation.md
new file mode 100644
index 0000000000000000000000000000000000000000..3b431509a5ee7fa3ca07a4a00b595343431e840a
--- /dev/null
+++ b/ensiie-project/document/Presentation.md
@@ -0,0 +1,140 @@
+![matters](https://cdn-images-1.medium.com/max/2000/1*Pl-fB1X01RfcEbPP-FVlew.jpeg)
+
+Projet web ENSIIE 1A 2018
+======
+
+Objectif pédagogique
+----------
+
+>Apprendre à concevoir et développer des applications web utilisant un serveur de bases de données.
+>Prendre conscience des problématiques d’organisation d’équipes et de répartition des tâches.
+
+Les sujets
+------------
+
+Nous proposons trois sujets qui seront détaillés ultérieurement et présentés lors de la première séance :
+
+* [Agenda des associations](sujets/agenda-des-associations.md)
+* [Accueil des nouveaux arrivants](/sujets/accueil-des-nouveaux-arrivants.md)
+* [Le twitter de l’ENSIIE](sujets/twittiie-le-twitter-de-ensiie.md)
+
+PROJET LIBRE
+-----
+
+>Vous pouvez également proposer votre propre sujet. Celui-ci devra être défini, au plus tard, à la fin de la première séance et devra être validé.
+
+Soyez imaginatifs ! Mais veillez, tout de même, à respecter les contraintes présentées ci-dessous. N’hésitez pas à imaginer des sujets qui pourraient vous servir (ou vos associations) au quotidien. Nous serons là pour vous accompagner au cours de la réalisation de ce projet, alors profitez-en !
+
+Must have
+-------
+
+### Les sujets devront tous proposer **au minimum**
+
+> * Une authentification
+> * Un compte administrateur donnant les droits à certaines fonctionnalités (au choix)
+> * Un profil utilisateur éditable
+> * Une base de données relationnelle :
+> * au moins 3 tables
+> * au moins une table de jointure ( n…n)
+> * au moins une jointure dans une requête
+> * des INSERT, DELETE, UPDATE, SELECT
+> * Un CRUD (Create Read Update Delete)
+
+Du javascript (au minimum validation JS des formulaires).
+Nous attendons de la part des élèves une véritable appropriation du sujet. Il ne suffira pas de remplir des cases à cocher pour avoir la moyenne, nous voulons voir une démarche d’ingénieur, pas d’exécutant.
+
+### Les technologies
+
+#### On oblige
+
+> * PHP 7.0
+> * PostgreSQL
+> * JavaScript
+
+#### On aimera
+
+> * Toutes les bonnes pratiques citées sur http://www.phptherightway.com/
+> * PHP 7.1+
+> * Les tests automatisés (unitaires, fonctionnels, de sécurité, de performance, …)
+> * Une API REST bien faite
+> * Les animations CSS parcimonieuses qui profitent à l’UX
+
+#### On n’aimera pas
+
+* Les frameworks (Zend Framework, Symfony, Angular, etc)
+* Le XML
+* jQuery utilisé n’importe comment
+* HTML5 utilisé n’importe comment
+
+### Séances
+
+> * **3 avril 2018** : choix du sujet, début des projets, présentation de Docker (documentation)
+> * **24 avril 2018** : point d’avancement, échange sur les bonnes pratiques, analyse du code
+> * **22 mai 2018** : soutenance, livraison des sources
+
+### La notation
+
+Une partie de la note sera attribuée par groupe, une autre réservée à l’investissement personnel.
+
+> Les points auxquels nous ferons attention lors de la notation :
+> * La méthodologie, quels vont être vos choix d’organisation ?
+> * La participation au sein de l’équipe, on attend que vous soyez moteur et que vous soyez force de proposition.
+> * La qualité technique du projet, nous voulons pouvoir comprendre votre code sans nous arracher les cheveux. Préférez peu de code bien fait avec des fonctionnalités complètes à une grosse quantité de code illisible, avec beaucoup de fonctionnalités copiées collées et/ou à moitié terminées.
+> * La soutenance du projet, nous souhaitons voir une soutenance dynamique. Pas de présentation point par point afin de vérifier que oui il y a bien une inscription et ou un CRUD. On veut voir que ça marche, on veut être convaincu et on veut se l’arracher votre projet. Encore moins une lecture de votre rapport.
+> * Le rapport du projet a un but complètement différent de la soutenance. La soutenance nous permet de voir le produit tel que vous avez imaginé son utilisation, le rapport nous permet de comprendre la partie interne du fonctionnement de votre groupe. Il est très important pour nous de bien comprendre quels ont été les enjeux de chaque groupe, quelles ont été les difficultés rencontrées et surtout quelles ont été les solutions trouvées pour les contourner.
+
+### L’environnement de développement
+
+Afin de s’affranchir de problème d’infrastructure, nous vous mettons à disposition un environnement de développement pour ce projet.
+>Lors du premier cours nous vous présenterons l'utilisation du git que nous avons mis à votre disposition ainsi que le fonctionnement d'un Docker entièrement configuré et prêt à être utilisé pour développer votre projet.
+
+### Le rendu des sources et du rapport
+
+>Les projets devront être pushé sur ce [repository git](https://github.com/Un3x/ensiie-project) sur une branche ```<nom-de-votre-groupe>-group```.
+
+**ATTENTION**: ce repo git n'as pas pour but d'être utilisé pendant le développement. Il s'agit de notre outil pour récupérer vos projets et pouvoir les utiliser. L'utilisation d'un git au cours du développement n'est pas obligatoire, mais nous vous encourageons à en utiliser un (github, arise, ensiie, bitbucket, gitlab etc)/
+
+> Le rapport doit être inclus dans les sources du projet, à la racine: ```/rapport.pdf```
+
+Toutefois, il serait dommage de rester bloquer sur le rendu donc préparez-vous avant et contactez nous le plus tôt possible en cas de problème.
+
+#### Le rapport
+
+> * Faire 10 pages maximum pour refléter le monde de l’entreprise où la concision est une qualité
+> * Expliquer l’approche mise en place, les problématiques rencontrées (techniques comme méthodes) et les solutions apportées
+> * Expliquer la répartition des rôles au sein de l’équipe
+> * La problématique à laquelle il répond.
+
+#### La soutenance
+
+Nous souhaitons simuler une séance plénière devant des investisseurs. Nous voulons que vous vous mettiez dans la peau d’une jeune startup devant vendre sa toute nouvelle application à un public d’investisseurs intéressés.
+Ce format de soutenance sera aussi une bonne occasion de se faire une première expérience de communication autour d’un projet.
+
+> * Présentation plénière (tous les groupes devant tout le monde)
+> * 8 minutes par groupe, pas une minute de plus
+> * Pure démo de l’application, pas de questions
+
+L’objectif est de vendre l’application aux personnes dans la salle, mode start-up **ACTIVÉ**
+La note de soutenance ne sera pas donnée le jour même
+
+> **Tout le monde doit être présent lors des soutenances.**
+
+Aussi, n’oubliez pas qu’on est là pour passer un bon moment, pas de lynchage, uniquement des critiques constructives. Nous comprenons également que le facteur stress peut jouer en votre défaveur en fonction de votre personnalité, aussi ne vous inquiétez pas car nous sommes conscients de cela et nous sommes là pour noter l’adéquation de chacun avec les attentes d’un ingénieur:
+
+> * Méthode
+> * Apprentissage
+> * Qualité du travail rendu
+> * Expression
+> * Adaptabilité
+
+### Notre équipe
+
+* Thomas COMES : ENSIIE promo 2012, Project Lead chez Matters.
+* Nassim Kirouane : Tech Lead chez Matters.
+* Remi Parpaillon : Php Gourou chez Matters.
+
+### Comment nous contacter
+
+Nous mettons un slack à votre disposition pour échanger avec nous. L'url vous sera communiqué lors du premier cours.
+
+Vous êtes également les bienvenus tous les jeudis après-midi dans nos locaux au 10 rue du Faubourg Poissonnière 75010 PARIS. Ce sera l’occasion de faire un peu plus connaissance, et d’assister à nos SteamLearn, les formations hebdo !
diff --git a/ensiie-project/document/sujets/accueil-des-nouveaux-arrivants.md b/ensiie-project/document/sujets/accueil-des-nouveaux-arrivants.md
new file mode 100644
index 0000000000000000000000000000000000000000..0c4886359e941c189def5b044656f2f56fde5e8b
--- /dev/null
+++ b/ensiie-project/document/sujets/accueil-des-nouveaux-arrivants.md
@@ -0,0 +1,67 @@
+![matters](https://cdn-images-1.medium.com/max/2000/1*Pl-fB1X01RfcEbPP-FVlew.jpeg)
+
+Accueil des petits nouveaux
+======
+
+Contexte du projet
+-----
+
+Les premiers jours à Evry, c’est pas toujours facile. On arrive dans une toute nouvelle ville, on ne connait personne, et la seule chose que l’on a à faire c’est d’aller à l’école.
+
+La vie serait tellement plus simple si les élèves s’entraidaient un peu plus pour échanger sur tout ce qu’il y a à savoir. Connaître les endroits importants dans la ville, connaître la répartition des salles de l’école, qui contacter lorsqu’on a tel ou tel problème, où retrouver le planning de l’école, comment fonctionne le bar, etc.
+
+### Pré-requis
+Comme pour tous les sujets, on devra au moins retrouver dans l’application finale les parties suivantes :
+
+> * Une authentification
+> * Un compte administrateur donnant les droits à certaines > * fonctionnalités (au choix)
+> * Un profil utilisateur éditable
+> * Une base de données relationnelle :
+> * au moins 3 tables
+> * au moins une table de jointure ( n…n)
+> * au moins une jointure dans une requête
+> * des INSERT, DELETE, UPDATE, SELECT
+> * Un CRUD (Create Read Update Delete)
+> * Du javascript (au minimum validation JS des formulaires)
+
+Nous attendons de la part des élèves une véritable appropriation du sujet. Il ne suffira pas de remplir des cases à cocher pour avoir la moyenne, nous voulons voir une démarche d’ingénieur, pas d’exécutant.
+
+### Objectifs
+
+Proposer une application qui va permettre d’assigner des élèves comme tuteurs d’autres nouveaux élèves et suivre leur découverte de la ville d’Evry et du fonctionnement de l’école.
+
+L’application devra donc gérer, un ensemble d’élèves, d’achievement, de types d’élèves, de types d’achievement.
+Les élèves pourront être des nouveaux arrivants, des administrateurs ou des tuteurs.
+Pour qu’un élève soit tuteur, il faut qu’il ait déjà été onboardé par d’autres tuteurs.
+
+Les administrateurs pourront désigner des élèves comme étant des tuteurs (pour l’initialisation principalement).
+Lorsqu’un nouvel arrivant s’inscrit, une liste d’achievement lui est automatiquement assignée ainsi que plusieurs tuteurs.
+
+Les nouveaux arrivants pourront attribuer un status à unachievement.
+Une fois que la liste d’achievement est complètement finie, le nouvel arrivant se voit promu au rang de tuteur et pourra être assigné à l’accueil d’un autre élève.
+Comme les nouveaux arrivants arrivent en masse, il faudra prévoir un système permettant d’importer une liste d’élèves (leur assigner un mot de passe, les achievement, les tuteurs).
+
+Certains achievement devront nécessiter des compétences spécifiques afin de pouvoir être faites (la présentation arise par exemple). Les tuteurs auront donc des compétences qui leur permettront de faire réaliser certains achievement avec les nouveaux arrivants. La validation d’un achievement nécessitant des compétences particulières n’est possible que si au moins 1 un des tuteurs possède cette compétence.
+
+### Les difficultés du projet
+
+Une gestion propre des status des élèves et des achievement nous permettra de voir clair dans les intentions que vous allez donner à ce projet. Faites bien attention à la syntaxe des status et soyez stratégique dans votre implémentation afin d’avoir un code propre. On se mêle rapidement les pinceaux.
+
+La gestion de déclenchement automatique peut s’avérer un problème. Il faudra bien vous mettre d’accord sur ce qui se passe et à quel moment.
+Si l’algorithme d’attribution automatique d’achievement n’est pas extrêmement complexe, l’attribution automatique des tuteurs tout en gérant les compétences requises pour la réalisation des achievement pourra s’avérer être un exercice plus difficile. Attention ici à bien faire les choses dans l’ordre (et proprement :)).
+
+### Propositions de features
+
+Comme pour tous les projets, vous pouvez choisir de l’adapter / de l’étoffer tant que tous les pré-requis sont remplis.
+
+Voici en exemple une petite liste de fonctionnalités qui pourraient être implémentées dans le cadre du projet :
+
+> * La gestion des compétences des étudiants par les administrateurs / autres tuteurs.
+> * La possibilité d’avoir différentes listes d’achievements initiaux en fonction de l’élève. Peut-être y aura-t-il différente chose à faire pour accueillir un élève en milieu d’année qu’en début d’année. Ou il y aura d’autres choses à montrer aux arrivants étrangers, aux FIPAS etc.
+> * La gestion des promotions. Les étudiants appartiennent à une promotion. Gérer les changements de promo.
+> * Le suivi de l’avancée de l’accueil d’une promo. Une page permettant de savoir quels élèves ont quels tuteurs et où ils en sont de l’avancée de leur onboarding.
+> * Ce sont ici bien évidemment des propositions de fonctionnalités supplémentaires, il y en a beaucoup d’autres qui pourraient être pertinentes dans le cadre du projet. Ces fonctionnalités dépendront des objectifs que vous souhaiterez donner à votre projet.
+
+Ce sont ici bien évidemment des propositions de fonctionnalités supplémentaires, il y en a beaucoup d’autres qui pourraient être pertinentes dans le cadre du projet. Ces fonctionnalités dépendront des objectifs que vous souhaiterez donner à votre projet.
+
+**Bon courage.**
\ No newline at end of file
diff --git a/ensiie-project/document/sujets/agenda-des-associations.md b/ensiie-project/document/sujets/agenda-des-associations.md
new file mode 100644
index 0000000000000000000000000000000000000000..8cfd62a001cbc2511c4a56d810c50196c9142263
--- /dev/null
+++ b/ensiie-project/document/sujets/agenda-des-associations.md
@@ -0,0 +1,71 @@
+![matters](https://cdn-images-1.medium.com/max/2000/1*Pl-fB1X01RfcEbPP-FVlew.jpeg)
+
+Agenda des associations
+=====
+
+Contexte du projet
+-----
+
+Les associations à l’écoles, ça nous connait. Le BdE, le bar, LudIIe, l’AS, ForumIIe, GalaxIIe etc. Et forcément, quand on est dans une association, on a besoin d’échanger de s’organiser et de se réunir.
+
+Etant donné que beaucoup d’élèves sont de petits cumulars et il est parfois difficile d’organiser des réunions où tout le monde pourra être présent (et encore, sans compter la multitude de raisons personnelles qu’il peut y avoir).
+Heureusement, l’agenda des associations sera bientôt là pour vous faciliter la vie. Grâce à cet agenda dédié aux associations vous pourrez savoir et gérer qui sera présent lors des réunions.
+
+### Pré-requis
+Comme pour tous les sujets, on devra au moins retrouver dans l’application finale les parties suivantes :
+
+> * Une authentification
+> * Un compte administrateur donnant les droits à certaines fonctionnalités (au choix)
+> * Un profil utilisateur éditable
+> * Une base de données relationnelle :
+> * au moins 3 tables
+> * au moins une table de jointure ( n…n)
+> * au moins une jointure dans une requête
+> * des INSERT, DELETE, UPDATE, SELECT
+> * Un CRUD (Create Read Update Delete)
+> * Du javascript (au minimum validation JS des formulaires)
+
+Nous attendons de la part des élèves une véritable appropriation du sujet. Il ne suffira pas de remplir des cases à cocher pour avoir la moyenne, nous voulons voir une démarche d’ingénieur, pas d’exécutant.
+
+### Objectifs
+
+Proposer une application qui va permettre d’organiser les réunions / événements associatifs.
+
+Dans ce projet il va falloir gérer, les élèves, les associations, les réunions et la participation des élèves à ces réunions.
+Les associations auront des adhérents qui pourront être soit des membres soit des administrateurs. Nous vous laissons le soin de mettre en place le modèle relationnel de données.
+
+Chaque élève pourra appartenir à une ou plusieurs associations, avec des rôles différents.
+
+Chaque élève aura un agenda personnalisé de ses réunions / événements à venir.
+
+> * Seuls les administrateurs des associations pourront créer des réunions
+> * Les élèves pourront dire s’ils participent à une réunion.
+> * Les status possibles des réunions seront Oui, Non, En attente de réponse.
+> * Les élèves seront notifiés des nouvelles réunions auxquelles ils doivent répondre.
+
+Si un élève a déjà une réunion à ce moment là, il en sera notifié (et ne pourra pas répondre présent aux deux réunions).
+
+### Les difficultés du projet
+
+La gestion des dates pourra aussi s’avérer être un challenge technique. Faites bien attention aux formats de dates que vous allez utiliser. Nous vous renvoyons vers PhpTheRightWay pour un premier aperçu de la gestion des dates en PHP.
+
+Il faudra aussi penser un affichage propre de l’agenda.
+Enfin, la gestion des statuts pourra s’avérer être un problème. Cela implique une gestion de droit au niveau de la participation aux réunions (qui peut être invité ?), mais aussi au niveau des administrateurs des associations qui seront les seuls à pouvoir créer des réunions ou événements.
+
+### Propositions de features
+
+Comme pour tous les projets, vous pouvez choisir de l’adapter / de l’étoffer tant que tous les pré-requis sont remplis. Vous pouvez choisir de faire un agenda sportif pour l’AS, un agenda des soirées etc.
+
+Voici en exemple une petite liste de fonctionnalités qui pourraient être implémentées dans le cadre du projet :
+
+> * Les administrateurs pourront voir l’agenda des réunions de toutes les associations.
+> * Lorsqu’un administrateur crée une réunion, l’agenda lui propose les créneaux où > tous les membres de l’association sont disponibles.
+> * Un système de notifications pour que les administrateurs soient au courant des > réponses de participation.
+> * Un envoi de mail automatique avant une réunion pour un rappel.
+> * Un mode réunion privée / réunion publique. En réunion privée, seuls les membres > pourront voir la réunion dans l’agenda, tandis que lors d’une réunion publique, tous > les élèves seront invités à participer (mais seuls les membres pourront répondre > présent ou non).
+> * Un mode d’annulation automatique des réunions 24h avant si moins de X personnes > répondent présent.
+> * Une synchronisation avec d’autres calendrier en ligne.
+
+Ce sont ici bien évidemment des propositions de fonctionnalités supplémentaires, il y en a beaucoup d’autres qui pourraient être pertinentes dans le cadre du projet. Ces fonctionnalités dépendront des objectifs que vous souhaiterez donner à votre projet.
+
+**Bon courage.**
\ No newline at end of file
diff --git a/ensiie-project/document/sujets/twittiie-le-twitter-de-ensiie.md b/ensiie-project/document/sujets/twittiie-le-twitter-de-ensiie.md
new file mode 100644
index 0000000000000000000000000000000000000000..80712bda39cd10195c81b0c06311b74508a6c198
--- /dev/null
+++ b/ensiie-project/document/sujets/twittiie-le-twitter-de-ensiie.md
@@ -0,0 +1,67 @@
+![matters](https://cdn-images-1.medium.com/max/2000/1*Pl-fB1X01RfcEbPP-FVlew.jpeg)
+
+Twitiie le twitter de l'ENSIIE
+=====
+
+Contexte du projet
+-------
+
+Twitter ne pourra pas toujours conserver son statut de leader du marché en termes de communication sociale. Il est temps de mettre fin à ce monopole.
+Je vous présente TwittIIe, l’application qui copie tout de twitter et qui va leur voler tout le marché.
+
+### Pré-requis
+
+Comme pour tous les sujets, on devra au moins retrouver dans l’application finale les parties suivantes :
+
+> * Une authentification
+> * Un compte administrateur donnant les droits à certaines fonctionnalités (au choix)
+> * Un profil utilisateur éditable
+> * Une base de données relationnelle :
+> * au moins 3 tables
+> * au moins une table de jointure ( n…n)
+> * au moins une jointure dans une requête
+> * des INSERT, DELETE, UPDATE, SELECT
+> * Un CRUD (Create Read Update Delete)
+> * Du javascript (au minimum validation JS des formulaires)
+
+Nous attendons de la part des élèves une véritable appropriation du sujet. Il ne suffira pas de remplir des cases à cocher pour avoir la moyenne, nous voulons voir une démarche d’ingénieur, pas d’exécutant.
+
+### Objectifs
+
+Proposer une application qui va permettre aux utilisateurs de communiquer via des messages augmentés.
+
+Dans ce projet il va falloir gérer, les élèves, les publications, les hashtags etc
+Les utilisateurs auront un feed d’activité et un feed de leur propre activité (mur perso etc).
+
+> * Les utilisateurs inscrits ont le droit de diffuser du contenu (limité en caractères, et avec un langage augmenté, émoticon, @, # ou autre)
+> * Les utilisateurs inscrits peuvent s’abonner aux contenu d’autres utilisateurs. Ce contenu apparaîtra alors dans leur feed d’activité.
+> * Les hashtag et les noms d’utilisateurs devront être cliquables afin de voir leur flux d’activité respectifs.
+> * Les administrateurs peuvent supprimer les publications. Les utilisateurs doivent faire une demande de suppression qui s’affichera dans une notification pour les administrateurs (tant qu’elle n’a pas été supprimée).
+> * Les utilisateurs peuvent ‘liker’ un message. Un contenu automatique pourrait alors être diffusé (tel utilisateur a ‘liké’ ce message, à diffuser sur le mur perso par exemple, ou sur une page dédiée).
+> * Les utilisateurs peuvent répondre à un message (et répondre à la réponse etc).
+
+Ce sont ici les features minimales que nous avons sélectionnées pour que le projet soit fonctionnel. Il conviendra de les adapter en fonction de la direction que vous souhaitez donner à votre projet.
+
+### Les difficultés du projet
+
+La première difficulté relative à ce sujet concernera évidement le parsing des messages afin de pouvoir rajouter des liens rapides vers les utilisateurs ou hastag. Attention à l’architecture de vos outils pour que le code soit propre.
+Enfin, dans ce genre de projet à but social il y a beaucoup d’écrans qui présentent la même donnée mais agencée de différentes façons. Avoir un bon modèle relationnel vous aidera à manipuler la données facilement. Essayez de prévoir !
+
+### Propositions de features
+
+Comme pour tous les projets, vous pouvez choisir de l’adapter / de l’étoffer tant que tous les pré-requis sont remplis. Vous pouvez choisir de faire un agenda sportif pour l’AS, un agenda des soirées etc.
+
+Voici en exemple une petite liste de fonctionnalités qui pourraient être implémentées dans le cadre du projet :
+
+> * Du contenu automatique pourrait être proposé aux nouveaux utilisateurs en fonction de leur goût (ou n’importe quel autre critère).
+> * La possibilité de partager le message de quelqu’un d’autre
+> * La possibilité d’envoyer un message privée à quelqu’un. En réponse d’un autre message par exemple.
+> * La possibilité de poster un message dans le futur. Ceci implique donc une bonne gestion des dates ainsi qu’une automatisation de l’envoi d’un post et d’une gestion de statut des messages.
+> * La possibilité d’afficher du contenu d’un autre format, comme des gifs ou des vidéos.
+> * Des accès rapides aux trendings topics (les hashtags sur lesquels il y a le plus d’activités).
+> * Une suggestion automatique des utilisateurs lorsqu’on écrit un @ et/ou des hashtag lorsqu’on a un # qui s’adapte à ce que l’utilisateur écrit.
+> * Ce sont ici bien évidemment des propositions de fonctionnalités supplémentaires, il y en a beaucoup d’autres qui pourraient être pertinentes dans le cadre du projet. Ces fonctionnalités dépendront des objectifs que vous souhaiterez donner à votre projet.
+
+Ce sont ici bien évidemment des propositions de fonctionnalités supplémentaires, il y en a beaucoup d’autres qui pourraient être pertinentes dans le cadre du projet. Ces fonctionnalités dépendront des objectifs que vous souhaiterez donner à votre projet.
+
+**Bon courage.**
\ No newline at end of file
diff --git a/ensiie-project/phpunit.xml b/ensiie-project/phpunit.xml
new file mode 100644
index 0000000000000000000000000000000000000000..abad26bee7a1e09d0bae5db13593507b9cdeaeec
--- /dev/null
+++ b/ensiie-project/phpunit.xml
@@ -0,0 +1,16 @@
+<phpunit
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/6.3/phpunit.xsd"
+        backupGlobals="true"
+        cacheTokens="false">
+    <testsuites>
+        <testsuite name="ensiie">
+            <directory>test</directory>
+        </testsuite>
+    </testsuites>
+    <filter>
+        <whitelist>
+            <directory suffix=".php">./src</directory>
+        </whitelist>
+    </filter>
+</phpunit>
\ No newline at end of file
diff --git a/ensiie-project/public/index.php b/ensiie-project/public/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..025bf597af4de4b489fd1a1e05678890ddad51c7
--- /dev/null
+++ b/ensiie-project/public/index.php
@@ -0,0 +1,43 @@
+<?php
+require '../vendor/autoload.php';
+
+//postgres
+$dbName = getenv('DB_NAME');
+$dbUser = getenv('DB_USER');
+$dbPassword = getenv('DB_PASSWORD');
+$connection = new PDO("pgsql:host=postgres user=$dbUser dbname=$dbName password=$dbPassword");
+
+$userRepository = new \User\UserRepository($connection);
+$users = $userRepository->fetchAll();
+?>
+
+<html>
+<head>
+    <!-- Latest compiled and minified CSS -->
+    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
+</head>
+<body>
+
+<div class="container">
+    <h3><?php echo 'Hello world from Docker! php' . PHP_VERSION; ?></h3>
+
+    <table class="table table-bordered table-hover table-striped">
+        <thead style="font-weight: bold">
+            <td>#</td>
+            <td>Firstname</td>
+            <td>Lastname</td>
+            <td>Age</td>
+        </thead>
+        <?php /** @var \User\User $user */
+        foreach ($users as $user) : ?>
+            <tr>
+                <td><?php echo $user->getId() ?></td>
+                <td><?php echo $user->getFirstname() ?></td>
+                <td><?php echo $user->getLastname() ?></td>
+                <td><?php echo $user->getAge() ?> years</td>
+            </tr>
+        <?php endforeach; ?>
+    </table>
+</div>
+</body>
+</html>
diff --git a/ensiie-project/src/User/User.php b/ensiie-project/src/User/User.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6fdba666cc991872c8883a4bd1239a155210039
--- /dev/null
+++ b/ensiie-project/src/User/User.php
@@ -0,0 +1,114 @@
+<?php
+namespace User;
+
+class User
+{
+    /**
+     * @var int
+     */
+    private $id;
+
+    /**
+     * @var string
+     */
+    private $firstname;
+
+    /**
+     * @var string
+     */
+    private $lastname;
+
+    /**
+     * @var \DateTimeInterface
+     */
+    private $birthday;
+
+    /**
+     * @return int
+     */
+    public function getId()
+    {
+        return $this->id;
+    }
+
+    /**
+     * @param int $id
+     * @return User
+     */
+    public function setId($id)
+    {
+        $this->id = $id;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getFirstname()
+    {
+        return $this->firstname;
+    }
+
+    /**
+     * @param string $firstname
+     * @return User
+     */
+    public function setFirstname($firstname)
+    {
+        $this->firstname = $firstname;
+        return $this;
+    }
+
+    /**
+     * @return string
+     */
+    public function getLastname()
+    {
+        return $this->lastname;
+    }
+
+    /**
+     * @param string $lastname
+     * @return User
+     */
+    public function setLastname($lastname)
+    {
+        $this->lastname = $lastname;
+        return $this;
+    }
+
+    /**
+     * @return \DateTimeInterface
+     */
+    public function getBirthday(): \DateTimeInterface
+    {
+        return $this->birthday;
+    }
+
+    /**
+     * @param \DateTimeInterface $birthday
+     * @return User
+     */
+    public function setBirthday(\DateTimeInterface $birthday)
+    {
+        $this->birthday = $birthday;
+        return $this;
+    }
+
+
+    /**
+     * @return int
+     * @throws \OutOfRangeException
+     */
+    public function getAge(): int
+    {
+        $now = new \DateTime();
+
+        if ($now < $this->getBirthday()) {
+            throw new \OutOfRangeException('Birthday in the future');
+        }
+
+        return $now->diff($this->getBirthday())->y;
+    }
+}
+
diff --git a/ensiie-project/src/User/UserRepository.php b/ensiie-project/src/User/UserRepository.php
new file mode 100644
index 0000000000000000000000000000000000000000..2d2e1dad2f3c909319263d1e27f8c6b344c3f5c6
--- /dev/null
+++ b/ensiie-project/src/User/UserRepository.php
@@ -0,0 +1,38 @@
+<?php
+namespace User;
+class UserRepository
+{
+    /**
+     * @var \PDO
+     */
+    private $connection;
+
+    /**
+     * UserRepository constructor.
+     * @param \PDO $connection
+     */
+    public function __construct(\PDO $connection)
+    {
+        $this->connection = $connection;
+    }
+
+    public function fetchAll()
+    {
+        $rows = $this->connection->query('SELECT * FROM "user"')->fetchAll(\PDO::FETCH_OBJ);
+        $users = [];
+        foreach ($rows as $row) {
+            $user = new User();
+            $user
+                ->setId($row->id)
+                ->setFirstname($row->firstname)
+                ->setLastname($row->lastname)
+                ->setBirthday(new \DateTimeImmutable($row->birthday));
+
+            $users[] = $user;
+        }
+
+        return $users;
+    }
+
+
+}
diff --git a/ensiie-project/test/unit/User/UserTest.php b/ensiie-project/test/unit/User/UserTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..334dbefc9b0939318b13e7b6e42ca84ee820b974
--- /dev/null
+++ b/ensiie-project/test/unit/User/UserTest.php
@@ -0,0 +1,38 @@
+<?php
+namespace User;
+
+use PHPUnit\Framework\TestCase;
+
+class UserTest extends TestCase
+{
+    /**
+     * @test
+     */
+    public function ageWhenBirthdayInThePast()
+    {
+        $user = new User();
+        $user->setBirthday(new \DateTime('-10 years'));
+        self::assertSame(10, $user->getAge());
+    }
+
+    /**
+     * @test
+     */
+    public function ageWhenBirthdayNow()
+    {
+        $user = new User();
+        $user->setBirthday(new \DateTime());
+        self::assertSame(0, $user->getAge());
+    }
+
+    /**
+     * @test
+     * @expectedException \OutOfRangeException
+     */
+    public function ageWhenBirthdayInTheFuture()
+    {
+        $user = new User();
+        $user->setBirthday(new \DateTime('+10 years'));
+        $user->getAge();
+    }
+}
\ No newline at end of file