mise en place des actions de vue, du loggeur du MVC

test des resultat des reponse Rest avec les methode GET PUT DELETE POST avec curl

FIXME: appel curl ou fopen d'une methode http depuis une action ou un controlleur.

TODO: sécuriser les accès HTTP1.1 par un fichier config similaire a l'applet Discourse faite pour Tinternet

TODO: ajouter un plug-in symfony permettant de charger un utilisateur dans les apps a partir de l'authentification multiple

TODO: lire les documentation officielles provenant des 4 plate-formes tranquillement afin de comprendre commet doit on tester ces type d'auth quitte a créé un sous domaine particulier directement hebergé sur gittea
 -->Sécuriser le serveur de dev
This commit is contained in:
Emmanuel ROY 2019-12-04 15:21:19 +01:00
commit 893becebab
22 changed files with 523 additions and 78 deletions

View file

@ -6,10 +6,15 @@ require APPLICATION_PATH . DIRECTORY_SEPARATOR . "parameters.php";
class Application
{
public $http;
public $url;
public $browser;
public function __construct(){
$this->url = new Url();
$this->http = new HttpMethod();
$this->browser = new Browser();
$this->url = new Url($this->http->method, $this->browser->isAppRequest());
}
public function launch(){

View file

@ -0,0 +1,93 @@
<?php
namespace MVC\Classe;
class Browser
{
public $user;
public $userAgent;
public function __construct()
{
$this->userAgent = $_SERVER['HTTP_USER_AGENT'];
$this->user = $this->get_browser_name();
}
protected function get_browser_name()
{
// Make case insensitive.
$t = strtolower($this->userAgent);
// If the string *starts* with the string, strpos returns 0 (i.e., FALSE). Do a ghetto hack and start with a space.
// "[strpos()] may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE."
// http://php.net/manual/en/function.strpos.php
$t = " " . $t;
// Humans / Regular Users
if (strpos($t, 'opera') || strpos($t, 'opr/')) return 'Opera';
elseif (strpos($t, 'edge')) return 'Edge';
elseif (strpos($t, 'chrome')) return 'Chrome';
elseif (strpos($t, 'safari')) return 'Safari';
elseif (strpos($t, 'firefox')) return 'Firefox';
elseif (strpos($t, 'msie') || strpos($t, 'trident/7')) return 'Internet Explorer';
// Application Users
elseif (strpos($t, 'curl')) return '[App] Curl';
// Search Engines
elseif (strpos($t, 'google')) return '[Bot] Googlebot';
elseif (strpos($t, 'bing')) return '[Bot] Bingbot';
elseif (strpos($t, 'slurp')) return '[Bot] Yahoo! Slurp';
elseif (strpos($t, 'duckduckgo')) return '[Bot] DuckDuckBot';
elseif (strpos($t, 'baidu')) return '[Bot] Baidu';
elseif (strpos($t, 'yandex')) return '[Bot] Yandex';
elseif (strpos($t, 'sogou')) return '[Bot] Sogou';
elseif (strpos($t, 'exabot')) return '[Bot] Exabot';
elseif (strpos($t, 'msn')) return '[Bot] MSN';
// Common Tools and Bots
elseif (strpos($t, 'mj12bot')) return '[Bot] Majestic';
elseif (strpos($t, 'ahrefs')) return '[Bot] Ahrefs';
elseif (strpos($t, 'semrush')) return '[Bot] SEMRush';
elseif (strpos($t, 'rogerbot') || strpos($t, 'dotbot')) return '[Bot] Moz or OpenSiteExplorer';
elseif (strpos($t, 'frog') || strpos($t, 'screaming')) return '[Bot] Screaming Frog';
// Miscellaneous
elseif (strpos($t, 'facebook')) return '[Bot] Facebook';
elseif (strpos($t, 'pinterest')) return '[Bot] Pinterest';
// Check for strings commonly used in bot user agents
elseif (strpos($t, 'crawler') || strpos($t, 'api') ||
strpos($t, 'spider') || strpos($t, 'http') ||
strpos($t, 'bot') || strpos($t, 'archive') ||
strpos($t, 'info') || strpos($t, 'data')) return '[Bot] Other';
return 'Other (Unknown)';
}
public function isBot()
{
if (preg_match('#Bot#', $this->user)) {
return true;
} else {
return false;
}
}
// Alternative TO https://www.php.net/manual/fr/function.get-browser.php
// Function written and tested December, 2018
public function isAppRequest()
{
if (preg_match('#App#', $this->user)) {
return true;
} else {
return false;
}
}
}

View file

@ -9,40 +9,19 @@ class Controlleur{
public function __construct($application){
$requete = new MVC\Classe\Request();
switch ($requete->method) {
switch ($application->http->method) {
//cas des requètes PUT et DELETE
case 'PUT':
case 'DELETE':
require CONTROLLER_PATH . DIRECTORY_SEPARATOR . $application->url->page['name'] . 'HttpReponse.php';
$reponseHttp = lcfirst($application->url->page['name']) . 'HttpReponse';
$response = new $reponseHttp($application->url, $requete->getData());
if ($requete->method == 'DELETE') {
$reponseHttp->delete();
} else {
$reponseHttp->put();
}
break;
//cas des requètes POST et GET
case 'POST':
case 'GET':
if (!file_exists(CONTROLLER_PATH . DIRECTORY_SEPARATOR . $application->url->page['name'] . '')) {
if ($application->browser->isAppRequest()) {
require CONTROLLER_PATH . DIRECTORY_SEPARATOR . $application->url->page['name'] . 'HttpReponse.php';
$reponseHttp = lcfirst($application->url->page['name']) . 'HttpReponse';
$response = new $reponseHttp($application->url, $requete->getData());
if ($requete->method == 'POST') {
$reponseHttp->post();
} else {
$reponseHttp->get();
}
$this->callHttpResponse($application);
break;
}
default:
if ($application->url->page['control']) {
$url_params = $application->url->page['params'];
require TRAITEMENT_PATH . DIRECTORY_SEPARATOR . $application->url->page['name'] . '.php';
@ -54,5 +33,25 @@ class Controlleur{
}
public function callHttpResponse($application)
{
$reponseHttp = "\\" . $application->url->page['name'] . 'HttpReponse';
//FIXME:
//Le passage par le contructeur dans le cas d'une instanciation dynamique ne fonctionne pas
//$reponse = new $reponseHttp($application->url, $application->http->getData());
//il faut passer par une fonction personnelle permettant l'instanciation des variables
$reponse = new $reponseHttp();
$reponse->instanciate($application->url, $application->http->getData());
$method = strtolower($application->http->method);
$this->vue = new VueVide();
ob_start();
$reponse->$method();
$this->vue->ecran = ob_get_clean();
return;
}
}

View file

@ -0,0 +1,33 @@
<?php
namespace MVC\Classe;
class ControlleurAction
{
public static function inserer($action, $data = array())
{
$action = explode('.', $action);
$class = ucfirst($action[0]) . "Action";
//echo $class;
if (is_file(ACTION_PATH . DIRECTORY_SEPARATOR . $class . ".php")) {
require_once ACTION_PATH . DIRECTORY_SEPARATOR . $class . ".php";
$slot = new $class();
if (isset($action[1])) {
$method = $action[1];
return $slot->$method($data);
} else {
return $slot->default($data);
}
} else {
/*HandleError*/
}
}
}

View file

@ -7,7 +7,11 @@ class Dumper{
public static function dump($var){
echo "<pre>";
print_r($var);
if (is_bool($var)) {
echo ($var) ? "true" : "false";
} else {
print_r($var);
}
echo "</pre>";
}

View file

@ -4,11 +4,11 @@
namespace MVC\Classe;
class Request
class HttpMethod
{
public $method;
public $data;
protected $data;
public function __construct()
{
@ -26,11 +26,11 @@ class Request
case 'PUT':
//$this->data['GET'] = ...
//POST DATA except enctype="multipart/form-data"
$this->data['POST'] = json_decode(file_get_contents("php://input"), true);
$this->data = json_decode(file_get_contents("php://input"), true);
case 'DELETE':
//$this->data['GET'] = ...
//POST DATA except enctype="multipart/form-data"
$this->data['POST'] = json_decode(file_get_contents("php://input"), true);
$this->data = json_decode(file_get_contents("php://input"), true);
break;
default:
// Requête invalide

View file

@ -40,10 +40,13 @@ namespace MVC\Classe;
*
* @package MVC\Classe
*/
class Response
class HttpMethodRequete
{
protected $url;
protected $options;
protected $method;
protected $data;
protected $content;
/**
* Response multi-constructor.
@ -85,7 +88,7 @@ class Response
public function __construct2($url, $method)
{
$this->url = $url;
$this->method = $method;
// utilisez 'http' même si vous envoyez la requête sur https:// ...
$this->options = array(
'http' => array(
@ -102,28 +105,57 @@ class Response
return $this;
}
public function setGetParamsUrl($url, $params = array())
{
$this->url = $url . (strpos($url, '?') ? '&' : '?') . http_build_query($params);
return $this;
}
public function get($params = array())
{
return $this->replaceContext('GET')->addContent($params)->send();
}
/*
public function setGetParamsUrl($url, $params = array())
{
$this->url = $url . (strpos($url, '?') ? '&' : '?') . http_build_query($params);
return $this;
}
*/
public function send()
{
$context = stream_context_create($this->options);
$result = file_get_contents($this->url, false, $context);
if ($result === FALSE) {
/* Handle error */
// /** Pour utiliser ce code il faut mettre la variable allow_furl_open a ON dans php.ini */
//
// ob_start();
// Dumper::dump($this->options);
// Dumper::dump($this->url);
// $text = ob_get_clean();
// Logger::addLog('fopen',$text);
//
// $context = stream_context_create($this->options);
// $result = file_get_contents($this->url, false, $context);
// if ($result === FALSE) {
// /* Handle error */
// return false;
// } else {
// return true;
// }
$curl_cmd = "curl -i -X $this->method -H 'Content-Type: application/json' -d '$this->content' $this->url";
/** Pour utiliser ce code il faut utiliser la variable curl.cainfo dans php.ini */
Logger::addLog('curl', $curl_cmd);
$curl = curl_init($this->url);
//curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $this->method);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($this->data));
$response = curl_exec($curl);
curl_close($curl);
if (!$response) {
return false;
} else {
return true;
}
/** Pour utiliser ce code il faut mettre la variable safe_mode a ON dans php.ini */
//exec($curl_cmd);
}
/**
@ -131,23 +163,21 @@ class Response
*/
public function addContent($data)
{
//Exemple
//$this->data = array('name' => 'PEC', 'description' => 'Pencil 2H', 'price' => '2.25', 'category' => '9');
//'content' => http_build_query($data)
if (is_array($data)) {
$pContent = http_build_query($data);
}
$this->options['http']['content'] = $data;
$this->data = $data;
$this->content = json_encode($data);
$this->options['http']['content'] = http_build_query($data);
return $this;
}
public function replaceContext($method)
{
$this->method = $method;
return $this->createContext($method);
}
public function createContext($method)
{
$this->method = $method;
// utilisez 'http' même si vous envoyez la requête sur https:// ...
$this->options = array(
'http' => array(
@ -158,6 +188,11 @@ class Response
return $this;
}
public function get($params = array())
{
return $this->replaceContext('GET')->addContent($params)->send();
}
public function post($params = array())
{
return $this->replaceContext('POST')->addContent($params)->send();

View file

@ -0,0 +1,27 @@
<?php
namespace MVC\Classe\Implement;
class Action
{
public function render($view, $data)
{
//ob_start();
$paths = new \SplPriorityQueue;
$paths->insert(VIEW_PATH . DIRECTORY_SEPARATOR . "system", 100);
$paths->insert(VIEW_PATH . DIRECTORY_SEPARATOR . "layout", 200);
$paths->insert(VIEW_PATH . DIRECTORY_SEPARATOR . "view", 300);
$renderer = new \Windwalker\Renderer\BladeRenderer($paths, array('cache_path' => VIEW_PATH . DIRECTORY_SEPARATOR . "cache"));
return $renderer->render($view, $data);
//return ob_get_clean();
}
}

View file

@ -5,13 +5,20 @@ namespace MVC\Classe\Implement;
use MVC\Classe\Implement\Contrat\HttpReponseInterface;
class HttpReponse implements HttpReponseInterface
class HttpReponse extends Action implements HttpReponseInterface
{
public $url;
public $params;
public $data;
/**
* Le passage par le contructeur dans le cas d'une instanciation dynamique ne fonctionne pas
* http://www.thedarksideofthewebblog.com/appel-dynamique-de-constructeur-en-php/
* il faut passer par une fonction personnelle permettant l'instanciation des variables
* @param $url
* @param $requestData
*/
public function __contruct($url, $requestData)
{
$this->url = $url;
@ -19,6 +26,13 @@ class HttpReponse implements HttpReponseInterface
$this->data = $requestData;
}
public function instanciate($url, $requestData)
{
$this->url = $url;
$this->params = $url->page['params'];
$this->data = $requestData;
}
public function put()
{

View file

@ -3,19 +3,36 @@
namespace MVC\Classe\Implement;
use MVC\Classe\Dumper;
use MVC\Classe\Url;
use MVC\Classe\HttpMethod;
use MVC\Classe\Implement\Contrat\RestReponseInterface;
class HttpReponse implements RestReponseInterface
class RestReponse implements RestReponseInterface
{
public $url;
public $params;
public $data;
/**
* Le passage par le contructeur dans le cas d'une instanciation dynamique ne fonctionne pas
* http://www.thedarksideofthewebblog.com/appel-dynamique-de-constructeur-en-php/
* il faut passer par une fonction personnelle permettant l'instanciation des variables
* @param $url
* @param $requestData
*/
public function __contruct($url, $requestData)
{
$this->url = $url;
$this->params = $url['params'];
$this->params = $url->page['params'];
$this->data = $requestData;
}
public function instanciate($url, $requestData)
{
$this->url = $url;
$this->params = $url->page['params'];
$this->data = $requestData;
}

View file

@ -0,0 +1,25 @@
<?php
namespace MVC\Classe;
use Symfony\Component\Validator\Constraints\Date;
class Logger
{
static function addLog($type = 'default', $what = "")
{
$file = LOG_PATH . DIRECTORY_SEPARATOR . 'app.' . $type . '.log';
$browser = new Browser();
$date = date("F j, Y, g:i a");
$what = PHP_EOL . '[' . $date . ' by ' . $browser->user . ']' . PHP_EOL . $browser->userAgent . PHP_EOL . $what;
if (is_file($file)) {
file_put_contents($file, PHP_EOL . $what, FILE_APPEND | LOCK_EX);
} else {
file_put_contents($file, $what);
}
}
}

View file

@ -10,7 +10,8 @@ class Url
public $registre;
public function __construct(){
public function __construct($method, $appRequest)
{
//on créé le registre des modules symfony
$this->registre = new \MVC\Classe\ModularRegister();
@ -77,11 +78,33 @@ class Url
if($page['control']){
$pageFile = TRAITEMENT_PATH . DIRECTORY_SEPARATOR . $page['name'] . '.php';
}else {
$pageFile = CONTROLLERS_PATH . DIRECTORY_SEPARATOR . $page['name'] . '.php';
//recherche du fichier controlleur correpondant HTTP1.1 ou HTTP1.0
switch ($method) {
//cas des requètes HTTP1.1
case 'PUT':
case 'DELETE':
case 'GET':
case 'POST':
if ($appRequest) {
$page['name'] = ucfirst($page['name']);
$pageFile = CONTROLLER_PATH . DIRECTORY_SEPARATOR . $page['name'] . 'HttpReponse.php';
} else {
$page['name'] = lcfirst($page['name']);
$pageFile = CONTROLLERS_PATH . DIRECTORY_SEPARATOR . $page['name'] . '.php';
if (!file_exists($pageFile)) {
$page['name'] = ucfirst($page['name']);
$pageFile = CONTROLLER_PATH . DIRECTORY_SEPARATOR . $page['name'] . 'HttpReponse.php';
}
}
}
}
if(!file_exists($pageFile)){
$page['name'] = 'error';
if (!file_exists($pageFile)) {
if ($appRequest) {
$page['name'] = 'error';
} else {
$page['name'] = 'Error';
}
}
$this->page = $page;
@ -115,4 +138,22 @@ class Url
return '/' . 'control' . '/' . $page . $stringParams;
}
static public function absolute_link_rewrite($isControlPatern, $page, $params = array())
{
$url = $_SERVER['HTTP_HOST'];
if ($isControlPatern) {
$uri = self::controlLink_rewrite($page, $params);
} else {
$uri = self::link_rewrite_slashParam($page, $params);
}
if (isset($_SERVER['REQUEST_SCHEME'])) {
$scheme = $_SERVER['REQUEST_SCHEME'];
} else {
$scheme = 'http';
}
return ($scheme . "://" . $url . $uri);
}
}

View file

@ -0,0 +1,15 @@
<?php
namespace MVC\Classe;
class VueVide
{
public $ecran;
public function __construct()
{
}
}

View file

@ -4,6 +4,7 @@ define("MODULES_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "modules");
define("CONTROLLERS_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . "controlleurs");
define("CONFIG_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "config");
define("LOG_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "logs");
define("ACTION_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . "actions");
define("MODELS_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . "modeles");
define("VIEW_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . "vues");
define("CONTROLLER_PATH", APPLICATION_PATH . DIRECTORY_SEPARATOR . "include" . DIRECTORY_SEPARATOR . "controlleurs");

View file

@ -0,0 +1,67 @@
<?php
use MVC\Classe\HttpMethodRequete;
use MVC\Classe\Implement\Action;
use MVC\Classe\Url;
use MVC\Classe\Response;
class DefaultAction extends Action
{
public function default($data)
{
/**your action algorythm**/
if (isset($data[0])) {
$var1 = $data[0];
} else {
$var1 = 1;
}
if (isset($data[1])) {
$var2 = $data[1];
} else {
$var2 = 2;
}
if (isset($data[2])) {
$var3 = $data[2];
} else {
$var3 = 3;
}
return $this->render('action', array('var1' => $var1, 'var2' => $var2, 'var3' => $var3));
}
public function variableSlug($data)
{
/**your action algorythm**/
if (isset($data[0])) {
$var1 = $data[0];
} else {
$var1 = 1;
}
if (isset($data[1])) {
$var2 = $data[1];
} else {
$var2 = 2;
}
if (isset($data[2])) {
$var3 = $data[2];
} else {
$var3 = 3;
}
return $this->render('action', array('var1' => $var1, 'var2' => $var2, 'var3' => $var3));
}
public function makeHttp11($data)
{
$data = array('myval' => 25);
$request = new HttpMethodRequete();
//$request->setUrl(Url::absolute_link_rewrite(false,'accueil',['var10'=>'val10']))->get($data);
//$request->setUrl(Url::absolute_link_rewrite(false,'accueil',['var10'=>'val10']))->post($data);
$request->setUrl(Url::absolute_link_rewrite(false, 'accueil', ['var10' => 'val10']))->put($data);
//$request->setUrl(Url::absolute_link_rewrite(false,'accueil',['var10'=>'val10']))->delete($data);
}
}

View file

@ -1,16 +0,0 @@
<?php
use MVC\Classe\Implement\HttpReponse;
class AcceuilHttpReponse extends HttpReponse
{
public function put()
{
echo $this->params . "<br/>" . $this->data;
}
public function delete()
{
}
}

View file

@ -0,0 +1,45 @@
<?php
use MVC\Classe\Dumper;
use MVC\Classe\Implement\RestReponse;
use MVC\Classe\Logger;
class AccueilHttpReponse extends RestReponse
{
public function put()
{
ob_start();
Dumper::dump($this->params);
Dumper::dump($this->data);
$text = ob_get_clean();
Logger::addLog('put', '____Hello Put____' . PHP_EOL . $text);
}
public function delete()
{
ob_start();
Dumper::dump($this->params);
Dumper::dump($this->data);
$text = ob_get_clean();
Logger::addLog('delete', '____Hello Delete:____' . PHP_EOL . $text);
}
public function get()
{
ob_start();
Dumper::dump($this->params);
Dumper::dump($this->data);
$text = ob_get_clean();
Logger::addLog('get', '____Hello GET____' . PHP_EOL . $text);
}
public function post()
{
ob_start();
Dumper::dump($this->params);
Dumper::dump($this->data);
$text = ob_get_clean();
Logger::addLog('post', '____Hello POST____' . PHP_EOL . $text);
}
}

View file

@ -0,0 +1,27 @@
<?php
use MVC\Classe\Implement\RestReponse;
use MVC\Classe\Logger;
class ErrorHttpReponse extends RestReponse
{
public function put()
{
Logger::addLog('put', 'Error PUT');
}
public function delete()
{
Logger::addLog('delete', 'Error DELETE');
}
public function get()
{
Logger::addLog('get', 'Error GET');
}
public function post()
{
Logger::addLog('post', 'Error POST');
}
}

View file

@ -1,2 +1,7 @@
<?php
$templateData = array("templating_a"=>'blade',"templating_b"=>'twig',"templating_c"=>'edge');
use MVC\Classe\Logger;
$templateData = array("templating_a"=>'blade',"templating_b"=>'twig',"templating_c"=>'edge');
Logger::addLog('ok', 'Hello world');

View file

@ -13,5 +13,10 @@
<hr/>
{{$templating_a}}::{{$templating_b}}::{{$templating_c}}
{{\MVC\Classe\ControlleurAction::inserer('default',[])}}
{{\MVC\Classe\ControlleurAction::inserer('default.default',[4,5,6])}}
{{\MVC\Classe\ControlleurAction::inserer('default.variableSlug',['var1','var2','var3'])}}
{{\MVC\Classe\ControlleurAction::inserer('default.makeHttp11',[])}}
@endsection

View file

@ -0,0 +1 @@
{{$var1}}::{{$var2}}::{{$var3}}

View file

@ -12,6 +12,8 @@
"require": {
"php": "^7.1.3",
"ext-json": "*",
"ext-curl": "*",
"windwalker/renderer": "3.*",
"illuminate/view": "4.*",
"hybridauth/hybridauth": "~3.0"