Commit 81917c8e authored by Quentin Vrel's avatar Quentin Vrel

TP3 13/11

parent 08ad5375
<?php
// define __ROOT_DIR constant which contains the absolute path on disk
// of the directory that contains this file (index.php)
// e.g. http://eden.imt-lille-douai.fr/~luc.fabresse/index.php => __ROOT_DIR = /home/luc.fabresse/public_html
$rootDirectoryPath = realpath(dirname(__FILE__));
define ('__ROOT_DIR', $rootDirectoryPath );
// Load all application config
require_once(__ROOT_DIR . "/config/config.php");
// Load the Loader class to automatically load classes when needed
require_once(__ROOT_DIR . '/classes/AutoLoader.class.php');
// Reify the current request
$request = Request::getCurrentRequest();
Response::interceptEchos();
try {
$controller = Dispatcher::dispatch($request);
$response = $controller->execute();
} catch (Exception $e) {
$log = Response::getEchos();
$log .= " " . $e->getMessage();
$response = Response::errorResponse($log);
}
$response->send();
\ No newline at end of file
<?php
class AutoLoader {
public function __construct() {
spl_autoload_register( array($this, 'load') );
// spl_autoload_register(array($this, 'loadComplete'));
}
// This method will be automatically executed by PHP whenever it encounters an unknown class name in the source code
private function load($className) {
$_model=["Model", "Role", "User"];
$_classes=["DatabasePDO", "Dispatcher", "Request", "Response"];
$_controller=["Controller", "DefaultController", "UserController"];
if(in_array($className, $_model)){
require_once "model/$className.class.php";
if (is_readable("sql/$className.sql.php"))
require_once "sql/$className.sql.php";
}
if (in_array($className, $_classes))
require_once "classes/$className.class.php";
if (in_array($className, $_controller))
require_once "controller/$className.class.php";
// TODO : compute path of the file to load (cf. PHP function is_readable)
// it is in one of these subdirectory '/classes/', '/model/', '/controller/'
// if it is a model, load its sql queries file too in sql/ directory
}
}
$__LOADER = new AutoLoader();
\ No newline at end of file
<?php
class DatabasePDO extends PDO {
protected static $singleton = NULL;
public static function singleton(){
if(is_null(static::$singleton))
static::$singleton = new static();
return static::$singleton;
}
public function __construct() {
// $db = new PDO("sqlite::memory");
$connectionString = "mysql:host=". DB_HOST;
if(defined('DB_PORT'))
$connectionString .= ";port=". DB_PORT;
$connectionString .= ";dbname=" . DB_DATABASE;
$connectionString .= ";charset=utf8";
parent::__construct($connectionString,DB_USERNAME,DB_PASSWORD);
$this->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
}
\ No newline at end of file
<?php
/*
* Analyses a request, created the right Controller passing it the request
*/
class Dispatcher {
public static function dispatch($request) {
return static::dispatchToController($request->getControllerName(),$request);
}
public static function dispatchToController($controllerName, $request) {
$controllerClassName = ucfirst($controllerName) . 'Controller';
if(!class_exists($controllerClassName))
throw(new Exception("Class $controllerName does not exist"));
return new $controllerClassName($controllerName, $request);
}
}
\ No newline at end of file
<?php
class Request {
protected $controllerName;
protected $uriParameters;
protected static $_instance;
public static function getCurrentRequest(){
if(is_null(self::$_instance)) {
self::$_instance = new Request();
}
return self::$_instance;
}
public function __construct() {
$this->initBaseURI();
$this->initControllerAndParametersFromURI();
}
// intialise baseURI
// e.g. http://eden.imt-lille-douai.fr/~luc.fabresse/api.php => __BASE_URI = /~luc.fabresse
// e.g. http://localhost/CDAW/api.php => __BASE_URI = /CDAW
protected function initBaseURI() {
$this->baseURI = parse_url($_SERVER['REQUEST_URI'], PHP_URL_QUERY);
}
// intialise controllerName et uriParameters
// controllerName contient chaîne 'default' ou le nom du controleur s'il est présent dans l'URI (la requête)
// uriParameters contient un tableau vide ou un tableau contenant les paramètres passés dans l'URI (la requête)
// e.g. http://eden.imt-lille-douai.fr/~luc.fabresse/api.php
// => controllerName == 'default'
// uriParameters == []
// e.g. http://eden.imt-lille-douai.fr/~luc.fabresse/api.php/user/1
// => controllerName == 'user'
// uriParameters == [ 1 ]
protected function initControllerAndParametersFromURI(){
$prefix = $_SERVER['SCRIPT_NAME'];
$uriParameters = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$i=0;
while($i<strlen($prefix) && $i<strlen($uriParameters))
if($prefix[$i]===$uriParameters[$i])
$i++;
$uriParameters = substr($uriParameters, $i);
$uriParameters = trim($uriParameters, '/');
$uriSegments = explode('/', $uriParameters);
$this->controllerName = array_shift($uriSegments) ?: "default";
$this->uriParameters = $uriSegments;
}
// ==============
// Public API
// ==============
// retourne le name du controleur qui doit traiter la requête courante
public function getControllerName() {
return $this->controllerName;
}
// retourne la méthode HTTP utilisée dans la requête courante
public function getHttpMethod() {
return $_SERVER["REQUEST_METHOD"];
}
}
\ No newline at end of file
<?php
class Response {
protected $code;
protected $body;
public function __construct($code = 404, $msg = "") {
$this->code = $code;
$this->body = $msg;
}
public static function errorResponse($message = "") {
return new Response(400,$message);
}
public static function serverErrorResponse($message = "")
{
return new Response(500,$message);
}
public static function okResponse($message = "")
{
return new Response(200,$message);
}
public static function notFoundResponse($message = "")
{
return new Response(404,$message);
}
public static function errorInParametersResponse($message = "")
{
return new Response(400,$message);
}
public static function interceptEchos() {
ob_start();
}
public static function getEchos() {
return ob_get_clean();
}
public function send() {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods
header("Access-Control-Allow-Methods: GET,POST,PUT,DELETE");
header("Access-Control-Max-Age: 3600"); // Maximum number of seconds the results can be cached.
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers
header("Access-Control-Allow-Headers: Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With");
http_response_code($this->code);
echo $this->body;
exit; // do we keep that?
}
}
\ No newline at end of file
<?php
define('DB_HOST','127.0.0.1');
define('DB_PORT',3306);
define('DB_DATABASE','dbtest');
define('DB_USERNAME','root');
define('DB_PASSWORD','');
// define('__DEBUG', false);
define('__DEBUG', true);
// ================================================================================
// Debug utilities
// ================================================================================
if(__DEBUG) {
error_reporting(E_ALL);
ini_set("display_errors", E_ALL);
} else {
error_reporting(0);
ini_set("display_errors", 0);
}
function myLog($msg) {
if(__DEBUG) {
echo $msg;
}
}
function myDump($var) {
if(__DEBUG) {
var_dump($var);
}
}
\ No newline at end of file
<?php
/*
* A Controller is dedicated to process a request
* its responsabilities are:
* - analyses the action to be done
* - analyses the parameters
* - act on the model objects to perform the action
* - process the data
* - call the view and passes it the data
* - return the response
*/
abstract class Controller {
protected $name;
protected $request;
public function __construct($name, $request) {
$this->request = $request;
$this->name = $name;
}
public abstract function processRequest();
public function execute() {
$response = $this->processRequest();
if(empty($response)) {
// $response = Response::serverErrorResponse("error processing request in ". self::class); // Oh my PHP!
$response = Response::serverErrorResponse("error processing request in ". static::class);
}
return $response;
}
}
\ No newline at end of file
<?php
class DefaultController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
// ==============
// Actions
// ==============
public function processRequest() {
return Response::errorResponse('{ "message" : "Unsupported endpoint"}' );
}
}
\ No newline at end of file
<?php
class UserController extends Controller {
public function __construct($name, $request) {
parent::__construct($name, $request);
}
// ==============
// Actions
// ==============
public function processRequest()
{
switch ($this->request->getHttpMethod()) {
case 'GET':
return $this->getAllUsers();
break;
}
return Response::errorResponse("unsupported parameters or method in users");
}
protected function getAllUsers()
{
$users = User::getList();
$response = Response::okResponse(json_encode($users));
//var_dump($json);die;
// TODO
return $response;
}
}
\ No newline at end of file
<?php
class Model {
protected static function db(){
return DatabasePDO::singleton();
}
// *** Queries in sql/model.sql.php ****
protected static $requests = array();
public static function addSqlQuery($key, $sql){
static::$requests[$key] = $sql;
}
public static function sqlQueryNamed($key){
return static::$requests[$key];
}
protected static function query($sql){
$st = static::db()->query($sql) or die("sql query error ! request : " . $sql);
$st->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, get_called_class());
return $st;
}
protected static function exec($sqlKey,$values=array()){
$sth = static::db()->prepare(static::sqlQueryNamed($sqlKey));
$sth->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, get_called_class());
$sth->execute($values);
return $sth;
}
}
\ No newline at end of file
<?php
class User extends Model {
// ===========
// = Statics =
// ===========
protected static $table_name = 'USER';
// load all users from Db
public static function getList() {
$stm = parent::exec('USER_LIST');
return $stm->fetchAll();
}
}
\ No newline at end of file
<?php
User::addSqlQuery('USER_LIST',
'SELECT * FROM USER ORDER BY USER_LOGIN');
User::addSqlQuery('USER_GET_WITH_LOGIN',
'SELECT * FROM USER WHERE USER_LOGIN=:login');
User::addSqlQuery('USER_CREATE',
'INSERT INTO USER (USER_ID, USER_LOGIN, USER_EMAIL, USER_ROLE, USER_PWD, USER_NAME, USER_SURNAME) VALUES (NULL, :login, :email, :role, :pwd, :name, :surname)');
User::addSqlQuery('USER_CONNECT',
'SELECT * FROM USER WHERE USER_LOGIN=:login and USER_PWD=:password');
\ No newline at end of file
-- phpMyAdmin SQL Dump
-- version 5.0.3
-- https://www.phpmyadmin.net/
--
-- Host: localhost
-- Generation Time: Nov 13, 2020 at 05:47 PM
-- Server version: 10.4.14-MariaDB
-- PHP Version: 7.4.11
SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
START TRANSACTION;
SET time_zone = "+00:00";
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8mb4 */;
--
-- Database: `dbtest`
--
-- --------------------------------------------------------
--
-- Table structure for table `USER`
--
CREATE TABLE `USER` (
`USER_ID` int(11) NOT NULL,
`USER_LOGIN` varchar(55) NOT NULL,
`USER_EMAIL` varchar(100) NOT NULL,
`USER_ROLE` varchar(100) NOT NULL,
`USER_PWD` varchar(100) NOT NULL,
`USER_NAME` varchar(55) NOT NULL,
`USER_SURNAME` varchar(55) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
--
-- Dumping data for table `USER`
--
INSERT INTO `USER` (`USER_ID`, `USER_LOGIN`, `USER_EMAIL`, `USER_ROLE`, `USER_PWD`, `USER_NAME`, `USER_SURNAME`) VALUES
(1, 'qvrel', 'qvrel@mail.fr', 'Admin', '123456', 'Quentin', 'Vrel');
--
-- Indexes for dumped tables
--
--
-- Indexes for table `USER`
--
ALTER TABLE `USER`
ADD PRIMARY KEY (`USER_ID`);
--
-- AUTO_INCREMENT for dumped tables
--
--
-- AUTO_INCREMENT for table `USER`
--
ALTER TABLE `USER`
MODIFY `USER_ID` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=2;
COMMIT;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment