Compare commits

...

177 Commits

Author SHA1 Message Date
Antoine PEREDERII e72636c4d7 Update 'Sources/config/config.php'
continuous-integration/drone/push Build is passing Details
8 months ago
Antoine PEREDERII 97623ba062 Merge branch 'master' of codefirst.iut.uca.fr:HeartDev/Web
continuous-integration/drone/push Build is passing Details
9 months ago
Antoine PEREDERII 32afdd093c 📝 Add MCD on the readme file
9 months ago
David D'ALMEIDA 81b7a60267 Mise à jour de 'Sources/public/index.php'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 134f3ae997 Mise à jour de 'Sources/config/config.php'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA f80492db66 Mise à jour de 'Sources/config/config.php'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 3bc50ae677 Mise à jour de 'Sources/config/config.php'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 9c03d12906 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA bfd039d9bb Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 701563d0ee Mise à jour de 'Sources/config/httpd.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA b4fe541a4f Ajouter 'Sources/config/httpd.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 505d4cd71d Mise à jour de 'Sources/src/app/controller/Controller.php'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 8d000f997b Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 88d778f245 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 32b05eeb11 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 8d5f1ddefe Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA ac7b90f0fb Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 7cdd12df73 Ajouter 'Sources/config/virtual-host.conf'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA bcd043ceb1 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 1b66f277b5 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 1fb406c58a Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA f78276dbec Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA b52ba793d3 Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA bb6e76f54f Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 4ce92111d1 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA c7f0ab60d6 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA ddc7d843ed Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA b20436b938 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 3fb3822ac7 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 23e04e3d71 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA cb04fc199b Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 0d090a7183 Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA e4a74cb353 Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 8b14c2c95b Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 0653af150b Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA c334f89aba Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 2acea545ae Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA f1b97a1c0d Mise à jour de 'Sources/config/nginx.conf'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 884307f6b0 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA b0b34843b3 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
9 months ago
David D'ALMEIDA f750992a07 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build encountered an error Details
9 months ago
David D'ALMEIDA 99405eb8b7 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 4f314cf7e3 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 93f68abf43 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA f6212b6d5e Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA f0bb8fed65 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 8b1ca8d371 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 837941721d Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 664f270062 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is running Details
9 months ago
David D'ALMEIDA 9d53db8000 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA b6fdae005b Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 39cc037569 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA c5632a47fb Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 373cc847ab Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 99f9e2ec22 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 43bd7295f9 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 2d5bc5303f Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 255a81c29c Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 92e196c7e3 Mise à jour de 'Sources/config/.htaccess'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA d0db1ad041 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 176e70d020 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 64a5a2c7c6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA 65b63b0f2f Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA eeb2b8e3ab Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA b5c62a9791 Mise à jour de 'Sources/config/Dockerfile'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA e827554413 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA e4688dbe28 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA d241bd15a1 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 7042c6a2b6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 71d1f58cc4 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA db8ed755db Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA b58ebcf3e8 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is passing Details
9 months ago
David D'ALMEIDA e2ed1aa3e6 Mise à jour de '.drone.yml'
9 months ago
David D'ALMEIDA f7016ba5b5 Mise à jour de '.drone.yml'
9 months ago
David D'ALMEIDA b1a486622e Mise à jour de '.drone.yml'
9 months ago
David D'ALMEIDA 5caaf280b6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
9 months ago
David D'ALMEIDA 397cc32336 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
10 months ago
David D'ALMEIDA 4b8e69eec6 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
10 months ago
David D'ALMEIDA 06a5b72d1a Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
10 months ago
David D'ALMEIDA 3a579bb606 Mise à jour de '.drone.yml'
continuous-integration/drone/push Build is failing Details
10 months ago
David D'ALMEIDA d2296ff7d0 Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
10 months ago
Antoine PEREDERII 8cf1786672 update some diagrams for futur evaluation
continuous-integration/drone/push Build is failing Details
10 months ago
Antoine PEREDERII 705edbf4e5 Merge branch 'master' of codefirst.iut.uca.fr:HeartDev/Web
continuous-integration/drone/push Build is failing Details
10 months ago
Antoine PEREDERII af00c88542 add MLD and update somes diagrams
10 months ago
Antoine PEREDERII d6484b9f16 Update 'README.md'
continuous-integration/drone/push Build is failing Details
11 months ago
Antoine PEREDERII c4adf90c8d Update 'Documents/Diagramme/DiagrammeDeClasses/README_accesDonnees.md'
continuous-integration/drone/push Build is failing Details
12 months ago
Antoine PEREDERII 4609a3e3d1 Merge remote-tracking branch 'origin/merged'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII cba3a4e1ae update diagrams with introduction
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 718a97ff32 update all diagrams without description
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 687824e429 add general diagram
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII ce09893056 update branch
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 18a384b869 update diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 330282f147 upadate diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 9b1ca87c73 upadate diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 18fcf85be9 update diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII d57f95ca62 Merge remote-tracking branch 'origin/merged'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 461d08126d last merged with issu022
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII fcc4b3a250 merge issue030 with merged
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 52ac902d0f problemes de git
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII a374a77ca0 Merge branch 'merged' of codefirst.iut.uca.fr:HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 0f59ed962c updates controllers
1 year ago
Antoine PINAGOT 225b4d58e8 try athelte controller
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII a5b3648320 Merge branch 'merged' of codefirst.iut.uca.fr:HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 484a87554d merge issue_030 on merged
1 year ago
Antoine PINAGOT 9a8e711522 Mise à jour de 'Documents/Diagramme/DiagrammeDeClasses/README_accesDonnees.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII cdbc9bf5a3 Update 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 29e611487e update readme
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 29f226ebbb Mise à jour de 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII aec3fe9b85 Merge branch 'merged' of codefirst.iut.uca.fr:HeartDev/Web into merged
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII e79a6b275a update uses cases
1 year ago
Antoine PINAGOT 470092f36f link de toutes les pages entre elles
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII cfdf27e7e7 Update 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 2afefb54ba update my diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 673f9183fe update path diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII c0b2d76ceb update path diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII caa907c93c update path diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 48d615fea1 update path diagrams
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 16228a51fe update diagramme
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 872f848a11 Update 'Documents/Diagramme/DiagrammeDeClasses/README_accesDonnees.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 04e9078aa7 Update 'Documents/Diagramme/DiagrammeDeClasses/README_accesDonnees.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 9333fb3499 update diagramme
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII 8d1953c4c4 upaded merged branch
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 0c0704e51e Ajout pages authentification
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PINAGOT 109b6860ee Page erreur 404 finie avec la meme template que les autres erreurs
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 74a79a055c Ajouter 'Documents/Diagramme/DiagrammeDeClasses/README_issue016.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 13b7b07534 Ajouter 'Documents/Diagramme/DiagrammeDeClasses/README_issue021.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 20f0aabbd3 Ajouter 'Documents/Diagramme/DiagrammeDeClasses/README_issue022.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT a663a7212e Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Paul LEVRAULT 731d23ba4a Mise à jour de 'README.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT b257ff4526 Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT 6714855b5a Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT 0ee1df5c44 Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT 2817e79a69 Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT 564799a781 Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Paul LEVRAULT 4a04a27acf Mise à jour de 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII ce6f9ef7ae Update 'README.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII f21d6e9e17 update README.md
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII b4b89a7a66 rename to good format
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 43b106ec19 Update 'README.md'
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII a8641f617e Update 'Documents/Diagramme/DiagrammeDeClasses/README_issue028.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII c6c1f50834 Update 'Documents/Diagramme/DiagrammeDeClasses/README_issue028.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 47db3d10ad Update 'Documents/Diagramme/README_DIAGRAMMES.md'
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 54fb6a74a7 📝 🚚 update Documentation folder and add somes README.md
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 1fdce42f49 Add .fit feature
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 15e854a508 🚀 🧪 add fit file feature
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 5286bdabfb 📝 add LICENSE.md and update README.md
1 year ago
Antoine PEREDERII f6eafff4cd pull master
1 year ago
Antoine PEREDERII d86b2550b0 update class diagramme
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 208b134bc7 add Athlete Manager ans her dependences
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 7d8d8fa945 update class diagramme
1 year ago
Antoine PEREDERII a8035d5be0 update training add in coach
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII d61d120f08 🚧 🧪 add Listing TrainingList
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII a696e4eb5a 💩 🚧 add TrainingRepository and and Training Menu in Console.php
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 5c925326a9 🚧 add Coach management Team
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 4498de7839 update branch
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII f0cf8d96a4 add some classes files
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 6f9d60fa27 🙈 remove .phpunit.cache files
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 00c772492b 🚧 💩 add coach management
1 year ago
Antoine PEREDERII 9aa054b2b5 update Classes diagram
1 year ago
Antoine PEREDERII 91422418ed initialized Coach US
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII eec7dfb069 🔧 📌 Downgrade User.php to php7
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII d5a73fa41f 💥 update Classes Diagramme
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 31a3b5c070 💥 update Classes Diagramme
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 9db411bbc3 update src project for our US
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 82a1feaa0d update src project for our US
1 year ago
Antoine PEREDERII 198d40a7fe update classes diagram
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 01fcd70127 Merge branch 'WORK-APE' of codefirst.iut.uca.fr:HeartDev/Web into issue_16_statistics_coach
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII d0cef575ff Merge branch 'issue_020_Auth_Stub' of codefirst.iut.uca.fr:HeartDev/Web into issue_16_statistics_coach
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 497a91b915 🙈 update .gitignore for macOSX
continuous-integration/drone/push Build is passing Details
1 year ago
antoine.perederii e0645c5142 update class diagram
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII e9a34565c5 update Classes Diagram
continuous-integration/drone/push Build is passing Details
1 year ago
antoine.perederii f6a54918a8 🚧 introducing SAE reseau script vdn
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII d4cb530029 introduce conception and Main
continuous-integration/drone/push Build is passing Details
1 year ago
Antoine PEREDERII 8b3d28553d update .gitignore for macOS
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII dd22aacf08 update ClassesDiagramme
1 year ago
antoine.perederii 6c80f37d3b add new Classes Diagrammes
continuous-integration/drone/push Build is failing Details
1 year ago
Antoine PEREDERII eea1a6b502 update Console.php
continuous-integration/drone/push Build is failing Details
1 year ago

@ -2,19 +2,20 @@ kind: pipeline
type: docker
name: HeartWave
trigger:
trigger:
event:
- push
steps:
# Test ✔️
- name: test
image: composer:2.6
commands:
- cd Sources
- rm -r vendor
- rm composer.lock
# Installe les dépendances PHP si nécessaire
- composer install --no-interaction
- php composer.phar install --no-interaction
- ./vendor/bin/phpunit tests
# Sonar static code analisis deployment
@ -35,19 +36,45 @@ steps:
- cd Sources
- sonar-scanner -D sonar.projectKey=HeartTrack -D sonar.host.url=https://codefirst.iut.uca.fr/sonar
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" {} +
settings:
container_path: https://codefirst.iut.uca.fr/containers/HeartDev-web/
# build image and push on the registry ✔️
- name: docker-build-and-push
image: plugins/docker
settings:
commands: ls
dockerfile: Sources/config/Dockerfile
context: Sources
registry: hub.codefirst.iut.uca.fr
repo: hub.codefirst.iut.uca.fr/david.d_almeida/web
mirror: https://proxy.iut.uca.fr:8443
username:
from_secret: SECRET_REGISTRY_USERNAME
password:
from_secret: SECRET_REGISTRY_PASSWORD
depends_on:
- rewrite-urls
- name: deploy-container
image: >-
hub.codefirst.iut.uca.fr/thomas.bellembois/codefirst-dockerproxy-clientdrone:latest
environment:
IMAGENAME: 'hub.codefirst.iut.uca.fr/david.d_almeida/web:latest'
CONTAINERNAME: web
COMMAND: create
OVERWRITE: true
ADMINS: david.d_almeida
depends_on:
- docker-build-and-push
- name: notify
image: ruby:2.1
@ -59,3 +86,5 @@ steps:
commands:
- sh ./notifymail.sh
depends_on: [ docker-build-and-push ]

7
.gitignore vendored

@ -6,7 +6,12 @@ dist
*.swo
.env
loginDatabase.php
# Cache file on macOS
.DS_Store
.phpunit.cache
# Cache files for Sublime Text
*.tmlanguage.cache
*.tmPreferences.cache
@ -24,4 +29,4 @@ sftp-config.json
sftp-config-alt*.json
*.log*
coverage/
coverage/

@ -1,107 +0,0 @@
<mxfile host="app.diagrams.net" modified="2023-09-25T06:43:46.406Z" agent="Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 Firefox/102.0" etag="e-4pS3rH9xNpreRilvi5" version="21.8.2" type="device">
<diagram name="Page-1" id="2OfyMqm8PIhWsBFCJvOv">
<mxGraphModel dx="2049" dy="1071" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="Ym5UIEUMnJ661rIFWdHi-1" value="Sportif&lt;br&gt;" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="100" y="240" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-6" value="" style="rounded=0;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="230" y="170" width="340" height="890" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-7" value="Application FitWeb" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="340" y="170" width="120" height="30" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-8" value="" style="endArrow=none;html=1;rounded=0;exitX=-0.006;exitY=0.037;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="Ym5UIEUMnJ661rIFWdHi-6" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="230" y="201" as="sourcePoint" />
<mxPoint x="570" y="200" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-9" value="" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="320" y="220" width="160" height="100" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-10" value="Analyser la fréquence cardique" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="332" y="255" width="136" height="30" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-22" value="" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="320" y="355" width="160" height="100" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-23" value="Statistique condition physique&amp;nbsp;&amp;nbsp;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="340" y="375" width="120" height="60" as="geometry" />
</mxCell>
<mxCell id="Ym5UIEUMnJ661rIFWdHi-26" value="Améliorer les entrainements" style="ellipse;whiteSpace=wrap;html=1;" parent="1" vertex="1">
<mxGeometry x="320" y="485" width="158" height="100" as="geometry" />
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-7" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" parent="1" target="Ym5UIEUMnJ661rIFWdHi-9" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="130" y="270" as="sourcePoint" />
<mxPoint x="310" y="270" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-9" value="" style="endArrow=classic;html=1;rounded=0;" parent="1" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="130" y="280" as="sourcePoint" />
<mxPoint x="320" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-10" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0;entryDx=0;entryDy=0;" parent="1" target="Ym5UIEUMnJ661rIFWdHi-26" edge="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="130" y="290" as="sourcePoint" />
<mxPoint x="320" y="485" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-11" value="Développeur" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" parent="1" vertex="1">
<mxGeometry x="712" y="930" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-13" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.5;entryDx=0;entryDy=0;" parent="1" edge="1" source="gRiRGuH9TPFdmmPZYA_R-11">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="132" y="857.5" as="sourcePoint" />
<mxPoint x="480" y="960" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="gRiRGuH9TPFdmmPZYA_R-15" value="&lt;font style=&quot;font-size: 16px;&quot;&gt;Diagramme de cas d&#39;utilisation de l&#39;application Fit Web&lt;/font&gt;" style="text;html=1;strokeColor=none;fillColor=none;align=center;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="199" y="60" width="400" height="30" as="geometry" />
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-1" value="Coach Sportif" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
<mxGeometry x="712" y="630" width="30" height="60" as="geometry" />
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-5" value="Consulter les statistiques de son équipe" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="318" y="610" width="158" height="100" as="geometry" />
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-6" value="Développer et maintenir l&#39;application" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="320" y="910" width="158" height="100" as="geometry" />
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-7" value="" style="endArrow=classic;html=1;rounded=0;" edge="1" parent="1">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="710" y="660" as="sourcePoint" />
<mxPoint x="480" y="660" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-8" value="&amp;nbsp;Reporter un bug" style="ellipse;whiteSpace=wrap;html=1;" vertex="1" parent="1">
<mxGeometry x="318" y="740" width="158" height="100" as="geometry" />
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-9" value="" style="endArrow=classic;html=1;rounded=0;entryX=1;entryY=0.41;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" target="aGqo4vDs0eBD3chBgCWU-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="710" y="670" as="sourcePoint" />
<mxPoint x="792" y="730" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-12" value="" style="endArrow=classic;html=1;rounded=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" target="aGqo4vDs0eBD3chBgCWU-8">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="140" y="330" as="sourcePoint" />
<mxPoint x="160" y="385" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="aGqo4vDs0eBD3chBgCWU-13" value="" style="endArrow=none;dashed=1;html=1;dashPattern=1 3;strokeWidth=2;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="aGqo4vDs0eBD3chBgCWU-8" target="aGqo4vDs0eBD3chBgCWU-6">
<mxGeometry width="50" height="50" relative="1" as="geometry">
<mxPoint x="268" y="930" as="sourcePoint" />
<mxPoint x="318" y="880" as="targetPoint" />
</mxGeometry>
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

@ -1,55 +0,0 @@
@startuml
class User {
+ name : string
}
User "1" --> "*" User: friends
User "1" --> "*" Notification: notifications
User "1" --> "*" Ask: friendRequests
class Notification {
- text : string
}
interface INotifier {
+ notify() : void
}
INotifier --|> Observer
abstract class UserManager {
- currentUser : User
+ deleteFriend(userId : int) : void
+ addFriend(userId : int) : void
+ respondToFriendRequest(requestId : int, choice : bool) : void
+ getFriends(userId : int) : User[]
}
class Ask {
- fromUser : int
- toUser : int
}
Ask --|> Subject
abstract class Subject {
+ attach(o : Observer) : void
+ detach(o : Observer) : void
+ notify() : void
}
Subject "1" --> "*" Observer
interface Observer {
+ update() : void
}
UserManager ..> User
UserManager o-- IUserRepository
UserManager o-- INotifier
interface IUserRepository {
+ findByUsername(username : string) : User
+ addUser(user : User) : bool
}
IUserRepository ..> User
@enduml

@ -1,20 +0,0 @@
@startuml
actor User as u
boundary View as v
control Controller as c
entity Model as m
m-->c: pendingRequests: Request[]
c-->v: DisplayPendingRequests(pendingRequests)
v-->u: Show Friend Requests
u->v: RespondToRequest(requestId, response)
v-->c: RecordResponse(requestId, response)
c->m: UpdateRequestStatus(requestId, response)
m-->c: updateStatus: success/failure
c-->v: NotifyUpdateResult(updateStatus)
v-->u: Show Response Result
@enduml

@ -1,28 +0,0 @@
@startuml
actor User as u
boundary View as v
control Controller as c
entity Model as m
u->v: Request Friends Page
v->c: Get /Friends
c->m: getFriends(userId)
alt successful retrieval
m-->c: friendsList: User[]
else retrieval failed
m-->c: error
end
c-->v: renderView(friendsList)
v-->u: Display Friends
u->v: clickDeleteFriend(idUser)
v->c: Post: deleteFriend(idUser)
c->m: deleteFriend(idUser)
alt successful deletion
m-->c: updatedFriendsList: User[]
else deletion failed
m-->c: error
end
c-->v: renderView(updatedFriendsList)
v-->u: Display Updated Friends
@enduml

@ -0,0 +1,276 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# BDD
## Modèle Logique de Données (MLD)
Le MLD représente la structure de données de l'application, décrivant les entités et les relations entre elles. Voici un aperçu des principales entités du MLD :
### Athlète (Athlete)
L'entité principale représentant un athlète avec ces informations propre à lui telles que l'identifiant, le nom, le prénom, l'email, etc. Les athlètes peuvent être coach avec le boolean idCoach et être liés par des amitiés, ou par un coaching via la table `Amitie`.
### Amitié (Friendship)
Une entité qui modélise les relations d'amitié entre les athlètes et de coaching entre les athlètes et les coachs. Elle stocke les identifiants des deux utilisateurs impliqués.
### Notification (Notification)
L'entité qui stocke les notifications destinées aux athlètes, avec des détails tels que le message, la date, le statut, et le degré d'urgence.
### Envoi de Notification (SendNotification)
Une entité de liaison entre les athlètes et les notifications, indiquant quel athlète ou coach a envoyé quelle notification. Cela peut-être utile lors d'une notification d'ajout d'amie par exemple.
### Statistique (Statistic)
Les statistiques relatives à un athlètes, y compris le poids, la fréquence cardiaque moyenne, la fréquence cardiaque maximale, etc.
### Entraînement (Training)
Détails sur les sessions d'entraînement planifiés par un coach pour ses athlètes, comprenant la date, la description, la localisation, etc. Les athlètes peuvent participer à des entraînements et donner leur feedback sur l'entrainement donné.
### Participation (Participate)
Une entité de liaison entre les athlètes et les entraînements, indiquant quels athlètes participent à quels entraînements.
### Don (GiveParticipation)
Une entité de liaison entre les coachs et les entraînements, indiquant quels coachs ont attribué quels entraînements.
### Source de Données (DataSource)
L'entité représentant la source des données des enregistrements sportif, telle que le type, le modèle, la précision, etc., utilisée par les athlètes pour enregistrer une ou des activités.
### Activité (Activity)
Les détails des activités des athlètes, y compris le type, la date, les heures de début et de fin, l'effort ressenti, etc.
### Fréquence Cardiaque (HeartRate)
Les données de fréquence cardiaque enregistrées pendant les activités, avec des informations telles que l'altitude, la température, etc.
Ce MLD forme la base de données sous-jacente pour l'application, offrant une structure organisée pour stocker et récupérer les informations relatives aux athlètes et à leurs activités.
```plantuml
@startuml
skinparam classAttributeIconSize 0
package MLD{
entity "Athlete" as athlete {
{static} idAthlete
username
nom
prenom
email
sexe
taille
poids
motDePasse
dateNaissance
isCoach
}
entity "Amitie" as friendship{
{static}# idAthlete1
{static}# idAthlete2
début
}
entity "Notification" as notif {
{static} idNotif
message
date
statut
urgence
#athleteId
}
entity "Envoi" as sendNotif{
{static}# idAthlete
{static}# idNotif
}
entity "Statistique" as stats {
{static} idStatistique
poids
fcMoyenne
fcMax
caloriesBruleesMoy
date
#athleteId
}
entity "Entrainement" as training {
{static} idEntrainement
date
description
latitude
longitude
feedback
#athleteId
}
entity "Participe" as takepart {
{static} #athleteId
{static} #entrainementId
}
entity "Donne" as givepart {
{static} #coachId
{static} #entrainementId
}
entity "SourceDonnee" as source {
{static} idSource
type
modele
precision
#athleteId
}
entity "Activite" as activity {
{static} idActivité
type
date
heureDeDebut
heureDeFin
effortRessent
variabilite
variance
ecartType
moyenne
maximum
minimum
temperatureMoyenne
#athleteId
#sourceId
}
entity "FréquenceCardiaque" as fc {
{static} idFc
altitude
temps : time
température
bpm
longitude
latitude
#activitéId
}
}
activity --> athlete
activity --> source
activity <-- fc
athlete <-- source
stats --> athlete
takepart --> athlete
takepart --> training
givepart --> athlete
givepart --> training
sendNotif --> athlete
sendNotif --> notif
friendship --> athlete
notif --> athlete
athlete <-- friendship
@enduml
```
```plantuml
@startuml
skinparam classAttributeIconSize 0
package MCD{
entity "Athlete" as athlete {
{static} idAthlete
username
nom
prenom
email
sexe
taille
poids
motDePasse
dateNaissance
isCoach
}
entity "Notification" as notif {
{static} idNotif
message
date
statut
urgence
#athleteId
}
entity "Statistique" as stats {
{static} idStatistique
poids
fcMoyenne
fcMax
caloriesBruleesMoy
date
#athleteId
}
entity "Entrainement" as training {
{static} idEntrainement
date
description
latitude
longitude
feedback
#athleteId
}
entity "SourceDonnee" as source {
{static} idSource
type
modele
precision
#athleteId
}
entity "Activite" as activity {
{static} idActivité
type
date
heureDeDebut
heureDeFin
effortRessent
variabilite
variance
ecartType
moyenne
maximum
minimum
temperatureMoyenne
#athleteId
#sourceId
}
entity "FréquenceCardiaque" as fc {
{static} idFc
altitude
temps : time
température
bpm
longitude
latitude
#activitéId
}
}
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
@enduml
```

@ -0,0 +1,56 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Cas d'utilisation : Suivi d'une Équipe Sportive
Bienvenue dans le monde dynamique du suivi d'équipe sportive, où notre application offre une plateforme complète pour les entraîneurs soucieux d'optimiser les performances de leurs athlètes. Ce diagramme de cas d'utilisation vous plonge dans les fonctionnalités clés qui facilitent la gestion d'une équipe sportive avec efficacité.
**Acteurs Principaux :**
- **Coach :** Le protagoniste central, utilisant l'application pour gérer et superviser son équipe.
**Fonctionnalités Clés :**
- **Ajouter un Athlète :** Permet au coach d'ajouter de nouveaux membres à son équipe, avec des étapes incluant la validation par l'athlète et l'authentification.
- **Supprimer un Athlète :** Offre la possibilité de retirer des athlètes de l'équipe, avec une authentification préalable pour garantir la légitimité de l'action.
- **Afficher ses Athlètes :** Permet au coach de visualiser la liste complète de ses athlètes, nécessitant une authentification pour accéder à ces informations sensibles.
- **Afficher les Activités de Tous les Athlètes :** Donne au coach un aperçu global des activités de toute l'équipe, nécessitant une authentification pour garantir la confidentialité des données.
**Flux d'Interaction :**
- Le processus d'ajout d'un athlète inclut des étapes telles que la validation par l'athlète et l'authentification, garantissant une intégration fluide.
- Les actions de suppression, affichage des athlètes et affichage des activités nécessitent une authentification préalable pour assurer la sécurité des données.
- Des extensions telles que la visualisation des activités d'un athlète et l'analyse des performances offrent des fonctionnalités avancées pour un suivi détaillé.
Explorez ce diagramme pour comprendre l'étendue des fonctionnalités que notre application offre aux entraîneurs, les aidant à gérer leurs équipes de manière efficace et à maximiser le potentiel de chaque athlète.
```plantuml
left to right direction
:Coach: as a
a --> (Ajouter un athlète)
a --> (Supprimer un athlète)
a --> (Afficher ses athlètes )
a --> (Afficher les activités de tous les athlètes)
(Ajouter un athlète).>(Validation par l'athlète) : <<include>>
(Ajouter un athlète)..>(S'authentifier) : <<include>>
(Supprimer un athlète)..>(S'authentifier) : <<include>>
(Afficher ses athlètes )..>(S'authentifier) : <<include>>
(Afficher les activités de tous les athlètes)..>(S'authentifier) : <<include>>
(S'authentifier)..>(S'inscrire) : <<extends>>
(S'inscrire).>(Inscription Coach) : <<include>>
(S'authentifier)..>(Se connecter) : <<include>>
(Afficher ses athlètes )..>(Voir les activités d'un athlète) : <<extends>>
(Afficher ses athlètes )..>(Voir les stats d'un athlète) : <<extends>>
(Afficher les activités de tous les athlètes)..>(Sélectionner une activité) : <<include>>
(Sélectionner une activité)..>(Voir l'analyse) : <<extends>>
(Sélectionner une activité)..>(Exporter l'analyse) : <<extends>>
(Voir les activités d'un athlète)..>(Voir l'analyse) : <<extends>>
(Voir les activités d'un athlète)..>(Exporter l'analyse) : <<extends>>
```

@ -0,0 +1,58 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Cas d'utilisation : Gestion d'Activités pour un Athlète
Bienvenue dans l'univers dédié à la gestion d'activités sportives personnalisées pour les athlètes ! Ce diagramme de cas d'utilisation explore les différentes fonctionnalités offertes aux utilisateurs, mettant en avant la flexibilité et la richesse d'interactions pour une expérience utilisateur optimale.
**Acteurs Principaux :**
- **Athlète :** Le protagoniste central, utilisant l'application pour importer, gérer et analyser ses activités sportives.
**Fonctionnalités Clés :**
- **Importer des Données :** Permet à l'athlète d'importer des données d'activités depuis différentes sources, avec la possibilité de spécifier la source pour une intégration transparente.
- **Exporter Mes Données :** Offre la possibilité d'exporter l'ensemble des activités, avec des extensions pour exporter une activité spécifique, le tout soumis à une authentification préalable.
- **Ajouter une Activité :** Permet à l'athlète d'ajouter de nouvelles activités, avec des étapes inclusives telles que la saisie du titre, du type d'activité, de la source, du matériel utilisé et de la visibilité, chacune accessible via l'authentification.
- **Voir une Activité :** Permet à l'athlète de visualiser en détail une activité particulière, avec la possibilité d'exporter une analyse et de gérer la visibilité, soumis à une authentification.
- **Supprimer une Activité :** Offre la possibilité de retirer une activité, requérant une authentification pour garantir la sécurité des données.
**Flux d'Interaction :**
- Les actions telles que l'importation, l'exportation, l'ajout et la visualisation d'activités impliquent une authentification préalable pour garantir la confidentialité des données personnelles.
- Des inclusions précises, telles que la saisie du titre, du type d'activité, de la source, du matériel utilisé et de la visibilité, sont incorporées dans le processus d'ajout d'une activité, offrant une expérience utilisateur détaillée et conviviale.
Explorez ce diagramme pour comprendre la manière dont notre application place la gestion d'activités entre les mains des athlètes, les encourageant à suivre, analyser et optimiser leurs performances sportives de manière personnalisée et efficace.
```plantuml
left to right direction
:Athlete: as a
a --> (Importer des données)
(Importer des données) .> (Saisir la source) : <<include>>
a --> (Exporter mes données)
(Exporter mes données) .>(Exporter toutes les activités): <<extends>>
(Exporter mes données) ..>(Exporter une activité): <<include>>
a --> (Ajouter une activité)
(Ajouter une activité) ..>(Saisir un titre et une description): <<include>>
(Ajouter une activité) ..>(Saisir le type d'activité): <<include>>
(Ajouter une activité) .>(Saisir la source): <<include>>
(Saisir la source) ..>(Saisir le matériel utilisé): <<include>>
(Ajouter une activité) ..>(Saisir la visibilité): <<include>>
a --> (Voir une activité)
(Voir une activité) ..>(Exporter l'analyse): <<extends>>
(Voir une activité) ..>(Saisir la visibilité): <<extends>>
a --> (Supprimer une activité)
(Supprimer une activité) ..>(S'authentifier): <<include>>
(Importer des données) ...>(S'authentifier): <<include>>
(Exporter mes données) ...>(S'authentifier): <<include>>
(Ajouter une activité) ...>(S'authentifier): <<include>>
(Voir une activité) ...>(S'authentifier): <<include>>
```

@ -0,0 +1,56 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Cas d'utilisation : Gestion des Relations Sociales pour un Athlète
Bienvenue dans la sphère sociale de notre application dédiée aux athlètes ! Ce diagramme de cas d'utilisation explore les fonctionnalités sociales clés offertes aux utilisateurs, mettant en lumière la connectivité et l'interaction sociale au sein de notre communauté sportive.
**Acteurs Principaux :**
- **Athlète :** Le protagoniste central, utilisant l'application pour gérer ses relations sociales et explorer les profils de ses pairs.
**Fonctionnalités Clés :**
- **Ajouter un Ami :** Permet à l'athlète d'ajouter de nouveaux amis, nécessitant la saisie du nom de l'ami et soumis à une authentification préalable.
- **Supprimer un Ami :** Offre la possibilité de retirer un ami, exigeant une authentification pour garantir la sécurité des données.
- **Voir Mes Amis :** Permet à l'athlète de visualiser la liste de ses amis, avec la possibilité d'accéder à des fonctionnalités supplémentaires comme la visualisation des profils.
- **Modifier Mes Informations :** Offre à l'athlète la possibilité de mettre à jour ses informations personnelles et de connexion, avec des extensions pour des détails plus spécifiques.
**Flux d'Interaction :**
- Le processus d'ajout d'un ami inclut la saisie du nom de l'ami, tandis que la suppression d'un ami et la visualisation de la liste des amis sont soumises à une authentification préalable pour protéger la confidentialité.
- Les modifications d'informations englobent deux extensions : la mise à jour des informations personnelles et la mise à jour des informations de connexion, offrant une personnalisation approfondie du profil athlétique.
- La visualisation du profil d'un ami s'étend à des fonctionnalités telles que la consultation des activités et des statistiques de l'ami, ajoutant une dimension sociale à l'expérience de suivi sportif.
Explorez ce diagramme pour découvrir comment notre application encourage l'interaction sociale entre les athlètes, favorisant une communauté engagée et collaborative au sein de laquelle les utilisateurs peuvent partager, interagir et se soutenir mutuellement dans leur parcours sportif.
```plantuml
left to right direction
:Athlete: as a
a --> (Ajouter un ami)
a --> (Supprimer un ami)
a --> (Voir mes amis)
a --> (Modifier mes informations)
(Ajouter un ami)->(Saisir le nom de l'ami)
(Supprimer un ami)..>(S'authentifier) : <<include>>
(Ajouter un ami)..>(S'authentifier) : <<include>>
(Voir mes amis)..>(S'authentifier) : <<include>>
(Voir mes amis)..>(Lister les amis) : <<include>>
(Modifier mes informations)..>(Informations personnelles) : <<extends>>
(Modifier mes informations)..>(Informations de connexion) : <<extends>>
(Modifier mes informations)..>(S'authentifier) : <<include>>
(Lister les amis)..>(Voir son profil) : <<include>>
(Voir son profil)..>(Voir ses activités) : <<extends>>
(Voir son profil)..>(Voir ses statistiques) : <<extends>>
(S'authentifier)..>(S'inscrire) : <<extends>>
(S'authentifier)..>(Se connecter) : <<include>>
(S'inscrire)..>(Inscription Athlète) : <<include>>
```

File diff suppressed because it is too large Load Diff

@ -0,0 +1,203 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de Classes : Plateforme de Gestion d'Activités Sportives
Bienvenue dans l'écosystème dynamique de notre plateforme de gestion d'activités sportives ! Ce diagramme de classes offre une vision complète des entités et des relations qui façonnent l'expérience des utilisateurs au sein de notre système.
**Entités Principales :**
- **Utilisateur (User) :** Représente les individus inscrits sur notre plateforme, avec des détails personnels tels que le nom, le prénom, l'email, etc. Chaque utilisateur a un rôle spécifique (Athlete, Coach) qui détermine ses interactions au sein de l'application.
- **Rôle (Role) :** Classe abstraite qui définit les rôles spécifiques des utilisateurs (Athlete, Coach). Contient des méthodes pour gérer les amis, les entraînements, et les demandes.
- **Athlète (Athlete) :** Spécialisation de la classe Role, représentant les utilisateurs actifs qui enregistrent des activités sportives, des statistiques, et interagissent avec d'autres athlètes.
- **Activité (Activite) :** Contient des détails sur une activité sportive tels que le type, la date, la durée, la fréquence cardiaque, etc.
- **Notification (Notification) :** Messages pour informer les utilisateurs des actions importantes.
- **Entraînement (Entrainement) :** Sessions planifiées d'activités physiques avec des détails comme la date, la localisation, la description, et les retours.
- **Statistique (Statistique) :** Informations détaillées sur les performances sportives d'un athlète, comprenant la distance totale, le poids, le temps total, la fréquence cardiaque, etc.
- **Source de Données (SourceDonnees) :** Représente les sources utilisées pour collecter des données, telles que les montres connectées.
**Relations Clés :**
- Les Utilisateurs ont un rôle spécifique (Athlete, Coach) qui détermine leurs fonctionnalités.
- Un Athlète peut enregistrer plusieurs Activités, possède des Statistiques, et une Sources de Données qui est la plus utilisé.
- Les Entraînements sont liés aux Utilisateurs, permettant une planification efficace.
- Les Notifications informent les Utilisateurs des événements importants tels qu'une demande d'amis ou une notification d'avertissement de ban.
Explorez ce diagramme pour comprendre comment notre plateforme offre une expérience complète, de la gestion des utilisateurs à l'enregistrement des activités sportives et au suivi des performances.
```plantuml
@startuml
class User {
- id: int
- username: String
- nom: string
- prenom: string
- email: string
- motDePasse: string
- sexe: string
- taille: float
- poids: float
- dateNaissance: \DateTime
+ getId(): int
+ getUsername(): string
+ setUsername(string $username): void
+ setId(int $id): void
+ getNom(): string
+ setNom(string $nom): void
+ getPrenom(): string
+ setPrenom(string $prenom): void
+ getEmail(): string
+ setEmail(string $email): void
+ getMotDePasse(): string
+ setMotDePasse(string $motDePasse): void
+ getSexe(): string
+ setSexe(string $sexe): void
+ getTaille(): float
+ setTaille(float $taille): void
+ getPoids(): float
+ setPoids(float $poids): void
+ getDateNaissance(): \DateTime
+ setDateNaissance(\DateTime $dateNaissance): void
+ getRole(): Role
+ setRole(Role $role): void
+ addNotification($notification): void
+ deleteNotification($index): void
+ isValidPassword(string $password): bool
+ __toString(): string
}
abstract class Role {
- id: int
- usersRequests: array
+ getUsersList(): array
+ getUsersRequests(): array
+ addUsersRequests(RelationshipRequest $request): void
+ removeRequest(RelationshipRequest $req): bool
+ CheckAdd(User $user): bool
+ addUser(User $user): bool
+ removeUser(User $user): bool
+ addTraining(Training $training): bool
+ getTrainingsList(): array
}
abstract class Coach extends Role {
}
class CoachAthlete extends Coach {
+ CheckAdd(User $user): bool
}
class Athlete extends Role {
+ getActivities(): array
+ addActivity(Activity $myActivity): bool
+ CheckAdd(User $user): bool
}
class Activite {
- idActivity: int
- type: String
- date: \DateTime
- heureDebut: \DateTime
- heureFin: \DateTime
- effortRessenti: int
- variability: float
- variance: float
- standardDeviation: float
- average: int
- maximum: int
- minimum: int
- avrTemperature: float
- hasAutoPause: bool
+ getIdActivity(): int
+ getType(): String
+ getDate(): \DateTime
+ getHeureDebut(): \DateTime
+ getHeureFin(): \DateTime
+ getEffortRessenti(): int
+ getVariability(): float
+ getVariance(): float
+ getStandardDeviation(): float
+ getAverage(): float
+ getMaximum(): int
+ getMinimum(): int
+ getAvrTemperature(): float
+ setType(String $type): void
+ setEffortRessenti(int $effortRessenti): void
+ __toString(): String
}
class Notification {
- type: string
- message: string
- toUserId: int
+ getType(): string
+ setType(string $type): void
+ getMessage(): string
+ setMessage(string $message): void
+ getToUserId(): int
+ setToUserId(int $toUserId): void
+ __construct(int $toUserId,string $type, string $message)
+ __toString(): string
}
class Entrainement {
- idTraining: int
- date: \DateTime
- latitude: float
- longitude: float
- description: String
- feedback: String
+ getId(): int
+ getDate(): \DateTime
+ getLocation(): String
+ getDescription(): String
+ getFeedback(): String
+ __toString(): String
}
class Statistique {
- idStat: int
- distanceTotale: float
- poids: float
- tempsTotal: time
- FCmoyenne: int
- FCmin: int
- FCmax: int
- cloriesBrulees: int
+ getIdStat(): int
+ getDistanceTotale(): float
+ getPoids(): float
+ getTempsTotal(): time
+ getFCmoyenne(): int
+ getFCmin(): int
+ getFCmax(): int
+ getCloriesBrulees(): int
+ __toString(): String
}
class SourceDonnees {
- idSource: int
- nom: String
- type: String
- precision: enum
- dateDerniereUtilisation: \DateTime
+ getIdSource(): int
+ getNom(): String
+ getType(): String
+ getPrecision(): enum
+ getDateDerniereUtilisation(): \DateTime
+ __toString(): String
}
User -> Role : role
Role -> User : usersList
Athlete -> Statistique : statsList
Athlete -> Activite : activityList
Athlete -> SourceDonnees : sdList
User -> Notification : notificationList
User -> Entrainement : trainingsList
Activite -> SourceDonnees : maSource
@enduml
```

@ -0,0 +1,91 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de la Couche d'Accès aux Données
Bienvenue dans le cœur de notre système, où les données prennent vie à travers des ensembles de données (repositories) structurés et performants. Ce diagramme met en lumière la conception de la couche d'accès aux données de notre application, offrant un aperçu clair de la gestion des entités clées telles que les utilisateurs, les notifications, les demandes de relations et les entraînements.
**Principes Fondamentaux :**
- **IGenericRepository :** Une abstraction générique établissant les contrats essentiels pour l'accès aux données. Définissant des opérations standardisées telles que la récupération, la mise à jour, l'ajout et la suppression d'entités.
- **Interfaces Spécialisées :** Des interfaces telles que `IUserRepository`, `INotificationRepository`, `IRelationshipRequestRepository` et `ITrainingRepository` étendent les fonctionnalités génériques pour répondre aux besoins spécifiques de chaque entité.
**Repositories Concrets :**
- **UserRepository :** Gère les données relatives aux utilisateurs, permettant des opérations de récupération, de mise à jour et de suppression avec une efficacité optimale.
- **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.
- **TrainingRepository :** Permet l'accès et la manipulation des données liées aux entraînements, facilitant le suivi des performances athlétiques.
Explorez ce diagramme pour découvrir la robustesse de notre architecture de gestion des données, mettant en œuvre des pratiques de développement SOLID pour assurer une expérience utilisateur fiable et évolutive.
```plantuml
@startuml couche_acces_aux_donnees
interface IGenericRepository {
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array
+ getItemsByName(string substring, int index, int count, string orderingPropertyName, bool descending) : array
+ getItemByName(string substring, int index, int count, string orderingPropertyName, bool descending) : object
+ updateItem(oldItem, newItem) : void
+ addItem(item) : void
+ deleteItem(item) : bool
}
interface IUserRepository extends IGenericRepository {
}
interface INotificationRepository extends IGenericRepository {
}
interface IRelationshipRequestRepository extends IGenericRepository {
}
interface ITrainingRepository extends IGenericRepository {
}
class NotificationRepository implements INotificationRepository {
- notifications : array
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array
+ getItemsByName(string substring, int index, int count, string orderingPropertyName, bool descending) : array
+ getItemByName(string substring, int index, int count, string orderingPropertyName, bool descending) : object
+ updateItem(oldItem, newItem) : void
+ addItem(item) : void
+ deleteItem(item) : bool
}
class RelationshipRequestRepository implements IRelationshipRequestRepository {
- requests : array
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array
+ getItemsByName(string substring, int index, int count, string orderingPropertyName, bool descending) : array
+ getItemByName(string substring, int index, int count, string orderingPropertyName, bool descending) : object
+ updateItem(oldItem, newItem) : void
+ addItem(item) : void
+ deleteItem(item) : bool
}
class TrainingRepository implements ITrainingRepository {
- trainings : array
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array
+ getItemsByDate(date, int index, int count, string orderingPropertyName, bool descending) : array
+ updateItem(oldItem, newItem) : void
+ addItem(item) : void
+ deleteItem(item) : bool
}
class UserRepository implements IUserRepository {
- users : array
+ getItemById(int id) : object
+ getNbItems() : int
+ getItems(int index, int count, string orderingPropertyName, bool descending) : array
+ getItemsByName(string substring, int index, int count, string orderingPropertyName, bool descending) : array
+ getItemByName(string substring, int index, int count, string orderingPropertyName, bool descending) : object
+ updateItem(oldItem, newItem) : void
+ addItem(item) : void
+ deleteItem(item) : bool
}
@enduml
```

@ -0,0 +1,139 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de Classes : Statistiques pour Coach
Bienvenue dans l'univers captivant de notre système de gestion d'activités sportives avec une mise au point spéciale sur les statistiques destinées aux athlètes. Ce diagramme de classes offre une vue approfondie de la manière dont les utilisateurs, en particulier les athlètes, interagissent avec leurs statistiques.
**Entités Principales :**
- **Utilisateur (User) :** Représente les individus inscrits sur notre plateforme, avec des détails personnels et un rôle spécifique dans l'écosystème sportif.
- **Athlète (Athlete) :** Un type spécialisé d'utilisateur qui possède des statistiques liées à ses activités sportives.
- **Coach (Coach) :** Un rôle qui s'étend à partir de la classe abstraite Role, dédié à la gestion des athlètes et de la vision de leurs statistiques.
- **Statistique (Statistique) :** Contient des informations détaillées sur les performances sportives d'un athlète, telles que la distance totale, le poids, le temps total, la fréquence cardiaque moyenne, minimale et maximale, ainsi que les calories brûlées.
**Relations Clés :**
- Les Utilisateurs ont un rôle spécifique (Athlete, Coach) qui influence leurs interactions au sein de la plateforme.
- Un Coach peut gérer une liste d'athlètes et avoir accès à leurs statistiques.
- Un Athlète peut enregistrer plusieurs activités afin d'avoir des statistiques liées à celle-ci.
**Objectif Principal :**
- Permettre aux coachs d'accéder et de surveiller les statistiques détaillées de leurs athlètes, offrant ainsi un aperçu complet de leurs performances sportives.
Explorez ce diagramme pour découvrir comment notre application crée une synergie entre les utilisateurs, les rôles, et les statistiques, contribuant ainsi à une expérience enrichissante dans le suivi des activités sportives.
```plantuml
@startuml
class Athlete {
+ getAthlete(): Athlete
+ getStatistic(): ?array
+ getUsersList(): array
+ getUserList(user: User): User
+ CheckAdd(user: User): bool
+ addUser(user: User): bool
+ removeUser(user: User): bool
}
abstract class Coach {
+ abstract getUsersList(): ?array
+ abstract getUserList(user: User): User
}
class CoachAthlete {
+ getUsersList(): ?array
+ getUserList(user: User): User
}
abstract class Role {
- int id
- array usersList
- TrainingRepository trainingRepository
+ abstract __construct(trainingRepository: ?TrainingRepository)
+ abstract getUsersList(): ?array
+ abstract getUserList(user: User): User
+ abstract getTraining(): ?TrainingRepository
+ abstract getTrainingsList(): ?array
+ abstract getTrainingList(training: Training): ?Training
+ abstract CheckAdd(user: User): bool
+ abstract CheckAddTraining(training: Training): bool
+ abstract addUser(user: User): bool
+ abstract removeUser(user: User): bool
+ abstract addTraining(training: Training): bool
+ abstract removeTraining(training: Training): bool
}
class User {
- int id
- String username
- string nom
- string prenom
- string email
- string motDePasse
- string sexe
- float taille
- float poids
- DateTime dateNaissance
+ __construct(id: int, username: String, nom: string, prenom: string, email: string, motDePasse: string, sexe: string, taille: float, poids: float, dateNaissance: DateTime, role: Role)
+ getId(): int
+ setId(id: int): void
+ getUsername(): String
+ setUsername(username: int): void
+ getNom(): string
+ setNom(nom: string): void
+ getPrenom(): string
+ setPrenom(prenom: string): void
+ getEmail(): string
+ setEmail(email: string): void
+ getMotDePasse(): string
+ setMotDePasse(motDePasse: string): void
+ getSexe(): string
+ setSexe(sexe: string): void
+ getTaille(): float
+ setTaille(taille: float): void
+ getPoids(): float
+ setPoids(poids: float): void
+ getDateNaissance(): DateTime
+ setDateNaissance(dateNaissance: DateTime): void
+ getRole(): Role
+ setRole(role: Role): void
+ isValidPassword(password: string): bool
+ __toString(): String
}
class Statistique {
- idStat: int
- distanceTotale: float
- poids: float
- tempsTotal: time
- FCmoyenne: int
- FCmin: int
- FCmax: int
- cloriesBrulees: int
+ getIdStat(): int
+ getDistanceTotale(): float
+ getPoids(): float
+ getTempsTotal(): time
+ getFCmoyenne(): int
+ getFCmin(): int
+ getFCmax(): int
+ getCloriesBrulees(): int
+ __toString(): String
}
CoachAthlete --|> Coach
Coach --|> Role
Athlete --|> Role
User -> Role : role
Role -> User : usersList
Athlete -> Statistique : statsList
@enduml
````

@ -0,0 +1,92 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Diagramme de Classes : Gestion des Utilisateurs et Notifications
Bienvenue dans le cœur de notre système, où la gestion des utilisateurs et des notifications prend vie à travers ce diagramme de classes. Explorez les relations et les fonctionnalités essentielles qui orchestrent l'interaction entre les utilisateurs, les demandes d'amis, et les notifications.
**Entités Principales :**
- **Utilisateur (User) :** Représente les individus inscrits sur notre plateforme, caractérisés par leur nom et établissant des liens d'amitié avec d'autres utilisateurs.
- **Notification (Notification) :** Contient le texte informatif des notifications qui peuvent être émises par le système.
- **Demande d'Ami (Ask) :** Modélise une demande d'amitié émise par un utilisateur en direction d'un autre.
**Interfaces et Classes Abstraites :**
- **INotifier :** Interface définissant la méthode `notify()`, implémentée par des classes concrètes pour gérer la notification aux observateurs.
- **Observer :** Interface définissant la méthode `update()`, implémentée par les classes qui souhaitent être informées des changements dans un sujet observé.
- **UserManager :** Classe abstraite gérant la logique métier liée aux utilisateurs, tels que l'ajout ou la suppression d'amis, la réponse aux demandes d'amis, et la récupération de la liste d'amis.
- **IUserRepository :** Interface définissant les méthodes pour la recherche d'utilisateurs et l'ajout d'un nouvel utilisateur.
**Relations Clés :**
- Les utilisateurs peuvent avoir plusieurs amis et plusieurs notifications.
- La classe UserManager est connectée à IUserRepository pour gérer les opérations liées aux utilisateurs.
- Observer et Subject sont des composants du modèle de conception "Observer", permettant la notification efficace des changements dans le système.
Plongez-vous dans ce diagramme pour découvrir comment notre application crée un écosystème social dynamique, permettant aux utilisateurs d'interagir, de rester informés et de développer des liens significatifs au sein de la communauté.
```plantuml
class User {
+ name : string
}
User "1" --> "*" User: friends
User "1" --> "*" Notification: notifications
User "1" --> "*" Ask: friendRequests
class Notification {
- text : string
}
interface INotifier {
+ notify() : void
}
INotifier --|> Observer
abstract class UserManager {
- currentUser : User
+ deleteFriend(userId : int) : void
+ addFriend(userId : int) : void
+ respondToFriendRequest(requestId : int, choice : bool) : void
+ getFriends(userId : int) : User[]
}
class Ask {
- fromUser : int
- toUser : int
}
Ask --|> Subject
abstract class Subject {
+ attach(o : Observer) : void
+ detach(o : Observer) : void
+ notify() : void
}
Subject "1" --> "*" Observer
interface Observer {
+ update() : void
}
UserManager ..> User
UserManager o-- IUserRepository
UserManager o-- INotifier
interface IUserRepository {
+ findByUsername(username : string) : User
+ addUser(user : User) : bool
}
IUserRepository ..> User
```

@ -0,0 +1,201 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Modèle de Données de l'Application
L'architecture de données de notre application de suivi d'activités sportives repose sur un modèle robuste, avec des entités clés pour représenter les activités, les athlètes et les coachs et la récupération de ces données au sein de notre application. Découvrez les composants principaux de notre modèle de données :
## Activité
L'entité Activité représente une session d'activité sportive avec des détails variés tels que le type d'activité, la date, la durée, l'effort ressenti, etc. Le `ActiviteEntity` encapsule ces données, tandis que le `ActiviteGateway` gère la communication avec la base de données pour les activités.
## Athlète
L'entité Athlète représente un utilisateur de l'application qui participe à des activités sportives. Le `AthleteEntity` stocke les détails de l'athlète, et le `AtheletGateway` facilite l'accès et la gestion des données des athlètes.
## Coach
L'entité Coach représente un utilisateur qui peut superviser et coacher d'autres athlètes. Le `CoachEntity` stocke les détails du coach, tandis que le `CoachGateway` gère les interactions avec la base de données.
## Mapper
Les mappers, tels que `ActiviteMapper`, `AthleteMapper`, et `CoachMapper`, facilitent la conversion entre les entités et les modèles utilisés dans l'application.
## Connexion à la Base de Données
La classe `Connection` étend de `PDO` et assure la connexion à la base de données. Chaque Gateway utilise cette connexion pour interagir avec la base de données.
```plantuml
@startuml
class ActiviteEntity {
- idActivite: int
- type: string
- date: string
- heureDebut: string
- heureFin: string
- effortRessenti: int
- variabilite: int
- variance: int
- ecartType: int
- moyenne: int
- maximum: int
- minimum: int
- temperatureMoyenne: int
+ getIdActivite(): int
+ getType(): string
+ getDate(): string
+ getHeureDebut(): string
+ getHeureFin(): string
+ getEffortRessenti(): int
+ getVariabilite(): int
+ getVariance(): int
+ getEcartType(): int
+ getMoyenne(): int
+ getMaximum(): int
+ getMinimum(): int
+ getTemperatureMoyenne(): int
+ setIdActivite(idActivite: int): void
+ setType(type: string): void
+ setDate(date: string): void
+ setHeureDebut(heureDebut: string): void
+ setHeureFin(heureFin: string): void
+ setEffortRessenti(effortRessenti: int): void
+ setVariabilite(variabilite: int): void
+ setVariance(variance: int): void
+ setEcartType(ecartType: int): void
+ setMoyenne(moyenne: int): void
+ setMaximum(maximum: int): void
+ setMinimum(minimum: int): void
+ setTemperatureMoyenne(temperatureMoyenne: int): void
}
class ActiviteGateway {
+ __construct(connection: Connection)
+ getActivite(): ?array
+ getActiviteById(activiteId: int): ?array
+ getActiviteByType(type: string): ?array
+ getActiviteByDate(date: string): ?array
+ getActiviteByTimeRange(startTime: string, endTime: string): ?array
+ getActiviteByEffort(effortRessenti: int): ?array
+ getActiviteByVariability(variabilite: int): ?array
+ getActiviteByTemperature(temperatureMoyenne: int): ?array
+ addActivite(activite: ActiviteEntity): bool
+ updateActivite(oldActivite: ActiviteEntity, newActivite: ActiviteEntity): bool
+ deleteActivite(idActivite: int): bool
}
class ActiviteMapper {
+ map(data: array): ActiviteEntity
+ ActiviteEntityToModel(activiteEntity: ActiviteEntity): Activite
}
class AthleteEntity {
- idAthlete: int
- nom: string
- prenom: string
- email: string
- sexe: string
- taille: float
- poids: float
- motDePasse: string
- dateNaissance: string
+ getIdAthlete(): int
+ getNom(): string
+ getPrenom(): string
+ getEmail(): string
+ getSexe(): string
+ getTaille(): float
+ getPoids(): float
+ getMotDePasse(): string
+ getDateNaissance(): string
+ setIdAthlete(idAthlete: int): void
+ setNom(nom: string): void
+ setPrenom(prenom: string): void
+ setEmail(email: string): void
+ setSexe(sexe: string): void
+ setTaille(taille: float): void
+ setPoids(poids: float): void
+ setMotDePasse(motDePasse: string): void
+ setDateNaissance(dateNaissance: string): void
}
class AtheletGateway {
+ __construct(connection: Connection)
+ getAthlete(): ?array
+ getAthleteById(userId: int): ?array
+ getAthleteByName(name: string): ?array
+ getAthleteByFirstName(firstName: string): ?array
+ getAthleteByEmail(email: string): ?array
+ getAthleteByGender(gender: string): ?array
+ getAthleteByHeight(height: int): ?array
+ getAthleteByWeight(weight: int): ?array
+ getAthleteByBirthDate(birthdate: string): ?array
+ addAthlete(athlete: AthleteEntity): bool
+ updateAthlete(oldAthlete: AthleteEntity, newAthlete: AthleteEntity): bool
+ deleteAthlete(idAthlete: int): bool
}
class AthleteMapper {
+ fromSqlToEntity(data: array): array
+ athleteEntityToModel(athleteEntity: AthleteEntity): User
+ athleteToEntity(user: User): AthleteEntity
}
class CoachEntity {
- idCoach: int
- nom: string
- prenom: string
- email: string
- sexe: string
- taille: float
- poids: float
- motDePasse: string
- dateNaissance: string
+ getIdCoach(): int
+ getNom(): string
+ getPrenom(): string
+ getEmail(): string
+ getSexe(): string
+ getTaille(): float
+ getPoids(): float
+ getMotDePasse(): string
+ getDateNaissance(): string
+ setIdCoach(idCoach: int): void
+ setNom(nom: string): void
+ setPrenom(prenom: string): void
+ setEmail(email: string): void
+ setSexe(sexe: string): void
+ setTaille(taille: float): void
+ setPoids(poids: float): void
+ setMotDePasse(motDePasse: string): void
+ setDateNaissance(dateNaissance: string): void
}
class CoachGateway {
+ __construct(connection: Connection)
+ getCoach(): ?array
+ getCoachById(userId: int): ?array
+ getCoachByName(name: string): ?array
+ getCoachByFirstName(firstName: string): ?array
+ getCoachByEmail(email: string): ?array
+ getCoachByGender(gender : string): ?array
+ getCoachByHeight(height: int): ?array
+ getCoachByBirthDate(birthdate: string): ?array
+ addCoach(coach: CoachEntity): bool
+ updateCoach(oldCoach: CoachEntity, newCoach: CoachEntity): bool
+ deleteCoach(idCoach: int): bool
}
class CoachMapper {
+ map(data: array): CoachEntity
+ CoachEntityToModel(coachEntity: CoachEntity): User
+ CoachToEntity(user: User): CoachEntity
}
class Connection extends PDO {
- stmt
+ __construct(dsn: string, username: string, password: string)
+ executeQuery(query: string, parameters: array): bool
+ executeWithErrorHandling(query: string, params: array): array
+ getResults(): array
}
Connection <- ActiviteGateway : connection
Connection <- AtheletGateway : connection
Connection <- CoachGateway : connection
AthleteMapper -> AthleteEntity
CoachMapper -> CoachEntity
ActiviteMapper -> ActiviteEntity
ActiviteMapper -> ActiviteGateway
CoachMapper -> CoachGateway
AthleteMapper -> AtheletGateway
@enduml
```

@ -0,0 +1,137 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Diagramme de classes pour l'importation de fichiers .fit
Bienvenue dans le monde de la gestion d'activités sportives avec notre application innovante ! Ce diagramme de classe se concentre sur une fonctionnalité essentielle qui améliorera l'expérience des utilisateurs : l'importation de fichiers .fit. Nous avons conçu un diagramme de classes pour vous offrir une vision claire et structurée de la manière dont cette fonctionnalité est implémentée au sein de notre application.
**Acteurs Principaux :**
- Utilisateur (User) : Représente un individu inscrit sur notre plateforme.
- Athlète (Athlete) : Un type spécialisé d'utilisateur, bénéficiant de fonctionnalités supplémentaires liées à la gestion d'activités sportives et avec la capacité d'importer des fichiers .fit.
**Entités Clés :**
- Activité (Activity) : Représente une session d'activité physique, avec des détails tels que le type, la date, la durée, et plus encore.
- Gestionnaires (Managers) : Gérant différentes facettes de l'application, notamment les utilisateurs, les activités et les fichiers.
**Fonctionnalité Clé :**
- Importation de fichiers .fit : Permet aux utilisateurs de charger des données provenant de fichiers .fit via la bibliothèque `php-fit-file-analysis`, générés par des dispositifs de suivi d'activité. Ces fichiers contiennent des informations précieuses telles que la fréquence cardiaque, la distance parcourue et d'autres données de santé importante pour nos analyses.
**Architecture :**
- AuthService (Service d'Authentification) : Gère l'authentification des utilisateurs, garantissant un accès sécurisé à la fonction d'importation.
- UserManager (Gestionnaire d'Utilisateurs) : Gère les opérations liées aux utilisateurs, y compris l'importation de fichiers .fit.
- ActivityManager (Gestionnaire d'Activités) : Responsable du stockage et de la gestion des activités importées.
**Objectif :**
Offrir aux utilisateurs, en particulier aux athlètes, la possibilité d'enrichir leur profil et de suivre leur performance en important des données détaillées à partir de fichiers .fit.
```plantuml
@startuml issue028_DiagrammeDeClasses
class Activite {
-idActivite:int
-type:String
-date:Date
-heureDebut:Date
-heureFin:Date
-effortRessenti:int
-variability:float
-variance:float
-standardDeviation:float
-average:float
-maximum:int
-minimum:int
-avrTemperature:float
-hasAutoPause:boolean
+getIdActivite():int
+getType():String
+getDate():Date
+getHeureDebut():Date
+getHeureFin():Date
+getEffortRessenti():int
+getVariability():float
+getVariance():float
+getStandardDeviation():float
+getAverage():float
+getMaximum():int
+getMinimum():int
+getAvrTemperature():float
+setType(type:String):void
+setEffortRessenti(effortRessenti:int):void
+__toString():String
}
class Role {
-id:int
}
class Athlete {
+getActivities():array
+addActivity(myActivity:Activity):boolean
}
class User {
-id:int
-username:String
-nom:String
-prenom:String
-email:String
-motDePasse:String
-sexe:String
-taille:float
-poids:float
-dateNaissance:Date
+getId():int
+setId(id:int):void
+getUsername():String
+setUsername(username:String):void
+getNom():String
+setNom(nom:String):void
+getPrenom():String
+setPrenom(prenom:String):void
+getEmail():String
+setEmail(email:String):void
+getMotDePasse():String
+setMotDePasse(motDePasse:String):void
+getSexe():String
+setSexe(sexe:String):void
+getTaille():float
+setTaille(taille:float):void
+getPoids():float
+setPoids(poids:float):void
+getDateNaissance():Date
+setDateNaissance(dateNaissance:Date):void
+getRole():Role
+setRole(role:Role):void
+isValidPassword(password:String):boolean
+__toString():String
}
class AthleteManager {
+getActivities():array
}
class ActivityManager {
+saveFitFileToJSON(monFichierFit:object):boolean
+uploadFile(type:string, effortRessenti:int, file_path_or_data:string|resource, options:array):boolean
}
class DataManager {
}
class UserManager {
+login(loginUser:string, passwordUser:string):boolean
+register(loginUser:string, passwordUser:string, data:array):boolean
+deconnecter():boolean
}
User -> Role: role
Athlete -|> Role
DataManager -> UserManager: -userMgr
DataManager -> AthleteManager: -athleteMgr
DataManager -> ActivityManager: -activityMgr
UserManager -> AuthService: -authService
UserManager -> User: -currentUser
ActivityManager -> AuthService: -authService
Athlete -> Activite: listActivite
AthleteManager -> AuthService: -authService
@enduml
```

@ -0,0 +1,50 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de Séquence : Gestion des Demandes d'Amis
Bienvenue dans le processus dynamique de gestion des demandes d'amis au sein de notre application ! Ce diagramme de séquence met en évidence les étapes clés impliquées dans la gestion des demandes d'amis entre utilisateurs.
**Acteurs Principaux :**
- **Utilisateur (u) :** L'individu interagissant avec l'application, recevant et répondant aux demandes d'amis.
**Flux d'Interaction :**
1. **Réception d'une Demande d'Ami :** Lorsqu'un utilisateur reçoit une demande d'ami, le modèle (Model) notifie le contrôleur (Controller) de la nouvelle demande, spécifiant l'identifiant de l'utilisateur émetteur.
2. **Affichage de la Demande d'Ami :** Le contrôleur transmet l'information à la vue (View), qui affiche la demande d'ami à l'utilisateur.
3. **Affichage de la Page des Demandes d'Amis :** L'utilisateur visualise la page des demandes d'amis dans l'interface utilisateur.
4. **Réponse à la Demande d'Ami :** L'utilisateur prend une décision quant à la demande d'ami, en répondant par un choix binaire (accepter ou refuser).
5. **Enregistrement de la Réponse :** La vue (View) transmet la réponse de l'utilisateur au contrôleur, qui enregistre cette réponse.
6. **Envoi de la Réponse :** Le contrôleur communique avec le modèle pour envoyer la réponse, indiquant si la demande a été acceptée (true) ou refusée (false).
À travers ce diagramme de séquence, découvrez comment notre application gère efficacement le processus de gestion des demandes d'amis, offrant aux utilisateurs une expérience transparente et réactive lors de l'établissement de connexions sociales au sein de la plateforme.
````plantuml
@startuml
actor User as u
boundary View as v
control Controller as c
entity Model as m
m-->c: pendingRequests: Request[]
c-->v: DisplayPendingRequests(pendingRequests)
v-->u: Show Friend Requests
u->v: RespondToRequest(requestId, response)
v-->c: RecordResponse(requestId, response)
c->m: UpdateRequestStatus(requestId, response)
m-->c: updateStatus: success/failure
c-->v: NotifyUpdateResult(updateStatus)
v-->u: Show Response Result
@enduml
``````

@ -0,0 +1,31 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de Séquence : Recherche d'Amis
Bienvenue dans le processus dynamique de recherche d'amis au sein de notre application ! Ce diagramme de séquence met en lumière les étapes clés impliquées lorsque les utilisateurs recherchent des amis en utilisant un pseudo spécifique.
**Acteurs Principaux :**
- **Utilisateur (u) :** L'individu interagissant avec l'application, initié à la recherche d'amis.
**Flux d'Interaction :**
1. **Accès à la Fonctionnalité de Recherche :** L'utilisateur déclenche la fonctionnalité de recherche d'amis depuis son interface utilisateur.
2. **Saisie du Pseudo :** L'utilisateur entre le pseudo de l'ami qu'il souhaite rechercher.
3. **Requête de Recherche :** La vue (View) transmet la demande de recherche au contrôleur (Controller), qui déclenche une requête GET au serveur pour récupérer la liste des amis correspondant au pseudo saisi.
4. **Traitement de la Requête :** Le modèle (Model) récupère la liste d'amis correspondante en utilisant l'identifiant de l'utilisateur et notifie le contrôleur du résultat.
5. **Notification des Utilisateurs :** Le modèle informe également les utilisateurs concernés (émetteur et destinataire) de l'action de recherche effectuée.
6. **Rendu de la Vue :** Le contrôleur reçoit la liste d'amis du modèle et rend cette liste à la vue.
7. **Affichage des Résultats :** La vue affiche les résultats de la recherche à l'utilisateur, montrant les amis qui correspondent au pseudo saisi.
À travers ce diagramme de séquence, découvrez comment notre application facilite le processus de recherche d'amis, fournissant aux utilisateurs une interface conviviale et réactive pour élargir leur réseau social au sein de la plateforme.
<img src="AjouterAmis.png" alt="Diagramme de Séquence : Recherche d'Amis" width="1000"/>

@ -0,0 +1,41 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Processus de Connexion sur la Plateforme
Bienvenue sur notre plateforme de gestion d'activités sportives ! Pour offrir une expérience fluide et sécurisée, nous avons mis en place un processus de connexion intuitif. Découvrez comment accéder à votre compte ou créer un nouveau compte en quelques étapes simples.
**Étapes du Processus :**
1. **Demande de Page de Connexion :** L'utilisateur démarre en exprimant le désir de se connecter à la plateforme.
2. **Vérification de la Connexion Préexistante :** Le système vérifie si l'utilisateur est déjà connecté. En cas de connexion active, l'utilisateur est redirigé directement vers sa page de compte.
3. **Page de Connexion :** Si l'utilisateur n'est pas encore connecté, il est dirigé vers la page de connexion, où il peut saisir ses informations d'identification.
4. **Choix pour les Utilisateurs Possédant un Compte :** Si l'utilisateur a déjà un compte, il peut fournir ses informations de connexion existantes.
5. **Création de Compte pour les Nouveaux Utilisateurs :** Pour ceux qui n'ont pas encore de compte, l'option de création de compte est disponible. L'utilisateur peut fournir les détails nécessaires pour créer son compte.
6. **Page de Création de Compte :** Une page dédiée guide l'utilisateur tout au long du processus de création de compte, lui permettant de saisir les informations nécessaires.
7. **Validation et Connexion :** Une fois que les informations de connexion ou de création de compte sont fournies, le système procède à la vérification et connecte l'utilisateur à son compte.
```plantuml
actor User as u
u->Systeme : demandePageConnexion()
alt User déjà connecté
Systeme-->u : redirectionPageCompte()
end
Systeme-->u : PageConnexion()
alt User possède déjà un compte
u->Systeme:InfosConnexion()
else
u->Systeme:CreerCompte()
Systeme-->u :PageCreationCompte()
u->Systeme:InfosCreationCompte()
end
Systeme-->u :Connecter()
```

@ -0,0 +1,64 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour au diagramme de classes](../README_DIAGRAMMES.md)
# Introduction au Diagramme de Séquence : Gestion des Amis
Bienvenue dans le processus dynamique de gestion des amis au sein de notre application ! Ce diagramme de séquence met en lumière les interactions entre l'utilisateur et l'application, ainsi que le flux d'informations entre les différentes composantes du système.
**Acteurs Principaux :**
- **Utilisateur (u) :** L'individu interagissant avec l'application, souhaitant consulter et gérer sa liste d'amis.
**Flux d'Interaction :**
1. **Demande de la Page d'Amis :** L'utilisateur déclenche la demande de la page d'amis, amorçant le processus d'affichage de sa liste d'amis.
2. **Récupération des Amis :** Le contrôleur (Controller) reçoit la demande et interagit avec le modèle (Model) pour récupérer la liste d'amis associée à l'identifiant de l'utilisateur.
- *Cas de Récupération Réussi :* Si la récupération est réussie, le modèle transmet la liste d'amis au contrôleur.
- *Cas d'Échec de Récupération :* En cas d'échec, une notification d'erreur est renvoyée.
3. **Affichage de la Liste d'Amis :** Le contrôleur rend la vue (View) en utilisant la liste d'amis récupérée, qui est ensuite affichée à l'utilisateur.
4. **Suppression d'un Ami :** L'utilisateur décide de supprimer un ami spécifique en cliquant sur l'option correspondante.
5. **Traitement de la Suppression :** Le contrôleur, en réponse à la demande de suppression, envoie une requête au modèle pour effectuer la suppression de l'ami identifié par son identifiant utilisateur (idUser).
- *Cas de Suppression Réussie :* Si la suppression est réussie, le modèle renvoie la liste d'amis mise à jour.
- *Cas d'Échec de Suppression :* En cas d'échec, une notification d'erreur est renvoyée.
6. **Affichage de la Liste d'Amis Mise à Jour :** La vue est mise à jour avec la nouvelle liste d'amis, qui est ensuite affichée à l'utilisateur.
À travers ce diagramme de séquence, découvrez comment notre application gère de manière fluide et réactive les interactions de l'utilisateur avec sa liste d'amis, garantissant une expérience utilisateur cohérente et sans heurts.
```plantuml
actor User as u
boundary View as v
control Controller as c
entity Model as m
u->v: Request Friends Page
v->c: Get /Friends
c->m: getFriends(userId)
alt successful retrieval
m-->c: friendsList: User[]
else retrieval failed
m-->c: error
end
c-->v: renderView(friendsList)
v-->u: Display Friends
u->v: clickDeleteFriend(idUser)
v->c: Post: deleteFriend(idUser)
c->m: deleteFriend(idUser)
alt successful deletion
m-->c: updatedFriendsList: User[]
else deletion failed
m-->c: error
end
c-->v: renderView(updatedFriendsList)
v-->u: Display Updated Friends
```

@ -0,0 +1,26 @@
[retour au README.md](../../README.md)
[Retour aux Documents](../README_DOCUMENTS.md)
# Diagrammes nécéssaires à notre projet
## Diagrammes de classes
- [issue016 - Statistiques coach ](DiagrammeDeClasses/README_issue016.md)
- [issue022 - Ajout des amis ](DiagrammeDeClasses/README_issue022.md)
- [issue023 - User Gateway ](DiagrammeDeClasses/README_issue023.md)
- [issue028 - Importation de fichiers .fit](DiagrammeDeClasses/README_issue028.md)
- [couche d'accès aux données](DiagrammeDeClasses/README_accesDonnees.md)
- [Diagramme général](DiagrammeDeClasses/README_DIAGRAMME.md)
## Diagrammes de séquence
- [Envoi de demande d'ami](DiagrammeDeSequence/README_demandeAmi.md)
- [Accepter une demande d'ami](DiagrammeDeSequence/README_accepterAmi.md)
- [Supprimer un ami](DiagrammeDeSequence/README_suppressionAmi.md)
- [issue021 - Authentification ](DiagrammeDeSequence/README_issue021.md)
## Diagrammes de cas d'utilisation
- [Cas d'utilisation pour la gestion du compte et des amitiés](CasUtilisations/README_gestionCompteAmitie.md)
- [Cas d'utilisation pour la gestion des activités et données](CasUtilisations/README_gestionActivites.md)
- [Cas d'utilisation pour la suivi d'une équipe sportive](CasUtilisations/README_coachSuiviSportif.md)
## Base de Données
- [MLD](BDD/README_BDD.md)

Before

Width:  |  Height:  |  Size: 46 KiB

After

Width:  |  Height:  |  Size: 46 KiB

@ -0,0 +1,13 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour à la Gestion](../README_GESTION.md)
# GANTT
## Comparaison GANTT
- [Comparaison GANTT - Excel](CompraraisonGANTT.xlsx)
<img src="ComparaisonGANTT.png">
## Gestion de projet - MSProject
- [Gestion de projet - MSProject](Gantt.mpp)
- [GANTT - PDF](Gantt.pdf)

Before

Width:  |  Height:  |  Size: 39 KiB

After

Width:  |  Height:  |  Size: 39 KiB

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 22 KiB

@ -0,0 +1,10 @@
[retour au README.md](../../../README.md)
[Retour aux Documents](../../README_DOCUMENTS.md)
[Retour à la Gestion](../README_GESTION.md)
## PERT
- [PERT - Excel](PERT.xlsx)
### PERT - Image
<img src="PERT1.png">
<img src="PERT2.png">

@ -0,0 +1,10 @@
[retour au README.md](../../README.md)
[Retour aux Documents](../README_DOCUMENTS.md)
# Gestion de projet
## PERT
- [PERT](PERT/README_PERT.md)
## GANTT
- [GANTT](GANTT/README_GANTT.md)

@ -0,0 +1,8 @@
[retour au README.md](../../README.md)
[Retour aux Documents](../README_DOCUMENTS.md)
# Personas
- [Personas Elsa Justin - PDF](ElsaJustin.pdf)
- [Personas Ethan Hulist - PDF](EthanHulist.pdf)
- [Personas Jules Gerdoli - PDF](JulesGerdoli.pdf)

@ -0,0 +1,11 @@
[README.md](../README.md)
## SOMMAIRE
# Diagrammes
- [Diagrammes](Diagramme/README_DIAGRAMMES.md)
# Personnas
- [Personnas](Personnas/README_PERSONNAS.md)
# Gestion de projet
- [Gestion de projet](Gestion/README_GESTION.md)

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 antoine.perederii
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

@ -1,26 +1,34 @@
<div align = center>
<h1>HeartTrack</h1>
<img src="Documents/Images/logo.png" />
</div>
<div align = center>
[Présentation](#présentation) | [Répartion](#répartition-du-git) | [Développement](#développement) | [Wiki](https://codefirst.iut.uca.fr/git/HeartTrack_Dev/Web/wiki)
---
---
&nbsp; ![PHP](https://img.shields.io/badge/PHP-000?style=for-the-badge&logo=Php&logoColor=white&color=purple)
&nbsp; ![CSS](https://img.shields.io/badge/CSS-000?style=for-the-badge&logo=css3&logoColor=white&color=darkblue)
&nbsp; ![DOCKER](https://img.shields.io/badge/Docker-2496ED.svg?style=for-the-badge&logo=Docker&logoColor=white)
&nbsp; ![PostgreSQL](https://img.shields.io/badge/Postgresql-000?style=for-the-badge&logo=postgresql&logoColor=white&color=blue)
&nbsp; ![JAVASCRIPT](https://img.shields.io/badge/JavaScript-000?style=for-the-badge&logo=javascript&logoColor=white&color=yellow)
</br>
</br>
<!-- [![Build Status]()](https://codefirst.iut.uca.fr/git/HeartDev/Web)
[![Quality Gate Status]()](https://codefirst.iut.uca.fr/git/HeartDev/Web)
[![Bugs]()](https://codefirst.iut.uca.fr/git/HeartDev/Web)
[![Coverage]()](https://codefirst.iut.uca.fr/git/HeartDev/Web)
[![Vulnerabilities]()](https://codefirst.iut.uca.fr/git/HeartDev/Web) -->
---
</div>
</div>
# Table des matières
[Présentation](#présentation) | [Répartition du Git](#répartition-du-git) | [Documentation](#documentation) | [Prerequisites](#prerequisites) | [Getting Started](#getting-started) | [Features](#features) | [Ce que nous avons fait](#ce-que-nous-avons-fait) | [Fabriqué avec](#fabriqué-avec) | [Contributeurs](#contributeurs) | [Comment contribuer](#comment-contribuer) | [License](#license) | [Remerciements](#remerciements)
# HeartTrack
## Présentation
@ -29,20 +37,22 @@
### Contexte
HeartTrack est une application web PHP et mobile Android destinée aux sportifs pour l'analyse de courbes cardiaques. L'objectif principal de cette application est de récupérer les données de fréquence cardiaque à partir d'une montre, de les afficher sous forme de courbes, d'identifier des patterns, de fournir des statistiques et de réaliser des prédictions liées à l'effort physique, à la chaleur, à la récupération, etc.
HeartTrack est une application web PHP et mobile Android destinée aux sportifs et aux coachs afin de permettre l'analyse de courbes de fréquences cardiaques et le suivi d'équipe sportive. L'objectif principal de cette application est de récupérer les données de fréquence cardiaque à partir de fichiers .FIT, de les afficher sous forme de courbes, d'identifier des paternes, de fournir des statistiques et de réaliser des prédictions liées à l'effort physique, à la chaleur, à la récupération, etc.
### Récapitulatif du Projet
Le projet HeartTrack, avec son application HeartTrack, vise à offrir une solution complète pour l'analyse des données de fréquence cardiaque, en mettant l'accent sur les besoins des sportifs. L'application sera capable de traiter et d'interpréter les données de manière intelligente, fournissant ainsi des informations précieuses pour optimiser les performances sportives et la santé.
Le projet HeartTrack, avec son application HeartTrack, vise à offrir une solution Open Source d'analyse des données de fréquence cardiaque, en mettant l'accent sur les besoins des sportifs et des coachs. L'application sera capable de traiter et d'interpréter les données de manière intelligente, fournissant ainsi des informations précieuses pour optimiser les performances sportives et la santé.
## Répartition du Git
[**Sources**](Sources) : **Code de l'application**
[**Sources**](Sources/) : **Code de l'application**
[**Documents**](Documents) : **Documentation de l'application**
[**Documents**](Documents/README_DOCUMENTS.md) : **Documentation de l'application et diagrammes**
--
[**Wiki**](https://codefirst.iut.uca.fr/git/HeartDev/Web/wiki/PHP) : **Wiki de notre projet (attendus PHP)**
---
Le projet HeartTrack utilise un modèle de flux de travail Git (Gitflow) pour organiser le développement. Voici une brève explication des principales branches :
@ -50,70 +60,80 @@ Le projet HeartTrack utilise un modèle de flux de travail Git (Gitflow) pour or
- **branche master** : La branche master est similaire à la branche de production, mais elle peut contenir des fonctionnalités en cours de développement qui sont presque prêtes pour une mise en production.
- **branche test** : Cette branche est utilisée pour déployer une version démo de l'application. Elle est mise à jour avec les dernières fonctionnalités et surtout la totalité de leurs test en développement.
- **branche test** : Cette branche est utilisée pour permettre différents tests sur l'application.
- **branche issue** : Pour chaque problème (issue) que vous résolvez, vous devez créer une branche portant le nom de l'issue, par exemple, "issue_#32_nom" où 32 est le numéro de l'issue et nom est une description courte de l'issue. Une fois l'issue résolue, assurez-vous de mettre à jour le changelog et de créer une merge request.
## Développement
### Travailler sur une Issue
Si vous êtes amené à travailler sur une issue, suivez ces principes :
1. Les issues sont créées dans le système de gestion de versions (Git), chaque issue ayant un numéro unique.
2. Lorsque vous décidez de travailler sur une issue, attribuez-vous l'issue et créez une branche avec un nom correspondant à l'issue sous la forme suivante : "issue_#32_nom" où 32 est le numéro de l'issue et nom est son libellé.
3. Une fois que vous avez résolu l'issue dans votre branche, assurez-vous de mettre à jour le changelog avec les modifications apportées.
4. Ensuite, poussez votre branche sur le référentiel distant et créez une merge request pour que vos modifications soient examinées par les autres membres de l'équipe.
## Prérequis
Avant de commencer à travailler sur le projet HeartTrack, assurez-vous d'avoir les prérequis suivants installés :
- Serveur web (par exemple, Apache)
- PHP (version recommandée)
- Base de données (par exemple, MySQL)
- Git
## Installation
Pour installer et exécuter le projet HeartTrack, suivez ces étapes :
1. Clonez ce référentiel sur votre machine locale en utilisant la commande suivante :
`git clone https://codefirst.iut.uca.fr/git/FitDev/Projet_fit_web`
2. Configurez votre environnement de développement avec les prérequis mentionnés ci-dessus.
3. Copiez le fichier de configuration d'exemple et configurez les paramètres de l'application :
cp config/config.example.php config/config.php
[pas encore la pour l'instant]
4. Importez la structure de la base de données à partir du fichier SQL fourni :
mysql -u votre_nom_utilisateur -p < db_schema.sql ou psql comme vous le souhaitez
5. Démarrez votre serveur web et accédez à l'application via le navigateur.
`npm run dev`
ou
`composer dev` e.q `php composer.phar dev`
## Exécution
Pour exécuter l'application, suivez les instructions d'installation ci-dessus. Une fois l'application configurée et le serveur web en cours d'exécution, accédez à l'application via votre navigateur web.
## Déploiement en Démo
Pour déployer une version de démonstration de l'application, utilisez la branche "demo" du référentiel. Cette branche est généralement mise à jour avec les dernières fonctionnalités en développement.
## Déploiement en Production
Pour déployer la version de production de l'application, utilisez la branche "prod" du référentiel.
---
N'hésitez pas à contribuer au développement de HeartTrack en résolvant des issues ou en ajoutant de nouvelles fonctionnalités. Nous vous encourageons à suivre les principes et les pratiques décrites dans ce document pour un développement efficace et collaboratif.
- **branche démo** : Cette branche est utilisée pour déployer une version démo de l'application. Elle est mise à jour avec les dernières fonctionnalités en développement.
## Documentation
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
## Getting Started
1. Cloner le répos
2. Faire un `composer install` dans le dossier `Sources/`
3. Importer la base de données `Sources/Database/hearttrack.sql`
4. Lancer le serveur Apache et MySQL
5. Lancer le projet avec `php -S localhost:8000 -t Sources/`
6. Ouvrir le navigateur et aller sur `localhost:8000/index.php`
## Features
* [x] Import de fichier .fit
* [x] Ajout d'amis
* [x] Création de compte
* [x] Ajout d'athlete pour le coach
* [x] Création d'entrainement
* [x] Création de courbes
* [x] Gérer ses permissions
## Ce que nous avons fait
* [x] PDO et Pattern Gateway
* [x] implémentation MVC et 2 contrôleurs
* [x] pattern Frontcontroleur sans routage
* [x] autoloader simple sans namespace ?
* [x] validation des entrées
* [x] vues dont vue erreur
* [x] partie administration ou équivalent
* [x] vues complètes bien segmentées et utilisation bootstrap
* [x] utilisation namespace et psr4
* [x] moteur twig pour les vues
* [x] pattern Frontcontroleur avec routage
* [x] Javascript
* [x] pattern fabrique
## Fabriqué avec
* [JetBrains Toolbox](https://www.jetbrains.com/fr-fr/toolbox-app/) - IDE
* [CodeFirst](https://codefirst.iut.uca.fr/) - Gitea
* [Drone](https://codefirst.iut.uca.fr/) - CI
* [SonarQube](https://codefirst.iut.uca.fr/sonar/) - Qualité
* [PHP 8](https://www.php.net/downloads) - Langage
* [html 5, CSS 3](https://developer.mozilla.org/fr/docs/Web/HTML) - Langage
* [Twig](https://twig.symfony.com/) - Langage
* [Doxygen](https://codefirst.iut.uca.fr/sonar/) - Documentation
## Contributeurs
* [Antoine PEREDERII](https://codefirst.iut.uca.fr/git/antoine.perederii)
* [Paul LEVRAULT](https://codefirst.iut.uca.fr/git/paul.levrault)
* [Kevin MONTEIRO](https://codefirst.iut.uca.fr/git/kevin.monteiro)
* [Antoine PINAGOT](https://codefirst.iut.uca.fr/git/antoine.pinagot)
* [David D'HALMEIDA](https://codefirst.iut.uca.fr/git/david.d_almeida)
## Comment contribuer
1. Forkez le projet (<https://codefirst.iut.uca.fr/git/HeartDev/Web>)
2. Créez votre branche (`git checkout -b feature/featureName`)
3. commit vos changements (`git commit -am 'Add some feature'`)
4. Push sur la branche (`git push origin feature/featureName`)
5. Créez une nouvelle Pull Request
## License
Ce projet est sous licence ``MIT`` - voir le fichier [LICENSE.md](LICENSE.md) pour plus d'informations.
## Remerciements
Ce projet a été réalisé dans le cadre de la SAÉ Projet Web et Mobile de l'IUT de Clermont-Ferrand.

@ -9,12 +9,12 @@
"Repository\\": "src/data/model/repository",
"Manager\\": "src/data/model/manager",
"Network\\": "src/data/core/network",
"Console\\": "src/console",
"Stub\\": [
"src/data/stub",
"src/data/stub/service",
"src/data/stub/repository"
],
"Console\\": "src/console",
"Shared\\": "src/shared",
"App\\Router\\": "src/app/router",
"App\\Controller\\": "src/app/controller",
@ -29,16 +29,16 @@
},
"require": {
"twig/twig": "^3.0",
"vlucas/phpdotenv": "^5.5",
"adriangibbons/php-fit-file-analysis": "^3.2.0",
"altorouter/altorouter": "1.1.0",
"psr/container": "^2.0"
"vlucas/phpdotenv": "^5.5",
"psr/container": "^2.0",
"adriangibbons/php-fit-file-analysis": "^3.2.0"
},
"require-dev": {
"phpunit/phpunit": "*"
},
"scripts": {
"dev": "php -S localhost:8081 -t public -d display_errors=1 -d error_reporting=E_ALL",
"dev": "php -S localhost:8080 -t public -d display_errors=1 -d error_reporting=E_ALL",
"dev:console": "export APP_ENV=console && php public/index.php",
"dev:html" : "export APP_ENV=html && php -S localhost:8080 -t public -d display_errors=1 -d error_reporting=E_ALL"
}

@ -0,0 +1,2 @@
AddType text/css .css
AddType application/javascript .js

@ -1,17 +1,31 @@
FROM php:8.2-fpm
FROM php:8.2-apache as base
# 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/
# Copy configs
COPY ./config/virtual-host.conf /etc/apache2/sites-available/000-default.conf
COPY ./config/httpd.conf /etc/apache2/httpd.conf
# Setup App
RUN mkdir -p /app/public && chown -R www-data:www-data /app
WORKDIR /app
# add sources code
COPY . /app
ENV VOLUME_PATH /app/public
RUN composer install
WORKDIR /var/www/
EXPOSE 80
RUN composer install
CMD ["apache2-foreground"]

@ -1,11 +1,11 @@
<?php
use Dotenv\Dotenv;
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';
@ -17,5 +17,6 @@ const DB_HOST = 'localhost';
const DB_DATABASE = 'heartTrack';
const DB_USER = 'toto';
const DB_PASSWORD = 'achanger';
//const APP_ENV = 'console';
const DSN = "mysql:host=" . DB_HOST . ";dbname=" . DB_DATABASE;

@ -0,0 +1 @@
SetEnv ASSET_PREFIX containers/HeartDev-web/

@ -1,28 +1,19 @@
server {
listen 80;
index index.php;
root /var/www/public;
index index.php index.html index.htm;
root /usr/share/nginx/html;
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 / {
try_files $uri $uri/ /index.php?$query_string;
root /usr/share/nginx/html;
try_files $uri /index.php;
}
}

@ -0,0 +1,39 @@
<VirtualHost *:80>
ServerName default
<Directory />
Options FollowSymLinks
AllowOverride None
Require all denied
</Directory>
<Directory ${VOLUME_PATH}>
AllowOverride All
Require all granted
</Directory>
DocumentRoot ${VOLUME_PATH}
AccessFileName .htaccess
<FilesMatch "^\.ht">
Require all denied
</FilesMatch>
LogFormat "%v:%p %h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" vhost_combined
LogFormat "%h %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat "%h %l %u %t \"%r\" %>s %O" common
LogFormat "%{Referer}i -> %U" referer
LogFormat "%{User-agent}i" agent
CustomLog /proc/self/fd/1 combined
<FilesMatch \.php$>
SetHandler application/x-httpd-php
</FilesMatch>
# Multiple DirectoryIndex directives within the same context will add
# to the list of resources to look for rather than replace
# https://httpd.apache.org/docs/current/mod/mod_dir.html#directoryindex
DirectoryIndex disabled
DirectoryIndex index.php index.html
</VirtualHost>

@ -65,12 +65,4 @@ $appFactory->registerService(\Twig\Environment::class,\Twig\Environment::class);
// $databaseContext = DatabaseContext::getInstance();
$appFactory->AddControllers();
$app = $appFactory->create();
if (!is_null($app)){
// Ajout des Middleware
/*$app->use(new LoggingMiddleware());*/
$app->use(new AuthMiddleware());
$app->mapControllers();
$app->run(RequestFactory::createFromGlobals());
}

@ -0,0 +1,5 @@
#!/bin/sh
vdn-ssh root@web '
'

@ -7,7 +7,7 @@ use App\Router\Request\IRequest;
use App\Router\Response\Response;
use App\Router\Response\IResponse;
use Manager\UserManager;
use Couchbase\UserManager;
use Shared\Attributes\Route;
use Shared\Validation;
use Twig\Environment;
@ -118,8 +118,6 @@ class AuthController extends BaseController
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
{
@ -145,4 +143,5 @@ class AuthController extends BaseController
}
}
?>

@ -44,7 +44,6 @@
// 'member' => []
// ]);
// }
// #[Route('/global-stats', name: 'coach_global_stats', methods: ['GET'])]
// public function globalStats(): Response
// {
@ -70,7 +69,6 @@
// ]);
// }
// #[Route(path: '/coaching', name: 'coaching', methods: ['GET'])]
// public function coaching(): Response
// {
@ -94,7 +92,6 @@
// {
// $coach = $this->security->getUser();
// $athletes = $this->coachManager->getAthletesForCoach($coach);
// return $this->render('coach/list_athletes.html.twig', [
// 'athletes' => $athletes,
// ]);
@ -107,7 +104,6 @@
// 'athleteId' => $athleteId,
// ]);
// }
// #[Route('/add-athlete/{athleteId}', name: 'coach_add_athlete', methods: ['POST'])]
// public function addAthlete(IRequest $request, $athleteId): IResponse
// {
@ -125,4 +121,4 @@
// // }
// }
// }

@ -1,397 +0,0 @@
<?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;
// TODO : Remove this BaseClass
class Controller extends BaseController
{
#[Route(path: '/activity', name: 'activity', methods: ['GET'])]
public function activity(): Response
{
return $this->render('./page/activity.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/exercices', name: 'exercices', methods: ['POST'])] // 8
public function exercices(String $type, String $intensite, String $date, IRequest $req): Response
{
$exercicesArray = [
[
'date' => $date,
'type' => $type,
'intensite' => $intensite,
'status' => 'A venur',
]
];
return $this->render('./page/exercice.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => $exercicesArray,
'member' => []
]);
}
#[Route(path: '/search-user', name: 'search-user', methods: ['GET'])]
public function searchUser(string $username, IRequest $req): Response
{
$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/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"
]);
} catch (\Throwable $th) {
//throw $th;
// return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
}
// }
}
#[Route(path: '/search-member', name: 'search-member', methods: ['GET'])]
public function searchMember(string $username, IRequest $req): Response
{
$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",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => $utiliArray,
'infoUser' => [],
'exos' => [],
'member' => [],
'responce' => "Notification d'ajout envoyée à $username"
]);
} catch (\Throwable $th) {
//throw $th;
// return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
}
// }
}
#[Route(path: '/add-member', name: 'add-member', methods: ['POST'])]
public function addmember(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)){
try {
//code...
// $model->userMgr->addFriend($name);
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' => [],
'responce' => "Notification d'ajout envoyée à $username"
]);
} catch (\Throwable $th) {
//throw $th;
// return $this->render("addfriend.html.twig", ['tabError' => $taberror ]);
}
// }
}
#[Route(path: '/member', name: 'member', methods: ['GET'])]
public function member(): Response
{
$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(path: '/friendlist', name: 'friendlist', methods: ['POST'])]
public function friendlist(string $username, IRequest $req): Response
{
$utiliArray = [
[
'nom' => 'John',
'prenom' => 'Doe',
'img' => 'john_doe',
'username' => 'johndoe',
],
[
'nom' => 'Alice',
'prenom' => 'Smith',
'img' => 'alice_smith',
'username' => 'alicesmith',
],
];
/* TODO */
// -> Enlever ou bloquer un utilisateur en fonction de son username
return $this->render('./page/friend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => $utiliArray,
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => [],
]);
}
#[Route(path: '/friendlist', name: 'friendlist2', methods: ['GET'])]
public function friendlist2(): Response
{
$utiliArray = [
[
'nom' => 'John',
'prenom' => 'Doe',
'img' => 'test',
'status' => 'johndoe',
'username' => 'jdoe',
],
[
'nom' => 'Alice',
'prenom' => 'Smith',
'img' => 'test2',
'status' => 'alicesmith',
'username' => 'asmith',
],
];
return $this->render('./page/friend.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => $utiliArray,
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => [],
]);
}
#[Route(path: '/coaching', name: 'coaching', methods: ['GET'])]
public function coaching(): Response
{
return $this->render('./page/coaching.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[Route(path: '/mail', name: 'mail', methods: ['GET'])]
public function mail(): Response
{
return $this->render('./page/mail.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
#[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: '/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: '/psettings', name: 'psettings', methods: ['POST'])]
public function psettings(string $nom,string $prenom,string $dateNaissance,string $mail,string $tel, IRequest $req): Response
{
return $this->render('./page/settings.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => $prenom,
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
}

@ -3,5 +3,12 @@
{% block title %}{{code}} : {{title}}{% endblock %}
{% block nb %}<h1 class="display-1">{{code}}</h1>{% endblock %}
{% block nb %}
{% if code == 404 %}
<img class="mb-4 img-error" src="assets/img/error-404-monochrome.svg"/>
{% else %}
<h1 class="display-1">{{code}}</h1>
{% endif %}
{% endblock %}
{% block descr %}{{descr}}{% endblock %}

@ -0,0 +1 @@
<a href="/log">Se connecter</button>

@ -0,0 +1,33 @@
{% extends "authbase.html.twig" %}
{% block css %}{{css}}{% endblock %}
{% block title %}Mot de passe oublié - HearthTrack{% endblock %}
{% block main %}
<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">Récupération du mot de passe</h3></div>
<div class="card-body">
<div class="small mb-3 text-muted">Entrez votre adresse eMail pour recevoir un lien pour changer de mot de passe</div>
<form method="post" action="/password">
<div class="form-floating mb-3">
<input class="form-control" id="email" name="email" type="email" placeholder="name@example.com" />
<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>
</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>
</div>
</div>
</div>
</div>
{% endblock %}

@ -11,7 +11,7 @@
<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">
<form>
<form method="post" action="/register">
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
@ -29,14 +29,14 @@
<div class="row mb-3">
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputUsername" type="text" placeholder="Entrez votre pseudonyme" />
<label for="inputUsername"></label><input class="form-control" id="inputUsername" type="text" placeholder="Entrez votre pseudonyme" />
<label for="inputFirstName">Nom d'utilisateur</label>
</div>
</div>
<div class="col-md-6">
<div class="form-floating">
<label for="inputLastName">Sexe</label>
<select id="gender" name="gender">
<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>
@ -61,7 +61,7 @@
</div>
<div class="col-md-6">
<div class="form-floating mb-3 mb-md-0">
<input class="form-control" id="inputPoids" type="text" placeholder="Entrez votre poids" />
<label for="inputPoids"></label><input class="form-control" id="inputPoids" type="text" placeholder="Entrez votre poids" />
<label for="inputPasswordConfirm">Poids</label>
</div>
</div>

@ -9,8 +9,9 @@ use Model\RelationshipRequest;
use Model\Role;
use Model\Training;
use Model\User;
use Stub\StubData;
use Manager\DataManager;
use Stub\StubData;
$model = new Model(); // Couche d'accès au model
function clearScreen()
@ -54,7 +55,11 @@ function displayProfileMenu()
echo "1. Informations de l'utilisateur\n";
echo "2. Historique d'activité\n";
echo "3. Liste d'amis\n";
echo "4. Importer des données (FIT/GPX/TCX)/Manuel\n";
echo "4. Paramètres de confidentialité et visibilité\n";
echo "5. Ajouter une activité\n";
// Importer des données (FIT/GPX/TCX)/Manuel
// Synchroniser l'appareil de fréquence cardiaque
// Synchroniser l'app mobile
echo "0. Retour au menu principal\n";
echo "Choisissez une option: ";
}
@ -89,7 +94,6 @@ function displaySocialManagementMenu() {
echo "1. Rechercher des coach\n";
echo "2. Rechercher des athletes\n";
echo "3. Gérer la liste d'amis\n";
echo "4. Options de partage\n";
echo "0. Retour au menu principal\n";
echo "Choisissez une option: ";
@ -781,7 +785,6 @@ while (true) {
switch ($choice) {
case '1': // Se connecter
if($model->userMgr->login("john.doe@example.com", "password123"))
$loggedIn = true;
@ -862,4 +865,5 @@ while (true) {
}
}
}
?>

@ -0,0 +1,127 @@
<?php
namespace Database;
class ActiviteEntity {
private $idActivite;
private $type;
private $date;
private $heureDebut;
private $heureFin;
private $effortRessenti;
private $variabilite;
private $variance;
private $ecartType;
private $moyenne;
private $maximum;
private $minimum;
private $temperatureMoyenne;
// Getters
public function getIdActivite() {
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 getVariabilite() {
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 setIdActivite($idActivite) {
$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,120 @@
<?php
namespace Database;
class ActiviteGateway {
private $connection;
public function __construct(Connection $connection) {
$this->connection = $connection;
}
public function getActivite() {
$query = "SELECT * FROM Activite";
return $this->connection->executeWithErrorHandling($query);
}
public function getActiviteById(int $activiteId) {
$query = "SELECT * FROM Activite WHERE idActivite = :id";
$params = [':id' => [$activiteId, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActiviteByType(string $type) {
$query = "SELECT * FROM Activite WHERE type = :type";
$params = [':type' => [$type, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActiviteByDate(string $date) {
$query = "SELECT * FROM Activite WHERE date = :date";
$params = [':date' => [$date, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActiviteByTimeRange(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 getActiviteByEffort(int $effortRessenti) {
$query = "SELECT * FROM Activite WHERE effortRessenti = :effort";
$params = [':effort' => [$effortRessenti, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActiviteByVariability(int $variabilite) {
$query = "SELECT * FROM Activite WHERE variabilite = :variability";
$params = [':variability' => [$variabilite, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getActiviteByTemperature(int $temperatureMoyenne) {
$query = "SELECT * FROM Activite WHERE temperatureMoyenne = :temperature";
$params = [':temperature' => [$temperatureMoyenne, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function addActivite(ActiviteEntity $activite) {
$query = "INSERT INTO Activite (type, date, heureDebut, heureDeFin, effortRessenti, variabilite, variance, ecartType, moyenne, maximum, minimum, temperatureMoyenne)
VALUES (:type, :date, :heureDebut, :heureDeFin, :effortRessenti, :variabilite, :variance, :ecartType, :moyenne, :maximum, :minimum, :temperatureMoyenne)";
$params = [
':type' => $activite->getType(),
':date' => $activite->getDate()->format('Y-m-d'), // Format date pour SQL
':heureDebut' => $activite->getHeureDebut()->format('H:i:s'), // Format heure pour SQL
':heureDeFin' => $activite->getHeureFin()->format('H:i:s'), // Format heure pour SQL
':effortRessenti' => $activite->getEffortRessenti(),
':variabilite' => $activite->getVariabilite(),
':variance' => $activite->getVariance(),
':ecartType' => $activite->getEcartType(),
':moyenne' => $activite->getMoyenne(),
':maximum' => $activite->getMaximum(),
':minimum' => $activite->getMinimum(),
':temperatureMoyenne' => $activite->getTemperatureMoyenne(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function updateActivite(ActiviteEntity $oldActivite, ActiviteEntity $newActivite) {
$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' => $oldActivite->getIdActivite(),
':type' => $newActivite->getType(),
':date' => $newActivite->getDate()->format('Y-m-d'), // Format date pour SQL
':heureDebut' => $newActivite->getHeureDebut()->format('H:i:s'), // Format heure pour SQL
':heureDeFin' => $newActivite->getHeureFin()->format('H:i:s'), // Format heure pour SQL
':effortRessenti' => $newActivite->getEffortRessenti(),
':variabilite' => $newActivite->getVariabilite(),
':variance' => $newActivite->getVariance(),
':ecartType' => $newActivite->getEcartType(),
':moyenne' => $newActivite->getMoyenne(),
':maximum' => $newActivite->getMaximum(),
':minimum' => $newActivite->getMinimum(),
':temperatureMoyenne' => $newActivite->getTemperatureMoyenne(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteActivite(int $idActivite) {
$query = "DELETE FROM Activite WHERE idActivite = :idActivite";
$params = [
':idActivite' => $idActivite,
];
return $this->connection->executeWithErrorHandling($query, $params);
}
}
?>

@ -0,0 +1,51 @@
<?php
namespace Database;
use Model\Activite;
class ActiviteMapper {
public function map(array $data):ActiviteEntity {
$activite = new ActiviteEntity();
$activite->setIdActivite($data['idActivite']);
$activite->setType($data['type']);
$activite->setDate($data['date']);
$activite->setHeureDebut($data['heureDebut']);
$activite->setHeureFin($data['heureFin']);
$activite->setEffortRessenti($data['effortRessenti']);
$activite->setVariabilite($data['variabilite']);
$activite->setVariance($data['variance']);
$activite->setEcartType($data['ecartType']);
$activite->setMoyenne($data['moyenne']);
$activite->setMaximum($data['maximum']);
$activite->setMinimum($data['minimum']);
$activite->setTemperatureMoyenne($data['temperatureMoyenne']);
return $activite;
}
//public function ActiviteEntityToModel(ActiviteEntity entity): Activite;
public function ActiviteEntityToModel(ActiviteEntity $activiteEntity):Activite{
$act = new Activite(
$activiteEntity->getIdActivite(),
$activiteEntity->getType(),
$activiteEntity->getDate(),
$activiteEntity->getHeureDebut(),
$activiteEntity->getHeureFin(),
$activiteEntity->getEffortRessenti(),
$activiteEntity->getVariabilite(),
$activiteEntity->getVariance(),
$activiteEntity->getEcartType(),
$activiteEntity->getMoyenne(),
$activiteEntity->getMaximum(),
$activiteEntity->getMinimum(),
$activiteEntity->getTemperatureMoyenne()
);
return $act;
}
//public function ActiviteToEntity(Activite model): ActiviteEntity;
}
?>

@ -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 Coach";
return $this->connection->executeWithErrorHandling($query);
}
public function getCoachById(int $userId) {
$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";
$params = [':name' => [$name, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByFirstName(string $firstName) {
$query = "SELECT * FROM Coach WHERE 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";
$params = [':email' => [$email, PDO::PARAM_STR]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByGender(string $gender) {
$query = "SELECT * FROM Coach WHERE 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";
$params = [':height' => [$height, PDO::PARAM_INT]];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function getCoachByBirthDate(string $birthdate) {
$query = "SELECT * FROM Coach WHERE 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)";
$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 Coach
SET nom = :nom, prenom = :prenom, email = :email, sexe = :sexe,
taille = :taille, poids = :poids, motDePasse = :motDePasse, dateNaissance = :dateNaissance
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(),
];
return $this->connection->executeWithErrorHandling($query, $params);
}
public function deleteCoach(int $idCoach) {
$query = "DELETE FROM Coach WHERE idCoach = :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);
}
}
?>

@ -26,7 +26,7 @@ interface IAuthService {
* @param string $emailUser The emailUser of the user.
* @param string $password The password of the user.
*
* @return bool True if authentication is successful, false otherwise.
* @return ?User True if authentication is successful, false otherwise.
*/
public function login(string $emailUser, string $password): bool;

@ -61,6 +61,4 @@ class Athlete extends Role {
}
?>

@ -21,4 +21,5 @@ abstract class Observable {
$observer->update($this);
}
}
}
}
?>

@ -5,4 +5,5 @@ namespace Model;
interface Observer
{
public function update(Observable $observable);
}
}
?>

@ -1,12 +1,34 @@
<?php
/**
* Nom du fichier: Role.php
*
* @author PEREDERII Antoine
* @date 2023-11-25
* @description Classe abstraite Role représentant le rôle d'un utilisateur.
*
* @package model
*/
namespace Model;
use Stub\TrainingRepository;
/**
* @class Role
* @brief Classe abstraite représentant le rôle d'un utilisateur.
*/
abstract class Role {
protected int $id;
protected array $usersList = [];
protected array $usersRequests = [];
protected array $trainingList = [];
// Attributs spécifiques au Coach si nécessaire
/**
* Obtient la liste des utilisateurs associés au rôle.
*
* @return array|null La liste des utilisateurs associés au rôle, ou null si aucune.
*/
public function getUsersList(): ?array
{
return $this->usersList;
@ -30,8 +52,19 @@ abstract class Role {
return false;
}
/**
* Vérifie si un utilisateur peut être ajouté au rôle.
*
* @param User $user L'utilisateur à vérifier.
* @return bool True si l'utilisateur peut être ajouté, sinon false.
*/
public abstract function CheckAdd(User $user) : bool;
/**
* Ajoute un utilisateur à la liste des utilisateurs associés au rôle.
*
* @param User $user L'utilisateur à ajouter.
* @return bool True si l'ajout est réussi, sinon false.
*/
public function addUser(User $user): bool
{
if($this->CheckAdd($user)){
@ -41,8 +74,10 @@ abstract class Role {
return false;
}
/**
* @param User $user
* @return bool
* Supprime un utilisateur de la liste des utilisateurs associés au rôle.
*
* @param User $user L'utilisateur à supprimer.
* @return bool True si la suppression est réussie, sinon false.
*/
public function removeUser(User $user): bool
{
@ -55,7 +90,12 @@ abstract class Role {
}
return false;
}
/**
* Ajoute un entraînement à la liste des entraînements associés au rôle.
*
* @param Training $training L'entraînement à ajouter.
* @return bool True si l'ajout est réussi, sinon false.
*/
public function addTraining(Training $training)
{
$this->trainingList [] = $training;
@ -65,9 +105,5 @@ abstract class Role {
{
return $this->trainingList;
}
}
?>

@ -1,18 +1,25 @@
<?php
namespace Model;
/**
* Nom du fichier: User.php
*
* @author PEREDERII Antoine
* @date 2023-11-25
* @description Classe représentant un utilisateur.
*
* @package model
*/
// Data Class
namespace Model;
/**
* Class User
*
* Represents a user in the system
* @class User
* @brief Classe représentant un utilisateur.
*/
class User{
class User {
private int $id;
private String $username;
private string $nom;
private string $prenom;
private string $username;
private string $email;
private string $motDePasse;
private string $sexe;
@ -68,7 +75,11 @@ class User{
unset($this->notifications[$index]);
}
}
/**
* Obtient l'identifiant de l'utilisateur.
*
* @return int L'identifiant de l'utilisateur.
*/
public function getId(): int {
return $this->id;
}
@ -88,92 +99,195 @@ class User{
$this->username = $username;
}
/**
* Définit l'identifiant de l'utilisateur.
*
* @param int $id Le nouvel identifiant de l'utilisateur.
*/
public function setId(int $id): void {
$this->id = $id;
}
/**
* Obtient le nom d'utilisateur de l'utilisateur.
*
* @return string Le nom d'utilisateur de l'utilisateur.
*/
public function getNom(): string {
return $this->nom;
}
/**
* Définit le nom de l'utilisateur.
*
* @param string $nom Le nouveau nom de l'utilisateur.
*/
public function setNom(string $nom): void {
$this->nom = $nom;
}
/**
* Obtient le prénom de l'utilisateur.
*
* @return string Le prénom de l'utilisateur.
*/
public function getPrenom(): string {
return $this->prenom;
}
/**
* Définit le prénom de l'utilisateur.
*
* @param string $prenom Le nouveau prénom de l'utilisateur.
*/
public function setPrenom(string $prenom): void {
$this->prenom = $prenom;
}
/**
* Obtient l'adresse e-mail de l'utilisateur.
*
* @return string L'adresse e-mail de l'utilisateur.
*/
public function getEmail(): string {
return $this->email;
}
/**
* Définit l'adresse e-mail de l'utilisateur.
*
* @param string $email La nouvelle adresse e-mail de l'utilisateur.
*/
public function setEmail(string $email): void {
$this->email = $email;
}
/**
* @return string hashed password used to authenticate the user.
/**
* Obtient le mot de passe haché de l'utilisateur.
*
* @return string Le mot de passe haché de l'utilisateur.
*/
public function getMotDePasse(): string {
return $this->motDePasse;
}
/**
* Définit le mot de passe haché de l'utilisateur.
*
* @param string $motDePasse Le nouveau mot de passe haché de l'utilisateur.
*/
public function setMotDePasse(string $motDePasse): void {
$this->motDePasse = $motDePasse;
}
/**
* Obtient le sexe de l'utilisateur.
*
* @return string Le sexe de l'utilisateur.
*/
public function getSexe(): string {
return $this->sexe;
}
/**
* Définit le sexe de l'utilisateur.
*
* @param string $sexe Le nouveau sexe de l'utilisateur.
*/
public function setSexe(string $sexe): void {
$this->sexe = $sexe;
}
/**
* Obtient la taille de l'utilisateur.
*
* @return float La taille de l'utilisateur.
*/
public function getTaille(): float {
return $this->taille;
}
/**
* Définit la taille de l'utilisateur.
*
* @param float $taille La nouvelle taille de l'utilisateur.
*/
public function setTaille(float $taille): void {
$this->taille = $taille;
}
/**
* Obtient le poids de l'utilisateur.
*
* @return float Le poids de l'utilisateur.
*/
public function getPoids(): float {
return $this->poids;
}
/**
* Définit le poids de l'utilisateur.
*
* @param float $poids Le nouveau poids de l'utilisateur.
*/
public function setPoids(float $poids): void {
$this->poids = $poids;
}
/**
* Obtient la date de naissance de l'utilisateur.
*
* @return \DateTime La date de naissance de l'utilisateur.
*/
public function getDateNaissance(): \DateTime {
return $this->dateNaissance;
}
/**
* Définit la date de naissance de l'utilisateur.
*
* @param \DateTime $dateNaissance La nouvelle date de naissance de l'utilisateur.
*/
public function setDateNaissance(\DateTime $dateNaissance): void {
$this->dateNaissance = $dateNaissance;
}
/**
* Obtient le rôle de l'utilisateur.
*
* @return Role Le rôle de l'utilisateur.
*/
public function getRole(): Role {
return $this->role;
}
/**
* Définit le rôle de l'utilisateur.
*
* @param Role $role Le nouveau rôle de l'utilisateur.
*/
public function setRole(Role $role): void {
$this->role = $role;
}
public function isValidPassword(string $password) {
// TODO: Not implemented Hasher le mot de passe this not the responsability of the user this is not SOLID
/**
* Vérifie si le mot de passe fourni est valide.
*
* @param string $password Le mot de passe à vérifier.
* @return bool True si le mot de passe est valide, sinon false.
*/
public function isValidPassword(string $password): bool {
// TODO: Implémenter la vérification du mot de passe (hachage).
return $this->motDePasse === $password;
}
/**
* Obtient une représentation textuelle de l'utilisateur.
*
* @return string La représentation textuelle de l'utilisateur.
*/
public function __toString() {
return "Athlete [ID: {$this->id}, Username : $this->username, Nom: {$this->nom}, Prénom: {$this->prenom}, Email: {$this->email}]";
}
}
}
?>

@ -18,7 +18,6 @@ use Stub\AuthService;
* @brief Classe pour gérer les opérations liées aux athlètes.
*/
class AthleteManager {
private IAuthService $authService;
private DataManager $dataManager;
@ -31,7 +30,6 @@ class AthleteManager {
{
$this->authService = $authService;
$this->dataManager = $dataManager;
}
/**

@ -1,4 +1,13 @@
<?php
/**
* Nom du fichier: UserManager.php
*
* @author PEREDERII Antoine
* @date 2023-11-25
* @description Classe UserManager pour gérer les opérations liées aux utilisateurs.
*
* @package manager
*/
namespace Manager;
@ -35,6 +44,14 @@ class UserManager
return $this->currentUser;
}
/**
* Connecte un utilisateur avec les identifiants fournis.
*
* @param string $loginUser Le nom d'utilisateur.
* @param string $passwordUser Le mot de passe de l'utilisateur.
* @return bool Retourne true en cas de connexion réussie, sinon false.
* @throws \Exception En cas d'erreur dans les informations d'identification.
*/
public function login($emailUser, $passwordUser): bool
{
// Validate data format
@ -146,6 +163,15 @@ class UserManager
}
// NEED TO PERSIST
/**
* Enregistre un nouvel utilisateur avec les informations fournies.
*
* @param string $loginUser Le nom d'utilisateur.
* @param string $passwordUser Le mot de passe de l'utilisateur.
* @param array $data Les données supplémentaires pour l'enregistrement.
* @return bool Retourne true en cas d'enregistrement réussi, sinon false.
* @throws \Exception En cas d'erreur lors de la validation des données ou de l'enregistrement.
*/
public function register($loginUser, $passwordUser, $data): bool
{
// foreach ($data as $entry) {
@ -171,6 +197,11 @@ class UserManager
return false;
}
/**
* Déconnecte l'utilisateur actuel.
*
* @return bool Retourne true en cas de déconnexion réussie, sinon false.
*/
public function deconnecter(): bool
{
if ($this->authService->logoutUser()) {
@ -180,6 +211,4 @@ class UserManager
}
}
?>
?>

@ -5,4 +5,4 @@ namespace Repository;
interface ITrainingRepository extends IGenericRepository
{
}
}

@ -1,12 +1,42 @@
<?php
/**
* @file StubData.php
* @brief Définition de la classe StubData.
* @details Ce fichier contient la définition de la classe StubData, utilisée pour la gestion des données fictives
* dans le cadre des tests et de la simulation.
*
* @package Stub
*/
namespace Stub;
use Shared\HashPassword;
use Stub\AuthService;
use Manager\ActivityManager;
use Manager\AthleteManager;
use Manager\DataManager;
use Manager\UserManager;
use Shared\HashPassword;
use Stub\AuthService;
use Stub\UserRepository;
/**
* @class StubData
* @brief Classe de gestion des données fictives pour les tests et la simulation.
* @details Cette classe fournit des méthodes pour initialiser les gestionnaires d'utilisateurs, d'athlètes et d'activités
* avec des données fictives.
*
* @author Votre Nom
* @date YYYY-MM-DD
* @author OpenAI
*/
class StubData extends DataManager{
/**
* @brief Constructeur de la classe StubData.
* @details Initialise les dépôts, les services d'authentification et les gestionnaires nécessaires.
*
* @author Votre Nom
* @date YYYY-MM-DD
* @author OpenAI
*/
public function __construct(){
$this->userRepository = new UserRepository();
$this->relationshipRequestRepository = new RelationshipRequestRepository();
@ -15,4 +45,4 @@ class StubData extends DataManager{
}
}
?>
?>

@ -1,4 +1,13 @@
<?php
/**
* Nom du fichier: UserRepository.php
*
* @author PEREDERII Antoine
* @date 2023-11-25
* @description Classe représentant un dépôt d'utilisateurs pour l'accès aux données des utilisateurs.
*
* @package repository
*/
namespace Stub;
@ -7,9 +16,16 @@ use Model\CoachAthlete;
use Model\User;
use Repository\IUserRepository;
/**
* @class UserRepository
* @brief Classe représentant un dépôt d'utilisateurs pour l'accès aux données des utilisateurs.
*/
class UserRepository implements IUserRepository {
private array $users = [];
/**
* Constructeur de la classe UserRepository.
*/
public function __construct() {
$this->users[] = new User(1, "Doe", "John", "Doe","john.doe@example.com", "password123", 'M', 1.80, 75, new \DateTime("1985-05-15"), new CoachAthlete());
$this->users[] = new User(2, "Smith", "Jane","Smith", "jane.smith@example.com", "secure456", 'F', 1.65, 60, new \DateTime("1990-03-10"), new Athlete());
@ -18,6 +34,12 @@ class UserRepository implements IUserRepository {
$this->users[] = new User(5, "Lee", "Bruce","Lee", "bruce.lee@example.com", "hello321", 'M', 1.72, 70, new \DateTime("1970-02-05"), new Athlete());
}
/**
* Obtient un utilisateur par son identifiant.
*
* @param int $id L'identifiant de l'utilisateur.
* @return User|null L'utilisateur correspondant à l'identifiant donné, ou null s'il n'existe pas.
*/
public function getItemById(int $id): ?User {
foreach ($this->users as $user) {
if ($user->getId() === $id) {
@ -27,6 +49,26 @@ class UserRepository implements IUserRepository {
return null;
}
/**
* Obtient un utilisateur par son rôle.
*
* @return User|null L'utilisateur ayant le rôle spécifié, ou null s'il n'y en a pas.
*/
public function getItemByRole(): ?User {
foreach ($this->users as $user) {
if ($user->getRole() instanceof \Model\Coach) {
return $user;
}
}
return null;
}
/**
* Obtient un utilisateur par son adresse e-mail.
*
* @param string $email L'adresse e-mail de l'utilisateur.
* @return User|null L'utilisateur correspondant à l'adresse e-mail donnée, ou null s'il n'existe pas.
*/
public function getItemByEmail(string $email): ?User {
foreach ($this->users as $user) {
if ($user->getEmail() === $email) {
@ -36,6 +78,12 @@ class UserRepository implements IUserRepository {
return null;
}
/**
* Obtient le nombre total d'utilisateurs dans le dépôt.
*
* @return int Le nombre total d'utilisateurs.
*/
public function getNbItems(): int {
return count($this->users);
}
@ -45,31 +93,67 @@ class UserRepository implements IUserRepository {
return array_slice($this->users, $index, $count);
}
/**
* Obtient un tableau d'utilisateurs dont le nom ou le prénom contient la sous-chaîne spécifiée.
*
* @param string $substring La sous-chaîne pour la recherche.
* @param int $index L'indice de départ dans le tableau.
* @param int $count Le nombre d'utilisateurs à récupérer.
* @param string|null $orderingPropertyName Le nom de la propriété pour l'ordonnancement (facultatif).
* @param bool $descending Indique si l'ordonnancement doit être effectué en ordre descendant (facultatif, par défaut false).
* @return array|null Le tableau d'utilisateurs filtré, ou null s'il n'y a aucun utilisateur correspondant.
*/
public function getItemsByName(string $substring, int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): array {
$filteredUsers = array_filter($this->users, function ($user) use ($substring) {
return str_contains(strtolower($user->getNom()), strtolower($substring)) || str_contains(strtolower($user->getPrenom()), strtolower($substring));
});
return array_slice($filteredUsers, $index, $count);
}
/**
* Obtient un utilisateur dont le nom ou le prénom contient la sous-chaîne spécifiée.
*
* @param string $substring La sous-chaîne pour la recherche.
* @param int $index L'indice de départ dans le tableau.
* @param int $count Le nombre d'utilisateurs à récupérer.
* @param string|null $orderingPropertyName Le nom de la propriété pour l'ordonnancement (facultatif).
* @param bool $descending Indique si l'ordonnancement doit être effectué en ordre descendant (facultatif, par défaut false).
* @return User|null L'utilisateur filtré, ou null s'il n'y a aucun utilisateur correspondant.
*/
public function getItemByName(string $substring, int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): ?User {
$filteredUsers = $this->GetItemsByName($substring, $index, $count, $orderingPropertyName, $descending);
return $filteredUsers[0] ?? null;
}
// should have type here
/**
* Met à jour un utilisateur existant dans le dépôt.
*
* @param User $oldItem L'ancienne instance de l'utilisateur.
* @param User $newItem La nouvelle instance de l'utilisateur.
* @return void
*/
public function updateItem($oldUser, $newUser): void {
$index = array_search($oldUser, $this->users);
if ($index !== false) {
$this->users[$index] = $newUser;
$this->users[$index] = $newItem;
}
}
// should have type here
/**
* Ajoute un nouvel utilisateur au dépôt.
*
* @param User $user L'instance de l'utilisateur à ajouter.
* @return void
*/
public function addItem( $user): void {
$this->users[] = $user;
}
// should have type here
/**
* Supprime un utilisateur du dépôt.
*
* @param User $user L'instance de l'utilisateur à supprimer.
* @return bool Retourne true si la suppression a réussi, sinon false.
*/
public function deleteItem( $user): bool {
$index = array_search($user, $this->users);
if ($index !== false) {
@ -90,5 +174,4 @@ class UserRepository implements IUserRepository {
return true;
}
}
?>
?>

@ -21,15 +21,13 @@ class AuthService implements IAuthService {
public function login(string $emailUser,string $password): bool {
$user = $this->userRepository->getItemByEmail($emailUser);
if (!$user instanceof User) {
throw new \Exception('Unable to find user with that name');
}
if ($user->isValidPassword($password)) {
$this->currentUser = $user;
return true;
}
}
return false;
}
public function register(string $username, string $password, $data): bool
@ -38,11 +36,11 @@ class AuthService implements IAuthService {
$hashedPassword = $this->passwordHacher->hashPassword($password);
$existingUser = $this->userRepository->getItemByEmail($username);
if ($existingUser != null || $existingUser instanceof User ) {
throw new \Exception('User already exists');
}
$username = $data['username'];
$prenom = $data['prenom'];
$username = $data['username'];
$nom = $data['nom'];
@ -73,12 +71,11 @@ class AuthService implements IAuthService {
//should use reflexion
$role
);
$this->userRepository->addItem($user);
$this->currentUser = $user;
return true;
}
public function logoutUser(): bool
{

@ -26,7 +26,7 @@ final class Validation {
* @throws Exception Si la chaîne n'est pas valide (tentative d'injection de code).
*/
public static function val_string(string $string) : bool {
if (filter_var($string, FILTER_SANITIZE_STRING) !== $string) {
if (strlen(htmlspecialchars($string, ENT_QUOTES) === 0)) {
throw new Exception("$string n'est pas valide. Tentative d'injection de code (attaque sécurité)!");
} else {
return true;

@ -0,0 +1,13 @@
<?php
namespace DataManager;
class CoachManager
{
/**
*/
public function __construct()
{
}
}

@ -12,16 +12,20 @@ return array(
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
'Stub\\' => array($baseDir . '/src/data/stub', $baseDir . '/src/data/stub/service', $baseDir . '/src/data/stub/repository'),
'Repository\\' => array($baseDir . '/src/data/model/repository'),
'Network\\' => array($baseDir . '/src/data/core/network'),
'Model\\' => array($baseDir . '/src/data/model'),
'Manager\\' => array($baseDir . '/src/data/model/manager'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),
'Data\\' => array($baseDir . '/src/data'),
'Shared\\Exception\\' => array($baseDir . '/src/shared/exception'),
'Shared\\Attributes\\' => array($baseDir . '/src/shared/attributes'),
'Shared\\' => array($baseDir . '/src/shared'),
'Repository\\' => array($baseDir . '/src/data/model/repository'),
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
'PhpParser\\' => array($vendorDir . '/nikic/php-parser/lib/PhpParser'),
'PhpOption\\' => array($vendorDir . '/phpoption/phpoption/src/PhpOption'),
'Repository\\' => array($baseDir . '/src/data/model/repository'),
'Network\\' => array($baseDir . '/src/data/core/network'),
'Model\\' => array($baseDir . '/src/data/model'),
'Manager\\' => array($baseDir . '/src/data/model/manager'),
'Hearttrack\\' => array($baseDir . '/src'),
'GrahamCampbell\\ResultType\\' => array($vendorDir . '/graham-campbell/result-type/src'),
'Dotenv\\' => array($vendorDir . '/vlucas/phpdotenv/src'),

@ -63,9 +63,10 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
'D' =>
array (
'Dotenv\\' => 7,
'Data\\' => 5,
'Doctrine\\Instantiator\\' => 22,
'DeepCopy\\' => 9,
'Data\\Core\\' => 10,
'Data\\' => 5,
),
'C' =>
array (
@ -104,29 +105,29 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
),
'Stub\\' =>
'Stub\\' =>
array (
0 => __DIR__ . '/../..' . '/src/data/stub',
1 => __DIR__ . '/../..' . '/src/data/stub/service',
2 => __DIR__ . '/../..' . '/src/data/stub/repository',
),
'Shared\\Exception\\' =>
'Shared\\Exception\\' =>
array (
0 => __DIR__ . '/../..' . '/src/shared/exception',
),
'Shared\\Attributes\\' =>
'Shared\\Attributes\\' =>
array (
0 => __DIR__ . '/../..' . '/src/shared/attributes',
),
'Shared\\' =>
'Shared\\' =>
array (
0 => __DIR__ . '/../..' . '/src/shared',
),
'Repository\\' =>
'Repository\\' =>
array (
0 => __DIR__ . '/../..' . '/src/data/model/repository',
),
'Psr\\Container\\' =>
'Psr\\Container\\' =>
array (
0 => __DIR__ . '/..' . '/psr/container/src',
),
@ -138,7 +139,7 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
array (
0 => __DIR__ . '/..' . '/phpoption/phpoption/src/PhpOption',
),
'Network\\' =>
'Network\\' =>
array (
0 => __DIR__ . '/../..' . '/src/data/core/network',
),
@ -150,7 +151,7 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
array (
0 => __DIR__ . '/../..' . '/src/data/model/manager',
),
'Hearttrack\\' =>
'Hearttrack\\' =>
array (
0 => __DIR__ . '/../..' . '/src',
),
@ -162,11 +163,19 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
array (
0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src',
),
'DeepCopy\\' =>
'Doctrine\\Instantiator\\' =>
array (
0 => __DIR__ . '/..' . '/graham-campbell/result-type/src',
),
'Dotenv\\' =>
array (
0 => __DIR__ . '/..' . '/vlucas/phpdotenv/src',
),
'DeepCopy\\' =>
array (
0 => __DIR__ . '/..' . '/myclabs/deep-copy/src/DeepCopy',
),
'Data\\Core\\' =>
'Data\\Core\\' =>
array (
0 => __DIR__ . '/../..' . '/src/data/core',
),
@ -178,7 +187,7 @@ class ComposerStaticInit1887e85fc3cfddacf8d7e17588dae6f1
array (
0 => __DIR__ . '/../..' . '/src/console',
),
'App\\Views\\Directives\\' =>
'App\\Views\\Directives\\' =>
array (
0 => __DIR__ . '/../..' . '/src/app/views/directives',
),

@ -99,6 +99,177 @@
},
"install-path": "../altorouter/altorouter"
},
{
"name": "doctrine/instantiator",
"version": "1.5.0",
"version_normalized": "1.5.0.0",
"source": {
"type": "git",
"url": "https://github.com/adriangibbons/php-fit-file-analysis.git",
"reference": "8efd36b1b963f01c42dc5329626519c040dec664"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/adriangibbons/php-fit-file-analysis/zipball/8efd36b1b963f01c42dc5329626519c040dec664",
"reference": "8efd36b1b963f01c42dc5329626519c040dec664",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "4.8.*",
"satooshi/php-coveralls": "^2.0",
"squizlabs/php_codesniffer": "2.*"
},
"time": "2019-11-20T06:58:56+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"adriangibbons\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"description": "A PHP class for analysing FIT files created by Garmin GPS devices",
"homepage": "https://github.com/adriangibbons/php-fit-file-analysis",
"keywords": [
"Fit",
"garmin"
],
"support": {
"issues": "https://github.com/adriangibbons/php-fit-file-analysis/issues",
"source": "https://github.com/adriangibbons/php-fit-file-analysis/tree/master"
},
"install-path": "../adriangibbons/php-fit-file-analysis"
},
{
"name": "graham-campbell/result-type",
"version": "v1.1.2",
"version_normalized": "1.1.2.0",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862",
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.2"
},
"require-dev": {
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"time": "2023-11-12T22:16:48+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"GrahamCampbell\\ResultType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "An Implementation Of The Result Type",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
"Result Type",
"Result-Type",
"result"
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
"type": "tidelift"
}
],
"install-path": "../graham-campbell/result-type"
},
{
"name": "graham-campbell/result-type",
"version": "v1.1.2",
"version_normalized": "1.1.2.0",
"source": {
"type": "git",
"url": "https://github.com/GrahamCampbell/Result-Type.git",
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/fbd48bce38f73f8a4ec8583362e732e4095e5862",
"reference": "fbd48bce38f73f8a4ec8583362e732e4095e5862",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0",
"phpoption/phpoption": "^1.9.2"
},
"require-dev": {
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"time": "2023-11-12T22:16:48+00:00",
"type": "library",
"installation-source": "dist",
"autoload": {
"psr-4": {
"GrahamCampbell\\ResultType\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "An Implementation Of The Result Type",
"keywords": [
"Graham Campbell",
"GrahamCampbell",
"Result Type",
"Result-Type",
"result"
],
"support": {
"issues": "https://github.com/GrahamCampbell/Result-Type/issues",
"source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/graham-campbell/result-type",
"type": "tidelift"
}
],
"install-path": "../graham-campbell/result-type"
},
{
"name": "graham-campbell/result-type",
"version": "v1.1.2",
@ -480,6 +651,84 @@
],
"install-path": "../phpoption/phpoption"
},
{
"name": "phpunit/php-code-coverage",
"version": "10.1.9",
"version_normalized": "10.1.9.0",
"source": {
"type": "git",
"url": "https://github.com/schmittjoh/php-option.git",
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/schmittjoh/php-option/zipball/80735db690fe4fc5c76dfa7f9b770634285fa820",
"reference": "80735db690fe4fc5c76dfa7f9b770634285fa820",
"shasum": ""
},
"require": {
"php": "^7.2.5 || ^8.0"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8.2",
"phpunit/phpunit": "^8.5.34 || ^9.6.13 || ^10.4.2"
},
"time": "2023-11-12T21:59:55+00:00",
"type": "library",
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": true
},
"branch-alias": {
"dev-master": "1.9-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"PhpOption\\": "src/PhpOption/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"Apache-2.0"
],
"authors": [
{
"name": "Johannes M. Schmitt",
"email": "schmittjoh@gmail.com",
"homepage": "https://github.com/schmittjoh"
},
{
"name": "Graham Campbell",
"email": "hello@gjcampbell.co.uk",
"homepage": "https://github.com/GrahamCampbell"
}
],
"description": "Option Type for PHP",
"keywords": [
"language",
"option",
"php",
"type"
],
"support": {
"issues": "https://github.com/schmittjoh/php-option/issues",
"source": "https://github.com/schmittjoh/php-option/tree/1.9.2"
},
"funding": [
{
"url": "https://github.com/GrahamCampbell",
"type": "github"
},
{
"url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption",
"type": "tidelift"
}
],
"install-path": "../phpoption/phpoption"
},
{
"name": "phpunit/php-code-coverage",
"version": "10.1.9",
@ -976,6 +1225,62 @@
},
"install-path": "../psr/container"
},
{
"name": "sebastian/cli-parser",
"version": "2.0.0",
"version_normalized": "2.0.0.0",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"time": "2021-11-05T16:47:00+00:00",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0.x-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "PHP-FIG",
"homepage": "https://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
"homepage": "https://github.com/php-fig/container",
"keywords": [
"PSR-11",
"container",
"container-interface",
"container-interop",
"psr"
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
"source": "https://github.com/php-fig/container/tree/2.0.2"
},
"install-path": "../psr/container"
},
{
"name": "sebastian/cli-parser",
"version": "2.0.0",

@ -28,6 +28,33 @@
'aliases' => array(),
'dev_requirement' => false,
),
'doctrine/instantiator' => array(
'pretty_version' => '1.5.0',
'version' => '1.5.0.0',
'reference' => '0a0fa9780f5d4e507415a065172d26a98d02047b',
'type' => 'library',
'install_path' => __DIR__ . '/../adriangibbons/php-fit-file-analysis',
'aliases' => array(),
'dev_requirement' => false,
),
'graham-campbell/result-type' => array(
'pretty_version' => 'v1.1.2',
'version' => '1.1.2.0',
'reference' => 'fbd48bce38f73f8a4ec8583362e732e4095e5862',
'type' => 'library',
'install_path' => __DIR__ . '/../graham-campbell/result-type',
'aliases' => array(),
'dev_requirement' => false,
),
'graham-campbell/result-type' => array(
'pretty_version' => 'v1.1.2',
'version' => '1.1.2.0',
'reference' => 'fbd48bce38f73f8a4ec8583362e732e4095e5862',
'type' => 'library',
'install_path' => __DIR__ . '/../graham-campbell/result-type',
'aliases' => array(),
'dev_requirement' => false,
),
'graham-campbell/result-type' => array(
'pretty_version' => 'v1.1.2',
'version' => '1.1.2.0',

@ -1,53 +0,0 @@
<?php declare(strict_types=1);
/*
* This file is part of PHPUnit.
*
* (c) Sebastian Bergmann <sebastian@phpunit.de>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit\Framework;
/**
* @psalm-immutable
*
* @internal This class is not covered by the backward compatibility promise for PHPUnit
*/
final class PhptAssertionFailedError extends AssertionFailedError
{
private readonly string $syntheticFile;
private readonly int $syntheticLine;
private readonly array $syntheticTrace;
private readonly string $diff;
public function __construct(string $message, int $code, string $file, int $line, array $trace, string $diff)
{
parent::__construct($message, $code);
$this->syntheticFile = $file;
$this->syntheticLine = $line;
$this->syntheticTrace = $trace;
$this->diff = $diff;
}
public function syntheticFile(): string
{
return $this->syntheticFile;
}
public function syntheticLine(): int
{
return $this->syntheticLine;
}
public function syntheticTrace(): array
{
return $this->syntheticTrace;
}
public function diff(): string
{
return $this->diff;
}
}
Loading…
Cancel
Save