Compare commits

..

107 Commits

Author SHA1 Message Date
Antoine PEREDERII 81795d40c1 Update '.drone.yml'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 8be7fb9957 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII b3e1236176 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII a13036b9de 🧪 Tests ok
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 19f37061e0 🧪 Test
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 67ef8fc923 Merge branch 'clean_web' of codefirst.iut.uca.fr:HeartDev/Web into clean_web
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 21781d8823 🧪 Test vendor
1 year ago
Antoine PEREDERII 490506fc2f Update '.drone.yml'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 6f94f85078 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII aa0b84f93a Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 627907ee20 Update 'Sources/composer.json'
continuous-integration/drone/push Build was killed Details
1 year ago
Antoine PEREDERII 1752ee572c Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII ddeb801574 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 820aecc0c3 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 8a522b7aca Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 455af64c2e Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII f9347f0467 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 8b4babf647 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII ba40a2a7a7 Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 5c5b7cd772 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 3168c184b0 Merge branch 'clean_web' of codefirst.iut.uca.fr:HeartDev/Web into clean_web
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII e38ed2bfc1 🐛 Rename function
1 year ago
Antoine PEREDERII 8b74458ec7 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 44468d8b5a Update 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII fb150e7785 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII a5cced8301 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII a11439e090 Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 334d36381a Update '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 3f16bfd356 Update '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
1 year ago
David D'ALMEIDA 2772384e78 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
1 year ago
David D'ALMEIDA 836a8cce35 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
1 year ago
David D'ALMEIDA 82189f9ad1 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA 0086129d89 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA 15bc641e45 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA 7140f82593 merge with API
1 year ago
David D'ALMEIDA ef572e5a2b merge with API
1 year ago
David D'ALMEIDA 78e5f5da18 merge with master
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA e70e49bdf3 Merge remote-tracking branch 'origin/clean_web' into clean_web
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA bc17822bf4 merge with master
1 year ago
David D'ALMEIDA aa089f2da8 merge with master
1 year ago
David D'ALMEIDA 371d6088f6 Mise à jour de '.drone.yml'
1 year ago
David D'ALMEIDA 046b921113 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA ae8f2df270 Creating clean_web branch with changes
1 year ago
Antoine PEREDERII 9d64b7de40 update some bugs
1 year ago
Antoine PEREDERII c9b2a2d6c9 I don't know
1 year ago
Antoine PEREDERII 5b7cdafdf4 add API
1 year ago
Antoine PEREDERII e86b3f7b00 🚧 🏗️ 💥 🧪 WORK IN PROGRESS ! Wait for WORK
1 year ago
Antoine PEREDERII 2efb321f6a update some parts with database
1 year ago
Antoine PEREDERII d3d6dbb12f 🚀 introduce charts
1 year ago
Antoine PEREDERII 114dd33a4f Merge remote-tracking branch 'origin/merged_PLE' into merging_APE
1 year ago
Antoine PEREDERII 6786eea1c4 add heartRate Graph
1 year ago
Antoine PEREDERII 59de72856f merge merged with merged_PLE
1 year ago
Antoine PEREDERII 9e57169ae6 test to add chart but not conclude
1 year ago
Antoine PEREDERII 90c43b08f2 Merge branch 'merged_PLE' of codefirst.iut.uca.fr:HeartDev/Web into merged_PLE
1 year ago
Antoine PEREDERII a691e2a952 add activity analyze
1 year ago
Paul LEVRAULT 23ccabbb71 Test ajout graphique
1 year ago
Antoine PEREDERII 1b18825afa update merged, add .env file to resolve this
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 1b4448fecd update activities
1 year ago
Paul LEVRAULT f844bfaca2 Merge branch 'merged_PLE' of https://codefirst.iut.uca.fr/git/HeartDev/Web into merged_PLE
1 year ago
Antoine PEREDERII 6585a92eb6 Merge branch 'merged_PLE' of codefirst.iut.uca.fr:HeartDev/Web into merged_PLE
1 year ago
Antoine PEREDERII 98eddfc9f7 update controllers
1 year ago
Paul LEVRAULT 07b223c633 correction de trucs
1 year ago
Paul LEVRAULT d092f7c318 Ajout de notif dans la BD
1 year ago
Paul LEVRAULT 39f5026f99 Correction AthleteMapper
1 year ago
Paul LEVRAULT ca3e2591f0 Correction AthleteMapper
1 year ago
Antoine PEREDERII 0093f21b81 update vues with database
1 year ago
Antoine PEREDERII 6e935ce864 add database on athlete page
1 year ago
Antoine PEREDERII 8473b52a96 Update '.drone.yml'
1 year ago
Antoine PEREDERII 0b4e76e66f add Training Entity and gateway
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA 9eb7074df5 push
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT de5f390af1 Merge
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 76c6b4b8d1 Ok il me faut une base de données
1 year ago
Paul LEVRAULT 16ee9a131e Ca marche pas et ca commence a m'enerver
1 year ago
Antoine PEREDERII 15b97837f7 update paul's branch with database link on search user
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT d4ee62ce18 test
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA adb9584cba work with APE
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT fe2dbded3b J'en ai marre
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT ae9744cde6 Merge remote-tracking branch 'origin/WORK-KMO-Gateway' into merged_PLE
1 year ago
Paul LEVRAULT 0ac615539b Merge remote-tracking branch 'origin/merged' into merged_PLE
1 year ago
Paul LEVRAULT 7c1824f072 Controlleur athlete quasi terminée
1 year ago
Paul LEVRAULT aa49d0960a Un autre truc
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 9ee8e90065 Truc de test
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 661b9c80cf athlete controller quasi fini
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT d0d1d4c23d auth Ctrl fini
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 24919e6ba5 La recherche de users fonctionne
continuous-integration/drone/push Build is failing Details
1 year ago
Kevin MONTEIRO fe12112ce6 Finition gateway Athlete Coach et Activite a tester mais normalement fonctionnel
continuous-integration/drone/push Build is failing Details
1 year ago
Kevin MONTEIRO aba0924f64 Gateways, Mappers et Entity pour Athlete et Coach a tester mais fonctionnel normalement
continuous-integration/drone/push Build is failing Details
1 year ago
David D'ALMEIDA f804820e85 exemple
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii c311825459 Merge branch 'merged' of https://codefirst.iut.uca.fr/git/HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii 8488240e9c update gestion de projet
1 year ago
Paul LEVRAULT 1aa8dcc9fa test
1 year ago
Kevin MONTEIRO af9821709c Grosse Amélioration Gateways, Mappers, Entity Athlète et Coach
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 09dafc90c0 merge terminé
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 64ecdf87f2 Merge remote-tracking branch 'origin/issue_032_models' into merged
1 year ago
Antoine PINAGOT c201ee9bff Finition de link route/controller
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 35cb501e47 Il reste le AuthController, et le Athlete
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 637c522959 Ajout route dans les bons controller (pas terminé)
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii 3a2b0dd405 Merge branch 'merged' of https://codefirst.iut.uca.fr/git/HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii 591bbe67c1 update GANTT Project
1 year ago
Antoine PEREDERII 4d67c66080 update oral diaporama
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii a9c5c28143 Merge branch 'merged' of https://codefirst.iut.uca.fr/git/HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii 3f17b380ee update GANTT project
1 year ago
Kevin MONTEIRO acf783143f Début Diapo Oral 2
continuous-integration/drone/push Build is failing Details
1 year ago
antoine.perederii f15e45e197 update real GANTT
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 1918025c2f update msProject
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT c0c7d6560f final page
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 637085afce update app and diagrams
continuous-integration/drone/push Build is failing Details
1 year ago

@ -1,6 +1,6 @@
kind: pipeline
type: docker
name: HeartWave
name: HeartTrack
trigger:
event:
@ -14,9 +14,10 @@ steps:
- cd Sources
- rm -r vendor
- rm composer.lock
#- apk update && apk add --no-cache libcouchbase-dev && pecl install couchbase && docker-php-ext-enable couchbase
# Installe les dépendances PHP si nécessaire
- php composer.phar install --no-interaction
- ./vendor/bin/phpunit tests
# - ./vendor/bin/phpunit tests
# Sonar static code analisis deployment
# TODO : use an image that already have unzip
@ -35,16 +36,16 @@ steps:
- export SONAR_SCANNER_OPTS="-server"
- cd Sources
- sonar-scanner -D sonar.projectKey=HeartTrack -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
depends_on: [ test ]
#depends_on: [ test ]
# build image and push on the registry ✔️
- name: rewrite-urls
image: 'busybox:latest'
commands:
- cd Sources
- ls
- >-
find . -type f -exec sed -i -r
"s@(href|src)=\"/@\1=\"$${PLUGIN_CONTAINER_PATH}@g" {} +
#- >-
# find . -type f -exec sed -i -r
# "s@(href|src)=\"/@\1=\"$${PLUGIN_CONTAINER_PATH}@g" {} +
settings:
container_path: https://codefirst.iut.uca.fr/containers/HeartDev-web/
@ -71,20 +72,7 @@ steps:
IMAGENAME: 'hub.codefirst.iut.uca.fr/david.d_almeida/web:latest'
CONTAINERNAME: web
COMMAND: create
OVERWRITE: true
ADMINS: david.d_almeida
#OVERWRITE: true
ADMINS: davidd_almeida,kevinmonteiro,antoineperederii,paullevrault,antoinepinagot
depends_on:
- docker-build-and-push
- name: notify
image: ruby:2.1
when:
status: [ success ]
ref:
include:
- refs/tags/*-demo
commands:
- sh ./notifymail.sh
depends_on: [ docker-build-and-push ]

@ -11,6 +11,7 @@ entity "Athlète" as athlete {
poids
motDePasse
dateNaissance
isCoach
}
entity "Amitié" as friendship{
@ -28,11 +29,7 @@ entity "Notification" as notif {
#athleteId
}
entity "Coach" as coach {
{static} idCoach
// attributs spécifiques au coach
#athleteId
}
entity "Statistique" as stats {
{static} idStatistique
@ -52,7 +49,7 @@ entity "Entraînement" as training {
latitude
longitude
feedback
#coachId
#athleteId
}
entity "Participe" as takepart {
@ -101,13 +98,12 @@ entity "FréquenceCardiaque" as fc {
activity --> athlete
activity --> source
activity <-- fc
coach --> athlete
athlete <-- source
stats --> athlete
takepart --> athlete
takepart --> training
friendship --> athlete
notif --> athlete
coach <-- training
athlete <-- training
athlete <-- friendship
@enduml

@ -179,10 +179,9 @@ athlete <-- friendship
```plantuml
@startuml
skinparam classAttributeIconSize 0
package MCD{
entity "Athlete" as athlete {
{static} idAthlete
class Athlete {
idAthlete
username
nom
prenom
@ -195,45 +194,65 @@ entity "Athlete" as athlete {
isCoach
}
entity "Notification" as notif {
{static} idNotif
class Amitie {
idAthlete1
idAthlete2
}
class Notification {
idNotif
message
date
statut
urgence
#athleteId
athleteId
}
entity "Statistique" as stats {
{static} idStatistique
class Envoi {
idAthlete
idNotif
}
class Statistique {
idStatistique
poids
fcMoyenne
fcMax
caloriesBruleesMoy
date
#athleteId
athleteId
}
entity "Entrainement" as training {
{static} idEntrainement
class Entrainement {
idEntrainement
date
description
latitude
longitude
feedback
#athleteId
athleteId
}
entity "SourceDonnee" as source {
{static} idSource
class Participe {
athleteId
entrainementId
}
class Donne {
coachId
entrainementId
}
class SourceDonnee {
idSource
type
modele
precision
#athleteId
athleteId
}
entity "Activite" as activity {
{static} idActivité
class Activite {
idActivite
type
date
heureDeDebut
@ -246,31 +265,29 @@ entity "Activite" as activity {
maximum
minimum
temperatureMoyenne
#athleteId
#sourceId
athleteId
sourceId
}
entity "FréquenceCardiaque" as fc {
{static} idFc
class FrequenceCardiaque {
idFc
altitude
temps : time
température
temps
temperature
bpm
longitude
latitude
#activitéId
activiteId
}
}
activity "0..n" --- "1..1" athlete : réalise
activity "1..n" --- "1..1" source : possede
activity "1..1" --- "1..n" fc : enregistre
athlete "1..n" --- "0..1" source : possede
stats "0..n" --- "1..1" athlete : possede
training "0..n" --- "1..n" athlete : participe
training "0..n" --- "1..1" athlete : donne
athlete "0..n" --- "1..n" athlete : est ami
notif "0..n" --- "1..n" athlete : recoit
notif "0..n" --- "1..1" athlete : envoie
Athlete "1" --o "0..*" Amitie
Athlete "1" --o "0..*" Notification
Athlete "1" --o "0..*" Statistique
Athlete "1" --o "0..*" Entrainement
Entrainement "0..*" --o "0..*" Athlete : Participants
Entrainement "0..*" --o "0..*" Athlete : Coachs
Athlete "1" --o "0..*" SourceDonnee
Activite "1" --o "0..*" FrequenceCardiaque
@enduml
```

@ -18,7 +18,7 @@ Bienvenue dans le cœur de notre système, où les données prennent vie à trav
- **NotificationRepository :** Responsable de la gestion des notifications, assurant un accès structuré et une manipulation sécurisée de ces informations cruciales.
- **RelationshipRequestRepository :** Facilite la gestion des demandes de relations entre utilisateurs (amitiés), garantissant une interaction claire et ordonnée au sein de l'application.
- **RelationshipRequestRepository :** Facilite la gestion des demandes de relations entre utilisateurs, garantissant une interaction claire et ordonnée.
- **TrainingRepository :** Permet l'accès et la manipulation des données liées aux entraînements, facilitant le suivi des performances athlétiques.
@ -26,7 +26,7 @@ Explorez ce diagramme pour découvrir la robustesse de notre architecture de ges
```plantuml
@startuml couche_acces_aux_donnees
interface IGenericRepository {
abstract class IGenericRepository {
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -71,8 +71,7 @@ Documentation et informations à propos de `HearthTrack` disponible [ici]()
### Prerequisites
* [Visual Studio code](https://code.visualstudio.com/) - exemple d'IDE gratuit
* [Git](https://git-scm.com/) - Versioning
* [XAMPP : X, Apache, MySQL, Perl, PHP](https://www.apachefriends.org/fr/index.html) - Languages
* [PostgreSQL](https://www.postgresql.org/) - Base de Donnée
* [XAMPP : X, Apache, MySQL, Perl, PHP](https://www.apachefriends.org/fr/index.html) - Langages
## Getting Started
1. Cloner le répos

@ -24,7 +24,8 @@
"Shared\\Exception\\": "src/shared/exception",
"Shared\\Attributes\\": "src/shared/attributes",
"App\\Views\\Directives\\": "src/app/views/directives",
"Data\\Core\\": "src/data/core/"
"Data\\Core\\": "src/data/core/",
"Database\\": "src/data/core/database"
}
},
"require": {
@ -34,6 +35,9 @@
"psr/container": "^2.0",
"adriangibbons/php-fit-file-analysis": "^3.2.0"
},
"config": {
"process-timeout": 2000
},
"require-dev": {
"phpunit/phpunit": "*"
},

549
Sources/composer.lock generated

File diff suppressed because it is too large Load Diff

@ -28,4 +28,4 @@ RUN composer install
EXPOSE 80
CMD ["apache2-foreground"]
CMD composer dev

@ -0,0 +1,17 @@
FROM php:8.2-fpm
# Installation de dépendances nécessaires pour Composer
RUN apt-get update && apt-get install -y \
git \
unzip
# Installation de Composer
# TODO : should use a image with composer install
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN docker-php-ext-install pdo pdo_mysql
COPY . /var/www/
WORKDIR /var/www/
RUN composer install

@ -5,18 +5,18 @@ use Shared\Log;
$dotenv = Dotenv::createUnsafeImmutable(__DIR__,'.env');
$dotenv->safeLoad();
// echo($_ENV);
// apenrently getEnv is not a good thing cause
// const DB_HOST = $_ENV['DB_HOST'] ?? 'localhost';
// const DB_DATABASE = $_ENV['DB_DATABASE'] ?? 'heartTrack';
// const DB_USER = $_ENV['DB_USER'] ?? 'toto';
// const DB_PASSWORD = $_ENV['DB_PASSWORD'] ?? 'achanger';
define("APP_ENV", 'development');
const DB_HOST = 'localhost';
const DB_DATABASE = 'heartTrack';
const DB_USER = 'toto';
const DB_PASSWORD = 'achanger';
define("APP_ENV", getenv('APP_ENV'));
const DB_HOST = 'mysql';
const DB_DATABASE = 'test';
const DB_USER = 'user';
const DB_PASSWORD = 'pass';
//const APP_ENV = 'console';
const DSN = "mysql:host=" . DB_HOST . ";dbname=" . DB_DATABASE;

@ -1,19 +1,28 @@
server {
listen 80;
index index.php index.html index.htm;
root /usr/share/nginx/html;
index index.php;
root /var/www/public;
error_page 404 /index.php;
location ~ ^/(images|javascript|js|css|flash|media|static)/ {
root /var/www/public;
}
location ~ \.php$ {
fastcgi_pass web:9000; # service name defined in docker-compose.yml file like web
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
include fastcgi_params;
}
location ~ /\. {
deny all;
access_log off;
log_not_found off;
}
location / {
root /usr/share/nginx/html;
try_files $uri /index.php;
try_files $uri $uri/ /index.php?$query_string;
}
}

@ -71,7 +71,7 @@ class ActiviteEntity {
}
// Setters
public function setIdActivite($idActivite) {
public function setIdActivite($idActivity) {
$this->idActivity = $idActivity;
}

@ -0,0 +1,91 @@
<?php
namespace Database;
class AthleteEntity {
private $idAthlete;
private $nom;
private $prenom;
private $email;
private $sexe;
private $taille;
private $poids;
private $motDePasse;
private $dateNaissance;
// Getters
public function getIdAthlete() {
return $this->idAthlete;
}
public function getNom() {
return $this->nom;
}
public function getPrenom() {
return $this->prenom;
}
public function getEmail() {
return $this->email;
}
public function getSexe() {
return $this->sexe;
}
public function getTaille() {
return $this->taille;
}
public function getPoids() {
return $this->poids;
}
public function getMotDePasse() {
return $this->motDePasse;
}
public function getDateNaissance() {
return $this->dateNaissance;
}
// Setters
public function setIdAthlete($idAthlete) {
$this->idAthlete = $idAthlete;
}
public function setNom($nom) {
$this->nom = $nom;
}
public function setPrenom($prenom) {
$this->prenom = $prenom;
}
public function setEmail($email) {
$this->email = $email;
}
public function setSexe($sexe) {
$this->sexe = $sexe;
}
public function setTaille($taille) {
$this->taille = $taille;
}
public function setPoids($poids) {
$this->poids = $poids;
}
public function setMotDePasse($motDePasse) {
$this->motDePasse = $motDePasse;
}
public function setDateNaissance($dateNaissance) {
$this->dateNaissance = $dateNaissance;
}
}
?>

@ -0,0 +1,131 @@
<?php
namespace Database;
use \PDO;
class AthleteGateway {
private $connection;
public function __construct(Connexion $connection) {
$this->connection = $connection;
}
public function getAthlete() {
$query = "SELECT * FROM Athlete";
return $this->connection->executeWithErrorHandling($query);
}
public function getAthleteById(int $userId) {
$query = "SELECT * FROM Athlete WHERE idAthlete = :id";
$params = [':id' => [$userId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByName(string $name) {
$query = "SELECT * FROM Athlete WHERE nom = :name";
$params = [':name' => [$name, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByFirstName(string $firstName) {
$query = "SELECT * FROM Athlete WHERE prenom = :firstName";
$params = [':firstName' => [$firstName, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByEmail(string $email) {
$query = "SELECT * FROM Athlete WHERE email = :email";
$params = [':email' => [$email, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByGender(string $gender) {
$query = "SELECT * FROM Athlete WHERE sexe = :gender";
$params = [':gender' => [$gender, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByHeight(int $height) {
$query = "SELECT * FROM Athlete WHERE taille = :height";
$params = [':height' => [$height, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByWeight(int $weight) {
$query = "SELECT * FROM Athlete WHERE poids = :weight";
$params = [':weight' => [$weight, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByBirthDate(string $birthdate) {
$query = "SELECT * FROM Athlete WHERE dateNaissance = :birthdate";
$params = [':birthdate' => [$birthdate, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addAthlete(AthleteEntity $athlete) {
$query = "INSERT INTO Athlete (nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance)
VALUES (:nom, :prenom, :email, :sexe, :taille, :poids, :motDePasse, :dateNaissance)";
$params = [
':nom' => $athlete->getNom(),
':prenom' => $athlete->getPrenom(),
':email' => $athlete->getEmail(),
':sexe' => $athlete->getSexe(),
':taille' => $athlete->getTaille(),
':poids' => $athlete->getPoids(),
':motDePasse' => $athlete->getMotDePasse(),
':dateNaissance' => $athlete->getDateNaissance(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateAthlete(AthleteEntity $oldAthlete, AthleteEntity $newAthlete) {
$query = "UPDATE Athlete
SET nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance
WHERE idAthlete = :idAthlete";
$params = [
':idAthlete' => $oldAthlete->getIdAthlete(),
':nom' => $newAthlete->getNom(),
':prenom' => $newAthlete->getPrenom(),
':email' => $newAthlete->getEmail(),
':sexe' => $newAthlete->getSexe(),
':taille' => $newAthlete->getTaille(),
':poids' => $newAthlete->getPoids(),
':motDePasse' => $newAthlete->getMotDePasse(),
':dateNaissance' => $newAthlete->getDateNaissance(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteAthlete(int $idAthlete) {
$query = "DELETE FROM Athlete WHERE idAthlete = :idAthlete";
$params = [
':idAthlete' => $idAthlete,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
}
// Exemple d'utilisation
//$dsn = "pgsql:host=localhost;port=5432;dbname=mydatabase;user=myuser;password=mypassword";
//$connection = new Connection($dsn);
//$gateway = new AthleteGateway($connection);
//$allAth = $gateway->getAthlete();
//print_r($allAth);
//$singleAth = $gateway->getAthleteById(1);
//print_r($singleAth);
?>

@ -0,0 +1,99 @@
<?php
namespace Database;
use Model\User;
use \PDO;
use \DateTime;
use Model\Role;
use Model\Athlete;
class AthleteMapper {
public function fromSqlToEntity(array $data): array {
$athleteEntities = [];
foreach ($data as $athleteData) {
$athlete = new AthleteEntity();
if (isset($athleteData['idAthlete'])) {
$athlete->setIdAthlete($athleteData['idAthlete']);
}
if (isset($athleteData['nom'])) {
$athlete->setNom($athleteData['nom']);
}
if (isset($athleteData['prenom'])) {
$athlete->setPrenom($athleteData['prenom']);
}
if (isset($athleteData['email'])) {
$athlete->setEmail($athleteData['email']);
}
if (isset($athleteData['sexe'])) {
$athlete->setSexe($athleteData['sexe']);
}
if (isset($athleteData['taille'])) {
$athlete->setTaille($athleteData['taille']);
}
if (isset($athleteData['poids'])) {
$athlete->setPoids($athleteData['poids']);
}
if (isset($athleteData['motDePasse'])) {
$athlete->setMotDePasse($athleteData['motDePasse']);
}
if (isset($athleteData['dateNaissance'])) {
$athlete->setDateNaissance($athleteData['dateNaissance']);
}
$athleteEntities[] = $athlete;
}
return $athleteEntities;
}
public function athleteEntityToModel(AthleteEntity $athleteEntity): User {
$role = new Athlete(); // Utilisez la classe Athlete
$dateSpecifique = $athleteEntity->getDateNaissance();
$date = new DateTime($dateSpecifique);
$user = new User(
$athleteEntity->getIdAthlete(),
$athleteEntity->getNom(),
$athleteEntity->getPrenom(),
$athleteEntity->getEmail(),
$athleteEntity->getMotDePasse(),
$athleteEntity->getSexe(),
$athleteEntity->getTaille(),
$athleteEntity->getPoids(),
$date,
$role
);
return $user;
}
public function athleteToEntity(User $user):AthleteEntity{
$ath = new AthleteEntity();
$ath->setIdAthlete($user->getId());
$ath->setNom($user->getNom());
$ath->setPrenom($user->getPrenom());
$ath->setEmail($user->getEmail());
$ath->setSexe($user->getSexe());
$ath->setTaille($user->getTaille());
$ath->setPoids($user->getPoids());
$ath->setMotDePasse($user->getMotDePasse());
$ath->setDateNaissance($user->getDateNaissance());
return $ath;
}
}
?>

@ -0,0 +1,91 @@
<?php
namespace Database;
class CoachEntity {
private $idCoach;
private $nom;
private $prenom;
private $email;
private $sexe;
private $taille;
private $poids;
private $motDePasse;
private $dateNaissance;
// Getters
public function getIdCoach() {
return $this->idCoach;
}
public function getNom() {
return $this->nom;
}
public function getPrenom() {
return $this->prenom;
}
public function getEmail() {
return $this->email;
}
public function getSexe() {
return $this->sexe;
}
public function getTaille() {
return $this->taille;
}
public function getPoids() {
return $this->poids;
}
public function getMotDePasse() {
return $this->motDePasse;
}
public function getDateNaissance() {
return $this->dateNaissance;
}
// Setters
public function setIdCoach($idCoach) {
$this->idCoach = $idCoach;
}
public function setNom($nom) {
$this->nom = $nom;
}
public function setPrenom($prenom) {
$this->prenom = $prenom;
}
public function setEmail($email) {
$this->email = $email;
}
public function setSexe($sexe) {
$this->sexe = $sexe;
}
public function setTaille($taille) {
$this->taille = $taille;
}
public function setPoids($poids) {
$this->poids = $poids;
}
public function setMotDePasse($motDePasse) {
$this->motDePasse = $motDePasse;
}
public function setDateNaissance($dateNaissance) {
$this->dateNaissance = $dateNaissance;
}
}
?>

@ -0,0 +1,109 @@
<?php
namespace Database;
use \PDO;
class CoachGateway {
private $connection;
public function __construct(Connexion $connection) {
$this->connection = $connection;
}
public function getCoach() {
$query = "SELECT * FROM Athlete WHERE isCoach = TRUE;";
return $this->connection->executeWithErrorHandling($query);
}
public function getCoachById(int $userId) {
$query = "SELECT * FROM Athlete WHERE idAthlete = :id AND isCoach = TRUE";
$params = [':id' => [$userId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByName(string $name) {
$query = "SELECT * FROM Athlete WHERE nom = :name AND isCoach = TRUE";
$params = [':name' => [$name, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByFirstName(string $firstName) {
$query = "SELECT * FROM Athlete WHERE prenom = :firstName AND isCoach = TRUE";
$params = [':firstName' => [$firstName, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByEmail(string $email) {
$query = "SELECT * FROM Athlete WHERE email = :email AND isCoach = TRUE";
$params = [':email' => [$email, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByGender(string $gender) {
$query = "SELECT * FROM Athlete WHERE sexe = :gender AND isCoach = TRUE";
$params = [':gender' => [$gender, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByHeight(int $height) {
$query = "SELECT * FROM Athlete WHERE taille = :height AND isCoach = TRUE";
$params = [':height' => [$height, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByBirthDate(string $birthdate) {
$query = "SELECT * FROM Athlete WHERE dateNaissance = :birthdate AND isCoach = TRUE";
$params = [':birthdate' => [$birthdate, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addCoach(CoachEntity $coach) {
$query = "INSERT INTO Athlete (nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance, isCoach)
VALUES (:nom, :prenom, :email, :sexe, :taille, :poids, :motDePasse, :dateNaissance, TRUE)";
$params = [
':nom' => $coach->getNom(),
':prenom' => $coach->getPrenom(),
':email' => $coach->getEmail(),
':sexe' => $coach->getSexe(),
':taille' => $coach->getTaille(),
':poids' => $coach->getPoids(),
':motDePasse' => $coach->getMotDePasse(),
':dateNaissance' => $coach->getDateNaissance(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateCoach(CoachEntity $oldCoach, CoachEntity $newCoach) {
$query = "UPDATE Athlete
SET nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance, isCoach = TRUE
WHERE idCoach = :idCoach";
$params = [
':idAthlete' => $oldCoach->getIdCoach(),
':nom' => $newCoach->getNom(),
':prenom' => $newCoach->getPrenom(),
':email' => $newCoach->getEmail(),
':sexe' => $newCoach->getSexe(),
':taille' => $newCoach->getTaille(),
':poids' => $newCoach->getPoids(),
':motDePasse' => $newCoach->getMotDePasse(),
':dateNaissance' => $newCoach->getDateNaissance(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteCoach(int $idCoach) {
$query = "DELETE FROM Athlete WHERE idAthlete = :idCoach";
$params = [
':idCoach' => $idCoach,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
}

@ -0,0 +1,62 @@
<?php
namespace Database;
use Model\User;
use \PDO;
use \DateTime;
use Model\Role;
use Model\Coach;
class CoachMapper {
public function map(array $data) {
$coach = new CoachEntity();
$coach->setIdCoach($data['idCoach']);
$coach->setNom($data['nom']);
$coach->setPrenom($data['prenom']);
$coach->setEmail($data['email']);
$coach->setSexe($data['sexe']);
$coach->setTaille($data['taille']);
$coach->setPoids($data['poids']);
$coach->setMotDePasse($data['motDePasse']);
$coach->setDateNaissance($data['dateNaissance']);
return $coach;
}
public function CoachEntityToModel(CoachEntity $coachEntity):User{
$role = "Coach";
$user = new User(
$coachEntity->getIdCoach(),
$coachEntity->getNom(),
$coachEntity->getPrenom(),
$coachEntity->getEmail(),
$coachEntity->getMotDePasse(),
$coachEntity->getSexe(),
$coachEntity->getTaille(),
$coachEntity->getPoids(),
$coachEntity->getDateNaissance(),
$role
);
return $user;
}
public function CoachToEntity(User $user):CoachEntity{
$coach = new CoachEntity();
$coach->setIdCoach($user->getId());
$coach->setNom($user->getNom());
$coach->setPrenom($user->getPrenom());
$coach->setEmail($user->getEmail());
$coach->setSexe($user->getSexe());
$coach->setTaille($user->getTaille());
$coach->setPoids($user->getPoids());
$coach->setMotDePasse($user->getMotDePasse());
$coach->setDateNaissance($user->getDateNaissance());
return $coach;
}
}
?>

@ -0,0 +1,49 @@
<?php
namespace Database;
class Connexion extends \PDO {
private $stmt;
public function __construct(string $dsn,string $username, string $password) {
try {
parent::__construct($dsn,$username,$password);
$this->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
} catch (\PDOException $e) {
// Log error or handle it as needed
throw new \PDOException("Error connecting to the database: " . $e->getMessage());
}
}
public function executeQuery(string $query, array $parameters = []): bool {
$this->stmt = $this->prepare($query);
//foreach ($parameters as $name => $value) {
// $this->stmt->bindValue($name, $value[0], $value[1]);
//}
foreach ($parameters as $name => $value) {
$bindValueResult = $this->stmt->bindValue($name, $value, \PDO::PARAM_STR);
if (!$bindValueResult) {
// Gérez l'erreur, par exemple, en lançant une exception.
throw new \PDOException('Failed to bind value for parameter ' . $name);
}
}
return $this->stmt->execute();
}
public function executeWithErrorHandling(string $query, array $params = []): array {
try {
$this->beginTransaction();
$this->executeQuery($query, $params);
$this->commit();
return $this->getResults();
} catch (\PDOException $e) {
$this->rollBack();
throw new \PDOException('Unexpected error on database client: ' . $e->getMessage());
}
}
public function getResults(): array {
return $this->stmt->fetchAll(\PDO::FETCH_ASSOC);
}
}
?>

@ -0,0 +1,133 @@
DROP TABLE IF EXISTS Athlete, Friendship, Notification, Statistique, Entrainement, Participe, SourceDonnee, Activite, FrequenceCardiaque CASCADE;
CREATE TABLE Athlete (
idAthlete INT PRIMARY KEY,
nom VARCHAR(255),
prenom VARCHAR(255),
email VARCHAR(255) UNIQUE,
sexe CHAR(1),
taille DECIMAL,
poids DECIMAL,
motDePasse VARCHAR(255),
dateNaissance DATE,
isCoach BOOLEAN
);
CREATE TABLE Friendship (
idAthlete1 INT,
idAthlete2 INT,
debut DATE,
PRIMARY KEY (idAthlete1, idAthlete2),
FOREIGN KEY (idAthlete1) REFERENCES Athlete(idAthlete),
FOREIGN KEY (idAthlete2) REFERENCES Athlete(idAthlete)
);
CREATE TABLE Notification (
idNotif INT PRIMARY KEY,
message TEXT,
date DATE,
statut BOOLEAN,
urgence INT,
athleteId INT,
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete)
);
CREATE TABLE Statistique (
idStatistique INT PRIMARY KEY,
poids DECIMAL,
fcMoyenne DECIMAL,
fcMax DECIMAL,
caloriesBruleesMoy DECIMAL,
date DATE,
athleteId INT,
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete)
);
CREATE TABLE Entrainement (
idEntrainement INT PRIMARY KEY,
date DATE,
description TEXT,
latitude DECIMAL,
longitude DECIMAL,
feedback TEXT,
athleteId INT,
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete)
);
CREATE TABLE Participe (
athleteId INT,
entrainementId INT,
PRIMARY KEY (athleteId, entrainementId),
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete),
FOREIGN KEY (entrainementId) REFERENCES Entrainement(idEntrainement)
);
CREATE TABLE SourceDonnee (
idSource INT PRIMARY KEY,
type VARCHAR(255),
modele VARCHAR(255),
precision2 DECIMAL,
athleteId INT,
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete)
);
CREATE TABLE Activite (
idActivite INT PRIMARY KEY,
type VARCHAR(255),
date DATE,
heureDeDebut TIME,
heureDeFin TIME,
effortRessent DECIMAL,
variabilite DECIMAL,
variance DECIMAL,
ecartType DECIMAL,
moyenne DECIMAL,
maximum DECIMAL,
minimum DECIMAL,
temperatureMoyenne DECIMAL,
athleteId INT,
sourceId INT,
FOREIGN KEY (athleteId) REFERENCES Athlete(idAthlete),
FOREIGN KEY (sourceId) REFERENCES SourceDonnee(idSource)
);
CREATE TABLE FrequenceCardiaque (
idFc INT PRIMARY KEY,
altitude DECIMAL,
temps TIME,
temperature DECIMAL,
bpm INT,
longitude DECIMAL,
latitude DECIMAL,
activiteId INT,
FOREIGN KEY (activiteId) REFERENCES Activite(idActivite)
);
INSERT INTO Athlete (idAthlete, nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance, isCoach) VALUES
(1, 'Doe', 'John', 'john.doe@example.com', 'M', 1.80, 70, 'password123', '1990-01-01', FALSE),
(2, 'Smith', 'Jane', 'jane.smith@example.com', 'F', 1.65, 60, 'password456', '1992-02-02', TRUE);
INSERT INTO Friendship (idAthlete1, idAthlete2, debut) VALUES
(1, 2, '2023-01-01');
INSERT INTO Notification (idNotif, message, date, statut, urgence, athleteId) VALUES
(1, 'Training session at 10 AM', '2023-03-10', TRUE, 1, 1);
INSERT INTO Statistique (idStatistique, poids, fcMoyenne, fcMax, caloriesBruleesMoy, date, athleteId) VALUES
(1, 70, 80, 150, 500, '2023-03-10', 1);
INSERT INTO Entrainement (idEntrainement, date, description, latitude, longitude, feedback, athleteId) VALUES
(1, '2023-03-12', 'Long run in the park', 40.7128, -74.0060, 'Good effort', 1);
INSERT INTO Participe (athleteId, entrainementId) VALUES
(1, 1);
INSERT INTO SourceDonnee (idSource, type, modele, precision2, athleteId) VALUES
(1, 'Heart Rate Monitor', 'HRM-Pro', 98.5, 1);
INSERT INTO Activite (idActivite, type, date, heureDeDebut, heureDeFin, effortRessent, variabilite, variance, ecartType, moyenne, maximum, minimum, temperatureMoyenne, athleteId, sourceId) VALUES
(1, 'Running', '2023-03-10', '08:00:00', '09:00:00', 7, 0.5, 1, 0.1, 140, 160, 120, 20, 1, 1);
INSERT INTO FrequenceCardiaque (idFc, altitude, temps, temperature, bpm, longitude, latitude, activiteId) VALUES
(1, 100, '08:15:00', 15, 130, -74.0060, 40.7128, 1);

@ -15,7 +15,7 @@ services:
web:
build:
context: .
dockerfile: ./config/Dockerfile
dockerfile: ./config/Dockerfile.local
ports:
- 9000:9000
volumes:
@ -40,3 +40,5 @@ services:
MYSQL_PASSWORD: pass
ports:
- "3307:3306"
volumes:
- ./mysql-data:/var/lib/mysql

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 586 B

After

Width:  |  Height:  |  Size: 692 B

File diff suppressed because it is too large Load Diff

@ -12,7 +12,7 @@ use Manager\DataManager;
use Repository\IUserRepository;
use Shared\ArgumentControllerResolver;
use Shared\IArgumentResolver;
use Stub\AuthService;
use Network\AuthService;
use Stub\NotificationRepository;
use Stub\TrainingRepository;
use Stub\UserRepository;
@ -23,26 +23,25 @@ use App\Router\Middleware\AuthMiddleware;
use Network\IAuthService;
use Network\IFriendRequestService;
use Network\RelationshipService;
use Network\INotificationService;
use Stub\NotificationService;
use App\Router\Session;
use Stub\StubData;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Shared\IHashPassword;
use Shared\HashPassword;
use Shared\Log;
$appFactory = new AppCreator();
$appFactory->registerService(IArgumentResolver::class, ArgumentControllerResolver::class);
$appFactory->registerService(UserManager::class, UserManager::class);
$appFactory->registerSingleton(UserManager::class, UserManager::class);
$appFactory->registerService(DataManager::class, StubData::class);
$appFactory->registerService(IAuthService::class, AuthService::class);
$appFactory->registerSingleton(IAuthService::class, AuthService::class);
$appFactory->registerService(IFriendRequestService::class, RelationshipService::class);
$appFactory->registerService(IHashPassword::class, HashPassword::class);
$appFactory->registerService(INotificationService::class, NotificationService::class);
@ -50,11 +49,6 @@ $appFactory->registerService(INotificationRepository::class, NotificationReposit
$appFactory->registerService(IUserRepository::class, UserRepository::class);
$appFactory->registerService(\Twig\Loader\LoaderInterface::class, function() {
return new FilesystemLoader(__DIR__ . '/../src/app/views/Templates');
});
@ -66,3 +60,12 @@ $appFactory->registerService(\Twig\Environment::class,\Twig\Environment::class);
$appFactory->AddControllers();
$app = $appFactory->create();
if (!is_null($app)){
// Ajout des Middleware
/*$app->use(new LoggingMiddleware());*/
$app->use(new AuthMiddleware($appFactory->getDicontainer()->get(IAuthService::class) ));
$app->mapControllers();
$app->run(RequestFactory::createFromGlobals());
}

@ -0,0 +1,34 @@
/*!
* Start Bootstrap - New Age v6.0.7 (https://startbootstrap.com/theme/new-age)
* Copyright 2013-2023 Start Bootstrap
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-new-age/blob/master/LICENSE)
*/
//
// Scripts
//
window.addEventListener('DOMContentLoaded', event => {
// Activate Bootstrap scrollspy on the main nav element
const mainNav = document.body.querySelector('#mainNav');
if (mainNav) {
new bootstrap.ScrollSpy(document.body, {
target: '#mainNav',
offset: 74,
});
};
// Collapse responsive navbar when toggler is visible
const navbarToggler = document.body.querySelector('.navbar-toggler');
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
responsiveNavItems.map(function (responsiveNavItem) {
responsiveNavItem.addEventListener('click', () => {
if (window.getComputedStyle(navbarToggler).display !== 'none') {
navbarToggler.click();
}
});
});
});

@ -0,0 +1,34 @@
/*!
* Start Bootstrap - New Age v6.0.7 (https://startbootstrap.com/theme/new-age)
* Copyright 2013-2023 Start Bootstrap
* Licensed under MIT (https://github.com/StartBootstrap/startbootstrap-new-age/blob/master/LICENSE)
*/
//
// Scripts
//
window.addEventListener('DOMContentLoaded', event => {
// Activate Bootstrap scrollspy on the main nav element
const mainNav = document.body.querySelector('#mainNav');
if (mainNav) {
new bootstrap.ScrollSpy(document.body, {
target: '#mainNav',
offset: 74,
});
};
// Collapse responsive navbar when toggler is visible
const navbarToggler = document.body.querySelector('.navbar-toggler');
const responsiveNavItems = [].slice.call(
document.querySelectorAll('#navbarResponsive .nav-link')
);
responsiveNavItems.map(function (responsiveNavItem) {
responsiveNavItem.addEventListener('click', () => {
if (window.getComputedStyle(navbarToggler).display !== 'none') {
navbarToggler.click();
}
});
});
});

@ -9,6 +9,7 @@ use App\Router\Middleware\IHttpMiddleware;
use App\Router\Request\IRequest;
use App\Router\Route;
use App\Views\Directives\Navigate;
use Manager\UserManager;
use Shared\Attributes\Route as RouteAttribute;
use App\Router\Router;
use App\Router\Session;
@ -29,9 +30,6 @@ class App
private FrontController $frontController;
private Session $session;
public function __construct(string $appName, int $version, \App\Container $diContainer)
{
$this->appName = $appName;
@ -39,7 +37,7 @@ class App
$this->container = $diContainer;
$this->router = new Router("");
$this->frontController = new FrontController($this->router,$this->container);
$this->session = Session::getInstance();
Session::getInstance();
}
public function use(IHttpMiddleware $middleware)
@ -103,6 +101,7 @@ class App
// Exécutez le middleware en utilisant le pipeline
return $this->middlewarePipeline->handle($request, function($request) {
// Logique de gestion principale de la requête ici
$this->frontController->dispatch($request);
});
@ -142,7 +141,7 @@ class App
$route = $attribute->newInstance();
$this->router->addControllerRoute(
implode('|', $route->getMethods()),
$route->getMethods(),
$prefix . $route->getPath(),
$controllerClass,
$method->getName(),

@ -24,6 +24,13 @@ class AppCreator
return $this;
}
public function registerSingleton(string $serviceId, $service): self
{
$this->container->set($serviceId, $service, Container::SINGLETON);
$this->services[] = $serviceId;
return $this;
}
/**
* Create an instance or perform actions based on the current application environment.
*
@ -33,6 +40,7 @@ class AppCreator
{
// Check the application environment
switch (APP_ENV) {
case 'console':
// Load the Console.php file in case of the 'console' environment
require_once __DIR__ . '/../console/Console.php';
@ -40,7 +48,6 @@ class AppCreator
case 'development':
// Create a new instance of the App class in the 'development' environment
return new App("HeartTrack", 1, $this->container);
break;
case 'html':
// Load the index.test.php file in case of the 'html' environment
require_once __DIR__ . '/index.test.php';
@ -53,7 +60,6 @@ class AppCreator
}
function AddControllers($namespacePrefix = 'App\Controller', $pathToControllers = __DIR__ . '/controller'): self
{
$controllerFiles = glob($pathToControllers . '/*.php');
@ -71,7 +77,8 @@ class AppCreator
if ($reflectionClass->isSubclassOf(BaseController::class)) {
// Register in DI container
$this->container->set($fullClassName, function () use ($fullClassName) {
$controllerInstance = new $fullClassName();
/** @var $controllerInstance * */
$controllerInstance = $this->container->resolve($fullClassName);
$controllerInstance->setContainer($this->container);
return $controllerInstance;
});
@ -81,11 +88,15 @@ class AppCreator
return $this;
}
public function getServiceRegistered(): array
{
return $this->services;
}
public function getDicontainer()
{
return $this->container;
}
}

@ -11,31 +11,45 @@ class Container implements ContainerInterface
{
private array $entries = [];
const SINGLETON = 'singleton';
const TRANSIENT = 'transient';
public function get(string $id)
{
if ($this->has($id)) {
$entry = $this->entries[$id];
if (is_callable($entry)) {
return $entry($this);
if ($entry['lifecycle'] === self::SINGLETON) {
if ($entry['instance'] === null) {
$entry['instance'] = $this->resolve($entry['concrete']);
}
return $entry['instance'];
}
$id = $entry;
if (is_callable($entry['concrete'])) {
return $entry['concrete']($this);
}
return $this->resolve($entry['concrete']);
}
return $this->resolve($id);
}
public function has(string $id): bool
{
return isset($this->entries[$id]);
}
public function set(string $id, callable|string $concrete): void
public function set(string $id, callable|string $concrete, string $lifecycle = self::TRANSIENT): void
{
$this->entries[$id] = $concrete;
$this->entries[$id] = [
'concrete' => $concrete,
'lifecycle' => $lifecycle,
'instance' => null
];
}
public function resolve(string $id)

@ -0,0 +1,131 @@
<?php
namespace App\Controller;
use App\Router\Request\IRequest;
use App\Router\Response\Response;
use Database\ActivityGateway;
use Database\ActivityMapper;
use Database\Connexion;
use Json\JsonSerializer;
use Manager\UserManager;
use Shared\Attributes\Route;
use Shared\Log;
class ApiController extends BaseController
{
private UserManager $userMgr;
public function __construct(UserManager $manager){
parent::__construct();
$this->userMgr = $manager;
}
#[Route(path: '/api/activities', name: 'api-activities', methods: ['GET'])]
public function apiActivities(IRequest $request)
{
$activityGateway = new ActivityGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
$listSearch = $activityGateway->getActivity();
$map = new ActivityMapper();
$activityGateway = $map->activitySqlToEntity($listSearch);
$listActivity = [];
foreach ($activityGateway as $entity) {
$activity = $map->activityEntityToModel($entity);
$listActivity[] = ['idactivity' => number_format($activity->getIdActivity()), 'type' => $activity->getType(),
'date' => $activity->getDate()->format("Y-m-d"), 'heureDebut' => $activity->getHeureDebut()->format("Y-m-d"), 'heureFin' => $activity->getHeureFin()->format("Y-m-d"),
'effortRessenti' => $activity->getEffortRessenti(), 'variabilite' => $activity->getVariability(), 'variance' => $activity->getVariance(),
'ecartType' => $activity->getStandardDeviation(), 'moyenne' => $activity->getAverage(),
'max' => $activity->getMaximum(), 'min' => $activity->getMinimum(), 'temperature' => $activity->getAvrTemperature()];
}
$jsonSerializer = new JsonSerializer();
$jsonData = $jsonSerializer::serialize($listActivity);
$response = new Response();
$response->setContent($jsonData);
$response->setHeader('Content-Type', 'application/json');
return $response;
}
// cela ne trouve pas la methode avec la route '/api/activities/1'
#[Route(path: '/api/activities/{id}', name: 'api-activities-by-id', methods: ['GET'])]
public function apiActivityById(IRequest $request, int $id)
{
$activityGateway = new ActivityGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
$listSearch = $activityGateway->getActivityById($id);
Log::dd($listSearch);
$map = new ActivityMapper();
$activityGateway = $map->activitySqlToEntity($listSearch);
$listActivity = [];
foreach ($activityGateway as $entity) {
$activity = $map->activityEntityToModel($entity);
$listActivity[] = ['idactivity' => number_format($activity->getIdActivity()), 'type' => $activity->getType(),
'date' => $activity->getDate()->format("Y-m-d"), 'heureDebut' => $activity->getHeureDebut()->format("Y-m-d"), 'heureFin' => $activity->getHeureFin()->format("Y-m-d"),
'effortRessenti' => $activity->getEffortRessenti(), 'variabilite' => $activity->getVariability(), 'variance' => $activity->getVariance(),
'ecartType' => $activity->getStandardDeviation(), 'moyenne' => $activity->getAverage(),
'max' => $activity->getMaximum(), 'min' => $activity->getMinimum(), 'temperature' => $activity->getAvrTemperature()];
}
$jsonSerializer = new JsonSerializer();
$jsonData = $jsonSerializer::serialize($listActivity);
$response = new Response();
$response->setContent($jsonData);
$response->setHeader('Content-Type', 'application/json');
// pour delete renvoyer 204 pour dire ok et supprimer
// update 200
return $response;
}
//
// #[Route(path: '/api/activities', name: 'api-activities-post', methods: ['POST'])]
// public function apiAddActivity(IRequest $request)
// {
// $activityGateway = new ActivityGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
// $listSearch = $activityGateway->getActivity();
// $map = new ActivityMapper();
// $activityGateway = $map->activitySqlToEntity($listSearch);
// $listActivity = [];
// foreach ($activityGateway as $entity) {
// $activity = $map->activityEntityToModel($entity);
// $listActivity[] = ['idactivity' => number_format($activity->getIdActivity()), 'type' => $activity->getType(),
// 'date' => $activity->getDate()->format("Y-m-d"), 'heureDebut' => $activity->getHeureDebut()->format("Y-m-d"), 'heureFin' => $activity->getHeureFin()->format("Y-m-d"),
// 'effortRessenti' => $activity->getEffortRessenti(), 'variabilite' => $activity->getVariability(), 'variance' => $activity->getVariance(),
// 'ecartType' => $activity->getStandardDeviation(), 'moyenne' => $activity->getAverage(),
// 'max' => $activity->getMaximum(), 'min' => $activity->getMinimum(), 'temperature' => $activity->getAvrTemperature()];
// }
//
// $jsonSerializer = new JsonSerializer();
// $jsonData = $jsonSerializer::serialize($listActivity);
//
// $response = new Response();
// $response->setContent($jsonData);
// $response->setHeader('Content-Type', 'application/json');
//
// return $response;
// }
// #[Route(path: '/api/activities/{id}', name: 'api-activities-post', methods: ['DELETE'])]
// public function apiDeleteActivity(IRequest $request, int $id)
// {
// $activityGateway = new ActivityGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
// $listSearch = $activityGateway->removeActivityById($id);
//
// $response = new Response();
// $response->setContent($jsonData);
// $response->setHeader('Content-Type', 'application/json');
//
// return $response;
// }
// #[Route(path: '/api/activities/{id}', name: 'api-activities-post', methods: ['PUT'])]
// public function apiUpdateActivity(IRequest $request, int $id)
// {
// $activityGateway = new ActivityGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
// $listSearch = $activityGateway->updateActivity($id);
//
// $response = new Response();
// $response->setContent($jsonData);
// $response->setHeader('Content-Type', 'application/json');
//
// return $response;
// }
}

@ -1,7 +1,9 @@
<?php
namespace App\Controller;
namespace App\Controller;
use Shared\Validation;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\Response;
@ -9,51 +11,49 @@ use Shared\Attributes\Route;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
use Manager\UserManager;
class AthleteController extends BaseController
{
#[Route(path: '/search-ath', name: 'search-ath', methods: ['GET'])]
private Environment $twig;
protected Preferences $preference;
public function __construct()
{
//session_start();
$this->preference = new Preferences();
}
#[Route(path: '/search-user', name: 'search-user', methods: ['GET'])]
public function searchUser(string $username, IRequest $req): Response
{
$taberror = [];
$utiliArray = [
[
'nom' => 'John',
'prenom' => 'Doe',
'img' => 'john_doe',
'username' => 'johndoe',
],
[
'nom' => 'Alice',
'prenom' => 'Smith',
'img' => 'alice_smith',
'username' => 'alicesmith',
],
];
// if(!Validation::val_string($name)){
if(!Validation::val_string($username)){
print("Nom invalide.");
}
else {
try {
//code...
// $model->userMgr->getUser($name);
return $this->render('./page/addfriend.html.twig', [
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => $utiliArray,
'infoUser' => [],
'exos' => [],
'member' => [],
'responce' => "Notification d'ajout envoyée à $username"
$listSearch=$this->container->get(UserManager::class)->searchUsersByName($username);
$i=0;
foreach ($listSearch as $user){
$listUsers[$i++]=['nom' => $user->getNom(), 'prenom'=>$user->getPrenom(), 'img'=>'john_doe', 'username'=>$user->getUsername()];
}
//$currentUser=$this->container->get(UserManager::class)->getCurrentUser();
//$currentUser=$_SESSION['user'];
$response = $this->render('./page/addfriend.html.twig',[
'css' => $_COOKIE['preferences'],
'pp' => "test",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'users' => $listUsers
]);
} catch (\Throwable $th) {
//throw $th;
// return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
$th;
return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
}
// }
}
return $response;
}
@ -63,8 +63,26 @@ class AthleteController extends BaseController
return $this->render('./page/analyze.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/activity', name: 'activity', methods: ['GET'])]
public function activity(): Response
{
return $this->render('./page/activity.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
@ -82,8 +100,8 @@ class AthleteController extends BaseController
return $this->render('./page/exercice.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
@ -94,57 +112,84 @@ class AthleteController extends BaseController
]);
}
#[Route(path: '/add-friend', name: 'add-friend', methods: ['POST'])]
public function addFriend(string $username, IRequest $req): Response
#[Route(path: '/exercices', name: 'exercices', methods: ['POST'])] // 8
public function exercices(String $type, String $intensite, String $date, IRequest $req): Response
{
$taberror = [];
$utiliArray = [
[
'nom' => 'John',
'prenom' => 'Doe',
'img' => 'john_doe',
'username' => 'johndoe',
],
$exercicesArray = [
[
'nom' => 'Alice',
'prenom' => 'Smith',
'img' => 'alice_smith',
'username' => 'alicesmith',
],
'date' => $date,
'type' => $type,
'intensite' => $intensite,
'status' => 'A venir',
]
];
// if(!Validation::val_string($name)){
return $this->render('./page/exercice.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => $exercicesArray,
'member' => []
]);
}
#[Route(path: '/add-friend', name: 'add-friend', methods: ['POST'])]
public function addFriend(string $username, IRequest $req): Response
{
try {
//code...
// $model->userMgr->addFriend($name);
//Ajouter la personne sur laquelle on a clique dans la liste de currentuser
$listSearch=$this->container->get(UserManager::class)->searchUsersByName($username);
$i=0;
foreach ($listSearch as $user){
$listUsers[$i++]=['nom' => $user->getNom(), 'prenom'=>$user->getPrenom(), 'img'=>'test', 'username'=>$user->getUsername()];
}
return $this->render('./page/addfriend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => $utiliArray,
'users' => $listUsers,
'infoUser' => [],
'exos' => [],
'member' => [],
'responce' => "Notification d'ajout envoyée à $username"
]);
} catch (\Throwable $th) {
//throw $th;
// return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
throw $th;
return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
}
// }
}
#[Route(path: '/friend', name: 'friend', methods: ['GET'])]
public function friend(): Response
{
$utiliArray = [
return $this->render('./page/addfriend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => 'John',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => [],
]);
}
/*#[Route(path: '/friendlist', name: 'friendlist', methods: ['POST'])]
public function friendlist(string $username, IRequest $req): Response
{
$friendList = [
[
'nom' => 'John',
'prenom' => 'Doe',
@ -158,19 +203,40 @@ class AthleteController extends BaseController
'username' => 'alicesmith',
],
];
return $this->render('./page/addfriend.html.twig',[
// TODO
// -> Enlever ou bloquer un utilisateur en fonction de son username
//$friendList = currentUser->getFriends();
return $this->render('./page/friend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => 'johndoe',//$currentUser->getUsername(),
'role' => 'Athlete',//$currentUser->getRole(),
'friendship' => $friendList,
]);
}*/
#[Route(path: '/friendlist', name: 'friendlist2', methods: ['GET'])]
public function friendlist2(): Response
{
$friendList = $this->container->get(UserManager::class)->getFriends();//$currentUser->getFriends();
return $this->render('./page/friend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'friendship' => $friendList,
'analyzes' => [],
'mails' => [],
'users' => $utiliArray,
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => [],
]);
}
// #[Route(path: '/delete-friend', name: 'delete-friend', methods: ['POST'])]
}
?>

@ -4,98 +4,95 @@ namespace App\Controller;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\RedirectResponse;
use App\Router\Response\Response;
use App\Router\Response\IResponse;
use Couchbase\UserManager;
use App\Router\Session;
use Manager\UserManager;
use Shared\Attributes\Route;
use Shared\Validation;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
use Shared\Validation;
use function PHPUnit\Framework\isEmpty;
class AuthController extends BaseController
{
private UserManager $userMgr;
public function __construct(UserManager $manager){
parent::__construct();
$this->userMgr = $manager;
}
#[Route('/login', name: 'login',methods: ['POST'])]
public function login(IRequest $request): IResponse {
public function login(string $email,string $password, IRequest $request): IResponse {
$error = [];
try {
$log=Validation::clean_string($request->getBody()['email']);
$mdp=Validation::clean_string($request->getBody()['password']);
} catch (\Throwable $th) {
$error = "Wrong cred";
}
$log=$email; // should check email with verrify email
$mdp=Validation::clean_string($password);
if($this->container->get(UserManager::class)->login($log,$mdp)){
return $this->redirectToRoute('/');
if($this->userMgr->login($log,$mdp)){
return new RedirectResponse('/home');
}
else{
$error [] = "Erreur de connexion. Essayez encore";
}
return $this->render('./page/login.html.twig', ['error' => $error]);
return $this->render('./page/login.html.twig',[
'css' => $this->preference->getCookie(),
'login_error'=> $error,
]);
}
#[Route('/log', name: 'baseLog',methods: ['GET'])]
public function index(IRequest $request): IResponse {
// should only cath a type of Exception not all
} catch (\Throwable $th) {
$error [] =$th->getMessage();
return $this->render('./page/login.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
'login_error'=> $error,
]);
}
#[Route('/register', name: 'register' , methods:['GET'])]
public function register(IRequest $request): IResponse
{
if ($request->getMethod() == 'POST') {
$nom = $request->getBody()['nom'];
$prenom = $request->getBody()['prenom'];
$username = $request->getBody()['username'];
$email = $request->getBody()['email'];
$motDePasse = $request->getBody()['motDePasse'];
$sexe = $request->getBody()['sexe'];
$taille = $request->getBody()['taille'];
$poids = $request->getBody()['poids'];
$dateNaissanceStr = $request->getBody()['nom'];
$dateNaissance = new \DateTime($dateNaissanceStr);
}
#[Route('/login', name: 'login2',methods: ['GET'])]
public function login2(IRequest $request): IResponse {
return $this->render('./page/login.html.twig',[
'css' => $this->preference->getCookie(),
]);
if (!$dateNaissance) {
throw new \Exception("Date de naissance non valide. Format attendu : YYYY-MM-DD");
}
#[Route('/register', name: 'register2' , methods:['GET'])]
public function register2(IRequest $request): IResponse{
return $this->render('./page/register.html.twig',[
'css' => $this->preference->getCookie(),
]);
}
$roleName = $request->getBody()['roleName'];
#[Route('/register', name: 'register' , methods:['POST'])]
public function register(
string $nom,
string $prenom,
string $username,
string $mail,
string $motDePasse,
string $sexe,
float $taille,
float $poids,
string $dateNaissance,
string $roleName,
IRequest $request): IResponse
{
$error = [];
try {
$registrationData = [
'nom' => $nom,
'prenom' => $prenom,
'username' => $username,
'email' => $email,
'email' => $mail,
'sexe' => $sexe,
'taille' => $taille,
'poids' => $poids,
@ -103,45 +100,65 @@ class AuthController extends BaseController
'roleName' => $roleName
];
try {
if ($this->container->get(UserManager::class)->register($email, $motDePasse, $registrationData)) {
return $this->redirectToRoute('/');
if ($this->userMgr->register($mail, $motDePasse, $registrationData) ) {
return new RedirectResponse('/home');
} else {
$error [] = 'L\'inscription a échoué. Veuillez réessayer.';
return $this->render('./page/register.html.twig',[
'css' => $this->preference->getCookie(),
'register_error'=> $error,
]);
}
} catch (\Exception $e) {
$error [] = 'Erreur lors de l\'inscription: ' . $e->getMessage();
}
} catch (\Throwable $e) {
$error [] =$e->getMessage();
return $this->render('./page/register.html.twig', ['css' => $this->preference->getCookie(),"register_error" => $error ]);
}
return $this->render('/register.html.twig');
}
#[Route(path: '/mdp', name: 'mdp', methods: ['POST'])]
public function mdp(string $ancienMotDePasse,string $nouveauMotDePasse,string $confirmerMotDePasse, IRequest $req): Response
//string $ancienMotDePasse,string $nouveauMotDePasse,string $confirmerMotDePasse,
#[Route(path: '/forgetPassword', name: 'forget-password2', methods: ['GET'])]
public function forgetPassword2(IRequest $request): IResponse
{
return $this->render('./page/password.html.twig',[
'css' => $this->preference->getCookie(),
]);
}
// CONFIRMER LES DONNESS !!!!! IMPORTANT
#[Route(path: '/forgetPassword', name: 'forget-password', methods: ['POST'])]
public function forgetPassword(string $mail, IRequest $request): IResponse
{
return $this->render('./page/settings.html.twig',[
return $this->render('./page/password.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/logout', name: 'logout', methods: ['POST'])]
public function logout(IRequest $request): IResponse
{
$error = [];
try {
if($this->userMgr->deconnecter()){
return new RedirectResponse('/');
}
else{
$error [] = "Erreur de deconnexion. Essayez encore";
return new RedirectResponse('/');
}
} catch (\Throwable $th) {
$error [] =$th->getMessage();
return new RedirectResponse('/');
}
}
}
?>

@ -8,13 +8,14 @@ use App\Router\Response\RedirectResponse;
use App\Router\Response\Response;
use Psr\Container\ContainerInterface;
use Shared\Log;
abstract class BaseController
{
protected Preferences $preference;
public function __construct(){
$this->preference = new Preferences();
}
protected ContainerInterface $container;
@ -62,18 +63,5 @@ abstract class BaseController
return new RedirectResponse($url, $status);
}
protected function redirectToRoute(string $route, array $parameters = [], int $status = 302): RedirectResponse
{
return $this->redirect($this->generateUrl($route, $parameters), $status);
}
/*
* TODO : Should hanle ierror if the route is not existing
* */
protected function generateUrl(string $route, array $parameters = []): string
{
return $this->container->get(\App\Router\Router::class)->generate($route, $parameters);
}
}

@ -1,40 +1,50 @@
<?php
// namespace App\Controller;
namespace App\Controller;
// use App\Container;
// use App\Router\Request\IRequest;
// use App\Router\Response\Response;
// use App\Router\Response\IResponse;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\Response;
use App\Router\Response\IResponse;
// use Shared\Attributes\Route;
// use Twig\Environment;
// use Data\Core\Preferences;
// use Shared\Log;
use Shared\Attributes\Route;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
// #[Route(path: '/coach', name: 'coach')]
// class CoachController extends BaseController
// {
// private ICoachManager $coachManager;
// private $security;
// private Environment $twig;
// protected Preferences $preference;
// public function __construct(DataManager $dataManager, Security $security)
// {
// session_start();
// $this->coachManager = $dataManager->coachMgr;
// $this->security = $security;
// $this->preference = new Preferences();
// }
// #[Route(path: '/', name: 'home', methods: ['GET'])]
// public function index(): Response
// // #[Route('/global-stats', name: 'coach_global_stats', methods: ['GET'])]
// // public function globalStats(): Response
// // {
// // // Add logic to fetch and process global stats
// // return $this->render('coach/global_stats.html.twig');
// // }
// #[Route(path: '/coaching', name: 'coaching', methods: ['GET'])]
// public function coaching(): Response
// {
// return $this->render('./page/home.html.twig',[
// return $this->render('./page/coaching.html.twig',[
// 'css' => $this->preference->getCookie(),
// 'pp' => "test2",
// 'user' => "Doe",
// 'role' => "Athlète",
// 'role' => "Coach",
// 'friendship' => [],
// 'analyzes' => [],
// 'mails' => [],
@ -44,17 +54,31 @@
// 'member' => []
// ]);
// }
// #[Route('/global-stats', name: 'coach_global_stats', methods: ['GET'])]
// public function globalStats(): Response
// {
// // Add logic to fetch and process global stats
// return $this->render('coach/global_stats.html.twig');
// }
// #[Route(path: '/exercice', name: 'exercice', methods: ['GET'])] // 8
// public function exercice(): Response
// #[Route(path: '/search-member', name: 'search-member', methods: ['GET'])]
// public function searchMember(string $username, IRequest $req): Response
// {
// return $this->render('./page/exercice.html.twig',[
// $taberror = [];
// // FILTER
// $utiliArray = [
// [
// 'nom' => 'John',
// 'prenom' => 'Doe',
// 'img' => 'john_doe',
// 'username' => 'johndoe',
// ],
// [
// 'nom' => 'Alice',
// 'prenom' => 'Smith',
// 'img' => 'alice_smith',
// 'username' => 'alicesmith',
// ],
// ];
// // if(!Validation::val_string($name)){
// try {
// //code...
// // $model->userMgr->addFriend($name);
// return $this->render('./page/addmember.html.twig',[
// 'css' => $this->preference->getCookie(),
// 'pp' => "test2",
// 'user' => "Doe",
@ -62,17 +86,43 @@
// 'friendship' => [],
// 'analyzes' => [],
// 'mails' => [],
// 'users' => [],
// 'users' => $utiliArray,
// 'infoUser' => [],
// 'exos' => [],
// 'member' => []
// 'member' => [],
// 'responce' => "Notification d'ajout envoyée à $username"
// ]);
// } catch (\Throwable $th) {
// //throw $th;
// // return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
// }
// // }
// #[Route(path: '/coaching', name: 'coaching', methods: ['GET'])]
// public function coaching(): Response
// }
// #[Route(path: '/add-member', name: 'add-member', methods: ['POST'])]
// public function addmember(string $username, IRequest $req): Response
// {
// return $this->render('./page/coaching.html.twig',[
// $taberror = [];
// $utiliArray = [
// [
// 'nom' => 'John',
// 'prenom' => 'Doe',
// 'img' => 'john_doe',
// 'username' => 'johndoe',
// ],
// [
// 'nom' => 'Alice',
// 'prenom' => 'Smith',
// 'img' => 'alice_smith',
// 'username' => 'alicesmith',
// ],
// ];
// // if(!Validation::val_string($name)){
// try {
// //code...
// // $model->userMgr->addFriend($name);
// return $this->render('./page/addmember.html.twig',[
// 'css' => $this->preference->getCookie(),
// 'pp' => "test2",
// 'user' => "Doe",
@ -80,45 +130,84 @@
// 'friendship' => [],
// 'analyzes' => [],
// 'mails' => [],
// 'users' => [],
// 'users' => $utiliArray,
// 'infoUser' => [],
// 'exos' => [],
// 'member' => []
// 'member' => [],
// 'responce' => "Notification d'ajout envoyée à $username"
// ]);
// } catch (\Throwable $th) {
// //throw $th;
// // return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
// }
// // }
// #[Route('/list-athletes', name: 'coach_list_athletes')]
// public function listAthletes(): Response
// {
// $coach = $this->security->getUser();
// $athletes = $this->coachManager->getAthletesForCoach($coach);
// return $this->render('coach/list_athletes.html.twig', [
// 'athletes' => $athletes,
// ]);
// }
// #[Route('/athlete-analysis/{athleteId}', name: 'coach_athlete_analysis', methods: ['GET'])]
// public function athleteAnalysis($athleteId): Response
// #[Route(path: '/member', name: 'member', methods: ['GET'])]
// public function member(): Response
// {
// // Fetch and process data specific to the athlete
// return $this->render('coach/athlete_analysis.html.twig', [
// 'athleteId' => $athleteId,
// $utiliArray = [
// [
// 'nom' => 'John',
// 'prenom' => 'Doe',
// 'img' => 'john_doe',
// 'username' => 'johndoe',
// ],
// [
// 'nom' => 'Alice',
// 'prenom' => 'Smith',
// 'img' => 'alice_smith',
// 'username' => 'alicesmith',
// ],
// ];
// return $this->render('./page/addmember.html.twig',[
// 'css' => $this->preference->getCookie(),
// 'pp' => "test2",
// 'user' => "Doe",
// 'role' => "Athlète",
// 'friendship' => [],
// 'analyzes' => [],
// 'mails' => [],
// 'users' => $utiliArray,
// 'infoUser' => [],
// 'exos' => [],
// 'member' => [],
// ]);
// }
// #[Route('/add-athlete/{athleteId}', name: 'coach_add_athlete', methods: ['POST'])]
// public function addAthlete(IRequest $request, $athleteId): IResponse
// {
// // Implement logic to add athlete
// // ...
// return $this->redirectToRoute('coach_list_athletes');
// }
// // #[Route('/remove-athlete', name: 'coach_remove_athlete', methods: ['POST'])]
// // public function removeAthlete(int $athleteId, IRequest $request): IResponse
// // #[Route('/list-athletes', name: 'coach_list_athletes')]
// // public function listAthletes(): Response
// // {
// // $coach = $this->security->getUser();
// // $athletes = $this->coachManager->getAthletesForCoach($coach);
// // return $this->render('coach/list_athletes.html.twig', [
// // 'athletes' => $athletes,
// // ]);
// // }
// // #[Route('/athlete-analysis/{athleteId}', name: 'coach_athlete_analysis', methods: ['GET'])]
// // public function athleteAnalysis($athleteId): Response
// // {
// // // Fetch and process data specific to the athlete
// // return $this->render('coach/athlete_analysis.html.twig', [
// // 'athleteId' => $athleteId,
// // ]);
// // }
// // #[Route('/add-athlete/{athleteId}', name: 'coach_add_athlete', methods: ['POST'])]
// // public function addAthlete(IRequest $request, $athleteId): IResponse
// // {
// // // Implement logic to add athlete
// // // ...
// // return $this->redirectToRoute("/athletes");
// // return $this->redirectToRoute('coach_list_athletes');
// // }
// // // #[Route('/remove-athlete', name: 'coach_remove_athlete', methods: ['POST'])]
// // // public function removeAthlete(int $athleteId, IRequest $request): IResponse
// // // {
// // // return $this->redirectToRoute("/athletes");
// // // }
// }

@ -48,6 +48,7 @@ class FrontController {
$this->handleError(404, $e->getMessage());
}
catch(\Throwable $e){
Log::dd($e->getLine() . $e->getFile() . $e->getMessage() );
$this->handleError(501, $e->getMessage());
}
}
@ -65,7 +66,7 @@ class FrontController {
// TODO : Don't work need Antoine help
private function handleError(int $statusCode, $message) : void {
if (!$this->container->has(\Twig\Environment::class)) {
throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".');
throw new \LogicException('You cannot use the "renderView" method if the Twig Bundle is not available. Try running "composer require ".');
}
$response = new Response($this->container->get(\Twig\Environment::class)->render('./error/error.html.twig',['title'=> $message , "code" => $statusCode, "name" => $message, "descr" => $message ]),$statusCode);

@ -1,36 +1,94 @@
<?php
// namespace App\Controller;
// use App\Container;
// use App\Router\Request\IRequest;
// use App\Router\Response\Response;
// use Shared\Attributes\Route;
// use Twig\Environment;
// use Data\Core\Preferences;
// use Shared\Log;
// class HeartRateController extends BaseController
// {
// #[Route(path: '/import', name: 'import', methods: ['GET'])]
// public function import(): Response
// {
// return $this->render('./page/import.html.twig',[
// 'css' => $this->preference->getCookie(),
// 'pp' => "test2",
// 'user' => "Doe",
// 'role' => "Athlète",
// 'friendship' => [],
// 'analyzes' => [],
// 'mails' => [],
// 'users' => [],
// 'infoUser' => [],
// 'exos' => [],
// 'member' => []
// ]);
// }
// }
namespace App\Controller;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\IResponse;
use App\Router\Response\RedirectResponse;
use App\Router\Response\Response;
use Manager\ActivityManager;
use Shared\Attributes\Route;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
class HeartRateController extends BaseController
{
private ActivityManager $activityMgr;
public function __construct(ActivityManager $manager)
{
parent::__construct();
$this->activityMgr = $manager;
}
#[Route(path: '/import', name: 'import', methods: ['GET'])]
public function import(): Response
{
return $this->render('./page/import.html.twig', [
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/upload', name: 'upload', methods: ['POST'])]
public function uploadFile(string $activityType, int $effort, IRequest $req): IResponse
{
$error = $this->validateRequest($effort);
if (!empty($error)) {
return $this->renderError($error);
}
$tmp_file = $_FILES['uploaded_file']['tmp_name'];
if (!$this->isValidFile($tmp_file)) {
return $this->renderError(['Failed to get file be sure that you provide the file']);
}
$content = file_get_contents($tmp_file);
try {
if ($this->activityMgr->uploadFile($activityType, 5, $content)) {
return new RedirectResponse('/home');
}
} catch (\Exception $e) {
return $this->renderError([$e->getMessage()]);
}
return $this->renderError(['Failed to save activity.']);
}
private function validateRequest(int $effort): array
{
$error = [];
if ($effort < 0 || $effort > 5) {
$error[] = 'Invalid effort level.';
}
$fileExtension = pathinfo($_FILES['uploaded_file']['name'], PATHINFO_EXTENSION);
if ($fileExtension !== 'fit') {
$error[] = 'Invalid file type. Only .fit files are allowed.';
}
return $error;
}
private function isValidFile(string $tmp_file): bool
{
return file_exists($tmp_file) && is_uploaded_file($tmp_file);
}
private function renderError(array $error): Response
{
// Consolidez la logique de rendu ici
return $this->render('./error/error.html.twig', ['title'=> "Failed" , "code" => 400, "name" => "error import", "descr" => $error[0] ], new Response('$error', 400));
}
}

@ -1,19 +1,66 @@
<?php
// namespace App\Controller;
namespace App\Controller;
// use App\Container;
// use App\Router\Request\IRequest;
// use App\Router\Response\Response;
// use App\Router\Response\IResponse;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\Response;
use Database\AthleteGateway;
use Database\AthleteMapper;
use Database\Connexion;
use Database\NotificationGateway;
use Database\NotificationMapper;
use Shared\Attributes\Route;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
// use Shared\Attributes\Route;
// use Twig\Environment;
// use Data\Core\Preferences;
// use Shared\Log;
class SocialController extends BaseController
{
protected Preferences $preference;
public function __construct(){
$this->preference = new Preferences();
}
#[Route(path: '/notification', name: 'notification', methods: ['GET'])]
public function mail(): Response
{
try {
$notificationGateway = new NotificationGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
$listSearch = $notificationGateway->getNotifications();
$map = new NotificationMapper();
$notificationEntity = $map->notificationSqlToEntity($listSearch);
// #[Route(path: '/coach', name: 'coach')]
// class CoachController extends BaseController
// {
$listUsers = [];
foreach ($notificationEntity as $entity) {
$notification = $map->notificationEntityToModel($entity);
$listUsers[] = ['idnotif' => $notification->getId(), 'message' => $notification->getMessage(),
'date' => $notification->getDate()->format("D j F Y"),'statut' => $notification->getStatut(), 'urgence' => $notification->getUrgence(),
'idathlete' => $notification->getToUserId()];
}
$response = $this->render('./page/notification.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => $listUsers,
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
} catch (\Throwable $th) {
throw $th;
return $this->render("notification.html.twig", ['tabError' => $taberror]);
}
return $response;
}
}

@ -4,21 +4,37 @@ namespace App\Controller;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\RedirectResponse;
use App\Router\Response\Response;
use App\Router\Response\IResponse;
use App\Router\Session;
use Manager\UserManager;
use Shared\Attributes\Route;
use Shared\Validation;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
use Stub\AthleteGateway;
use Stub\Connexion;
use DateInterval;
use DateTime;
use \PDOException;
class UserController extends BaseController
{
private UserManager $userMgr;
public function __construct(UserManager $manager)
{
parent::__construct();
$this->userMgr = $manager;
}
#[Route(path: '/', name: 'home', methods: ['GET'])]
#[Route(path: '/', name: 'index', methods: ['GET'])]
public function index(): Response
{
return $this->render('./page/home.html.twig',[
return $this->render('./page/index.html', [
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
@ -33,6 +49,106 @@ class UserController extends BaseController
]);
}
#[Route(path: '/mock', name: 'mock', methods: ['GET'])]
public function createTablesFromMock()
{
try {
$connection = new Connexion(DSN, DB_USER, DB_PASSWORD);
echo "Connexion à la base de données réussie";
// Lire le contenu du fichier mock/tables.sql
$sql = file_get_contents(__DIR__ . '/../../data/core/database/data/tables.sql'); // Assurez-vous de spécifier le chemin correct
// Exécuter la requête SQL pour créer les tables
$result = $connection->executeQuery($sql);
if ($result) {
echo "Tables créées avec succès.";
} else {
Log::dd("Erreur lors de la création des tables.");
}
$sql = file_get_contents(__DIR__ . '/../../data/core/database/data/athlete.sql');
$result = $connection->executeQuery($sql);
if ($result) {
echo "Athlete créées avec succès.";
} else {
Log::dd("Erreur lors de la création des Athlete.");
}
$sql = file_get_contents(__DIR__ . '/../../data/core/database/data/friendship.sql');
$result = $connection->executeQuery($sql);
if ($result) {
echo "friendship créées avec succès.";
} else {
Log::dd("Erreur lors de la création des friendship.");
}
$sql = file_get_contents(__DIR__ . '/../../data/core/database/data/frequenceCardiaque.sql');
$result = $connection->executeQuery($sql);
if ($result) {
echo "frequenceCardiaque créées avec succès.";
} else {
Log::dd("Erreur lors de la création des friendship.");
}
} catch (PDOException $e) {
Log::dd("Erreur de connexion à la base de données : " . $e->getMessage());
}
Log::dd("Database Mock succesfully create");
}
#[Route(path: '/home', name: 'home', methods: ['GET'])]
public function home(): IResponse
{
$athleteGateway = new AthleteGateway(new Connexion(DSN, DB_USER, DB_PASSWORD));
$activity = $athleteGateway->getListActivity($this->userMgr->getCurrentUser()->getId());
$charts = [];
$currentDate = new DateTime();
$interval = new DateInterval('P1M'); // Période d'un mois
for ($i = 0; $i < 12; $i++) {
$currentMonth = $currentDate->format('n');
// Recherche de l'indice du mois dans le tableau $activity
$activityIndex = null;
for ($j = 0; $j < count($activity); $j++) {
if (!empty($activity[$j]['mois']) && $activity[$j]['mois'] == $currentMonth) {
$activityIndex = $j;
break;
}
}
// Récupération du nombre d'activités et réinitialisation à 0
$nbActivity = isset($activityIndex) ? $activity[$activityIndex]['nbactivite'] : 0;
if (isset($activityIndex)) {
$activity[$activityIndex]['nbactivite'] = 0;
}
$charts[] = ['act' => $nbActivity, 'mois' => $currentMonth];
$currentDate->sub($interval);
}
$charts = array_reverse($charts);
return $this->render('./page/home.html.twig', [
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => $this->userMgr->getCurrentUser()->getNom(),
'role' => $this->userMgr->getCurrentUser()->getRole()::class,
'friendship' => $this->userMgr->getCurrentUser()->getRole()->getUsersList(),
'analyzes' => $this->userMgr->getCurrentUser()->getRole()->getUsersList(),
'charts' => $charts,
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/settings', name: 'settings', methods: ['GET'])]
public function settings(IRequest $req): Response
@ -52,10 +168,28 @@ class UserController extends BaseController
]);
}
#[Route(path: '/profile', name: 'profile', methods: ['GET'])]
public function profile(): Response
{
return $this->render('./page/profile.html.twig', [
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/preferences', name: 'preferences', methods: ['POST'])]
public function preferences(string $theme, IRequest $req): Response
{
/*TODO*/
// VALIDER LES DONNEES
$this->preference->majCookie($theme);

@ -1,12 +1,15 @@
<?php
namespace App\Router;
use App\Router\Request\IRequest;
/**
* Router class to manage a collection of routes in the application.
* It provides functionalities to add routes and check if a given URL matches any of the defined routes.
*/
class Router {
class Router
{
/**
* The base path for routing.
@ -34,7 +37,8 @@ class Router {
*
* @param string $path The base path for the router.
*/
public function __construct(string $path = "/PHP/project/index.php") {
public function __construct(string $path = "/PHP/project/index.php")
{
$this->path = $path;
$this->routes = new \AltoRouter();
}
@ -46,7 +50,8 @@ class Router {
* @param Route $route The route object.
* @throws \InvalidArgumentException If method is not supported.
*/
public function add(string $method, Route $route) {
public function add(string $method, Route $route)
{
if (!in_array($method, self::$verbs)) {
throw new \InvalidArgumentException("Method not supported");
}
@ -55,20 +60,28 @@ class Router {
/**
* Adds a route for a controller action.
*
* @param string $method The HTTP method.
* TODO : the problème is that AltoRouter is a map so i can't have mutilple Route just by doing this:(i need to find a logic to resolve this beavior) #[Route('/login', name: 'login',methods: ['POST','GET'])]
* @param string|array $methods HTTP method.
* @param string $path The path for the route.
* @param mixed $controller The controller object.
* @param string $action The action method in the controller.
* @param string $name (Optional) The name of the route.
* @throws \InvalidArgumentException If method is not supported.
*/
public function addControllerRoute(string $method, string $path, $controller, string $action, string $name = '') {
public function addControllerRoute(string|array $methods, string $path, $controller, string $action, string $name = '')
{
if (is_string($methods)) {
$methods = [$methods]; // Convert to an array if it's a string
}
foreach ($methods as $method) {
if (!in_array($method, self::$verbs)) {
throw new \InvalidArgumentException("Method not supported");
}
$this->routes->map($method, $path, [$controller, $action], $name);
}
}
// TODO: Implement the extractParams method.
// public function extractParams(string $path) {}
@ -80,7 +93,8 @@ class Router {
* @param callable $callable The callback function.
* @param string $name The name of the route.
*/
public function get(string $path, callable $callable, $name) {
public function get(string $path, callable $callable, $name)
{
$this->routes->map('GET', $path, $callable, $name);
}
@ -92,7 +106,8 @@ class Router {
* @param IRequest $request The request object.
* @return array|null The matched route or null if no match.
*/
public function match(IRequest $request): ?array {
public function match(IRequest $request): ?array
{
return $this->routes->match($request->getRequestUri(), $request->getMethod()) ?: null;
}
@ -101,7 +116,8 @@ class Router {
*
* @return array The array of routes.
*/
public function getRoutes() {
public function getRoutes()
{
return []; // TODO: Implement the actual logic to return routes.
}

@ -111,8 +111,7 @@ class Session
if ( $this->sessionState == self::SESSION_STARTED )
{
$this->sessionState = !session_destroy();
unset( $_SESSION );
session_unset(); // Clear all session variables
return !$this->sessionState;
}

@ -2,26 +2,24 @@
namespace App\Router\Middleware;
use App\Router\Session;
use Network\IAuthService;
use Shared\Log;
use App\Router\Request\IRequest;
use App\Router\Response\RedirectResponse;
class AuthMiddleware extends Middleware {
public function handle(IRequest $request, callable $next) {
// if (isset($_SESSION['user'])) {
// $resp =new RedirectResponse("/");
// $resp->send();
// exit;
// }
// La page nest pas redirigée correctement
// Firefox a détecté que le serveur redirige la demande pour cette adresse dune manière qui naboutira pas.
private IAuthService $auth;
public function __construct(IAuthService $auth) {
$this->auth = $auth;
}
public function handle(IRequest $request, callable $next) {
$excludedUrls = ['/login', '/register','/forgetPassword', '/', '/mock'];
if ($this->auth->getCurrentUser() === null && !in_array($request->getRequestUri(), $excludedUrls)) {
$resp = new RedirectResponse("/login");
$resp->send();
exit;
}
// La cause de ce problème peut être la désactivation ou le refus des cookies.
// if (!isset($_SESSION['user'])) {
// $resp =new RedirectResponse("/log");
// $resp->send();
// exit;
// }
return parent::handle($request, $next);
}
}

@ -2,6 +2,9 @@
namespace App\Router\Response;
use App\Router\Session;
use Shared\Log;
class RedirectResponse implements IResponse
{
private $content;
@ -49,6 +52,7 @@ class RedirectResponse implements IResponse
public function send(): void
{
http_response_code($this->statusCode);
foreach ($this->headers as $name => $value) {

@ -1,6 +1,8 @@
<?php
namespace App\Router\Response;
use Shared\Log;
class Response implements IResponse {
private string $content;
private int $statusCode;

@ -1,5 +1,6 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
@ -34,14 +35,10 @@
<input class="form-check-input" id="inputRememberPassword" type="checkbox" value="" />
<label class="form-check-label" for="inputRememberPassword">Mémoriser le mot de passe</label>
</div>
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="password.html">Mot de passe oublié ?</a>
<a class="btn btn-primary" href="index.html">Se connecter</a>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="register.html">Besoin d'un compte ? Inscrivez-vous !</a></div>
</div>
</div>
</div>

@ -7,9 +7,12 @@
<meta name="description" content="Accueil" />
<meta name="author" content="PINAGOT Antoine" />
<title>{% block title %}{% endblock %}</title>
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@7.1.2/dist/style.min.css" rel="stylesheet" />
<link href="/css/{% block css %}style{% endblock %}.css" rel="stylesheet" />
<link href="/css/{% block css %}styles{% endblock %}.css" rel="stylesheet" />
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet/dist/leaflet.css" />
</head>
<body class="sb-nav-fixed">
<nav class="sb-topnav navbar navbar-expand navbar-dark bg-dark">
@ -35,7 +38,7 @@
<li><a class="dropdown-item" href="/profile">Profile</a></li>
<li><a class="dropdown-item" href="/settings">Paramètres</a></li>
<li><hr class="dropdown-divider" /></li>
<li><a class="dropdown-item" href="/logout">Déconnexion</a></li>
<li><a class="dropdown-item" href="/">Déconnexion</a></li>
</ul>
</li>
</ul>
@ -46,7 +49,7 @@
<div class="sb-sidenav-menu">
<div class="nav">
<div class="sb-sidenav-menu-heading">Menu</div>
<a class="nav-link" href="/">
<a class="nav-link" href="/home">
<div class="sb-nav-link-icon"><img src="/assets/img/house.png"></div>
Accueil
</a>
@ -55,9 +58,9 @@
<div class="sb-nav-link-icon"><img src="/assets/img/sprinter.png"></div>
Exercices
</a>
<a class="nav-link" href="/analyses">
<a class="nav-link" href="/activity">
<div class="sb-nav-link-icon"><i class="fas fa-chart-area"></i></div>
Analyses
Activités
</a>
<div class="sb-sidenav-menu-heading">Social</div>
<a class="nav-link" href="/friendlist">
@ -68,7 +71,7 @@
<div class="sb-nav-link-icon"><img src="/assets/img/coaching.png"></div>
Coaching
</a>
<a class="nav-link" href="/mail">
<a class="nav-link" href="/notification">
<div class="sb-nav-link-icon"><img src="/assets/img/letter.png"></div>
Messagerie
</a>
@ -108,7 +111,6 @@
<script src="js/scripts.js"></script>
{# <script src="js/preference.js"></script> #}
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.8.0/Chart.min.js" crossorigin="anonymous"></script>
<script src=".assets/demo/chart-area-demo.js"></script>
<script src="assets/demo/chart-bar-demo.js"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@7.1.2/dist/umd/simple-datatables.min.js" crossorigin="anonymous"></script>
<script src="js/datatables-simple-demo.js"></script>

@ -21,7 +21,7 @@
<h1 class="display-1">{% block nb %}{% endblock %}</h1>
<p class="lead">{% block name %}{% endblock %}</p>
<p>{% block descr %}{% endblock %}</p>
<a href="/">
<a href="/home">
<i class="fas fa-arrow-left me-1"></i>
Retour à l'accueil
</a>

@ -4,30 +4,84 @@
{% block css %}{{css}}{% endblock %}
{% block title %}Exercices - HearthTrack{% endblock %}
{% block title %}Analyses - HearthTrack{% endblock %}
{% block user %}{{user}} - {{role}}{% endblock %}
{% block body %}
<div class="container-fluid px-4">
<h1 class="mt-4">Exercices</h1>
<h1 class="mt-4">Analyses</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item active">Exercices</li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Analyses</li>
</ol>
<div class="card-body">
<div class="datatable-container">
<form method="post" action="/exercices">
Type : <input type="text" name="type"/>
Intensité : <input type="text" name="intensite"/>
Date : <input type="text" name="date"/>
<button class="btn btn-primary btn-mrg" id="btnNavbarSearch" type="submit">Ajouter l'exercice</button>
</form>
<table id="datatablesSimple" class="datatable-table">
<thead>
<tr>
<th>Date</th>
<th>Heure de début</th>
<th>Heure de fin</th>
<th>Type</th>
<th>effort ressenti</th>
<th>Variabilité</th>
<th>Variance</th>
<th>Ecart type</th>
<th>Moyenne</th>
<th>Maximum</th>
<th>Minimum</th>
<th>Temperature moyenne</th>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date</th>
<th>Heure de début</th>
<th>Heure de fin</th>
<th>Type</th>
<th>effort ressenti</th>
<th>Variabilité</th>
<th>Variance</th>
<th>Ecart type</th>
<th>Moyenne</th>
<th>Maximum</th>
<th>Minimum</th>
<th>Temperature moyenne</th>
</tr><tr></tr>
</tfoot>
<tbody>
{% for analyze in analyzes %}
<tr>
<td>{{analyze.date}}</td>
<td>{{analyze.heureDebut}}</td>
<td>{{analyze.heureFin}}</td>
<td>{{analyze.type}}</td>
<td>{{analyze.effortRessenti}}</td>
<td>{{analyze.variabilite}}</td>
<td>{{analyze.variance}}</td>
<td>{{analyze.ecartType}}</td>
<td>{{analyze.moyenne}} Bpm</td>
<td>{{analyze.max}} Bpm</td>
<td>{{analyze.min}} Bpm</td>
<td>{{analyze.temperature}} °C</td>
<td><a href="/analyze?id={{ analyze.idactivity }}">En savoir plus</a></td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<h1>{{responce}}</h1>
{% endblock %}
{% block script %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="js/scripts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@7.1.2/dist/umd/simple-datatables.min.js" crossorigin="anonymous"></script>
<script src="js/datatables-simple-demo.js"></script>
{% endblock %}

@ -12,7 +12,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Liste d'ami</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Ami</li>
</ol>

@ -12,7 +12,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Coaching</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Coaching</li>
</ol>

@ -4,63 +4,151 @@
{% block css %}{{css}}{% endblock %}
{% block title %}Analyses - HearthTrack{% endblock %}
{% block title %}Exercices - HearthTrack{% endblock %}
{% block user %}{{user}} - {{role}}{% endblock %}
{% block body %}
<div class="container-fluid px-4">
<h1 class="mt-4">Analyses</h1>
<h1 class="mt-4">Exercices</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item active">Analyses</li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Exercices</li>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
</ol>
<div class="card-body">
<div class="datatable-container">
<table id="datatablesSimple" class="datatable-table">
<thead>
<tr>
<th>Date</th>
<th>Type</th>
<th>BMP</th>
<th>KM/H</th>
<th>Distance</th>
<th></th>
</tr>
</thead>
<tfoot>
<tr>
<th>Date</th>
<th>Type</th>
<th>BPM</th>
<th>KM/H</th>
<th>Distance</th>
</tr><tr></tr>
{# <table id="datatablesSimple" class="datatable-table">#}
{# <thead>#}
{# <tr>#}
{# <th>id FC</th>#}
{# <th>altitude</th>#}
{# <th>temps</th>#}
{# <th>Temperature</th>#}
{# <th>bpm</th>#}
{# <th>longitude</th>#}
{# <th>latitude</th>#}
{# <th>activiteid</th>#}
{# <th></th>#}
{# </tr>#}
{# </thead>#}
{# {% for analyze in analyzes %}#}
{# <tbody>#}
{# <tr>#}
{# <td>{{analyze.idfc}}</td>#}
{# <td>{{analyze.altitude}}</td>#}
{# <td>{{analyze.temps}}</td>#}
{# <td>{{analyze.temperature}}</td>#}
{# <td>{{analyze.bpm}}</td>#}
{# <td>{{analyze.longitude}}</td>#}
{# <td>{{analyze.latitude}}</td>#}
{# <td>{{analyze.activiteid}}</td>#}
{# <td><a href="/home">Home</a></td>#}
{# </tr>#}
{# </tbody>#}
{# {% endfor %}#}
{# </table>#}
{# <div>#}
{# <canvas id="myChart" width="400" height="200">#}
{# <p>Hello Fallback World</p>#}
{# </canvas>#}
{# </div>#}
{# <script src="https://cdn.jsdelivr.net/npm/chart.js"></script>#}
{# <script>#}
{# const ctx = document.getElementById('myChart');#}
{# new Chart(ctx, {#}
{# type: 'line',#}
{# data: {#}
{# labels: [#}
{# {% for analyze in analyzes %}#}
{# {{analyze.temps}}#}
{# {% endfor %}#}
{# ],#}
{# datasets: [{#}
{# label: 'Batement par minute',#}
{# data: [#}
{# {% for analyze in analyzes %}#}
{# {{analyze.bpm}}#}
{# {% endfor %}#}
{# ],#}
{# borderWidth: 1#}
{# }]#}
{# },#}
{# options: {#}
{# scales: {#}
{# y: {#}
{# beginAtZero: true#}
{# }#}
{# }#}
{# }#}
{# });#}
{# </script>#}
<div>
<canvas id="myChart" height="50">
<p>Hello Fallback World</p>
</canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
const ctx = document.getElementById('myChart');
const labels = [
{% for analyze in analyzes %}
'{{ analyze.temps }}',
{% endfor %}
];
const data = [
{% for analyze in analyzes %}
{{ analyze.bpm }},
{% endfor %}
];
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Batement par minute',
data: data,
borderWidth: 1,
tension: 0.2,
fill: false,
borderColor: 'rgb(255, 0, 0)'
}]
},
options: {
scales: {
y: {
beginAtZero: false
}
}
}
});
</script>
<div class="card-body">
<div id="map" style="height: 500px;"></div>
<script>
document.addEventListener("DOMContentLoaded", function () {
{#var lat = {{ analyze.latitude }}#}
var map = L.map('map').setView([45.75771709151474, 3.113484980409329], 14);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map);
</tfoot>
<tbody>
{% for analyze in analyzes %}
<tr>
<td>{{analyze.date}}</td>
<td>{{analyze.type}}</td>
<td>{{analyze.bpm}}</td>
<td>{{analyze.kmh}} Km/H</td>
<td>{{analyze.distance}} Km</td>
<td><a href="#about">En savoir plus</a></td>
</tr>
var marker = L.marker([{{ analyze.latitude }}, {{ analyze.longitude }}]).addTo(map);
marker.bindPopup(`
<strong>Date:</strong> {{ analyze.temps }}<br>
<strong>FC:</strong> {{ analyze.bpm }}<br>
<strong>Altitude:</strong> {{ analyze.altitude }}<br>
<strong>Temperature:</strong> {{ analyze.temperature }}
`);
{% endfor %}
</tbody>
</table>
});
</script>
</div>
</div>
</div>
</div>
</div>
{% endblock %}
{% block script %}
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" crossorigin="anonymous"></script>
<script src="js/scripts.js"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@7.1.2/dist/umd/simple-datatables.min.js" crossorigin="anonymous"></script>
<script src="js/datatables-simple-demo.js"></script>
<h1>{{responce}}</h1>
{% endblock %}

@ -13,7 +13,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Coaching</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Coaching</li>
</ol>
<style>.btn-mrg{margin:15px; margin-left:83%}</style>

@ -9,10 +9,11 @@
{% block user %}{{user}} - {{role}}{% endblock %}
{% block body %}
<div class="container-fluid px-4">
<h1 class="mt-4">Exercices</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Exercices</li>
</ol>
<style>.btn-mrg{margin:15px; margin-left:85%}</style>
@ -25,18 +26,39 @@
<thead>
<tr>
<th>Date</th>
<th>Type</th>
<th>Intensité prévue</th>
<th>Status</th>
<th>Description</th>
<th>Localisation</th>
<th>FeedBack</th>
</tr>
</thead>
<tbody>
<script src="https://unpkg.com/leaflet/dist/leaflet.js"></script>
{% for exo in exos %}
<tr>
<td>{{ exo.date }}</td>
<td>{{exo.type}}</td>
<td>{{exo.intensite}}</td>
<td>{{exo.status}}</td>
<td>{{ exo.description }}</td>
<td>
<div id="map-{{ loop.index }}"
data-lat=45.758285982369415
data-lng=3.110223414416445
style="height: 300px; width: 650px;"></div>
<script>
document.addEventListener("DOMContentLoaded", function() {
var map{{ loop.index }} = L.map('map-{{ loop.index }}').setView([45.75771709151474, 3.113484980409329], 14);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: '© OpenStreetMap contributors'
}).addTo(map{{ loop.index }});
var marker{{ loop.index }} = L.marker([45.75771709151474, 3.113484980409329]).addTo(map{{ loop.index }});
marker{{ loop.index }}.bindPopup(`
<strong>Date:</strong> {{ exo.date }}<br>
<strong>Description:</strong> {{ exo.description }}<br>
<strong>Feedback:</strong> {{ exo.feedback }}
`);
});
</script>
</td>
<td>{{ exo.feedback }}</td>
</tr>
{% endfor %}
</tbody>

@ -12,7 +12,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Liste d'ami</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Ami</li>
</ol>
<style>.btn-mrg{margin:15px; margin-left:87%}</style>

@ -21,9 +21,42 @@
<i class="fas fa-chart-area me-1"></i>
Stastiques globales
</div>
<div class="card-body">
{# <canvas id="myAreaChart" width="100%" height="40"></canvas> #}
</div>
<div>
<canvas id="myChart" height="50" width="100">
</canvas>
</div>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
var ctx = document.getElementById('myChart');
var chartsData = {{ charts|json_encode|raw }};
var labels = chartsData.map((m) => m.mois);
var data = chartsData.map((m) => m.act);
new Chart(ctx, {
type: 'line',
data: {
labels: labels,
datasets: [{
label: 'Activité du mois',
data: data,
borderWidth: 1,
tension: 0.2,
fill: false,
borderColor: 'rgb(255, 0, 0)'
}]
},
options: {
scales: {
x: {
// type: 'linear', // Utiliser une échelle linéaire pour les mois
position: 'bottom'
},
y: {
beginAtZero: true
}
}
}
});
</script>
</div>
</div>

@ -12,30 +12,53 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Importer</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="home.html">Accueil</a></li>
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item active">Importer</li>
</ol>
<div class="row">
<div class="col">
<div class="card mb-4">
<div class="card-header">
<img src="/assets/img/bupload.png"></i>
Importer un fichier .fit
</div>
<div class="card-body">
<div style="text-align:center; margin-bottom: 15px;">
<label for="file-input">
<img src="/assets/img/uploadW.svg"/>
<div class="flex items-center justify-center">
<div class="sm:max-w-lg w-full p-10 bg-white rounded-xl z-10 ">
<div class="text-center">
<h2 class="mt-5 text-3xl font-bold text-gray-900">
Importer un fichier .fit !
</h2>
<p class="mt-2 text-sm text-gray-400">Let's go</p>
</div>
<form class="mt-8 space-y-3" action="/upload" method="POST" enctype="multipart/form-data">
<div class="grid grid-cols-1 space-y-2">
<label class="text-sm font-bold text-gray-500 tracking-wide">Veuillez renseigner le type d'activité</label>
<input class="text-base p-2 border border-gray-300 rounded-lg focus:outline-none focus:border-indigo-500" type="text" name="activityType" placeholder="Course à pied">
</div>
<div class="grid grid-cols-1 space-y-2">
<label class="text-sm font-bold text-gray-500 tracking-wide">Effort Level (0-5)</label>
<input class="text-base p-2 border border-gray-300 rounded-lg focus:outline-none focus:border-indigo-500" type="number" name="effort" min="0" max="5" placeholder="Enter effort level (0-5)">
</div>
<div class="grid grid-cols-1 space-y-2">
<label class="text-sm font-bold text-gray-500 tracking-wide">Attach Document</label>
<div class="flex items-center justify-center w-full">
<label class="flex flex-col rounded-lg border-4 border-dashed w-full h-60 p-10 group text-center cursor-pointer">
<div class="h-full w-full text-center flex flex-col items-center justify-center items-center ">
<div class="flex flex-auto max-h-48 w-2/5 mx-auto -mt-10">
<img class="has-mask h-36 object-center" src="https://img.freepik.com/free-vector/image-upload-concept-landing-page_52683-27130.jpg?size=338&ext=jpg" alt="freepik image">
</div>
<p class="pointer-none text-gray-500 "><span class="text-sm">Drag and drop</span> files here <br /> or
<span class="text-blue-600 hover:underline">select a file</span>
from your computer</p>
</div>
<input type="file" class="hidden" id="file-input" name="uploaded_file" accept=".fit">
</label>
<form action="/analyses" method="post">
<input id="file-input" type="file" name="fileToUpload" value=""style="visibility: hidden; width:0; height:0;"/>
<input type="submit" value="Soumettre le fichier" name="submit"/>
</form>
<p id="file-name-display" class="text-sm text-gray-500"></p>
</div>
</div>
<p class="text-sm text-gray-300">
<span>File type: .fit</span>
</p>
<div class="flex justify-center">
<button type="submit" class="my-5 w-3/4 flex justify-center bg-blue-500 text-gray-100 p-4 rounded-full tracking-wide
font-semibold focus:outline-none focus:shadow-outline hover:bg-blue-600 shadow-lg cursor-pointer transition ease-in duration-300">
Upload
</button>
</div>
</form>
</div>
</div>
</div>

@ -1 +1,338 @@
<a href="/log">Se connecter</button>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
<meta name="description" content="index page du site web" />
<meta name="author" content="PINAGOT Antoine" />
<title>HeartTrack - Getting Started</title>
<link rel="icon" type="image/x-icon" href="assets/favicon.ico" />
<!-- Bootstrap icons-->
<link href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css" rel="stylesheet" />
<!-- Google fonts-->
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,wght@0,600;1,600&amp;display=swap"
rel="stylesheet" />
<link
href="https://fonts.googleapis.com/css2?family=Mulish:ital,wght@0,300;0,500;0,600;0,700;1,300;1,500;1,600;1,700&amp;display=swap"
rel="stylesheet" />
<link href="https://fonts.googleapis.com/css2?family=Kanit:ital,wght@0,400;1,400&amp;display=swap"
rel="stylesheet" />
<!-- Core theme CSS (includes Bootstrap)-->
<link href="css/styles2.css" rel="stylesheet" />
</head>
<body id="page-top">
<!-- Navigation-->
<nav class="navbar navbar-expand-lg navbar-light fixed-top shadow-sm" id="mainNav">
<div class="container px-5">
<a class="navbar-brand fw-bold" href="/">HeartTrack</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarResponsive"
aria-controls="navbarResponsive" aria-expanded="false" aria-label="Toggle navigation">
Menu
<i class="bi-list"></i>
</button>
<div class="collapse navbar-collapse" id="navbarResponsive">
<ul class="navbar-nav ms-auto me-4 my-3 my-lg-0">
<li class="nav-item"><a class="nav-link me-lg-3" href="/login">Se connecter</a></li>
<li class="nav-item"><a class="nav-link me-lg-3" href="/register">S'inscire</a></li>
</ul>
<button class="btn btn-primary rounded-pill px-3 mb-2 mb-lg-0" data-bs-toggle="modal"
data-bs-target="#feedbackModal">
<span class="d-flex align-items-center">
<i class="bi-chat-text-fill me-2"></i>
<span class="small">Donnez votre avis</span>
</span>
</button>
</div>
</div>
</nav>
<!-- Mashead header-->
<header class="masthead">
<div class="container px-5">
<div class="row gx-5 align-items-center">
<div class="col-lg-6">
<!-- Mashead text and app badges-->
<div class="mb-5 mb-lg-0 text-center text-lg-start">
<h1 class="display-1 lh-1 mb-3">HeartTrack pour mobile !</h1>
<p class="lead fw-normal text-muted mb-5">Une application pour suivre vos analyses en direct,
est en cours de développement.</p>
<!-- <div class="d-flex flex-column flex-lg-row align-items-center">
<a class="me-lg-3 mb-4 mb-lg-0" href="#!"><img class="app-badge" src="assets/img/google-play-badge.svg" alt="..." /></a>
<a href="#!"><img class="app-badge" src="assets/img/app-store-badge.svg" alt="..." /></a>
</div> -->
</div>
</div>
<div class="col-lg-6">
<!-- Masthead device mockup feature-->
<div class="masthead-device-mockup">
<svg class="circle" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="circleGradient" gradientTransform="rotate(45)">
<stop class="gradient-start-color" offset="0%"></stop>
<stop class="gradient-end-color" offset="100%"></stop>
</linearGradient>
</defs>
<circle cx="50" cy="50" r="50"></circle>
</svg><svg class="shape-1 d-none d-sm-block" viewBox="0 0 240.83 240.83"
xmlns="http://www.w3.org/2000/svg">
<rect x="-32.54" y="78.39" width="305.92" height="84.05" rx="42.03"
transform="translate(120.42 -49.88) rotate(45)"></rect>
<rect x="-32.54" y="78.39" width="305.92" height="84.05" rx="42.03"
transform="translate(-49.88 120.42) rotate(-45)"></rect>
</svg><svg class="shape-2 d-none d-sm-block" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"></circle>
</svg>
<div class="device-wrapper">
<div class="device" data-device="iPhoneX" data-orientation="portrait" data-color="black">
<div class="screen bg-black">
<!-- PUT CONTENTS HERE:-->
<!-- * * This can be a video, image, or just about anything else.-->
<!-- * * Set the max width of your media to 100% and the height to-->
<!-- * * 100% like the demo example below.-->
<video muted="muted" autoplay="" loop="" style="max-width: 100%; height: 100%">
<source src="assets/img/demo-screen.mp4" type="video/mp4" />
</video>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</header>
<!-- Quote/testimonial aside-->
<aside class="text-center bg-gradient-primary-to-secondary">
<div class="container px-5">
<div class="row gx-5 justify-content-center">
<div class="col-xl-8">
<div class="h2 fs-1 text-white mb-4">"Une solution gratuite pour analyser vos données de fréquences
cardiaques !"</div>
<img src="assets/img/tnw-logo.svg" alt="..." style="height: 3rem" />
</div>
</div>
</div>
</aside>
<!-- App features section-->
<section id="features">
<div class="container px-5">
<div class="row gx-5 align-items-center">
<div class="col-lg-8 order-lg-1 mb-5 mb-lg-0">
<div class="container-fluid px-5">
<div class="row gx-5">
<div class="col-md-6 mb-5">
<!-- Feature item-->
<div class="text-center">
<i class="bi-phone icon-feature text-gradient d-block mb-3"></i>
<h3 class="font-alt">Web/Mobile</h3>
<p class="text-muted mb-0">Gardez les informations tant bien dans l'application que
sur le site web avec la synchronisation des données !</p>
</div>
</div>
<div class="col-md-6 mb-5">
<!-- Feature item-->
<div class="text-center">
<i class="bi-cast icon-feature text-gradient d-block mb-3"></i>
<h3 class="font-alt">Importez vos données</h3>
<p class="text-muted mb-0">Importez vos données directement depuis un fichier .FIT !
</p>
</div>
</div>
</div>
<div class="row">
<div class="col-md-6 mb-5 mb-md-0">
<!-- Feature item-->
<div class="text-center">
<i class="bi-gift icon-feature text-gradient d-block mb-3"></i>
<h3 class="font-alt">Gratuit</h3>
<p class="text-muted mb-0">Ce site et cette application sont entièrement gratuites !
</p>
</div>
</div>
<div class="col-md-6">
<!-- Feature item-->
<div class="text-center">
<i class="bi-patch-check icon-feature text-gradient d-block mb-3"></i>
<h3 class="font-alt">Open Source</h3>
<p class="text-muted mb-0">Ce projet est fait en Open Source, tout le monde peut y
accéder !</p>
</div>
</div>
</div>
</div>
</div>
<div class="col-lg-4 order-lg-0">
<!-- Features section device mockup-->
<div class="features-device-mockup">
<svg class="circle" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<defs>
<linearGradient id="circleGradient" gradientTransform="rotate(45)">
<stop class="gradient-start-color" offset="0%"></stop>
<stop class="gradient-end-color" offset="100%"></stop>
</linearGradient>
</defs>
<circle cx="50" cy="50" r="50"></circle>
</svg><svg class="shape-1 d-none d-sm-block" viewBox="0 0 240.83 240.83"
xmlns="http://www.w3.org/2000/svg">
<rect x="-32.54" y="78.39" width="305.92" height="84.05" rx="42.03"
transform="translate(120.42 -49.88) rotate(45)"></rect>
<rect x="-32.54" y="78.39" width="305.92" height="84.05" rx="42.03"
transform="translate(-49.88 120.42) rotate(-45)"></rect>
</svg><svg class="shape-2 d-none d-sm-block" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50"></circle>
</svg>
<div class="device-wrapper">
<div class="device" data-device="iPhoneX" data-orientation="portrait" data-color="black">
<div class="screen bg-black">
<!-- PUT CONTENTS HERE:-->
<!-- * * This can be a video, image, or just about anything else.-->
<!-- * * Set the max width of your media to 100% and the height to-->
<!-- * * 100% like the demo example below.-->
<video muted="muted" autoplay="" loop="" style="max-width: 100%; height: 100%">
<source src="assets/img/demo-screen.mp4" type="video/mp4" />
</video>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- Basic features section-->
<section class="bg-light">
<div class="container px-5">
<div class="row gx-5 align-items-center justify-content-center justify-content-lg-between">
<div class="col-12 col-lg-5">
<h2 class="display-4 lh-1 mb-4">Fonctionnalité supplémentaire de notre application</h2>
<p class="lead fw-normal text-muted mb-5 mb-lg-0">Notre application propose un service de coaching
personnalisé en fonction du besoin que vous avez en tant qu'athelète. Vous pouvez aussi fournir
un service de coaching aux autres utilisateurs en vous inscrivant en tant que coach sportif.</p>
</div>
<div class="col-sm-8 col-md-6">
<div class="px-5 px-sm-0"><img class="img-fluid rounded-circle" src="./assets/img/bg1.png"
alt="..." /></div>
</div>
</div>
</div>
</section>
<!-- Call to action section-->
<section class="cta">
<div class="cta-content">
<div class="container px-5">
<h2 class="text-white display-1 lh-1 mb-4">
Arrêtez d'attendre...
<br />
Inscrivez-vous !
</h2>
<!-- <a class="btn btn-outline-light py-3 px-4 rounded-pill" href="#" target="_blank">Download for free</a> -->
</div>
</div>
</section>
<!-- App badge section-->
<section class="bg-gradient-primary-to-secondary" id="download">
<div class="container px-5">
<h2 class="text-center text-white font-alt mb-4">Application bientôt disponible !</h2>
<!-- <div class="d-flex flex-column flex-lg-row align-items-center justify-content-center">
<a class="me-lg-3 mb-4 mb-lg-0" href="#!"><img class="app-badge" src="assets/img/google-play-badge.svg" alt="..." /></a>
<a href="#!"><img class="app-badge" src="assets/img/app-store-badge.svg" alt="..." /></a>
</div> -->
</div>
</section>
<!-- Footer-->
<footer class="bg-black text-center py-5">
<div class="container px-5">
<div class="text-white-50 small">
<div class="mb-2">&copy; HeartTrack 2023. Tous droits réservé.</div>
<a href="#!">Politique de confidentialité</a>
<span class="mx-1">&middot;</span>
<a href="#!">Termes & Conditions d'utilisation</a>
</div>
</div>
</footer>
<!-- Feedback Modal-->
<div class="modal fade" id="feedbackModal" tabindex="-1" aria-labelledby="feedbackModalLabel" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered">
<div class="modal-content">
<div class="modal-header bg-gradient-primary-to-secondary p-4">
<h5 class="modal-title font-alt text-white" id="feedbackModalLabel">Envoyez votre avis</h5>
<button class="btn-close btn-close-white" type="button" data-bs-dismiss="modal"
aria-label="Close"></button>
</div>
<div class="modal-body border-0 p-4">
<!-- * * * * * * * * * * * * * * *-->
<!-- * * SB Forms Contact Form * *-->
<!-- * * * * * * * * * * * * * * *-->
<!-- This form is pre-integrated with SB Forms.-->
<!-- To make this form functional, sign up at-->
<!-- https://startbootstrap.com/solution/contact-forms-->
<!-- to get an API token!-->
<form id="contactForm" data-sb-form-api-token="API_TOKEN">
<!-- Name input-->
<div class="form-floating mb-3">
<input class="form-control" id="name" type="text" placeholder="Entrez votre nom complet..."
data-sb-validations="required" />
<label for="name">Nom complet</label>
<div class="invalid-feedback" data-sb-feedback="name:required">Un nom est requis.</div>
</div>
<!-- Email address input-->
<div class="form-floating mb-3">
<input class="form-control" id="email" type="email" placeholder="nom@exemple.com"
data-sb-validations="required,email" />
<label for="email">Adresse email</label>
<div class="invalid-feedback" data-sb-feedback="email:required">Adresse email requis.</div>
<div class="invalid-feedback" data-sb-feedback="email:email">L'adresse email n'est pas
valide.</div>
</div>
<!-- Phone number input-->
<div class="form-floating mb-3">
<input class="form-control" id="phone" type="tel" placeholder="06 12 34 56 78"
data-sb-validations="required" />
<label for="phone">Numéro de téléphone</label>
<div class="invalid-feedback" data-sb-feedback="phone:required">Numéro de téléphone requis.
</div>
</div>
<!-- Message input-->
<div class="form-floating mb-3">
<textarea class="form-control" id="message" type="text"
placeholder="Entrez votre message..." style="height: 10rem"
data-sb-validations="required"></textarea>
<label for="message">Message</label>
<div class="invalid-feedback" data-sb-feedback="message:required">Un message est requis.
</div>
</div>
<!-- Submit success message-->
<!---->
<!-- This is what your users will see when the form-->
<!-- has successfully submitted-->
<div class="d-none" id="submitSuccessMessage">
<div class="text-center mb-3">
<div class="fw-bolder">Avis envoyé !</div>
</div>
</div>
<!-- Submit error message-->
<!---->
<!-- This is what your users will see when there is-->
<!-- an error submitting the form-->
<div class="d-none" id="submitErrorMessage">
<div class="text-center text-danger mb-3">Erreur du formulaire !</div>
</div>
<!-- Submit Button-->
<div class="d-grid"><button class="btn btn-primary rounded-pill btn-lg disabled"
id="submitButton" type="submit">Envoyer</button></div>
</form>
</div>
</div>
</div>
</div>
<!-- Bootstrap core JS-->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js"></script>
<!-- Core theme JS-->
<script src="js/scripts2.js"></script>
<script src="https://cdn.startbootstrap.com/sb-forms-latest.js"></script>
</body>
</html>

@ -5,33 +5,72 @@
{% block title %}Connexion - HearthTrack{% endblock %}
{% block main %}
{#<<<<<<< HEAD#}
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-5">
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header"><h3 class="text-center font-weight-light my-4">Connexion</h3></div>
<div class="card-body">
<form>
{% if login_error %}
{% for value in login_error %}
<div class="alert alert-danger" role="alert">
{{ value }}
{#=======#}
{# <div class="container">#}
{# <div class="row justify-content-center">#}
{# <div class="col-lg-5">#}
{# <div class="card shadow-lg border-0 rounded-lg mt-5">#}
{# <div class="card-header"><h3 class="text-center font-weight-light my-4">Connexion</h3></div>#}
{# <div class="card-body">#}
{# <form>#}
{# <div class="form-floating mb-3">#}
{# <input class="form-control" id="inputEmail" type="email" placeholder="nom@exemple.com" />#}
{# <label for="inputEmail">Adresse eMail</label>#}
{# </div>#}
{# <div class="form-floating mb-3">#}
{# <input class="form-control" id="inputPassword" type="password" placeholder="Mot de passe" />#}
{# <label for="inputPassword">Mot de passe</label>#}
{# </div>#}
{# <div class="form-check mb-3">#}
{# <input class="form-check-input" id="inputRememberPassword" type="checkbox" value="" />#}
{# <label class="form-check-label" for="inputRememberPassword">Mémoriser le mot de passe</label>#}
{# </div>#}
{# <div class="d-flex align-items-center justify-content-between mt-4 mb-0">#}
{# <a class="small" href="/pass">Mot de passe oublié ?</a>#}
{# <a class="btn btn-primary" href="/home">Se connecter</a>#}
{# </div>#}
{# </form>#}
{# </div>#}
{# <div class="card-footer text-center py-3">#}
{# <div class="small"><a href="/regist">Besoin d'un compte ? Inscrivez-vous !</a></div>#}
{# </div>#}
{#>>>>>>> origin/merged_PLE#}
</div>
{% endfor %}
{% endif %}
<form method="post" action="/login">
<div class="form-floating mb-3">
<input class="form-control" id="inputEmail" type="email" placeholder="nom@exemple.com" />
<label for="inputEmail">Adresse eMail</label>
<input class="form-control" id="email" name="email" type="text" placeholder="Nom d'utilisateur" />
<label for="email">Nom d'utilisateur</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" id="inputPassword" type="password" placeholder="Mot de passe" />
<label for="inputPassword">Mot de passe</label>
<input class="form-control" id="password" name="password" type="password" placeholder="Mot de passe" />
<label for="password">Mot de passe</label>
</div>
<div class="form-check mb-3">
<input class="form-check-input" id="inputRememberPassword" type="checkbox" value="" />
<label class="form-check-label" for="inputRememberPassword">Mémoriser le mot de passe</label>
</div>
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="password.html">Mot de passe oublié ?</a>
<a class="btn btn-primary" href="index.html">Se connecter</a>
<a class="small" href="/forgetPassword">Mot de passe oublié ?</a>
<button class="btn btn-primary" type="submit">Se connecter</button>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="register.html">Besoin d'un compte ? Inscrivez-vous !</a></div>
<div class="small"><a href="/register">Besoin d'un compte ? Inscrivez-vous !</a></div>
</div>
</div>
</div>

@ -23,14 +23,16 @@
<th>Lu</th>
<th>De:</th>
<th>Description</th>
<th>Date</th>
</tr>
</thead>
<tbody>
{% for mail in mails %}
<tr>
<td><img src="/assets/img/verif/{{mail.lu}}.png" width="25px" height="25px"></td>
<td>{{mail.nom}} {{mail.prenom}}</td>
<td><img src="/assets/img/verif/{{mail.idnotif}}.png" width="25px" height="25px"></td>
<td>{{mail.idathlete}}</td>
<td><a href="#">{{mail.message}}</a></td>
<td>{{ mail.date }}</td>
</tr>
{% endfor %}
</tbody>

@ -18,13 +18,13 @@
<label for="email">Adresse eMail</label>
</div>
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="/log">Retour à la connexion</a>
<button class="btn btn-primary" type="submit">Réinitialiser votre mot de passe</a>
<a class="small" href="/login">Retour à la connexion</a>
<button class="btn btn-primary" type="submit">Réinitialiser votre mot de passe</button>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="/regist">Besoin d'un compte ? Inscrivez-vous !</a></div>
<div class="small"><a href="/register">Besoin d'un compte ? Inscrivez-vous !</a></div>
</div>
</div>
</div>

@ -12,7 +12,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Profile</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Profile</li>
</ol>
<div class="row">

@ -11,82 +11,106 @@
<div class="card shadow-lg border-0 rounded-lg mt-5">
<div class="card-header"><h3 class="text-center font-weight-light my-4">Créer un compte</h3></div>
<div class="card-body">
{# Display error message if register_error is set #}
{% if register_error %}
{% for value in register_error %}
<div class="alert alert-danger" role="alert">
{{ value }}
</div>
{% endfor %}
{% endif %}
<form method="post" action="/register">
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputFirstName" type="text" placeholder="Entrez votre nom" />
<label for="inputFirstName">Nom de famille</label>
<input class="form-control" id="nom" name="nom" type="text" placeholder="Entrez votre nom" />
<label for="nom">Nom de famille</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<input class="form-control" id="inputLastName" type="text" placeholder="Entrez votre prénom" />
<label for="inputLastName">Prénom</label>
<input class="form-control" id="prenom" name="prenom" type="text" placeholder="Entrez votre prénom" />
<label for="prenom">Prénom</label>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<label for="inputUsername"></label><input class="form-control" id="inputUsername" type="text" placeholder="Entrez votre pseudonyme" />
<label for="inputFirstName">Nom d'utilisateur</label>
<input class="form-control" id="username" name="username" type="text" placeholder="Entrez votre pseudonyme" />
<label for="username">Nom d'utilisateur</label>
</div>
</div>
<div class="col-md-6">
<label for="sexe" >Sexe:</label>
<div class="form-floating">
<label for="inputLastName">Sexe</label>
<label for="gender"></label><select id="gender" name="gender">
<option value="male">Homme</option>
<option value="female">Femme</option>
<option value="unknown">Ne se prononce pas</option>
<select id="sexe" name="sexe">
<option value="M">Homme</option>
<option value="H">Femme</option>
<option value="M">Ne se prononce pas</option>
</select>
</div>
</div>
</div>
<div class="form-floating mb-3">
<input class="form-control" id="inputEmail" type="email" placeholder="nom@exemple.com" />
<label for="inputEmail">Adresse eMail</label>
<input class="form-control" id="mail" name="mail" type="mail" placeholder="nom@exemple.com" />
<label for="mail">Adresse eMail</label>
</div>
<div class="form-floating mb-3">
<input class="form-control" id="inputDateNaissance" type="date" placeholder="" />
<label for="inputEmail">Date de naissance</label>
<input class="form-control" id="dateNaissance" name="dateNaissance" type="date" placeholder="" />
<label for="dateNaissance">Date de naissance</label>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputTaille" type="text" placeholder="Entrez votre taille" />
<label for="inputPassword">Taille</label>
<input class="form-control" id="taille" name="taille" type="text" placeholder="Entrez votre taille" />
<label for="taille">Taille</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<label for="inputPoids"></label><input class="form-control" id="inputPoids" type="text" placeholder="Entrez votre poids" />
<label for="inputPasswordConfirm">Poids</label>
<input class="form-control" id="poids" name="poids" type="text" placeholder="Entrez votre poids" />
<label for="poids">Poids</label>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputPassword" type="password" placeholder="Créez un mot de passe" />
<label for="inputPassword">Mot de passe</label>
<input class="form-control" id="motDePasse" name="motDePasse" type="password" placeholder="Créez un mot de passe" />
<label for="motDePasse">Mot de passe</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputPasswordConfirm" type="password" placeholder="Confirmez votre mot de passe" />
<label for="inputPasswordConfirm">Confirmer le mot de passe</label>
<input class="form-control" id="confirmMdp" name="confirmMdp" type="password" placeholder="Confirmez votre mot de passe" />
<label for="confirmMdp">Confirmer le mot de passe</label>
</div>
</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="roleName" >Role:</label>
<div class="form-floating">
<select id="roleName" name="roleName">
<option value="Athlete">Athlete</option>
<option value="Coach">Coach</option>
</select>
</div>
</div>
</div>
<div class="mt-4 mb-0">
<div class="d-grid"><a class="btn btn-primary btn-block" href="login.html.twig">Créer un compte</a></div>
<div class="d-grid">
<button type="submit" class="btn btn-primary btn-block">Créer un compte</button>
</div>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="login.html.twig">Avez-vous déjà un compte ? Connectez-vous ?</a></div>
<div class="small"><a href="/login">Avez-vous déjà un compte ? Connectez-vous ?</a></div>
</div>
</div>
</div>

@ -12,7 +12,7 @@
<div class="container-fluid px-4">
<h1 class="mt-4">Paramètres</h1>
<ol class="breadcrumb mb-4">
<li class="breadcrumb-item"><a href="/">Accueil</a></li>
<li class="breadcrumb-item"><a href="/home">Accueil</a></li>
<li class="breadcrumb-item active">Paramètres</li>
</ol>
<div class="row">

@ -763,7 +763,13 @@ function profileMenu(Model $model)
do {
$effort = trim(fgets(STDIN));
} while ($effort < 0 || $effort > 5);
try {
$isAddActivity = $model->activityMgr->uploadFile($typeActivity, $effort, $passFile);
}catch (\Throwable $exception){
echo $exception;
}
echo $isAddActivity ? "Activité ajoutée avec succès" : "Erreur lors de l'ajout de l'activité";
case '0':
return;
@ -793,7 +799,7 @@ while (true) {
}*/
break;
case '2': // S'inscrire
if($model->userMgr->login("bruce.lee@example.com", "hello321"))
if($model->userMgr->login("bruce.lee@example.com", "password123"))
$loggedIn = true;
// if (registerUser($model)) {
// $loggedIn = true;

@ -2,15 +2,19 @@
namespace Data\Core;
use Shared\Log;
class Preferences {
private String $cookie;
private Array $theme;
private string $cookie;
private array $theme;
public function __construct(){
if (isset($_COOKIE['preferences'])){
$this->cookie = $_COOKIE['preferences'];
} else {
$this->cookie = setcookie('preferences', 'base_theme', time()+(3600*24)*7);
if(setcookie('preferences', 'base_theme', time()+(3600*24)*7)){
$this->cookie = 'base_theme';
}
}
$this->theme = array(
'base_theme',
@ -19,7 +23,7 @@
);
}
public function majCookie(String $maj){
public function majCookie(string $maj){
try{
foreach($this->theme as $t){
$this->cookie = $maj;
@ -30,8 +34,8 @@
}
}
public function getCookie():String{
return $this->cookie;
public function getCookie():string{
return $this->cookie ?? "base_theme";
}
}

@ -0,0 +1,129 @@
<?php
namespace Database;
use DateTime;
class ActivityEntity {
private $idActivity;
private $type;
private DateTime $date;
private DateTime $heureDebut;
private DateTime $heureFin;
private $effortRessenti;
private $variabilite;
private $variance;
private $ecartType;
private $moyenne;
private $maximum;
private $minimum;
private $temperatureMoyenne;
// Getters
public function getIdActivity() {
return $this->idActivity;
}
public function getType() {
return $this->type;
}
public function getDate() {
return $this->date;
}
public function getHeureDebut() {
return $this->heureDebut;
}
public function getHeureFin() {
return $this->heureFin;
}
public function getEffortRessenti() {
return $this->effortRessenti;
}
public function getVariability() {
return $this->variabilite;
}
public function getVariance() {
return $this->variance;
}
public function getEcartType() {
return $this->ecartType;
}
public function getMoyenne() {
return $this->moyenne;
}
public function getMaximum() {
return $this->maximum;
}
public function getMinimum() {
return $this->minimum;
}
public function getTemperatureMoyenne() {
return $this->temperatureMoyenne;
}
// Setters
public function setIdActivity($idActivity) {
$this->idActivity = $idActivity;
}
public function setType($type) {
$this->type = $type;
}
public function setDate($date) {
$this->date = $date;
}
public function setHeureDebut($heureDebut) {
$this->heureDebut = $heureDebut;
}
public function setHeureFin($heureFin) {
$this->heureFin = $heureFin;
}
public function setEffortRessenti($effortRessenti) {
$this->effortRessenti = $effortRessenti;
}
public function setVariabilite($variabilite) {
$this->variabilite = $variabilite;
}
public function setVariance($variance) {
$this->variance = $variance;
}
public function setEcartType($ecartType) {
$this->ecartType = $ecartType;
}
public function setMoyenne($moyenne) {
$this->moyenne = $moyenne;
}
public function setMaximum($maximum) {
$this->maximum = $maximum;
}
public function setMinimum($minimum) {
$this->minimum = $minimum;
}
public function setTemperatureMoyenne($temperatureMoyenne) {
$this->temperatureMoyenne = $temperatureMoyenne;
}
}
?>

@ -0,0 +1,124 @@
<?php
namespace Database;
use \PDO;
use Shared\Log;
class ActivityGateway {
private Connexion $connection;
public function __construct(Connexion $connection) {
$this->connection = $connection;
}
public function getActivity() {
$query = "SELECT * FROM Activite";
return $this->connection->executeWithErrorHandling($query);
}
public function getActivityById(int $activityId) {
$query = "SELECT * FROM Activite WHERE idActivite = :id";
$params = [':id' => $activityId];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByType(string $type) {
$query = "SELECT * FROM Activite WHERE type = :type";
$params = [':type' => [$type, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByDate(string $date) {
$query = "SELECT * FROM Activite WHERE date = :date";
$params = [':date' => [$date, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByTimeRange(string $startTime, string $endTime) {
$query = "SELECT * FROM Activite WHERE heureDebut >= :startTime AND heureFin <= :endTime";
$params = [
':startTime' => [$startTime, PDO::PARAM_STR],
':endTime' => [$endTime, PDO::PARAM_STR]
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByEffort(int $effortRessenti) {
$query = "SELECT * FROM Activite WHERE effortRessenti = :effort";
$params = [':effort' => [$effortRessenti, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByVariability(int $variabilite) {
$query = "SELECT * FROM Activite WHERE variabilite = :variability";
$params = [':variability' => [$variabilite, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActivityByTemperature(int $temperatureMoyenne) {
$query = "SELECT * FROM Activite WHERE temperatureMoyenne = :temperature";
$params = [':temperature' => [$temperatureMoyenne, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addActivity(ActivityEntity $activity) {
$query = "INSERT INTO Activite (idactivite, type, date, heurededebut, heuredefin, effortressent, variabilite, variance, ecarttype, moyenne, maximum, minimum, temperaturemoyenne, athleteid, sourceid)
VALUES (:idactivite, :type, :date, :heureDebut, :heureDeFin, :effortRessenti, :variabilite, :variance, :ecartType, :moyenne, :maximum, :minimum, :temperatureMoyenne, :athleteid, :sourceid)";
$params = [
':idactivite' => $activity->getIdActivity(),
':type' => $activity->getType(),
':date' => $activity->getDate()->format('Y-m-d'), // Format date pour SQL
':heureDebut' => $activity->getHeureDebut()->format('H:i:s'), // Format heure pour SQL
':heureDeFin' => $activity->getHeureFin()->format('H:i:s'), // Format heure pour SQL
':effortRessenti' => $activity->getEffortRessenti(),
':variabilite' => $activity->getVariability(),
':variance' => $activity->getVariance(),
':ecartType' => $activity->getEcartType(),
':moyenne' => $activity->getMoyenne(),
':maximum' => $activity->getMaximum(),
':minimum' => $activity->getMinimum(),
':temperatureMoyenne' => $activity->getTemperatureMoyenne(),
':athleteid' => 1,
':sourceid' => 1,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateActivity(ActivityEntity $oldActivity, ActivityEntity $newActivity) {
$query = "UPDATE Activite
SET type = :type, date = :date, heureDebut = :heureDebut, heureDeFin = :heureDeFin,
effortRessenti = :effortRessenti, variabilite = :variabilite, variance = :variance, ecartType = :ecartType, moyenne = :moyenne, maximum = :maximum, minimum = :minimum, temperatureMoyenne = :temperatureMoyenne
WHERE idActivite = :idActivite";
$params = [
':idActivite' => $oldActivity->getIdActivity(),
':type' => $newActivity->getType(),
':date' => $newActivity->getDate()->format('Y-m-d'), // Format date pour SQL
':heureDebut' => $newActivity->getHeureDebut()->format('H:i:s'), // Format heure pour SQL
':heureDeFin' => $newActivity->getHeureFin()->format('H:i:s'), // Format heure pour SQL
':effortRessenti' => $newActivity->getEffortRessenti(),
':variabilite' => $newActivity->getVariabilite(),
':variance' => $newActivity->getVariance(),
':ecartType' => $newActivity->getEcartType(),
':moyenne' => $newActivity->getMoyenne(),
':maximum' => $newActivity->getMaximum(),
':minimum' => $newActivity->getMinimum(),
':temperatureMoyenne' => $newActivity->getTemperatureMoyenne(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteActivity(int $idActivity) {
$query = "DELETE FROM Activite WHERE idActivite = :idActivity";
$params = [
':idActivity' => $idActivity,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
}
?>

@ -0,0 +1,126 @@
<?php
namespace Database;
use DateTime;
use Model\Activity;
use Shared\Log;
class ActivityMapper {
public function activitySqlToEntity(array $data):array
{
$activityEntities = [];
foreach ($data as $activityData) {
$activity = new ActivityEntity();
if (isset($activityData['idActivite'])) {
$activity->setIdActivity($activityData['idActivite']);
}
if (isset($activityData['type'])) {
$activity->setType($activityData['type']);
}
if (isset($activityData['date'])) {
$activity->setDate(new DateTime($activityData['date']));
}
if (isset($activityData['heureDeDebut'])) {
$activity->setHeureDebut(new DateTime($activityData['heureDeDebut']));
}
if (isset($activityData['heureDeFin'])) {
$activity->setHeureFin(new DateTime($activityData['heureDeFin']));
}
if (isset($activityData['effortRessent'])) {
$activity->setEffortRessenti($activityData['effortRessent']);
}
if (isset($activityData['variabilite'])) {
$activity->setVariabilite($activityData['variabilite']);
}
if (isset($activityData['variance'])) {
$activity->setVariance($activityData['variance']);
}
if (isset($activityData['ecartType'])) {
$activity->setEcartType($activityData['ecartType']);
}
if (isset($activityData['moyenne'])) {
$activity->setMoyenne($activityData['moyenne']);
}
if (isset($activityData['maximum'])) {
$activity->setMaximum($activityData['maximum']);
}
if (isset($activityData['minimum'])) {
$activity->setMinimum($activityData['minimum']);
}
if (isset($activityData['temperatureMoyenne'])) {
$activity->setTemperatureMoyenne($activityData['temperatureMoyenne']);
}
$activityEntities[] = $activity;
}
return $activityEntities;
}
/**
* @throws \Exception
*/
public function ActivityEntityToModel(ActivityEntity $activiteEntity):Activity {
$date = new DateTime($activiteEntity->getDate()->format('Y-m-d'));
$heureDebut = new \DateTime($activiteEntity->getHeureDebut()->format('H:i:s'));
$heureFin = new \DateTime($activiteEntity->getHeureFin()->format('H:i:s'));
$effortRessenti = intval($activiteEntity->getEffortRessenti());
$variability = floatval($activiteEntity->getVariability());
$variance = floatval($activiteEntity->getVariance());
$ecartType = floatval($activiteEntity->getEcartType());
$act = new Activity(
$activiteEntity->getType(),
$date,
$heureDebut,
$heureFin,
$effortRessenti,
$variability,
$variance,
$ecartType,
$activiteEntity->getMoyenne(),
$activiteEntity->getMaximum(),
$activiteEntity->getMinimum(),
$activiteEntity->getTemperatureMoyenne(),
'false'
);
return $act;
}
//public function ActivityToEntity(Activity model): ActivityEntity;
public function activityToEntity(Activity $act):ActivityEntity{
$actEntity = new ActivityEntity();
$actEntity->setIdActivity($act->getIdActivity());
$actEntity->setType($act->getType());
$actEntity->setDate($act->getDate());
$actEntity->setHeureDebut($act->getHeureDebut());
$actEntity->setHeureFin($act->getHeureFin());
$actEntity->setEffortRessenti($act->getEffortRessenti());
$actEntity->setVariabilite($act->getVariability());
$actEntity->setVariance($act->getVariance());
$actEntity->setEcartType($act->getStandardDeviation());
$actEntity->setMoyenne($act->getAverage());
$actEntity->setMaximum($act->getMaximum());
$actEntity->setMinimum($act->getMinimum());
$actEntity->setTemperatureMoyenne($act->getAvrTemperature());
return $actEntity;
}
}
?>

@ -0,0 +1,79 @@
<?php
namespace Database;
class AnalyzeEntity
{
private $idFc;
private $altitude;
private $time;
private $temperature;
private $bpm;
private $longitude;
private $latitude;
private $idactivity;
public function getIdFC()
{
return $this->idFc;
}
public function getAltitude()
{
return $this->altitude;
}
public function getTime()
{
return $this->temps;
}
public function getTemperature()
{
return $this->temperature;
}
public function getBpm()
{
return $this->bpm;
}
public function getLongitude()
{
return $this->longitude;
}
public function getLatitude()
{
return $this->latitude;
}
public function getIdActivity()
{
return $this->idactivity;
}
public function setIdFC($idFc)
{
$this->idFc = $idFc;
}
public function setAltitude($altitude)
{
$this->altitude = $altitude;
}
public function setTime($time)
{
$this->time = $time;
}
public function setTemperature($temperature)
{
$this->temperature = $temperature;
}
public function setBpm($bpm)
{
$this->bpm = $bpm;
}
public function setLongitude($longitude)
{
$this->longitude = $longitude;
}
public function setLatitude($latitude)
{
$this->latitude = $latitude;
}
public function setIdActivity($idactivity)
{
$this->idactivity = $idactivity;
}
}

@ -0,0 +1,24 @@
<?php
namespace Database;
class AnalyzeGateway
{
private Connexion $connection;
public function __construct(Connexion $connection) {
$this->connection = $connection;
}
public function getFrequenceCardiaque() {
$query = "SELECT * FROM FrequenceCardiaque";
return $this->connection->executeWithErrorHandling($query);
}
public function getFrequenceCardiaqueByIdActivity(int $activityId)
{
$query = "SELECT * FROM FrequenceCardiaque WHERE activiteid = :id";
$params = [':id' => $activityId];
return $this->connection->executeWithErrorHandling($query, $params);
}
}

@ -0,0 +1,125 @@
<?php
namespace Database;
use Shared\Log;
class AnalyzeMapper
{
public function analyzeSqlToEntity(array $data):array
{
$analyzeEntities = [];
foreach ($data as $analyzeData) {
$analyze = new ActivityEntity();
if (isset($analyzeData['idactivite'])) {
$analyze->setIdActivity($analyzeData['idactivite']);
}
if (isset($analyzeData['type'])) {
$analyze->setType($analyzeData['type']);
}
if (isset($analyzeData['date'])) {
$analyze->setDate($analyzeData['date']);
}
if (isset($analyzeData['heurededebut'])) {
$analyze->setHeureDebut($analyzeData['heurededebut']);
}
if (isset($analyzeData['heuredefin'])) {
$analyze->setHeureFin($analyzeData['heuredefin']);
}
if (isset($analyzeData['effortressent'])) {
$analyze->setEffortRessenti($analyzeData['effortressent']);
}
if (isset($analyzeData['variabilite'])) {
$analyze->setVariabilite($analyzeData['variabilite']);
}
if (isset($analyzeData['variance'])) {
$analyze->setVariance($analyzeData['variance']);
}
if (isset($analyzeData['ecarttype'])) {
$analyze->setEcartType($analyzeData['ecarttype']);
}
if (isset($analyzeData['moyenne'])) {
$analyze->setMoyenne($analyzeData['moyenne']);
}
if (isset($analyzeData['maximum'])) {
$analyze->setMaximum($analyzeData['maximum']);
}
if (isset($analyzeData['minimum'])) {
$analyze->setMinimum($analyzeData['minimum']);
}
if (isset($analyzeData['temperaturemoyenne'])) {
$analyze->setTemperatureMoyenne($analyzeData['temperaturemoyenne']);
}
$analyzeEntities[] = $analyze;
}
return $analyzeEntities;
}
/**
* @throws \Exception
*/
// public function ActivityEntityToModel(ActivityEntity $activiteEntity):Activity {
// $date = new DateTime($activiteEntity->getDate());
// $heureDebut = new \DateTime($activiteEntity->getHeureDebut());
// $heureFin = new \DateTime($activiteEntity->getHeureFin());
// $effortRessenti = intval($activiteEntity->getEffortRessenti());
// $variability = floatval($activiteEntity->getVariability());
// $variance = floatval($activiteEntity->getVariance());
// $ecartType = floatval($activiteEntity->getEcartType());
//
// $act = new Activity(
// $activiteEntity->getIdActivity(),
// $activiteEntity->getType(),
// $date,
// $heureDebut,
// $heureFin,
// $effortRessenti,
// $variability,
// $variance,
// $ecartType,
// $activiteEntity->getMoyenne(),
// $activiteEntity->getMaximum(),
// $activiteEntity->getMinimum(),
// $activiteEntity->getTemperatureMoyenne(),
// 'false'
// );
//
// return $act;
// }
//public function ActivityToEntity(Activity model): ActivityEntity;
// public function activityToEntity( $act):ActivityEntity{
//
// $act = new ActivityEntity();
// $act->setIdActivity($act->getIdActivity()());
// $act->setType($act->getType());
// $act->setDate($act->getDate());
// $act->setHeureDebut($act->getHeureDebut());
// $act->setHeureFin($act->getHeureFin());
// $act->setEffortRessenti($act->getEffortRessenti());
// $act->setVariabilite($act->getVariability());
// $act->setVariance($act->getVariance());
// $act->setEcartType($act->getEcartType());
// $act->setMoyenne($act->getMoyenne());
// $act->setMaximum($act->getMaximum());
// $act->setMinimum($act->getMinimum());
// $act->setTemperatureMoyenne($act->getTemperatureMoyenne());
//
// return $act;
// }
}

@ -6,12 +6,14 @@ class AthleteEntity {
private $idAthlete;
private $nom;
private $prenom;
private $username;
private $email;
private $sexe;
private $taille;
private $poids;
private $motDePasse;
private $dateNaissance;
private $isCoach;
// Getters
public function getIdAthlete() {
@ -26,6 +28,10 @@ class AthleteEntity {
return $this->prenom;
}
public function getUsername(){
return $this->username;
}
public function getEmail() {
return $this->email;
}
@ -50,6 +56,10 @@ class AthleteEntity {
return $this->dateNaissance;
}
public function getIsCoach(){
return $this->isCoach;
}
// Setters
public function setIdAthlete($idAthlete) {
$this->idAthlete = $idAthlete;
@ -63,6 +73,10 @@ class AthleteEntity {
$this->prenom = $prenom;
}
public function setUsername($username){
$this->username = $username;
}
public function setEmail($email) {
$this->email = $email;
}
@ -86,6 +100,8 @@ class AthleteEntity {
public function setDateNaissance($dateNaissance) {
$this->dateNaissance = $dateNaissance;
}
}
?>
public function setIsCoach($isCoach){
$this->isCoach = $isCoach;
}
}

@ -1,71 +1,133 @@
<?php
namespace Database;
use \PDO;
use Shared\Log;
class AthleteGateway {
private $connection;
private Connexion $connection;
public function __construct(Connexion $connection) {
$this->connection = $connection;
}
public function getAthlete() {
$query = "SELECT * FROM Athlete";
return $this->connection->executeWithErrorHandling($query);
public function getAthlete(): array
{
$query = "SELECT * FROM Athlete WHERE isCoach=FALSE";
$res = $this->connection->executeWithErrorHandling($query);
return $res;
}
public function getAthleteById(int $userId) {
$query = "SELECT * FROM Athlete WHERE idAthlete = :id";
$params = [':id' => [$userId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
public function getAthleteById(int $userId): array
{
$query = "SELECT * FROM Athlete WHERE idAthlete = :id AND isCoach=FALSE";
$params = [':id' => $userId];
// log::dd($params);
$res = $this->connection->executeWithErrorHandling($query, $params);
return $res;
}
public function getAthleteByName(string $name) {
$query = "SELECT * FROM Athlete WHERE nom = :name";
$params = [':name' => [$name, PDO::PARAM_STR]];
public function getAthleteByName(string $name): array
{
$query = "SELECT * FROM Athlete WHERE nom = :name AND isCoach=FALSE";
$params = [':name' => $name];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByFirstName(string $firstName) {
$query = "SELECT * FROM Athlete WHERE prenom = :firstName";
$params = [':firstName' => [$firstName, PDO::PARAM_STR]];
public function getAthleteByFirstName(string $firstName): array
{
$query = "SELECT * FROM Athlete WHERE prenom = :firstName AND isCoach=FALSE";
$params = [':firstName' => $firstName];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByEmail(string $email) {
public function getAthleteByEmail(string $email): array
{
$query = "SELECT * FROM Athlete WHERE email = :email AND isCoach=FALSE";
$params = [':email' => $email];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getUserByEmail(string $email): array
{
$query = "SELECT * FROM Athlete WHERE email = :email";
$params = [':email' => [$email, PDO::PARAM_STR]];
$params = [':email' => $email];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByGender(string $gender) {
$query = "SELECT * FROM Athlete WHERE sexe = :gender";
$params = [':gender' => [$gender, PDO::PARAM_STR]];
public function getAthleteByGender(string $gender): array
{
$query = "SELECT * FROM Athlete WHERE sexe = :gender AND isCoach=FALSE";
$params = [':gender' => $gender];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByHeight(int $height) {
$query = "SELECT * FROM Athlete WHERE taille = :height";
public function getAthleteByHeight(int $height): array
{
$query = "SELECT * FROM Athlete WHERE taille = :height AND isCoach=FALSE";
$params = [':height' => [$height, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByWeight(int $weight) {
$query = "SELECT * FROM Athlete WHERE poids = :weight";
public function getAthleteByWeight(int $weight): array
{
$query = "SELECT * FROM Athlete WHERE poids = :weight AND isCoach=FALSE";
$params = [':weight' => [$weight, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getAthleteByBirthDate(string $birthdate) {
$query = "SELECT * FROM Athlete WHERE dateNaissance = :birthdate";
public function getAthleteByBirthDate(string $birthdate): array
{
$query = "SELECT * FROM Athlete WHERE dateNaissance = :birthdate AND isCoach=FALSE";
$params = [':birthdate' => [$birthdate, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addAthlete(AthleteEntity $athlete) {
$query = "INSERT INTO Athlete (nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance)
VALUES (:nom, :prenom, :email, :sexe, :taille, :poids, :motDePasse, :dateNaissance)";
public function getListIdFriends(int $idAthlete): array
{
$query = "SELECT idAthlete1, idAthlete2 FROM Friendship WHERE idAthlete1 = :idAthlete OR idAthlete2= :idAthlete";
$params = [
':idAthlete' => $idAthlete,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getListActivity(int $idAthlete): array
{
/*$query = "SELECT count(ac.idActivite) AS nbActivite, EXTRACT(MONTH FROM ac.date) AS mois
FROM Athlete at, Activite ac
WHERE at.idAthlete = :idAthlete
AND ac.date > CURRENT_DATE - INTERVAL '1 YEAR'
AND ac.athleteId = at.idAthlete
GROUP BY mois";*/
$query = "SELECT COUNT(ac.idActivite) AS nbActivite, EXTRACT(MONTH FROM ac.date) AS mois
FROM Athlete at
JOIN Activite ac ON ac.athleteId = at.idAthlete
WHERE at.idAthlete = :idAthlete
AND ac.date > CURRENT_DATE - INTERVAL 1 YEAR
GROUP BY mois";
// $query = "SELECT count(ac.idActivite) AS nbActivite, EXTRACT(MONTH FROM ac.date) AS mois
// FROM Athlete at, Activite ac
// WHERE at.idAthlete = :idAthlete
// AND ac.date > CURRENT_DATE - INTERVAL '1 YEAR'
// AND ac.athleteId = at.idAthlete
// GROUP BY mois";
$params = [
':idAthlete' => $idAthlete,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addAthlete(AthleteEntity $athlete): array
{
$query = "INSERT INTO Athlete (nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance, isCoach)
VALUES (:nom, :prenom, :email, :sexe, :taille, :poids, :motDePasse, :dateNaissance, :isCoach)";
$params = [
':nom' => $athlete->getNom(),
@ -76,19 +138,22 @@ class AthleteGateway {
':poids' => $athlete->getPoids(),
':motDePasse' => $athlete->getMotDePasse(),
':dateNaissance' => $athlete->getDateNaissance(),
':isCoach' => $athlete->getIsCoach(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateAthlete(AthleteEntity $oldAthlete, AthleteEntity $newAthlete) {
public function updateAthlete(AthleteEntity $oldAthlete, AthleteEntity $newAthlete): array
{
$query = "UPDATE Athlete
SET nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance
SET username = :username, nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance, isCoach = :isCoach
WHERE idAthlete = :idAthlete";
$params = [
':idAthlete' => $oldAthlete->getIdAthlete(),
':username' => $newAthlete->getUsername(),
':nom' => $newAthlete->getNom(),
':prenom' => $newAthlete->getPrenom(),
':email' => $newAthlete->getEmail(),
@ -97,12 +162,14 @@ class AthleteGateway {
':poids' => $newAthlete->getPoids(),
':motDePasse' => $newAthlete->getMotDePasse(),
':dateNaissance' => $newAthlete->getDateNaissance(),
':isCoach' => $newAthlete->getIsCoach(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteAthlete(int $idAthlete) {
public function deleteAthlete(int $idAthlete): array
{
$query = "DELETE FROM Athlete WHERE idAthlete = :idAthlete";
$params = [

@ -6,14 +6,14 @@ use \PDO;
use \DateTime;
use Model\Role;
use Model\Athlete;
use Shared\Log;
class AthleteMapper {
public function fromSqlToEntity(array $data): array {
public function athleteSqlToEntity(array $data): array {
$athleteEntities = [];
foreach ($data as $athleteData) {
$athlete = new AthleteEntity();
if (isset($athleteData['idAthlete'])) {
$athlete->setIdAthlete($athleteData['idAthlete']);
}
@ -26,6 +26,10 @@ class AthleteMapper {
$athlete->setPrenom($athleteData['prenom']);
}
if (isset($athleteData['username'])) {
$athlete->setUsername($athleteData['username']);
}
if (isset($athleteData['email'])) {
$athlete->setEmail($athleteData['email']);
}
@ -50,6 +54,10 @@ class AthleteMapper {
$athlete->setDateNaissance($athleteData['dateNaissance']);
}
if (isset($athleteData['isCoach'])) {
$athlete->setIsCoach($athleteData['isCoach']);
}
$athleteEntities[] = $athlete;
}
@ -58,19 +66,19 @@ class AthleteMapper {
public function athleteEntityToModel(AthleteEntity $athleteEntity): User {
$role = new Athlete(); // Utilisez la classe Athlete
$dateSpecifique = $athleteEntity->getDateNaissance();
$date = new DateTime($dateSpecifique);
$date = new DateTime($athleteEntity->getDateNaissance());
$poids = floatval($athleteEntity->getPoids());
$taille = floatval($athleteEntity->getTaille());
$user = new User(
$athleteEntity->getIdAthlete(),
$athleteEntity->getNom(),
$athleteEntity->getPrenom(),
$athleteEntity->getUsername(),
$athleteEntity->getEmail(),
$athleteEntity->getMotDePasse(),
$athleteEntity->getSexe(),
$athleteEntity->getTaille(),
$athleteEntity->getPoids(),
$taille,
$poids,
$date,
$role
);
@ -84,12 +92,15 @@ class AthleteMapper {
$ath->setIdAthlete($user->getId());
$ath->setNom($user->getNom());
$ath->setPrenom($user->getPrenom());
$ath->setUsername($user->getUsername());
$ath->setEmail($user->getEmail());
$ath->setSexe($user->getSexe());
$ath->setTaille($user->getTaille());
$ath->setPoids($user->getPoids());
$ath->setMotDePasse($user->getMotDePasse());
$ath->setDateNaissance($user->getDateNaissance());
$ath->setIsCoach(FALSE);
$ath->setCoachId(NULL);
return $ath;
}

@ -6,12 +6,14 @@ class CoachEntity {
private $idCoach;
private $nom;
private $prenom;
private $username;
private $email;
private $sexe;
private $taille;
private $poids;
private $motDePasse;
private $dateNaissance;
private $isCoach;
// Getters
public function getIdCoach() {
@ -26,6 +28,10 @@ class CoachEntity {
return $this->prenom;
}
public function getUsername(){
return $this->username;
}
public function getEmail() {
return $this->email;
}
@ -50,6 +56,11 @@ class CoachEntity {
return $this->dateNaissance;
}
public function getIsCoach(){
return $this->isCoach;
}
// Setters
public function setIdCoach($idCoach) {
$this->idCoach = $idCoach;
@ -63,6 +74,10 @@ class CoachEntity {
$this->prenom = $prenom;
}
public function setUsername($username){
$this->username = $username;
}
public function setEmail($email) {
$this->email = $email;
}
@ -86,6 +101,11 @@ class CoachEntity {
public function setDateNaissance($dateNaissance) {
$this->dateNaissance = $dateNaissance;
}
public function setIsCoach($isCoach){
$this->isCoach = $isCoach;
}
}
?>

@ -10,93 +10,96 @@ class CoachGateway {
$this->connection = $connection;
}
public function getCoach() {
public function getCoach(): array
{
$query = "SELECT * FROM Coach";
return $this->connection->executeWithErrorHandling($query);
}
public function getCoachById(int $userId) {
public function getCoachById(int $userId): array
{
$query = "SELECT * FROM Coach WHERE idCoach = :id";
$params = [':id' => [$userId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByName(string $name) {
$query = "SELECT * FROM Coach WHERE nom = :name";
public function getAthleteByCoachId(int $coachId): array
{
$query = "SELECT * FROM Athlete a, Coach c WHERE a.coachId = :id AND a.isCoach = TRUE";
$params = [':id' => [$coachId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByName(string $name): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.nom = :name";
$params = [':name' => [$name, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByFirstName(string $firstName) {
$query = "SELECT * FROM Coach WHERE prenom = :firstName";
public function getCoachByFirstName(string $firstName): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.prenom = :firstName";
$params = [':firstName' => [$firstName, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByEmail(string $email) {
$query = "SELECT * FROM Coach WHERE email = :email";
public function getCoachByEmail(string $email): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.email = :email";
$params = [':email' => [$email, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByGender(string $gender) {
$query = "SELECT * FROM Coach WHERE sexe = :gender";
public function getCoachByGender(string $gender): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.sexe = :gender";
$params = [':gender' => [$gender, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByHeight(int $height) {
$query = "SELECT * FROM Coach WHERE taille = :height";
public function getCoachByHeight(int $height): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.taille = :height";
$params = [':height' => [$height, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByBirthDate(string $birthdate) {
$query = "SELECT * FROM Coach WHERE dateNaissance = :birthdate";
public function getCoachByBirthDate(string $birthdate): array
{
$query = "SELECT * FROM Coach c, Athlete a WHERE c.athleteId = a.idAthlete AND a.dateNaissance = :birthdate";
$params = [':birthdate' => [$birthdate, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addCoach(CoachEntity $coach) {
$query = "INSERT INTO Coach (nom, prenom, email, sexe, taille, poids, motDePasse, dateNaissance)
VALUES (:nom, :prenom, :email, :sexe, :taille, :poids, :motDePasse, :dateNaissance)";
public function addCoach(CoachEntity $coach): array
{
$query = "INSERT INTO Coach (athleteId)
VALUES (:athleteId)";
$params = [
':nom' => $coach->getNom(),
':prenom' => $coach->getPrenom(),
':email' => $coach->getEmail(),
':sexe' => $coach->getSexe(),
':taille' => $coach->getTaille(),
':poids' => $coach->getPoids(),
':motDePasse' => $coach->getMotDePasse(),
':dateNaissance' => $coach->getDateNaissance(),
':athleteId' => $coach->getAthleteId(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateCoach(CoachEntity $oldCoach, CoachEntity $newCoach) {
public function updateCoach(CoachEntity $oldCoach, CoachEntity $newCoach): array
{
$query = "UPDATE Coach
SET nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance
SET athleteId = :athleteId
WHERE idCoach = :idCoach";
$params = [
':idCoach' => $oldCoach->getIdCoach(),
':nom' => $newCoach->getNom(),
':prenom' => $newCoach->getPrenom(),
':email' => $newCoach->getEmail(),
':sexe' => $newCoach->getSexe(),
':taille' => $newCoach->getTaille(),
':poids' => $newCoach->getPoids(),
':motDePasse' => $newCoach->getMotDePasse(),
':dateNaissance' => $newCoach->getDateNaissance(),
':athleteId' => $newCoach->getAthleteId(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteCoach(int $idCoach) {
public function deleteCoach(int $idCoach): array
{
$query = "DELETE FROM Coach WHERE idCoach = :idCoach";
$params = [

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save