ugly : this branch will be delete
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
7c79d2656a
commit
c780be4799
@ -1,30 +1,22 @@
|
|||||||
<?php
|
<?php
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
require_once __DIR__ . '/../config/config.php';
|
require_once __DIR__ . '/../config/config.php';
|
||||||
// turn the if in obj mode
|
use App\AppCreator;
|
||||||
// if (APP_ENV === 'console') {
|
use App\Router\Middleware\LoggingMiddleware;
|
||||||
// require_once __DIR__ . '/../src/console/Console.php';
|
use App\Router\Request\RequestFactory;
|
||||||
// }
|
use Controllers\ArgumentControllerResolver;
|
||||||
// elseif (APP_ENV === 'development') {
|
use Controllers\IArgumentResolver;
|
||||||
// on pourait aussi gérer le port sois ici comme dans express sois comme dans un fichier de config json...
|
$appFactory = new AppCreator();
|
||||||
$appFactory = new AppCreator();
|
$appFactory->registerService(IArgumentResolver::class,ArgumentControllerResolver::class);
|
||||||
// builder.Services.AddScoped<AuthMiddlewareFliter>();
|
// $appFactory->registerService('twig',);
|
||||||
$app = $appFactory->registerService('','');
|
|
||||||
|
|
||||||
$appFactory.errorProvider(class:: or port)
|
// // Connexion à la base de données
|
||||||
|
// $databaseContext = DatabaseContext::getInstance();
|
||||||
|
$appFactory->AddControllers();
|
||||||
|
$app = $appFactory->create();
|
||||||
|
$app->use(new LoggingMiddleware());
|
||||||
|
// $app->addHttpClient(HttpClient::class);
|
||||||
|
// je veux pas faire sa pour load les controller avec les anotation
|
||||||
|
$app->mapControllers();
|
||||||
|
|
||||||
// connexion string
|
$app->run(RequestFactory::createFromGlobals());
|
||||||
|
|
||||||
// var connectionString = builder.Configuration.GetConnectionString("LolDatabase");
|
|
||||||
// builder.Services.AddDbContext<LolDbContext>(options =>
|
|
||||||
// options.UseSqlite(connectionString), ServiceLifetime.Singleton);
|
|
||||||
|
|
||||||
$app->use(new LoggingMiddleware());
|
|
||||||
$app = $appFactory->create();
|
|
||||||
$app.addHttpClient(HttpClient::class)
|
|
||||||
|
|
||||||
// je veux pas faire sa pour load les controller avec les anotation
|
|
||||||
$app->RegisterControllers();
|
|
||||||
$app->
|
|
||||||
$app->run();
|
|
||||||
}
|
|
||||||
|
@ -1,12 +1,63 @@
|
|||||||
<?php
|
<?php
|
||||||
|
namespace App;
|
||||||
|
use Controllers\BaseController;
|
||||||
|
class AppCreator
|
||||||
|
{
|
||||||
|
private Container $container;
|
||||||
|
|
||||||
class AppCreator {
|
private array $services = [];
|
||||||
public function __construct() {
|
|
||||||
|
|
||||||
|
public function __construct()
|
||||||
|
{
|
||||||
|
$this->container = new Container;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function registerService(string $serviceId, callable|string $service): self
|
||||||
|
{
|
||||||
|
$this->container->set($serviceId, $service);
|
||||||
|
$this->services[] = $serviceId;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create()
|
||||||
|
{
|
||||||
|
|
||||||
|
if (APP_ENV === 'console') {
|
||||||
|
require_once __DIR__ . '/../src/console/Console.php';
|
||||||
|
return;
|
||||||
|
} elseif (APP_ENV === 'development') {
|
||||||
|
$app = new App("HeartTrack", 1, $this->container);
|
||||||
|
return $app;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function AddControllers($namespacePrefix = 'Controllers', $pathToControllers = __DIR__ . 'controller'): self
|
||||||
|
{
|
||||||
|
|
||||||
|
$controllerFiles = glob($pathToControllers . '/*.php');
|
||||||
|
|
||||||
|
foreach ($controllerFiles as $file) {
|
||||||
|
// Get class name from file name
|
||||||
|
$class = basename($file, '.php');
|
||||||
|
$fullClassName = $namespacePrefix . '\\' . $class;
|
||||||
|
|
||||||
|
if (!class_exists($fullClassName)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use reflection to check if class extends BaseController
|
||||||
|
$reflectionClass = new \ReflectionClass($fullClassName);
|
||||||
|
if ($reflectionClass->isSubclassOf(BaseController::class)) {
|
||||||
|
// Register in DI container
|
||||||
|
$this->container->set($fullClassName, function () use ($fullClassName) {
|
||||||
|
return new $fullClassName();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
<?php
|
||||||
|
namespace App;
|
||||||
|
use Shared\Exception\ContainerException;
|
||||||
|
use Shared\Exception\NotFoundException;
|
||||||
|
|
||||||
|
use Psr\Container\ContainerInterface;
|
||||||
|
|
||||||
|
class Container implements ContainerInterface
|
||||||
|
{
|
||||||
|
private array $entries = [];
|
||||||
|
|
||||||
|
public function get(string $id)
|
||||||
|
{
|
||||||
|
if ($this->has($id)) {
|
||||||
|
$entry = $this->entries[$id];
|
||||||
|
|
||||||
|
if (is_callable($entry)) {
|
||||||
|
return $entry($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
$id = $entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->resolve($id);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function has(string $id): bool
|
||||||
|
{
|
||||||
|
return isset($this->entries[$id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set(string $id, callable|string $concrete): void
|
||||||
|
{
|
||||||
|
$this->entries[$id] = $concrete;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resolve(string $id)
|
||||||
|
{
|
||||||
|
// 1. Inspect the class that we are trying to get from the container
|
||||||
|
try {
|
||||||
|
$reflectionClass = new \ReflectionClass($id);
|
||||||
|
} catch(\ReflectionException $e) {
|
||||||
|
throw new NotFoundException($e->getMessage(), $e->getCode(), $e);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! $reflectionClass->isInstantiable()) {
|
||||||
|
throw new ContainerException('Class "' . $id . '" is not instantiable');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. Inspect the constructor of the class
|
||||||
|
$constructor = $reflectionClass->getConstructor();
|
||||||
|
|
||||||
|
if (! $constructor) {
|
||||||
|
return new $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. Inspect the constructor parameters (dependencies)
|
||||||
|
$parameters = $constructor->getParameters();
|
||||||
|
|
||||||
|
if (! $parameters) {
|
||||||
|
return new $id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4. If the constructor parameter is a class then try to resolve that class using the container
|
||||||
|
$dependencies = array_map(
|
||||||
|
function (\ReflectionParameter $param) use ($id) {
|
||||||
|
$name = $param->getName();
|
||||||
|
$type = $param->getType();
|
||||||
|
|
||||||
|
if (! $type) {
|
||||||
|
throw new ContainerException(
|
||||||
|
'Failed to resolve class "' . $id . '" because param "' . $name . '" is missing a type hint'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof \ReflectionUnionType) {
|
||||||
|
throw new ContainerException(
|
||||||
|
'Failed to resolve class "' . $id . '" because of union type for param "' . $name . '"'
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($type instanceof \ReflectionNamedType && ! $type->isBuiltin()) {
|
||||||
|
return $this->get($type->getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ContainerException(
|
||||||
|
'Failed to resolve class "' . $id . '" because invalid param "' . $name . '"'
|
||||||
|
);
|
||||||
|
},
|
||||||
|
$parameters
|
||||||
|
);
|
||||||
|
|
||||||
|
return $reflectionClass->newInstanceArgs($dependencies);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getAllRegisteredClassNames(): array
|
||||||
|
{
|
||||||
|
return array_keys($this->entries);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
// getArguments() is also able to inject any Request attribute;
|
||||||
|
// if the argument has the same name as the corresponding attribute:
|
||||||
|
// the matching is done on the argument name or a type hint, the arguments order does not matter
|
||||||
|
namespace Controllers;
|
||||||
|
use App\Router\Request\IRequest;
|
||||||
|
/**
|
||||||
|
* Responsible for resolving the arguments passed to a controller action.
|
||||||
|
*/
|
||||||
|
class ArgumentControllerResolver implements IArgumentresolver{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolves and returns the arguments for a given controller callable.
|
||||||
|
*
|
||||||
|
* @param IRequest $request The HTTP request object.
|
||||||
|
* @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.
|
||||||
|
*/
|
||||||
|
public function getArguments(IRequest $request, callable $controller): array
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
$reflectionMethod = new \ReflectionMethod($controller);
|
||||||
|
} catch (\ReflectionException $e) {
|
||||||
|
throw new \InvalidArgumentException("Controller method error: " . $e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
$args = [];
|
||||||
|
foreach ($reflectionMethod->getParameters() as $param) {
|
||||||
|
if (IRequest::class === $param->getType()->getName() || is_subclass_of($param->getType()->getName(), IRequest::class)) {
|
||||||
|
$args[] = $request;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
$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");
|
||||||
|
}
|
||||||
|
|
||||||
|
$args[] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $args;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extracts a value from the request based on a key.
|
||||||
|
*
|
||||||
|
* @param string $key The key to look for in the request.
|
||||||
|
* @param IRequest $req The request object.
|
||||||
|
* @return mixed The value from the request or null if not found.
|
||||||
|
*/
|
||||||
|
public function getFromRequest(string $key, IRequest $req): mixed
|
||||||
|
{
|
||||||
|
$body = $req->getBody();
|
||||||
|
if (array_key_exists($key, $body)) {
|
||||||
|
return $body[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$queryParams = $req->getQueryParameters();
|
||||||
|
if (array_key_exists($key, $queryParams)) {
|
||||||
|
return $queryParams[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
$requestParams = $req->getRequestParameters();
|
||||||
|
if (array_key_exists($key, $requestParams)) {
|
||||||
|
return $requestParams[$key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,86 @@
|
|||||||
|
<?php
|
||||||
|
namespace Controleur;
|
||||||
|
use App\Attributes\Route;
|
||||||
|
use App\Container;
|
||||||
|
use App\Router\Request\IRequest;
|
||||||
|
use App\Router\Responce\Response;
|
||||||
|
use Shared\Validation;
|
||||||
|
// use App\Enums\HttpMethod;
|
||||||
|
|
||||||
|
class CoachControleur extends BaseController
|
||||||
|
{
|
||||||
|
private $DataManager;
|
||||||
|
public function __construct(Container $container)
|
||||||
|
{
|
||||||
|
global $twig;
|
||||||
|
session_start();
|
||||||
|
$this->DataManager = $container->get('DBDATAMANAGER');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/', name: 'test', methods:['GET'])] // 8
|
||||||
|
public function index(): Response{
|
||||||
|
return new Response( $this->Reinit());
|
||||||
|
|
||||||
|
}
|
||||||
|
#[Route(path: '/addAthl', name: 'test', methods:['Post'])] // 8
|
||||||
|
public function addAthlthe(IRequest $req,string $userName){
|
||||||
|
if(Validation::val_string($userName)){
|
||||||
|
$resp = $this->$DataManager->coachManager->addAthlthe($userName);
|
||||||
|
if($resp){
|
||||||
|
return new Response($container->get('twig')->render('listAthlet.html.twig',$this->$DataManager->coachManager->getCurrentUser()->listAthlete));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Reinit()
|
||||||
|
{
|
||||||
|
global $twig;
|
||||||
|
|
||||||
|
$dVue = [
|
||||||
|
'nom' => '',
|
||||||
|
'age' => 0,
|
||||||
|
'email'=> '',
|
||||||
|
];
|
||||||
|
return $twig->render('vuephp1.html.twig', [
|
||||||
|
'dVue' => $dVue
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
#[Route(path: '/hello', methods:['GET'], name: 'hello')]
|
||||||
|
public function hello(): Response{
|
||||||
|
return new Response('Hello');
|
||||||
|
}
|
||||||
|
|
||||||
|
#[Route(path: '/hi', methods:['GET'],name: 'hi')]
|
||||||
|
public function hi(string $name,IRequest $req): Response{
|
||||||
|
return new Response($name.$req->getMethod());
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ValidationFormulaire(array $dVueEreur)
|
||||||
|
{
|
||||||
|
global $twig; // nécessaire pour utiliser variables globales
|
||||||
|
|
||||||
|
//si exception, ca remonte !!!
|
||||||
|
$nom = $_POST['txtNom']; // txtNom = nom du champ texte dans le formulaire
|
||||||
|
$age = $_POST['txtAge'];
|
||||||
|
$email = $_POST['email'];
|
||||||
|
|
||||||
|
\config\Validation::val_form($nom, $age,$email, $dVueEreur);
|
||||||
|
|
||||||
|
$model = new \modeles\Simplemodel();
|
||||||
|
$data = $model->get_data();
|
||||||
|
|
||||||
|
$dVue = [
|
||||||
|
'nom' => $nom,
|
||||||
|
'email' => $email,
|
||||||
|
'age' => $age,
|
||||||
|
'data' => $data,
|
||||||
|
];
|
||||||
|
|
||||||
|
echo $twig->render('vuephp1.html.twig', ['dVue' => $dVue, 'dVueEreur' => $dVueEreur]);
|
||||||
|
}
|
||||||
|
}//fin class
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
|||||||
|
<?php
|
||||||
|
// // controller arguments are guessed by using this Interface getArguments()
|
||||||
|
// // introspects the controller signature to determine which arguments to pass to it by using the native PHP reflection.
|
||||||
|
// namespace Controllers;
|
||||||
|
// interface IArgumentResolver {
|
||||||
|
// public function getArguments(Object Source, callable);
|
||||||
|
// }
|
||||||
|
|
||||||
|
namespace Controllers;
|
||||||
|
|
||||||
|
use App\Router\Request\IRequest;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for classes that resolve arguments for controller methods.
|
||||||
|
*/
|
||||||
|
interface IArgumentResolver
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Resolves the arguments for a controller method based on the given request.
|
||||||
|
*
|
||||||
|
* @param IRequest $request The request object.
|
||||||
|
* @param callable $controller The controller callable.
|
||||||
|
* @return array An array of arguments resolved for the controller method.
|
||||||
|
*/
|
||||||
|
public function getArguments(IRequest $request, callable $controller): array;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace App\Enums;
|
||||||
|
enum HttpMethod: string {
|
||||||
|
case Get = 'GET';
|
||||||
|
case Post = 'POST';
|
||||||
|
case Put = 'PUT';
|
||||||
|
case Head = 'HEAD';
|
||||||
|
|
||||||
|
case Patch = "PATCH";
|
||||||
|
|
||||||
|
case Delete = 'Delete';
|
||||||
|
public static function values()
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
self::Get,
|
||||||
|
self::Post,
|
||||||
|
self::Put,
|
||||||
|
self::Delete,
|
||||||
|
self::Head,
|
||||||
|
self::Patch,
|
||||||
|
// Add more HTTP methods as needed
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,22 +1,51 @@
|
|||||||
<?php
|
<?php
|
||||||
|
namespace App\Router;
|
||||||
|
|
||||||
|
// // map users details page using controller#action string
|
||||||
|
// $router->map( 'GET', '/users/[i:id]/', 'UserController#showDetails' );
|
||||||
|
|
||||||
|
// // map contact form handler using function name string
|
||||||
|
// $router->map( 'POST', '/contact/', 'handleContactForm' );
|
||||||
class Route
|
class Route
|
||||||
{
|
{
|
||||||
|
private string $name;
|
||||||
|
|
||||||
private string $name;
|
private string $path;
|
||||||
|
|
||||||
private array $parrams;
|
private string $method; // callable|array
|
||||||
|
|
||||||
private $callable;
|
private $callable;
|
||||||
|
|
||||||
|
public function __construct(string $path, callable $callable, array $params = null,string $name = null)
|
||||||
|
{
|
||||||
|
$this->path = $path;
|
||||||
|
$this->callable = $callable;
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
public function __construct(array $params, callable $callable, string $name = null)
|
|
||||||
{
|
|
||||||
$this->path = $params;
|
|
||||||
$this->callable = $callable;
|
|
||||||
$this->name = $name;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function getName(): ?string
|
||||||
|
{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setName(?string $name): void
|
||||||
|
{
|
||||||
|
$this->name = $name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCallable()
|
||||||
|
{
|
||||||
|
return $this->callable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPath(): string
|
||||||
|
{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setCallable(callable $callable)
|
||||||
|
{
|
||||||
|
$this->callable = $callable;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,121 @@
|
|||||||
|
<?php
|
||||||
|
/*
|
||||||
|
Use the static method getInstance to get the object.
|
||||||
|
*/
|
||||||
|
namespace App\Router;
|
||||||
|
|
||||||
|
class Session
|
||||||
|
{
|
||||||
|
const SESSION_STARTED = TRUE;
|
||||||
|
const SESSION_NOT_STARTED = FALSE;
|
||||||
|
|
||||||
|
// The state of the session
|
||||||
|
private $sessionState = self::SESSION_NOT_STARTED;
|
||||||
|
|
||||||
|
// THE only instance of the class
|
||||||
|
private static $instance;
|
||||||
|
|
||||||
|
|
||||||
|
private function __construct() {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns THE instance of 'Session'.
|
||||||
|
* The session is automatically initialized if it wasn't.
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
**/
|
||||||
|
|
||||||
|
public static function getInstance()
|
||||||
|
{
|
||||||
|
if ( !isset(self::$instance))
|
||||||
|
{
|
||||||
|
self::$instance = new self;
|
||||||
|
}
|
||||||
|
|
||||||
|
self::$instance->startSession();
|
||||||
|
|
||||||
|
return self::$instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* (Re)starts the session.
|
||||||
|
*
|
||||||
|
* @return bool TRUE if the session has been initialized, else FALSE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
private function startSession()
|
||||||
|
{
|
||||||
|
if ( $this->sessionState == self::SESSION_NOT_STARTED )
|
||||||
|
{
|
||||||
|
$this->sessionState = session_start();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->sessionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stores datas in the session.
|
||||||
|
* Example: $instance->foo = 'bar';
|
||||||
|
*
|
||||||
|
* @param name Name of the datas.
|
||||||
|
* @param value Your datas.
|
||||||
|
* @return void
|
||||||
|
**/
|
||||||
|
|
||||||
|
public function __set( $name , $value )
|
||||||
|
{
|
||||||
|
$_SESSION[$name] = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets datas from the session.
|
||||||
|
* Example: echo $instance->foo;
|
||||||
|
*
|
||||||
|
* @param name Name of the datas to get.
|
||||||
|
* @return mixed Datas stored in session.
|
||||||
|
**/
|
||||||
|
|
||||||
|
public function __get( string $name )
|
||||||
|
{
|
||||||
|
if ( isset($_SESSION[$name]))
|
||||||
|
{
|
||||||
|
return $_SESSION[$name];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function __isset( $name )
|
||||||
|
{
|
||||||
|
return isset($_SESSION[$name]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function __unset( $name )
|
||||||
|
{
|
||||||
|
unset( $_SESSION[$name] );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the current session.
|
||||||
|
*
|
||||||
|
* @return bool TRUE is session has been deleted, else FALSE.
|
||||||
|
**/
|
||||||
|
|
||||||
|
public function destroy()
|
||||||
|
{
|
||||||
|
if ( $this->sessionState == self::SESSION_STARTED )
|
||||||
|
{
|
||||||
|
$this->sessionState = !session_destroy();
|
||||||
|
unset( $_SESSION );
|
||||||
|
|
||||||
|
return !$this->sessionState;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types = 1);
|
||||||
|
|
||||||
|
namespace App\Attributes;
|
||||||
|
|
||||||
|
use App\Enums\HttpMethod;
|
||||||
|
|
||||||
|
#[\Attribute(Attribute::TARGET_METHOD|Attribute::IS_REPEATABLE)]
|
||||||
|
class Get extends Route
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private string|array $path,
|
||||||
|
private ?string $name = null)
|
||||||
|
{
|
||||||
|
parent::__construct($path,$name,HttpMethod::Post);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Attributes;
|
||||||
|
use App\Enums\HttpMethod;
|
||||||
|
|
||||||
|
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_CLASS)]
|
||||||
|
class Route
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(
|
||||||
|
private string|array $path = null,
|
||||||
|
private ?string $name = null,
|
||||||
|
private array|HttpMethod $methods = HttpMethod::Get,
|
||||||
|
)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPath(): array| string{
|
||||||
|
return $this->path;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getName(): ?string{
|
||||||
|
return $this->name;
|
||||||
|
}
|
||||||
|
public function getMethods(): array | HttpMethod
|
||||||
|
{
|
||||||
|
return $this->methods;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
namespace App\Router\Middleware;
|
||||||
|
|
||||||
|
use App\Router\Request\IRequest;
|
||||||
|
|
||||||
interface IHttpMiddleware {
|
interface IHttpMiddleware {
|
||||||
public function handle(IRequest $request, callable $next);
|
public function handle(IRequest $request, callable $next);
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
<?php
|
<?php
|
||||||
|
namespace App\Router\Request;
|
||||||
|
|
||||||
interface ContentStrategy {
|
interface ContentStrategy {
|
||||||
public function getContent(): array;
|
public function getContent(): array;
|
||||||
|
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
class Connection extends PDO {
|
||||||
|
|
||||||
|
private $stmt;
|
||||||
|
|
||||||
|
public function __construct(string $dsn) {
|
||||||
|
// $dsn = "pgsql:host=$this->host;port=$this->port;dbname=$this->database;user=$this->username;password=$this->password";
|
||||||
|
parent::__construct($dsn);
|
||||||
|
echo "Successfully connected to the database";
|
||||||
|
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -0,0 +1,50 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
class DatabaseQueryExecutor {
|
||||||
|
private $connection;
|
||||||
|
|
||||||
|
// should be this IDatabaseConnection
|
||||||
|
public function __construct(Connection $dbConnection) {
|
||||||
|
$this->connection = $dbConnection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function executeQuery(string $query, array $parameters = []): bool {
|
||||||
|
$stmt = $this->connection->prepare($query);
|
||||||
|
foreach ($parameters as $name => $value) {
|
||||||
|
$stmt->bindValue($name, $value[0], $value[1]);
|
||||||
|
}
|
||||||
|
return $stmt->execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function executeTransaction(callable $transaction): bool {
|
||||||
|
try {
|
||||||
|
$this->connection->beginTransaction();
|
||||||
|
$transaction($this);
|
||||||
|
$this->connection->commit();
|
||||||
|
return true;
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
$this->connection->rollBack();
|
||||||
|
throw new Exception('Database transaction failed: ' . $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetchAll(string $query, array $parameters = []): array {
|
||||||
|
$stmt = $this->connection->prepare($query);
|
||||||
|
foreach ($parameters as $name => $value) {
|
||||||
|
$stmt->bindValue($name, $value[0], $value[1]);
|
||||||
|
}
|
||||||
|
$stmt->execute();
|
||||||
|
return $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function fetchOne(string $query, array $parameters = []): ?array {
|
||||||
|
$stmt = $this->connection->prepare($query);
|
||||||
|
foreach ($parameters as $name => $value) {
|
||||||
|
$stmt->bindValue($name, $value[0], $value[1]);
|
||||||
|
}
|
||||||
|
$stmt->execute();
|
||||||
|
$result = $stmt->fetch(PDO::FETCH_ASSOC);
|
||||||
|
return $result ?: null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
?>
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database;
|
||||||
|
|
||||||
|
abstract class DbContext {
|
||||||
|
protected $databaseConnection;
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
$this->onConfiguring();
|
||||||
|
$this->onModelCreating();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract function onConfiguring();
|
||||||
|
protected abstract function onModelCreating();
|
||||||
|
|
||||||
|
protected function isConfigured() {
|
||||||
|
return $this->databaseConnection !== null;
|
||||||
|
}
|
||||||
|
// getInstantce
|
||||||
|
protected function seedDatabase($sqlFilePath) {
|
||||||
|
if (!$this->isConfigured()) {
|
||||||
|
if (file_exists($sqlFilePath)) {
|
||||||
|
try {
|
||||||
|
$sql = file_get_contents($sqlFilePath);
|
||||||
|
$this->databaseConnection->exec($sql);
|
||||||
|
echo "Database seeded successfully.";
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
echo "Error seeding database: " . $e->getMessage();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
echo "SQL file not found: $sqlFilePath";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database;
|
||||||
|
use Manager\DataManager;
|
||||||
|
|
||||||
|
class DbManager extends DataManager{
|
||||||
|
public HeartDbContext $context;
|
||||||
|
public function __construct(){
|
||||||
|
$this->userMgr = new UserRepository($this);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database;
|
||||||
|
use Database\Gateway\UserGateway;
|
||||||
|
|
||||||
|
class HeartDbContext extends DbContext {
|
||||||
|
public $userGateWay;
|
||||||
|
private $seed = true;
|
||||||
|
// ... autres gateways pour chaque entité
|
||||||
|
|
||||||
|
public function __construct() {
|
||||||
|
// Initialisation de chaque gateway avec la connexion à la base de données
|
||||||
|
$databaseConnection = DatabaseConnection::getInstance("");
|
||||||
|
$this->userGateWay = new UserGateway($databaseConnection);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onConfiguring() {
|
||||||
|
if (!$this->isConfigured()) {
|
||||||
|
echo "!IsConfigured...\n";
|
||||||
|
try {
|
||||||
|
$options = $this->getConnectionOptions();
|
||||||
|
$this->databaseConnection = DatabaseConnection::getInstance($options['dsn'], $options['username'], $options['password']);
|
||||||
|
echo 'Successfully connected to the database';
|
||||||
|
} catch (PDOException $e) {
|
||||||
|
echo 'Error connecting to the database: ' . $e->getMessage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
protected function getConnectionOptions(): array {
|
||||||
|
// 'dbname' => 'mydb',
|
||||||
|
// 'user' => 'user',
|
||||||
|
// 'password' => 'secret',
|
||||||
|
// 'host' => 'localhost',
|
||||||
|
// 'driver' => 'pdo_mysql',
|
||||||
|
return [
|
||||||
|
'dsn' => 'mysql:host=localhost;dbname=your_database',
|
||||||
|
'username' => 'your_username',
|
||||||
|
'password' => 'your_password'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function onModelCreating() {
|
||||||
|
if (!$this->isConfigured() && $this->seed) {
|
||||||
|
$this->seedDatabase(__DIR__ . '/../../../config/heart.sql');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
<?
|
||||||
|
interface IDatabaseConnection {
|
||||||
|
public function connect();
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Mapper;
|
||||||
|
use Database\Entity;
|
||||||
|
|
||||||
|
|
||||||
|
use Model\User;
|
||||||
|
|
||||||
|
class UserMapper {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a User entity to a UserDTO.
|
||||||
|
*
|
||||||
|
* @param User $user
|
||||||
|
* @return UserEntity
|
||||||
|
*/
|
||||||
|
public static function toEntity(User $user): UserEntity {
|
||||||
|
return new UserEntity(
|
||||||
|
$user->getId(),
|
||||||
|
$user->getNom(),
|
||||||
|
$user->getPrenom(),
|
||||||
|
$user->getEmail(),
|
||||||
|
$user->getSexe(),
|
||||||
|
$user->getTaille(),
|
||||||
|
$user->getPoids(),
|
||||||
|
$user->getDateNaissance(),
|
||||||
|
$user->getRole()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a UserEntity to a User entity.
|
||||||
|
*
|
||||||
|
* @param UserEntity $entity
|
||||||
|
* @return User
|
||||||
|
*/
|
||||||
|
public static function toModel(UserEntity $entity): User {
|
||||||
|
$user = new User(
|
||||||
|
$entity->id,
|
||||||
|
$entity->nom,
|
||||||
|
$entity->prenom,
|
||||||
|
$entity->email,
|
||||||
|
// Handle password appropriately
|
||||||
|
'defaultPassword', // This is a placeholder. Handle with care.
|
||||||
|
$entity->sexe,
|
||||||
|
$entity->taille,
|
||||||
|
$entity->poids,
|
||||||
|
$entity->dateNaissance,
|
||||||
|
$entity->role
|
||||||
|
);
|
||||||
|
|
||||||
|
return $user;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Map SQL result to UserEntity object.
|
||||||
|
*
|
||||||
|
* @param array $row
|
||||||
|
* @return UserEntity
|
||||||
|
*/
|
||||||
|
public static function fromSql(array $row): UserEntity {
|
||||||
|
$dateNaissance = new \DateTime($row['date_naissance']); // Adjust the key as per your database column name
|
||||||
|
$role = new Role(/* parameters based on your Role class constructor */);
|
||||||
|
|
||||||
|
return new UserEntity(
|
||||||
|
$row['id'],
|
||||||
|
$row['nom'],
|
||||||
|
$row['prenom'],
|
||||||
|
$row['email'],
|
||||||
|
$row['mot_de_passe'], // Make sure this is handled securely
|
||||||
|
$row['sexe'],
|
||||||
|
$row['taille'],
|
||||||
|
$row['poids'],
|
||||||
|
$dateNaissance,
|
||||||
|
$role
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Entity;
|
||||||
|
class AthleteEntity {
|
||||||
|
public function __construct(
|
||||||
|
public ?int $id = null,
|
||||||
|
public ?string $nom = null,
|
||||||
|
public ?string $prenom = null,
|
||||||
|
public ?string $email = null,
|
||||||
|
public ?string $sexe = null,
|
||||||
|
public ?float $taille = null,
|
||||||
|
public ?float $poids = null,
|
||||||
|
public ?\DateTime $dateNaissance = null,
|
||||||
|
private ?int $coach_id = null
|
||||||
|
) {}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database\Gateway;
|
||||||
|
use Model\User;
|
||||||
|
use Repository\IUserRepository;
|
||||||
|
use DataMapper\UserMapper;
|
||||||
|
// changer car je suis censé provide une API simplifié genre un QuerryBuilder plus to que sa m'est bon on s'en fou
|
||||||
|
|
||||||
|
class UserGateway {
|
||||||
|
private DatabaseQueryExecutor $queryExecutor;
|
||||||
|
|
||||||
|
public function __construct(DatabaseQueryExecutor $queryExecutor) {
|
||||||
|
$this->queryExecutor = $queryExecutor;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemById(int $id): ?UserEntity {
|
||||||
|
$result = $this->queryExecutor->fetchOne("SELECT * FROM users WHERE id = :id", ['id' => [$id, PDO::PARAM_INT]]);
|
||||||
|
return $result ? UserMapper::fromSql($result) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemByEmail(string $email): ?UserEntity {
|
||||||
|
$result = $this->queryExecutor->fetchOne("SELECT * FROM users WHERE email = :email", ['email' => [$email, PDO::PARAM_STR]]);
|
||||||
|
return $result ? $this->mapper->mapToUser($result) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetNbItems(): int {
|
||||||
|
$result = $this->queryExecutor->fetchOne("SELECT COUNT(*) as count FROM users");
|
||||||
|
return $result ? (int)$result['count'] : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetItems(int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): array {
|
||||||
|
$order = $descending ? 'DESC' : 'ASC';
|
||||||
|
$query = "SELECT * FROM users " . ($orderingPropertyName ? "ORDER BY $orderingPropertyName $order " : "") . "LIMIT :index, :count";
|
||||||
|
$parameters = ['index' => [$index, PDO::PARAM_INT], 'count' => [$count, PDO::PARAM_INT]];
|
||||||
|
$results = $this->queryExecutor->fetchAll($query, $parameters);
|
||||||
|
return array_map([$this->mapper, 'mapToUser'], $results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetItemsByName(string $substring, int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): array {
|
||||||
|
$order = $descending ? 'DESC' : 'ASC';
|
||||||
|
$query = "SELECT * FROM users WHERE CONCAT(first_name, ' ', last_name) LIKE :substring " . ($orderingPropertyName ? "ORDER BY $orderingPropertyName $order " : "") . "LIMIT :index, :count";
|
||||||
|
$parameters = ['substring' => ["%$substring%", PDO::PARAM_STR], 'index' => [$index, PDO::PARAM_INT], 'count' => [$count, PDO::PARAM_INT]];
|
||||||
|
$results = $this->queryExecutor->fetchAll($query, $parameters);
|
||||||
|
return array_map([$this->mapper, 'mapToUser'], $results);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function UpdateItem(UserEntity $oldUser, UserEntity $newUser): void {
|
||||||
|
// Logique pour mettre à jour un utilisateur
|
||||||
|
// Utiliser $this->queryExecutor->executeQuery pour exécuter la requête de mise à jour
|
||||||
|
}
|
||||||
|
|
||||||
|
public function AddItem(UserEntity $user): void {
|
||||||
|
// Logique pour ajouter un nouvel utilisateur
|
||||||
|
// Utiliser $this->queryExecutor->executeQuery pour exécuter la requête d'insertion
|
||||||
|
}
|
||||||
|
|
||||||
|
public function DeleteItem(UserEntity $user): bool {
|
||||||
|
$success = $this->queryExecutor->executeQuery("DELETE FROM users WHERE id = :id", ['id' => [$user->getId(), PDO::PARAM_INT]]);
|
||||||
|
return $success;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
namespace Database;
|
||||||
|
|
||||||
|
use Model\User;
|
||||||
|
use Repository\IUserRepository;
|
||||||
|
use Database\DbContext;
|
||||||
|
|
||||||
|
class UserRepository implements IUserRepository {
|
||||||
|
private readonly DbManager $parent;
|
||||||
|
|
||||||
|
public function __construct(DbManager $dbContext) {
|
||||||
|
$this->parent = $dbContext;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemById(int $id): ?User {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
public function GetItemByName(string $substring, int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false){
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemByEmail(string $email): ?User {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNbItems(): int {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItems(int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): array {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getItemsByName(string $substring, int $index, int $count, ?string $orderingPropertyName = null, bool $descending = false): array {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addItem(User $user): ?User {
|
||||||
|
// Add a new user to the database
|
||||||
|
$userEntity = $this->parent->context->userGateWay->addUser($user->toEntity());
|
||||||
|
$this->parent->dbContext->userGateWay->saveChanges();
|
||||||
|
|
||||||
|
return $userEntity->ToModel();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateItem(User $oldUser, User $newUser): void {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteItem(User $user): bool {
|
||||||
|
// should use name and other things to equals
|
||||||
|
$usertoDelete = $this->parent->context->userGateWay->GetItemsByName($user->getNom());
|
||||||
|
// Where(c => c.Name == item.Name).First();
|
||||||
|
if ($usertoDelete != null)
|
||||||
|
{
|
||||||
|
$deleted = $this->dbContext->userGateWay->Remove($usertoDelete);
|
||||||
|
$this->parent->dbContext->saveChanges();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
?>
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shared\Exception;
|
||||||
|
|
||||||
|
final class ContainerException extends \Exception
|
||||||
|
{
|
||||||
|
public $message = "Container runs wrong";
|
||||||
|
}
|
@ -0,0 +1,8 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Shared\Exception;
|
||||||
|
|
||||||
|
final class NotFoundException extends \Exception
|
||||||
|
{
|
||||||
|
public $message = "Not found";
|
||||||
|
}
|
Loading…
Reference in new issue