Compare commits

...

4 Commits

Author SHA1 Message Date
David D'ALMEIDA 9eb7074df5 push
continuous-integration/drone/push Build is failing Details
11 months ago
David D'ALMEIDA adb9584cba work with APE
continuous-integration/drone/push Build is failing Details
12 months ago
Antoine PINAGOT d0d1d4c23d auth Ctrl fini
continuous-integration/drone/push Build is failing Details
12 months ago
David D'ALMEIDA f804820e85 exemple
continuous-integration/drone/push Build is failing Details
12 months ago

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 2.0 MiB

@ -18,13 +18,13 @@
"Shared\\": "src/shared",
"App\\Router\\": "src/app/router",
"App\\Controller\\": "src/app/controller",
"App\\Router\\Response\\" : "src/app/router/response",
"App\\Router\\Middleware\\" : "src/app/router/middleware",
"App\\Router\\Request\\" : "src/app/router/request",
"App\\Router\\Response\\": "src/app/router/response",
"App\\Router\\Middleware\\": "src/app/router/middleware",
"App\\Router\\Request\\": "src/app/router/request",
"Shared\\Exception\\": "src/shared/exception",
"Shared\\Attributes\\": "src/shared/attributes",
"App\\Views\\Directives\\" : "src/app/views/directives",
"Data\\Core\\": "src/data/core/"
"App\\Views\\Directives\\": "src/app/views/directives",
"Data\\Core\\": "src/data/core/"
}
},
"require": {
@ -34,12 +34,15 @@
"altorouter/altorouter": "1.1.0",
"psr/container": "^2.0"
},
"config": {
"process-timeout": 2000
},
"require-dev": {
"phpunit/phpunit": "*"
},
"scripts": {
"dev": "php -S localhost:8081 -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"
"dev:html": "export APP_ENV=html && php -S localhost:8080 -t public -d display_errors=1 -d error_reporting=E_ALL"
}
}
}

@ -11,7 +11,7 @@ $dotenv->safeLoad();
// const DB_DATABASE = $_ENV['DB_DATABASE'] ?? 'heartTrack';
// const DB_USER = $_ENV['DB_USER'] ?? 'toto';
// const DB_PASSWORD = $_ENV['DB_PASSWORD'] ?? 'achanger';
define("APP_ENV", 'development');
define("APP_ENV", getenv('APP_ENV'));
const DB_HOST = 'localhost';
const DB_DATABASE = 'heartTrack';

@ -12,7 +12,7 @@ use Manager\DataManager;
use Repository\IUserRepository;
use Shared\ArgumentControllerResolver;
use Shared\IArgumentResolver;
use Stub\AuthService;
use Network\AuthService;
use Stub\NotificationRepository;
use Stub\TrainingRepository;
use Stub\UserRepository;
@ -30,13 +30,13 @@ use Network\RelationshipService;
use Network\INotificationService;
use Stub\NotificationService;
use App\Router\Session;
use Stub\StubData;
use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Shared\IHashPassword;
use Shared\HashPassword;
use Shared\Log;
$appFactory = new AppCreator();
$appFactory->registerService(IArgumentResolver::class, ArgumentControllerResolver::class);
@ -54,7 +54,6 @@ $appFactory->registerService(IUserRepository::class, UserRepository::class);
$appFactory->registerService(\Twig\Loader\LoaderInterface::class, function() {
return new FilesystemLoader(__DIR__ . '/../src/app/views/Templates');
});
@ -69,7 +68,7 @@ $app = $appFactory->create();
if (!is_null($app)){
// Ajout des Middleware
/*$app->use(new LoggingMiddleware());*/
$app->use(new AuthMiddleware());
$app->use(new AuthMiddleware($appFactory->getDicontainer()->get(IAuthService::class) ));
$app->mapControllers();
$app->run(RequestFactory::createFromGlobals());
}

@ -29,9 +29,6 @@ class App
private FrontController $frontController;
private Session $session;
public function __construct(string $appName, int $version, \App\Container $diContainer)
{
$this->appName = $appName;
@ -39,7 +36,7 @@ class App
$this->container = $diContainer;
$this->router = new Router("");
$this->frontController = new FrontController($this->router,$this->container);
$this->session = Session::getInstance();
Session::getInstance();
}
public function use(IHttpMiddleware $middleware)
@ -140,9 +137,9 @@ class App
/** @var RouteAttribute $route */
$route = $attribute->newInstance();
$this->router->addControllerRoute(
implode('|', $route->getMethods()),
$route->getMethods(),
$prefix . $route->getPath(),
$controllerClass,
$method->getName(),

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

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

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

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

@ -332,10 +332,11 @@ class Controller extends BaseController
]);
}
#[Route(path: '/import', name: 'import', methods: ['GET'])]
public function import(): Response
#[Route(path: '/profile', name: 'profile', methods: ['GET'])]
public function profile(): Response
{
return $this->render('./page/import.html.twig',[
return $this->render('./page/profile.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
@ -351,13 +352,15 @@ class Controller extends BaseController
}
#[Route(path: '/profile', name: 'profile', methods: ['GET'])]
public function profile(): Response
#[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/profile.html.twig',[
return $this->render('./page/settings.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'user' => $prenom,
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
@ -370,15 +373,18 @@ class Controller extends BaseController
}
#[Route(path: '/psettings', name: 'psettings', methods: ['POST'])]
public function psettings(string $nom,string $prenom,string $dateNaissance,string $mail,string $tel, IRequest $req): Response
#[Route(path: '/pass', name: 'pass', methods: ['GET'])]
public function pass(): Response
{
return $this->render('./page/settings.html.twig',[
// CONFIRMER LES DONNESS !!!!! IMPORTANT
return $this->render('./page/password.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => $prenom,
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
@ -390,7 +396,27 @@ class Controller extends BaseController
]);
}
#[Route(path: '/password', name: 'password', methods: ['POST'])]
public function password(string $email, IRequest $req): Response
{
// CONFIRMER LES DONNESS !!!!! IMPORTANT
return $this->render('./page/login.html.twig',[
'css' => $this->preference->getCookie(),
'pp' => "test2",
'user' => "Doe",
'role' => "Athlète",
'friendship' => [],
'analyzes' => [],
'mails' => [],
'users' => [],
'infoUser' => [],
'exos' => [],
'member' => []
]);
}
}

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

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

@ -4,15 +4,27 @@ namespace App\Controller;
use App\Container;
use App\Router\Request\IRequest;
use App\Router\Response\RedirectResponse;
use App\Router\Response\Response;
use App\Router\Response\IResponse;
use App\Router\Session;
use Manager\UserManager;
use Shared\Attributes\Route;
use Shared\Validation;
use Twig\Environment;
use Data\Core\Preferences;
use Shared\Log;
use function PHPUnit\Framework\isEmpty;
class UserController extends BaseController
{
private UserManager $userMgr;
public function __construct(UserManager $manager){
parent::__construct();
$this->userMgr = $manager;
}
#[Route(path: '/', name: 'home', methods: ['GET'])]
public function index(): Response
@ -74,5 +86,26 @@ class UserController extends BaseController
'member' => []
]);
}
#[Route(path: '/logout', name: 'logout', methods: ['GET'])]
public function logout(IRequest $request): IResponse
{
$error = [];
try {
if($this->userMgr->deconnecter()){
return new RedirectResponse('/');
}
else{
$error [] = "Erreur de deconnexion. Essayez encore";
return new RedirectResponse('/');
}
} catch (\Throwable $th) {
$error [] =$th->getMessage();
return new RedirectResponse('/');
}
}
}

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

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

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

@ -2,6 +2,9 @@
namespace App\Router\Response;
use App\Router\Session;
use Shared\Log;
class RedirectResponse implements IResponse
{
private $content;
@ -49,12 +52,13 @@ class RedirectResponse implements IResponse
public function send(): void
{
http_response_code($this->statusCode);
foreach ($this->headers as $name => $value) {
header("$name: $value");
}
header("Location: " . $this->url);
// Optionally echo content if any

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

@ -34,15 +34,10 @@
<input class="form-check-input" id="inputRememberPassword" type="checkbox" value="" />
<label class="form-check-label" for="inputRememberPassword">Mémoriser le mot de passe</label>
</div>
<div class="d-flex align-items-center justify-content-between mt-4 mb-0">
<a class="small" href="password.html">Mot de passe oublié ?</a>
<a class="btn btn-primary" href="index.html">Se connecter</a>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="register.html">Besoin d'un compte ? Inscrivez-vous !</a></div>
</div>
</div>
</div>
</div>

@ -7,6 +7,8 @@
<meta name="description" content="Accueil" />
<meta name="author" content="PINAGOT Antoine" />
<title>{% block title %}{% endblock %}</title>
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/simple-datatables@7.1.2/dist/style.min.css" rel="stylesheet" />
<link href="/css/{% block css %}style{% endblock %}.css" rel="stylesheet" />
<script src="https://use.fontawesome.com/releases/v6.3.0/js/all.js" crossorigin="anonymous"></script>

@ -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 %}

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

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

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

@ -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="/">
<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="/login">Retour à la connexion</a>
<button class="btn btn-primary" type="submit">Réinitialiser votre mot de passe</button>
</div>
</form>
</div>
<div class="card-footer text-center py-3">
<div class="small"><a href="/register">Besoin d'un compte ? Inscrivez-vous !</a></div>
</div>
</div>
</div>
</div>
</div>
{% endblock %}

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

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

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

@ -1,34 +1,42 @@
<?php
namespace Data\Core;
namespace Network;
use App\Router\Session;
use Model\User;
use Model\Athlete;
use Model\CoachAthlete;
use Repository\IUserRepository;
use Shared\IHashPassword;
class AuthService implements IAuthService {
use Shared\Log;
const USER = 'USER';
class AuthService implements IAuthService
{
private IUserRepository $userRepository;
private IHashPassword $passwordHacher;
private ?User $currentUser = null;
public function __construct(IUserRepository $userRepository, IHashPassword $passwordHacher) {
public function __construct(IUserRepository $userRepository, IHashPassword $passwordHacher)
{
$this->userRepository = $userRepository;
$this->passwordHacher = $passwordHacher;
}
public function login(string $email, string $password): bool {
public function login(string $email, string $password): bool
{
$user = $this->userRepository->getItemByEmail($email);
if ($user === null || !$this->validatePassword($password, $user->getPasswordHash())) {
if ($user === null || !$this->passwordHacher->isPasswordValid( $user->getMotDePasse(),$password)) {
return false;
}
$this->currentUser = $user;
// Add session handling logic here
Session::getInstance()->__set(USER, $this->currentUser->getId());
return true;
}
public function register(string $email, string $password, array $data): bool {
public function register(string $email, string $password, $data): bool
{
if ($this->userRepository->getItemByEmail($email)) {
throw new \Exception('User already exists');
}
@ -37,50 +45,54 @@ class AuthService implements IAuthService {
$prenom = $data['prenom'];
$username = $data['username'];
$nom = $data['nom'];
$email = $data['email'];
$sexe = $data['sexe'];
$taille = $data['taille'];
$poids = $data['poids'];
$dateNaissance = $data['dateNaissance'] ;
$dateNaissance = $data['dateNaissance'];
$roleName = $data['roleName'];
$role = null;
if($roleName == "Coach"){
if ($roleName == "Coach") {
$role = new CoachAthlete();
}
else if($roleName == "Athlete"){
} else if ($roleName == "Athlete") {
$role = new Athlete();
}
// Create a new user instance (you should expand on this with more data as needed)
$user = new User(
random_int(0, 100),
$nom,
$prenom,
$username,
$email,
$hashedPassword,
$sexe,
$taille,
$poids,
$dateNaissance,
//should use reflexion
$role
);
$user = new User(
random_int(0, 100),
$nom,
$prenom,
$username,
$email,
$hashedPassword,
$sexe,
$taille,
$poids,
$dateNaissance,
//should use reflexion
$role
);
$this->userRepository->addItem($user);
$this->currentUser = $user;
// Add session handling logic here
Session::getInstance()->__set(USER,$this->currentUser->getId());
return true;
}
public function logout(): void {
public function logoutUser(): bool
{
$this->currentUser = null;
// Add session handling logic here
Session::getInstance()->destroy();
return true;
}
public function getCurrentUser(): ?User {
public function getCurrentUser(): ?User
{
if (!empty(Session::getInstance()->__get(USER)) && $this->currentUser === null) {
$this->currentUser = $this->userRepository->getItemById(Session::getInstance()->__get(USER));
}
return $this->currentUser;
}
private function validatePassword(string $password, string $hash): bool {
// Implement password validation logic (e.g., using password_verify if using bcrypt)
}
}

@ -33,18 +33,18 @@ interface IAuthService {
/**
* Register a new user.
*
* @param string $username The username of the new user.
* @param string $emailUser The emailUser of the new user.
* @param string $password The password of the new user.
* @param $data other data {undefined} for the moment.
*
* @return bool True if registration is successful, false otherwise.
*/
public function register(string $username, string $password, $data): bool;
public function register(string $emailUser, string $password, $data): bool;
/**
* Logout the currently authenticated user.
*
* @return void
* @return bool
*/
public function logoutUser(): bool;

@ -27,7 +27,7 @@ class Activity
private float $variability;
private float $variance;
private float $standardDeviation;
private int $average;
private float $average;
private int $maximum;
private int $minimum;
private float $avrTemperature;

@ -8,12 +8,14 @@
*
* @package manager
*/
namespace Manager;
use adriangibbons\phpFITFileAnalysis;
use Exception;
use Model\Activity;
use Network\IAuthService;
use Shared\Log;
use Stub\AuthService;
/**
@ -27,14 +29,21 @@ class ActivityManager
*/
private IAuthService $authService;
/**
* @var DataManager
*/
private DataManager $dataManager;
/**
* Constructeur de la classe ActivityManager.
*
* @param IAuthService $authService Le service d'authentification utilisé pour vérifier l'utilisateur actuel.
*/
public function __construct(DataManager $dataManager,IAuthService $authService)
public function __construct(DataManager $dataManager, IAuthService $authService)
{
$this->authService = $authService;
$this->dataManager = $dataManager;
}
/**
@ -49,23 +58,22 @@ class ActivityManager
try {
// Extraction des données du fichier FIT
$fitData = [
'timestamps' => $monFichierFit->data_mesgs['record']['timestamp'],
'latitudes' => $monFichierFit->data_mesgs['record']['position_lat'],
'longitudes' => $monFichierFit->data_mesgs['record']['position_long'],
'altitudes' => $monFichierFit->data_mesgs['record']['altitude'],
'heartRates' => $monFichierFit->data_mesgs['record']['heart_rate'],
'cadences' => $monFichierFit->data_mesgs['record']['cadence'],
'distances' => $monFichierFit->data_mesgs['record']['distance'],
'speeds' => $monFichierFit->data_mesgs['record']['speed'],
'powers' => $monFichierFit->data_mesgs['record']['power'],
'timestamps' => $monFichierFit->data_mesgs['record']['timestamp'],
'latitudes' => $monFichierFit->data_mesgs['record']['position_lat'],
'longitudes' => $monFichierFit->data_mesgs['record']['position_long'],
'altitudes' => $monFichierFit->data_mesgs['record']['altitude'],
'heartRates' => $monFichierFit->data_mesgs['record']['heart_rate'],
'cadences' => $monFichierFit->data_mesgs['record']['cadence'],
'distances' => $monFichierFit->data_mesgs['record']['distance'],
'speeds' => $monFichierFit->data_mesgs['record']['speed'],
'powers' => $monFichierFit->data_mesgs['record']['power'],
'temperatures' => $monFichierFit->data_mesgs['record']['temperature'],
];
// Conversion des données en format JSON
$jsonFitData = json_encode($fitData, JSON_PRETTY_PRINT);
// Enregistrement du fichier JSON
file_put_contents('/Users/Perederii/SAE/git/Web/Sources/src/data/model/fitFileSaver/jsonFiles/ActivitySave.json', $jsonFitData);
file_put_contents('./you.json', $jsonFitData);
return true;
} catch (\Exception $e) {
@ -85,21 +93,21 @@ class ActivityManager
* @return bool Retourne true en cas de succès, sinon false.
* @throws Exception En cas d'erreur lors du téléchargement, du traitement ou de l'enregistrement des données.
*/
public function uploadFile($type, $effortRessenti, $file_path_or_data, ?array $options = null): bool
public function uploadFile(string $type, int $effortRessenti, string $file_path_or_data, ?array $options = null): bool
{
try {
// Vérification des options par défaut
if (empty($options)) {
$options = [
'fix_data' => ['all'],
'data_every_second' => false,
'units' => 'metric',
'pace' => true,
'garmin_timestamps' => false,
'input_is_data' => true,
'fix_data' => ['all'],
'data_every_second' => false,
'units' => 'metric',
'pace' => true,
'garmin_timestamps' => false,
'overwrite_with_dev_data' => false
];
}
// Ouverture du fichier FIT
if (!($monFichierFit = new phpFITFileAnalysis($file_path_or_data, $options))) {
throw new Exception("Problème lors de l'ouverture du fichier FIT");
@ -128,9 +136,14 @@ class ActivityManager
$standardDeviation = number_format(sqrt($variance), 2);
$maximum = max($heartRateList);
$minimum = min($heartRateList);
$temperatureList = $monFichierFit->data_mesgs['record']['temperature'];
$averageTemperature = (!empty($temperatureList)) ? number_format(array_sum($temperatureList) / count($temperatureList), 1) : -200;
if(isset($monFichierFit->data_mesgs['record']['temperature'])){
// Extraction de la température moyenne (si disponible
$temperatureList = $monFichierFit->data_mesgs['record']['temperature'];
$averageTemperature = (!empty($temperatureList)) ? number_format(array_sum($temperatureList) / count($temperatureList), 1) : -200;
}
else{
$averageTemperature = -200;
}
$isPaused = count($monFichierFit->isPaused()) > 0;
@ -150,16 +163,23 @@ class ActivityManager
$averageTemperature,
$isPaused
);
// $this->dataManager->activityRepository->add($newActivity);
// if ($this->saveFitFileToJSON($monFichierFit)) {
// Ajout de l'activité et enregistrement du fichier FIT en JSON
if ($this->authService->getCurrentUser()->getRole()->addActivity($newActivity) && $this->saveFitFileToJSON($monFichierFit)) {
if ($this->authService->getCurrentUser()->getRole()->addActivity($newActivity)) {
return true;
}
} catch (\Exception $e) {
// }
return false;
}
catch(\Exception $e){
echo $e;
}
return false;
}
}
?>

@ -11,6 +11,7 @@ abstract class DataManager {
public IRelationshipRequestRepository $relationshipRequestRepository;
public ITrainingRepository $trainingRepository;
public INotificationRepository $notificationRepository;
public IActivityRepository $activityRepository;
}
?>

@ -10,7 +10,7 @@ use Network\IAuthService;
use Network\IFriendRequestService;
use Shared\Validation;
use Stub\UserRepository;
use Shared\Log;
class UserManager
{
private IAuthService $authService;
@ -48,7 +48,6 @@ class UserManager
return false;
}
if ($this->authService->login($emailUser, $passwordUser)) {
$this->currentUser = $this->authService->getCurrentUser();
// Check if the current user is correctly set
@ -146,6 +145,10 @@ class UserManager
}
// NEED TO PERSIST
/**
* @throws \Exception
*/
public function register($loginUser, $passwordUser, $data): bool
{
// foreach ($data as $entry) {
@ -155,6 +158,21 @@ class UserManager
// }
// }
$dateNaissance = new \DateTime($data['dateNaissance']);
$dateActuelle = new \DateTime();
// Vérifier si la date est dans le futur
if ($dateNaissance > $dateActuelle) {
throw new \Exception("La date de naissance ne peut pas être dans le futur.");
}
// Vérifier l'âge minimum (par exemple, 18 ans)
$ageMinimum = new \DateTime('-10 years');
if ($dateNaissance > $ageMinimum) {
throw new \Exception("Vous devez avoir au moins 18 ans pour vous inscrire.");
}
$data['dateNaissance'] = $dateNaissance;
$roleName = $data['roleName'];
if ($roleName !== "Athlete" && $roleName !== "Coach") {
throw new \Exception("Rôle non valide");

@ -5,6 +5,8 @@ interface IUserRepository extends IGenericRepository {
public function addFriend(int $user1,int $user2);
public function deleteFriend(int $user1,int $user2);
public function getItemByEmail(string $email);
}
?>

@ -11,11 +11,11 @@ class UserRepository implements IUserRepository {
private array $users = [];
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());
$this->users[] = new User(3, "Martin", "Paul","Martin", "paul.martin@example.com", "super789", 'M', 1.75, 68, new \DateTime("1988-08-20"), new CoachAthlete());
$this->users[] = new User(4, "Brown", "Anna","Brown", "anna.brown@example.com", "test000", 'F', 1.70, 58, new \DateTime("1992-11-25"), new Athlete());
$this->users[] = new User(5, "Lee", "Bruce","Lee", "bruce.lee@example.com", "hello321", 'M', 1.72, 70, new \DateTime("1970-02-05"), new Athlete());
$this->users[] = new User(1, "Doe", "John", "Doe","john.doe@example.com", '$2y$10$U59ioMTGZBM2FGQv.3lcbuL0IkO4Fx1jQU7f5hF7o/hvCX2t46mby', 'M', 1.80, 75, new \DateTime("1985-05-15"), new CoachAthlete());
$this->users[] = new User(2, "Smith", "Jane","Smith", "jane.smith@example.com", '$2y$10$U59ioMTGZBM2FGQv.3lcbuL0IkO4Fx1jQU7f5hF7o/hvCX2t46mby', 'F', 1.65, 60, new \DateTime("1990-03-10"), new Athlete());
$this->users[] = new User(3, "Martin", "Paul","Martin", "paul.martin@example.com", '$2y$10$U59ioMTGZBM2FGQv.3lcbuL0IkO4Fx1jQU7f5hF7o/hvCX2t46mby', 'M', 1.75, 68, new \DateTime("1988-08-20"), new CoachAthlete());
$this->users[] = new User(4, "Brown", "Anna","Brown", "anna.brown@example.com", '$2y$10$U59ioMTGZBM2FGQv.3lcbuL0IkO4Fx1jQU7f5hF7o/hvCX2t46mby', 'F', 1.70, 58, new \DateTime("1992-11-25"), new Athlete());
$this->users[] = new User(5, "Lee", "Bruce","Lee", "bruce.lee@example.com", '$2y$10$U59ioMTGZBM2FGQv.3lcbuL0IkO4Fx1jQU7f5hF7o/hvCX2t46mby', 'M', 1.72, 70, new \DateTime("1970-02-05"), new Athlete());
}
public function getItemById(int $id): ?User {

@ -1,5 +1,7 @@
<?php
namespace Stub;
use Model\Athlete;
use Model\CoachAthlete;
@ -8,41 +10,48 @@ use Repository\IUserRepository;
use Shared\Exception\NotImplementedException;
use Network\IAuthService;
use Shared\IHashPassword;
use Shared\Log;
use Stub\UserRepository;
class AuthService implements IAuthService {
class AuthService implements IAuthService
{
private IUserRepository $userRepository;
private IHashPassword $passwordHacher;
private ?User $currentUser;
public function __construct(UserRepository $userRepository, IHashPassword $passwordHacher) {
public function __construct(UserRepository $userRepository, IHashPassword $passwordHacher)
{
$this->userRepository = $userRepository;
$this->passwordHacher = $passwordHacher;
}
public function login(string $emailUser,string $password): bool {
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;
if (!$this->passwordHacher->isPasswordValid($user->getMotDePasse(), $password)) {
return false;
}
$this->currentUser = $user;
return true;
}
public function register(string $username, string $password, $data): bool
{
$hashedPassword = $this->passwordHacher->hashPassword($password);
$existingUser = $this->userRepository->getItemByEmail($username);
if ($existingUser != null || $existingUser instanceof User ) {
if ($existingUser != null || $existingUser instanceof User) {
throw new \Exception('User already exists');
}
$prenom = $data['prenom'];
$username = $data['username'];
$nom = $data['nom'];
@ -50,13 +59,12 @@ class AuthService implements IAuthService {
$sexe = $data['sexe'];
$taille = $data['taille'];
$poids = $data['poids'];
$dateNaissance = $data['dateNaissance'] ;
$dateNaissance = $data['dateNaissance'];
$roleName = $data['roleName'];
$role = null;
if($roleName == "Coach"){
if ($roleName == "Coach") {
$role = new CoachAthlete();
}
else if($roleName == "Athlete"){
} else if ($roleName == "Athlete") {
$role = new Athlete();
}
$user = new User(
@ -73,12 +81,12 @@ class AuthService implements IAuthService {
//should use reflexion
$role
);
$this->userRepository->addItem($user);
$this->currentUser = $user;
return true;
}
public function logoutUser(): bool
{

@ -2,6 +2,8 @@
namespace Shared;
use App\Router\Request\IRequest;
use InvalidArgumentException;
/**
* Responsible for resolving the arguments passed to a controller action.
*/
@ -14,7 +16,7 @@ class ArgumentControllerResolver implements IArgumentResolver{
* @param callable $controller The controller callable.
* @return array An array of resolved arguments.
* @throws \ReflectionException If the controller method does not exist.
* @throws \InvalidArgumentException If an argument cannot be resolved.
* @throws InvalidArgumentException If an argument cannot be resolved.
*/
public function getArguments(IRequest $request, callable $controller): array
{
@ -27,10 +29,10 @@ class ArgumentControllerResolver implements IArgumentResolver{
$reflectionMethod = new \ReflectionMethod($className, $methodName);
} else {
// Handle other types of callables if needed
throw new \InvalidArgumentException("Invalid controller callable format.");
throw new InvalidArgumentException("Invalid controller callable format.");
}
} catch (\ReflectionException $e) {
throw new \InvalidArgumentException("Controller method error: " . $e->getMessage());
throw new InvalidArgumentException("Controller method error: " . $e->getMessage());
}
$args = [];
@ -42,11 +44,10 @@ class ArgumentControllerResolver implements IArgumentResolver{
$name = $param->getName();
$value = $this->getFromRequest($name, $request);
if ($value === null && $param->isDefaultValueAvailable()) {
$value = $param->getDefaultValue();
} elseif ($value === null) {
throw new \InvalidArgumentException("Missing argument: $name");
throw new InvalidArgumentException("Missing argument: $name");
}
$args[] = $value;

@ -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 (!$string) {//filter_var($string, FILTER_SANITIZE_STRING) !== $string
throw new Exception("$string n'est pas valide. Tentative d'injection de code (attaque sécurité)!");
} else {
return true;
@ -101,7 +101,7 @@ final class Validation {
* @return string La chaîne nettoyée.
*/
public static function clean_string(string $string) : string {
return filter_var($string, FILTER_SANITIZE_STRING);
return filter_var($string);
}
/**

@ -1,4 +1,5 @@
<?php
use Shared\Log;
class AltoRouter {
@ -100,6 +101,8 @@ class AltoRouter {
public function generate($routeName, array $params = array()) {
// Check if named route exists
if(!isset($this->namedRoutes[$routeName])) {
throw new \Exception("Route '{$routeName}' does not exist.");
}

Loading…
Cancel
Save