HelloCSE/resources/views/webrouteslist.php
2024-04-10 19:31:01 +02:00

665 lignes
Pas d'EOL
30 Kio
PHP

<?php
// Pourquoi pas Blade ? Parce que cette documentation doit rester fonctionnelle quoi qu'il en coûte.
// Si elle s'affiche, alors vos fichiers de routage sont correctement écris : elle sert aussi de validation du routing.
// Pourquoi pas de dépendances lié à l'architecture et du CSS en ligne par exemple : exactement pour les mêmes raisons : on s'affranchit totalement du moteur de Laravel en cas de souci, on ne respecte que le routeur.
use App\Http\Utility\routeCollector;
$wr = new routeCollector();
$routes = $wr->getRoutes('web');
$menu='';
$body='';
// Tris des routes
function sortRoutes($a, $b){
return strnatcmp($a['api'], $b['api']);
}
usort($routes, 'sortRoutes');
function GenerateLinks($key,$apiArray){
$l='';
if (array_key_exists($key,$apiArray) && count($apiArray[$key])){
foreach ($apiArray[$key] as $api){
preg_match_all('/\w+/', $api['url'], $matches);
$link=$apiArray['api'].'-'.implode('-',$matches[0]);
$urlText=empty($api['url'])?'/':$api['url'];
$l.='<a href="#'.$link.'" class="pure-menu-link">'.$urlText.'</a>';
}
}
return $l;
}
function isSeqArray(array $array) {
return !count(array_filter(array_keys($array), 'is_string')) > 0;
}
function decodeJSONParam($params,$spacer=false,$isSequentialArray=false){
$t='';
foreach($params as $k=>$v){
if(!is_array($v)){
if(strpos($v,'[REQUIRED]')!==false)
$v=str_ireplace('[REQUIRED]','<span class="json_req">REQUIRED</span>',$v);
if(strpos($k,'!COMMENT!')!==false)
$t.='<div '.($spacer?'class="json_comm json_spacer"':'json_comm').'>// '.$v.'</div>';
else
$t.='<div '.($spacer?'class="json_spacer"':'').'><b>'.$k.'</b> : '.$v.'</div>';
}
else {
$delimiterIn='<b>{</b>';
$delimiterOut='<b>}</b>,';
$isSeq=false;
if(isSeqArray($v)){
$delimiterIn='<b>[</b>';
$delimiterOut='<b>]</b>,';
$isSeq=true;
}
$key='<b>'.$k.'</b> : ';
if($isSequentialArray)
$key='';
$t.='<div '.($spacer?'class="json_spacer"':'').'>'.$key.' '.$delimiterIn.decodeJSONParam($v,true,$isSeq).$delimiterOut.'</div>';
}
}
return $t;
}
function GenerateAnApiDoc($key,$apiArray){
$t='';
if (array_key_exists($key,$apiArray) && count($apiArray[$key])){
$t.='<h3 class="methodname">'.$key.'</h3>';
foreach ($apiArray[$key] as $api){
preg_match_all('/\w+/', $api['url'], $matches);
$link=$apiArray['api'].'-'.implode('-',$matches[0]);
$t.='<p id="'.$link.'" class="apiurl">'.$apiArray['api'].'/'.$api['url'].'</p>';
// description principale
if(array_key_exists('desc',$api)){
$t.='<p class="maindesc">'.$api['desc'].'</p>';
}
// paramètre de chemin
if (array_key_exists('params',$api) && count($api['params'])){
$t.='<h4 class="paramtitle">Paramètre du chemin</h4>';
$t.='<div class="paramsarray pmheader">
<div class="paramalias">Paramètre</div>
<div class="paramformat">Format (PCRE regex)</div>
<div class="paramdesc">Description</div>
</div>';
foreach ($api['params'] as $pathparam=>$pathRgx){
$desc='';
if(array_key_exists('params_desc',$api) && array_key_exists($pathparam,$api['params_desc']))
$desc='<div class="paramdesc">'.$api['params_desc'][$pathparam].'</div>';
$t.='<div class="paramsarray">
<div class="paramalias">'.$pathparam.'</div>
<div class="paramformat"><a target="_blank" href="https://regex101.com/?regex='.$pathRgx.'">'.$pathRgx.'</a></div>
'.$desc.'
</div>';
}
}
// paramètre d'URL
if ($key==='get' && array_key_exists('get_params',$api) && count($api['get_params'])){
$t.='<h4 class="paramtitle">Paramètre d\'URL</h4>';
$t.='<div class="paramsarray pmheader">
<div class="paramalias">Nom du paramètre</div>
<div class="paramformat">Format (PCRE regex ou JSON(string))</div>
<div class="paramdesc">Description</div>
</div>';
foreach ($api['get_params'] as $paramAlias=>$paramRgx){
$desc='';
if(array_key_exists('get_params_desc',$api) && array_key_exists($paramAlias,$api['get_params_desc']))
$desc='<div class="paramdesc">'.$api['get_params_desc'][$paramAlias].'</div>';
$t.='<div class="paramsarray">
<div class="paramalias">'.$paramAlias.'</div>
<div class="paramformat"><a target="_blank" href="https://regex101.com/?regex='.$paramRgx.'">'.$paramRgx.'</a></div>
'.$desc.'
</div>';
}
}
// paramètre optionnels d'URL
if ($key==='get' && array_key_exists('opt_get_params',$api) && count($api['opt_get_params'])){
$t.='<h4 class="paramtitle">Paramètre optionnels d\'URL</h4>';
$t.='<div class="paramsarray pmheader">
<div class="paramalias">Nom du paramètre</div>
<div class="paramformat">Format (PCRE regex ou JSON(string))</div>
<div class="paramdesc">Description</div>
</div>';
foreach ($api['opt_get_params'] as $paramAlias=>$paramRgx){
$desc='';
if(array_key_exists('get_params_desc',$api) && array_key_exists($paramAlias,$api['get_params_desc']))
$desc='<div class="paramdesc">'.$api['get_params_desc'][$paramAlias].'</div>';
$t.='<div class="paramsarray">
<div class="paramalias">'.$paramAlias.'</div>
<div class="paramformat"><a target="_blank" href="https://regex101.com/?regex='.$paramRgx.'">'.$paramRgx.'</a></div>
'.$desc.'
</div>';
}
}
// paramètre de POST, PATCH et DELETE
if (($key==='post' || $key==='patch' || $key==='delete') && array_key_exists('post_params',$api) && count($api['post_params'])){
$t.='<h4 class="paramtitle">Paramètres</h4>';
$t.='<div class="paramsarray pmheader">
<div class="paramalias">Nom du paramètre</div>
<div class="paramformat">Format (PCRE regex ou JSON(string))</div>
<div class="paramdesc">Description</div>
</div>';
foreach ($api['post_params'] as $paramAlias=>$paramRgx){
$desc='';
if($paramRgx!=='JSON' && array_key_exists('post_params_desc',$api) && array_key_exists($paramAlias,$api['post_params_desc'])){
$desc='<div class="paramdesc">'.$api['post_params_desc'][$paramAlias].'</div>';
if(strpos($desc,'[REQUIRED]')!==false)
$desc=str_ireplace('[REQUIRED]','<span class="json_req">REQUIRED</span>',$desc);
}
if($paramRgx==='JSON')
$desc='<div class="paramdesc">'.decodeJSONParam($api['post_params_desc'][$paramAlias]).'</div>';
$t.='<div class="paramsarray">
<div class="paramalias">'.$paramAlias.'</div>
<div class="paramformat"><a target="_blank" href="https://regex101.com/?regex='.$paramRgx.'">'.$paramRgx.'</a></div>
'.$desc.'
</div>';
}
}
// paramètre optionnels de POST ET PATCH
if (($key==='post' || $key==='patch' /* || $key==='delete' */) && array_key_exists('opt_post_params',$api) && count($api['opt_post_params'])){
$t.='<h4 class="paramtitle">Paramètres optionnels</h4>';
$t.='<div class="paramsarray pmheader">
<div class="paramalias">Nom du paramètre</div>
<div class="paramformat">Format (PCRE regex ou JSON(string))</div>
<div class="paramdesc">Description</div>
</div>';
foreach ($api['opt_post_params'] as $paramAlias=>$paramRgx){
$desc='';
if($paramRgx!=='JSON' && array_key_exists('post_params_desc',$api) && array_key_exists($paramAlias,$api['post_params_desc']))
$desc='<div class="paramdesc">'.$api['post_params_desc'][$paramAlias].'</div>';
if($paramRgx==='JSON')
$desc='<div class="paramdesc">'.decodeJSONParam($api['post_params_desc'][$paramAlias]).'</div>';
$t.='<div class="paramsarray">
<div class="paramalias">'.$paramAlias.'</div>
<div class="paramformat"><a target="_blank" href="https://regex101.com/?regex='.$paramRgx.'">'.$paramRgx.'</a></div>
'.$desc.'
</div>';
}
}
}
}
return $t;
}
if(is_array($routes)){
foreach ($routes as $api){
$get=GenerateLinks('get',$api);
$post=GenerateLinks('post',$api);
$patch=GenerateLinks('patch',$api);
$delete=GenerateLinks('delete',$api);
$menu.='
<a class="pure-menu-heading" href="#'.$api['api'].'">'.$api['api'].'/</a>
<ul class="pure-menu-list">';
if(!empty($get)){
$menu.='
<li class="pure-menu-item">
<div class="menuparttitle">GET</div>
'.$get.'
</li>
';
}
if(!empty($post)){
$menu.='
<li class="pure-menu-item">
<div class="menuparttitle">POST</div>
'.$post.'
</li>
';
}
if(!empty($patch)){
$menu.='
<li class="pure-menu-item">
<div class="menuparttitle">PATCH</div>
'.$patch.'
</li>
';
}
if(!empty($delete)){
$menu.='
<li class="pure-menu-item">
<div class="menuparttitle">DELETE</div>
'.$delete.'
</li>
';
}
$menu.='</ul>';
$body.='
<h2 id="'.$api['api'].'" class="content-subhead">'.$api['api'].'</h2>
<div class="apiblock">
';
$body.=GenerateAnApiDoc('get',$api);
$body.=GenerateAnApiDoc('post',$api);
$body.=GenerateAnApiDoc('patch',$api);
$body.=GenerateAnApiDoc('delete',$api);
$body.='
</div>
';
}
}
$html='
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>API ROUTES</title>
<link rel="stylesheet" href="https://unpkg.com/purecss@1.0.1/build/pure-min.css" integrity="sha384-oAOxQR6DkCoMliIh8yFnu25d7Eq/PHS21PClpwjOTeU2jRSq11vu66rf90/cZr47" crossorigin="anonymous"><link rel="stylesheet"
href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/styles/default.min.css">
<style>
body{color:#777}.pure-img-responsive{max-width:100%;height:auto}#layout,#menu,.menu-link{-webkit-transition:all .2s ease-out;-moz-transition:all .2s ease-out;-ms-transition:all .2s ease-out;-o-transition:all .2s ease-out;transition:all .2s ease-out}#layout{position:relative;left:0;padding-left:0}#layout.active #menu{left:150px;}#layout.active .menu-link{left:150px}.content{margin:0 auto;padding:0 2em;max-width:800px;margin-bottom:50px;line-height:1.6em}.header{margin:0;color:#333;text-align:center;padding:2.5em 2em 0;border-bottom:1px solid #eee}.header h1{margin:.2em 0;font-size:3em;font-weight:300}.header h2{font-weight:300;color:#ccc;padding:0;margin-top:0}.content-subhead{margin:50px 0 20px 0;font-weight:300;color:#888}#menu{margin-left:-150px;position:fixed;top:0;left:0;bottom:0;z-index:1000;background:#191818;overflow-y:auto;-webkit-overflow-scrolling:touch}#menu a{color:#999;border:none;padding: 0.2em 0.5em;}#menu .pure-menu,#menu .pure-menu ul{border:none;background:0 0}#menu .pure-menu .menu-item-divided,#menu .pure-menu ul{border-top:1px solid #333}#menu .pure-menu li a:focus,#menu .pure-menu li a:hover{background:#333}#menu .pure-menu-heading,#menu .pure-menu-selected{background:#1f8dd6}#menu .pure-menu-selected a{color:#fff}#menu .pure-menu-heading{font-size:110%;color:#fff;margin:0}.menu-link{position:fixed;display:block;top:0;left:0;background:#000;background:rgba(0,0,0,.7);font-size:10px;z-index:10;width:2em;height:auto;padding:2.1em 1.6em}.menu-link:focus,.menu-link:hover{background:#000}.menu-link span{position:relative;display:block}.menu-link span,.menu-link span:after,.menu-link span:before{background-color:#fff;width:100%;height:.2em}.menu-link span:after,.menu-link span:before{position:absolute;margin-top:-.6em;content:" "}.menu-link span:after{margin-top:.6em}@media (min-width:48em){.content,.header{padding-left:2em;padding-right:2em}#layout{padding-left:150px;left:0}#menu{left:150px}.menu-link{position:fixed;left:150px;display:none}#layout.active .menu-link{left:150px}}@media (max-width:48em){#layout.active{position:relative;left:150px}}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
font-size: 14px;
}
#menu {
position: absolute;
left: 0;
width: 17em;
margin: 0;
top: 0;
bottom: 0;
overflow: auto;
}
#main {
position: absolute;
left: 17em;
right: 0;
top: 0;
bottom: 0;
overflow: auto;
}
.menuparttitle {
color: #fff;
padding: 0.2em 0.5em;
}
#menu a {
overflow-wrap: break-word;
display: block;
white-space: break-spaces;
}
.content {
max-width: initial;
}
.content-subhead {
background: #1f8dd6;
color: #fff;
padding: 0.3em 0.25em;
margin-bottom: 0;
}
.apiblock {
padding: 0.8em 0 0.8em 0.8em;
}
.maindesc {
text-indent: 20px;
color: #333;
font-size: 0.9em;
background: #f4f4f4;
border-radius: 0.3em;
margin: 0.5em 0 !important;
border: 1px solid #eaeaea;
}
.methodname {
text-transform: uppercase;
border-bottom: 1px solid #D6D6D6;
color: #737373;
padding-bottom: 0.25em;
font-size: 1.5em;
}
.apiurl {
font-family: monospace;
background: #6292b2;
padding: 0 0.25em;
font-weight: bold;
font-size: 1.1em;
margin-top: 1.2em !important;
color: #fff;
}
.content p {
margin: 0.3em 0;
}
.paramtitle {
margin: 0.3em 0;
padding-left: 0.5em;
color: #535353;
}
.paramsarray {
display: flex;
font-size: 0.9em;
padding: 0 0.5em;
}
.paramsarray.pmheader {
background: #d2e2ee;
font-weight: bold;
}
.paramalias {
font-weight: bold;
color: #535353;
width: 10em;
}
.paramformat {
width: 20em;
overflow-wrap: break-word;
}
.paramdesc {
}
.json_spacer {
padding-left: 2em;
}
.json_comm {
color: #1abb02;
font-weight: bold;
font-style: italic;
}
.json_req {
color: #ff0000;
font-weight: bold;
}
#menu .pure-menu ul {
display: none;
}
#menu .pure-menu ul.visible {
display: block;
background: #002843;
}
#menu .pure-menu-heading {
position : relative;
border-bottom: 1px solid #176fa9;
}
#menu .pure-menu-heading.home::after {
display:none;
}
#menu .pure-menu-heading::after {
content: "\2BC8";
position: absolute;
right: 3px;
}
#menu .pure-menu-heading.open::after {
content: "\2BC6";
}
.deploybox {
height: 32px;
overflow: hidden;
margin: 1em 0;
}
.deploybox.open {
height: auto;
}
.deploybtn {
background: #1f8dd6;
color: #fff;
cursor: pointer;
padding: 0 0.5em;
display: inline-block;
height: 32px;
line-height: 32px;
}
</style>
</head>
<body>
<div id="menu">
<div class="pure-menu">
<a class="pure-menu-heading home" href="#home">🏠</a>
'.$menu.'
</div>
</div>
<div id="main">
<div id="home" class="header">
<h1>API</h1>
<h2>Routes disponibles</h2>
</div>
<div class="content">
<h3>Syntax d\'un fichier route</h3>
<p>Le fichier route doit être nommé web.routes.php et doit être placé à la racine du controlleur concerné.</p>';
$html.="
<div class='deploybox'>
<div class='deploybtn'>Voir la syntaxe</div>
<pre><code class=\"lang-php\">return [
// nom de l'API et préfixe de l'URL, est unique au système
'api'=>'apiname'
// namespace de la classe publique
,'class'=>'public\\class\\namespace'
// Les possibles restrictions d'accès au groupe de route (FACULTATIF). Tous les routes de tous les types seront restreint par les accès utilisateur
// Restrictions possibles :
// - sys_admin : administrateur système
// - admin : administrateur client
,'restrictions'=>['sys_admin','admin']
// Les routes GET (pour l'obtention de donnée)
,'get'=>[
[
// Description de la route
'desc'=>'La description détaillée de la route',
// Les possibles restrictions d'accès à la route (FACULTATIF). La route sera restreinte par les accès utilisateur
// Restrictions possibles :
// - sys_admin : administrateur système
// - admin : administrateur client
,'restrictions'=>['sys_admin','admin']
// Reste de l'URL
'url'=>'{dynamicparam}/path/to/something'
// méthode de la classe publique que ça atteindra
,'method'=>'methodName'
// paramètres dynamiques du path de l'URL, et l'expression régulière de contrôle du paramètre
,'params'=>[
'dynamicparam' =>'[PCRE REGEX]',
]
// description des paramètres dynamiques du path de l'URL
,'params_desc'=>[
'dynamicparam' =>'Un paramètre dynamique'
]
// paramètres requis de l'URL (ie mon/url?param=paramvalue)
,'get_params'=>[
'param' =>'[PCRE REGEX]'
]
// paramètres facultatifs de l'URL
,'opt_get_params'=>[
'param2' =>'[PCRE REGEX]'
]
// description des paramètres de l'URL
,'get_params_desc'=>[
'param' =>'description de param',
'param2' =>'description de param2'
]
],
]
// Les routes POST (pour la création d'éléments uniquement)
,'post'=>[
[
// Description de la route
'desc'=>'La description détaillée de la route',
// Les possibles restrictions d'accès à la route (FACULTATIF). La route sera restreinte par les accès utilisateur
// Restrictions possibles :
// - sys_admin : administrateur système
// - admin : administrateur client
,'restrictions'=>['sys_admin','admin']
// Reste de l'URL
'url'=>'{dynamicparam}/path/to/something'
// méthode de la classe publique que ça atteindra
,'method'=>'methodName'
// paramètres dynamiques du path de l'URL, et l'expression régulière de contrôle du paramètre
,'params'=>[
'dynamicparam' =>'[PCRE REGEX]',
]
// description des paramètres dynamiques du path de l'URL
,'params_desc'=>[
'dynamicparam' =>'Un paramètre dynamique'
]
// Paramètre du POST
,'post_params'=>[
'param' =>'[PCRE REGEX ou \"JSON\"]',
'jsonex' =>'[PCRE REGEX ou \"JSON\"]',
]
// Paramètres optionnels du POST
,'opt_post_params'=>[
'param2' =>'[PCRE REGEX ou \"JSON\"]'
]
// description des paramètres du POST
,'post_params_desc'=>[
'param' =>'description de param',
'param2' =>'description de param2',
'jsonex' =>'Un tableau PHP représentant l\'objet JSON',
]
],
]
// Les routes PATCH (pour la mise à jour d'éléments uniquement)
,'patch'=>[
[
// Description de la route
'desc'=>'La description détaillée de la route',
// Les possibles restrictions d'accès à la route (FACULTATIF). La route sera restreinte par les accès utilisateur
// Restrictions possibles :
// - sys_admin : administrateur système
// - admin : administrateur client
,'restrictions'=>['sys_admin','admin']
// Reste de l'URL
'url'=>'{dynamicparam}/path/to/something'
// méthode de la classe publique que ça atteindra
,'method'=>'methodName'
// paramètres dynamiques du path de l'URL, et l'expression régulière de contrôle du paramètre
,'params'=>[
'dynamicparam' =>'[PCRE REGEX ou \"JSON\"]',
]
// description des paramètres dynamiques du path de l'URL
,'params_desc'=>[
'dynamicparam' =>'Un paramètre dynamique'
]
// Paramètre du PATCH
,'post_params'=>[
'param' =>'[PCRE REGEX]'
]
// Paramètres optionnels du PATCH
,'opt_post_params'=>[
'param2' =>'[PCRE REGEX ou \"JSON\"]'
'jsonex' =>'[PCRE REGEX ou \"JSON\"]',
]
// description des paramètres du PATCH
,'post_params_desc'=>[
'param' =>'description de param',
'param2' =>'description de param2'
'jsonex' =>'Un tableau PHP représentant l\'objet JSON',
]
],
]
// Les routes DELETE (pour la suppression d'éléments uniquement)
,'delete'=>[
[
// Description de la route
'desc'=>'La description détaillée de la route',
// Les possibles restrictions d'accès à la route (FACULTATIF). La route sera restreinte par les accès utilisateur
// Restrictions possibles :
// - sys_admin : administrateur système
// - admin : administrateur client
,'restrictions'=>['sys_admin','admin']
// Reste de l'URL
'url'=>'{dynamicparam}/path/to/something'
// méthode de la classe publique que ça atteindra
,'method'=>'methodName'
// paramètres dynamiques du path de l'URL, et l'expression régulière de contrôle du paramètre
,'params'=>[
'dynamicparam' =>'[PCRE REGEX]',
]
// description des paramètres dynamiques du path de l'URL
,'params_desc'=>[
'dynamicparam' =>'Un paramètre dynamique'
]
// Paramètre du DELETE
,'post_params'=>[
'param' =>'[PCRE REGEX]'
]
// Paramètres optionnels du DELETE
,'opt_post_params'=>[
'param2' =>'[PCRE REGEX]'
]
// description des paramètres du DELETE
,'post_params_desc'=>[
'param' =>'description de param',
'param2' =>'description de param2'
]
],
]
];</code></pre>
</div>";
$html.=' </div>
<div class="content">'.$body.'</div>
</div>
<script src="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.18.1/highlight.min.js"></script>
<script>
// load HighLightJS
hljs.initHighlightingOnLoad();
const menuLinks=document.querySelectorAll("#menu .pure-menu > a.pure-menu-heading")
const foldAll=()=>{
console.log("la")
let bloc=document.querySelector("#menu .pure-menu > ul.visible")
if(bloc)
bloc.classList.remove("visible");
let link=document.querySelector("#menu .pure-menu > a.pure-menu-heading.open")
if(link)
link.classList.remove("open");
}
menuLinks.forEach((link)=>{
link.addEventListener("click",()=>{
if(link.classList.contains("open")){
foldAll();
return;
}
foldAll();
link.classList.add("open")
link.nextElementSibling.classList.add("visible")
});
});
const deployers=document.querySelectorAll(".deploybtn")
deployers.forEach((btn)=>{
btn.addEventListener("click",()=>{
btn.parentElement.classList.toggle("open")
});
});
</script>
</body>
</html>
';
echo $html;