Merge pull Github

This commit is contained in:
Emmanuel ROY 2021-12-12 15:42:05 +01:00
commit 10bc015688
43 changed files with 1154 additions and 154 deletions

View File

@ -1,4 +1,7 @@
SAND-FRAMEWORK for Modular-Applications
# SAND-FRAMEWORK for Modular-Applications
---
---
Cette architecture MVC Objet est composée d'un moteur de template (Blade ou Twig)
@ -6,14 +9,18 @@ Les urls d'accès sont de type www.domain.tld/le_nom_de_mapage/varname1/varvalue
Afin de créer une nouvelle page vous devez instancier trois fichiers contenant diverses variables, dont voici les adresses:
application > include > controlleurs > le_nom_de_mapage.php contenant:
---
les commandes permettant de gérer un formulaire
un ou plusieurs accès à la base de données
des variables instanciées dans le tableau $templateData permettant l'affichage dans la vue blade ou twig
`application > include > controlleurs > le_nom_de_mapage.php` contenant:
- les commandes permettant de gérer un formulaire
- un ou plusieurs accès à la base de données
- des variables instanciées dans le tableau `$templateData` permettant l'affichage dans la vue blade ou twig
application > include > modeles > le_nom_de_mapage.model contenant les variables spécifiques à la page de l'application. soit par exemple:
---
`application > include > modeles > le_nom_de_mapage.model` contenant
les variables spécifiques à la page de l'application. soit par exemple:
```
name : le_nom_de_mapage
page_title : le title du head de la page html rendue
description : ma description pour les moteurs de recherche
@ -22,13 +29,19 @@ authentification : no
ariane : {acceuil, test d'acceuil}
arianelink : {index, le_nom_de_mapage}
paramsN : paramètre(s) supplémentaire(s)
```
avec en plus de cela :
`engine : blade` pour un layout blade ou `engine : twig` pour un layout twig
avec en plus de cela : engine : blade pour un layout blade ou engine : twig pour un layout twig
---
application > include > vues > view > le_nom_de_mapage.blade.php contenant le layout blade a instancier application > include > vues > view > le_nom_de_mapage.html.twig contenant le layout twig a instancier
`application > include > vues > view > le_nom_de_mapage.blade.php` contenant le layout `blade` a instancier
`application > include > vues > view > le_nom_de_mapage.html.twig` contenant le layout `twig` a instancier
Vous pouvez aussi tout à fait utiliser la commande:
> Vous pouvez aussi tout à fait utiliser la commande:
>
> `php console/bin.php page:add`
php console/bin.php page:add
Pour les modules, c'est un peu plus compliqué : il faut instancier ces trois précédents fichiers en faisant appel la class Modular, ne pas oublier de référencer le module dans le dossier modules > setup > registre.model, ajouter le dossier contenant le code du module et faire correspondre le nom du controlleur frontal du module avec le registre.
Pour les modules, c'est un peu plus compliqué : il faut instancier ces trois précédents fichiers en faisant appel la class Modular,
ne pas oublier de référencer le module dans le dossier modules > setup > registre.model, ajouter le dossier contenant le code du module
et faire correspondre le nom du controlleur frontal du module avec le registre.

View File

@ -87,4 +87,41 @@ class Caracter
$chaine = str_replace('"', '', $chaine);
return $chaine;
}
public static function mettreEnMajusculeAccents($chaine, $trueAccent = false)
{
if (!$trueAccent) {
$chaine = str_replace('é', 'E', $chaine);
$chaine = str_replace('è', 'E', $chaine);
$chaine = str_replace('ë', 'E', $chaine);
$chaine = str_replace('ê', 'E', $chaine);
$chaine = str_replace('ç', 'C', $chaine);
$chaine = str_replace('Ç', 'C', $chaine);
$chaine = str_replace('à', 'A', $chaine);
// $chaine = str_replace('','&aeacute;',$chaine);
$chaine = str_replace('â', 'A', $chaine);
$chaine = str_replace('ä', 'A', $chaine);
$chaine = str_replace('î', 'I', $chaine);
$chaine = str_replace('ï', 'I', $chaine);
$chaine = str_replace('ù', 'U', $chaine);
$chaine = str_replace('û', 'U', $chaine);
$chaine = str_replace('ü', 'U', $chaine);
} else {
$chaine = str_replace('é', 'É', $chaine);
$chaine = str_replace('è', 'È', $chaine);
$chaine = str_replace('ë', 'Ë', $chaine);
$chaine = str_replace('ê', 'Ê', $chaine);
$chaine = str_replace('ç', 'Ç', $chaine);
$chaine = str_replace('Ç', 'Ç', $chaine);
$chaine = str_replace('à', 'À', $chaine);
// $chaine = str_replace('','&aeacute;',$chaine);
$chaine = str_replace('â', 'Â', $chaine);
$chaine = str_replace('ä', 'Ä', $chaine);
$chaine = str_replace('î', 'Î', $chaine);
$chaine = str_replace('ï', 'Ï', $chaine);
$chaine = str_replace('ù', 'Ù', $chaine);
$chaine = str_replace('û', 'Û', $chaine);
$chaine = str_replace('ü', 'Ü', $chaine);
}
return $chaine;
}
}

View File

@ -19,6 +19,8 @@ class Modular
break;
case "symfony":
break;
case "laravel":
break;
case "wordpress":
if (isset($options[0])) {
switch ($options[0]) {
@ -92,35 +94,69 @@ class Modular
public function load($type = "symfony")
{
ob_start();
global $buffer_sand;
switch ($type) {
case "gitlist":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . DIRECTORY_SEPARATOR . "index.php";
break;
case "symfony":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
$path = MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . DIRECTORY_SEPARATOR . "public" . DIRECTORY_SEPARATOR . "index.php";
return require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . DIRECTORY_SEPARATOR . "public" . DIRECTORY_SEPARATOR . "index.php";
break;
case "laravel":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . DIRECTORY_SEPARATOR . "public" . DIRECTORY_SEPARATOR . "index.php";
break;
case "wordpress":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . $this->subapp_dir . DIRECTORY_SEPARATOR . $this->subfile;
break;
case "prestashop":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . $this->subapp_dir . DIRECTORY_SEPARATOR . "index.php";
break;
case "phplist":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . $this->subapp_dir . DIRECTORY_SEPARATOR . "index.php";
break;
case "wanewsletter":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . $this->subapp_dir . DIRECTORY_SEPARATOR . $this->subfile;
break;
case "phpmynewsletter":
ob_start(array('\\MVC\\Classe\\Modular', 'rappel'),0,PHP_OUTPUT_HANDLER_STDFLAGS ^ PHP_OUTPUT_HANDLER_FLUSHABLE);
$level = ob_get_level();
require MODULES_PATH . DIRECTORY_SEPARATOR . $this->getAppName() . $this->subapp_dir . DIRECTORY_SEPARATOR . $this->subfile;
break;
}
$data = ob_get_contents();
ob_end_clean();
return $data;
$buffer_sand = "";
if (ob_get_level() == $level) {
if (ob_get_level() > 1) {
$buffer_sand = ob_get_contents();
ob_end_clean();
} else {
$buffer_sand = "BUFFER CLOSURE BY FRAMEWORK !<br/>".$buffer_sand;
}
}else{
$final_level = ob_get_level();
$buffer_sand = "BUFFER LEVEL $level CLOSURE $final_level BY FRAMEWORK !<br/>".$buffer_sand;
}
return $buffer_sand;
}
public static function rappel($buffer)
{
global $buffer_sand;
$buffer_sand = $buffer;
// remplace toutes les pommes par des carottes
return $buffer;
}
}

View File

@ -0,0 +1,84 @@
<?php
namespace MVC\Classe;
/**
* Class MyActionTwigExtension
* with call {{ static_call("AppBundle\Entity\YourEntity", "GetSomething", ["var1", "var2"]) }}
* other {{ action("AppBundle\Entity\YourEntity", "GetSomething", ["var1", "var2"]) }}
*
* @package MVC\Classe
*/
class TwigControlleurAction extends \Twig\Extension\AbstractExtension
{
/**
* Returns a list of functions to add to the existing list.
*
* @return \Twig\TwigFunction[]
*/
public function getFunctions() {
return array(
new \Twig\TwigFunction("action", array($this, "inserer")),
new \Twig\TwigFunction("call", array($this, "getClassMethodStatic")),
new \Twig\TwigFunction("session", array($this, "afficheSession")),
new \Twig\TwigFunction("server", array($this, "afficheServer"))
);
}
public function afficheServer($key_var = ''){
if($key_var !== ""){
if(isset($_SERVER[$key_var])) {
return $_SERVER[$key_var];
}else{
return null;
}
}else {
return $_SERVER;
}
return null;
}
public function afficheSession($key_var = ''){
if($key_var !== ""){
if(isset($_SESSION[$key_var])) {
return $_SESSION[$key_var];
}else{
return null;
}
}else {
return $_SESSION;
}
return null;
}
public static function inserer($action, $data = array())
{
//on extrait la classe d'appel de l'action
$action = explode('.', $action);
$class = ucfirst($action[0]) . "Action";
//TODO: use try ... catch with \MVC\Classe\Logger to log error
if (is_file(ACTION_PATH . DIRECTORY_SEPARATOR . $class . ".php")) {
require_once ACTION_PATH . DIRECTORY_SEPARATOR . $class . ".php";
//On charge la classe Action de façon réflextive
$slot = new $class();
//si l'action passé en parametre est fournit avec une methode pointée on charge celle demandée sinon on charge celle par defaut
if (isset($action[1])) {
$method = $action[1];
//On appel la méthode de la classe action de manière reflextive
return $slot->$method(...$data);
} else {
return $slot->default(...$data);
}
} else {
/*HandleError*/
}
}
public static function getClassMethodStatic($class, $method, $args = array())
{
return $class::$method(...$args);
}
}

View File

@ -60,6 +60,7 @@ class Vue
switch ($engine){
case 'twig':
$renderer = new \Windwalker\Renderer\TwigRenderer($paths);
$renderer->addExtension(new \MVC\Classe\TwigControlleurAction);
$name .= '.html';
break;
case 'blade':

View File

@ -1,51 +1,86 @@
<?php
use MVC\Classe\Dumper;
use MVC\Classe\HttpMethodRequete;
use MVC\Classe\Implement\Action;
use MVC\Classe\Url;
use MVC\Classe\Response;
class DefaultAction extends Action
class DefaultAction extends \MVC\Classe\Implement\Action
{
public function default()
{
/**your action algorythm**/
if (isset($data[0])) {
$var1 = $data[0];
if (isset($data1)) {
$var1 = $data1;
} else {
$var1 = 1;
}
if (isset($data[1])) {
$var2 = $data[1];
if (isset($data2)) {
$var2 = $data2;
} else {
$var2 = 2;
}
if (isset($data[2])) {
$var3 = $data[2];
if (isset($data3)) {
$var3 = $data3;
} else {
$var3 = 3;
}
return $this->render('action', array('var1' => $var1, 'var2' => $var2, 'var3' => $var3));
}
public function variableSlug($data)
public function defaultBlade($data1,$data2,$data3)
{
/**your action algorythm**/
if (isset($data[0])) {
$var1 = $data[0];
if (isset($data1)) {
$var1 = $data1;
} else {
$var1 = 1;
}
if (isset($data[1])) {
$var2 = $data[1];
if (isset($data2)) {
$var2 = $data2;
} else {
$var2 = 2;
}
if (isset($data[2])) {
$var3 = $data[2];
if (isset($data3)) {
$var3 = $data3;
} else {
$var3 = 3;
}
return $this->render('action', array('var1' => $var1, 'var2' => $var2, 'var3' => $var3),'blade');
}
public function defaultTwig($data1,$data2,$data3)
{
/**your action algorythm**/
if (isset($data1)) {
$var1 = $data1;
} else {
$var1 = 1;
}
if (isset($data2)) {
$var2 = $data2;
} else {
$var2 = 2;
}
if (isset($data3)) {
$var3 = $data3;
} else {
$var3 = 3;
}
return $this->render('action', array('var1' => $var1, 'var2' => $var2, 'var3' => $var3),'twig');
}
public function variableSlug($data1,$data2,$data3)
{
/**your action algorythm**/
if (isset($data1)) {
$var1 = $data1;
} else {
$var1 = 1;
}
if (isset($data2)) {
$var2 = $data2;
} else {
$var2 = 2;
}
if (isset($data3)) {
$var3 = $data3;
} else {
$var3 = 3;
}
@ -58,10 +93,10 @@ class DefaultAction extends Action
$data = array('myval' => 25);
//Dumper::dump($data);
\MVC\Classe\Logger::addLog('action', 'http11 make request');
$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);
$request = new \MVC\Classe\HttpMethodRequete();
$request->setUrl(\MVC\Classe\Url::absolute_link_rewrite(false, 'accueil', ['var10'=>'val10']))->get($data);
$request->setUrl(\MVC\Classe\Url::absolute_link_rewrite(false, 'accueil', ['var10'=>'val10']))->post($data);
$request->setUrl(\MVC\Classe\Url::absolute_link_rewrite(false, 'accueil', ['var10'=>'val10']))->put($data);
$request->setUrl(\MVC\Classe\Url::absolute_link_rewrite(false, 'accueil', ['var10'=>'val10']))->delete($data);
}
}

View File

@ -26,8 +26,8 @@ class DocConduit extends Conduit
asort($files);
$this->templateData['page_title'] = 'Foo';
$this->templateData['description'] = 'DocConduit';
$this->templateData['page_title'] = 'Sommaire de la documentation du Framework';
$this->templateData['description'] = 'Sommaire, Documentation, SAND, Framework';
$this->templateData['files'] = $files;
return $this->render('docs', $this->templateData);
@ -37,13 +37,39 @@ class DocConduit extends Conduit
public function readfile()
{
\MVC\Object\Session::createAndTestSession();
$files = array();
if ($handle = opendir(DATA_PATH . '/docs')) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
$files[] = $entry;
}
}
closedir($handle);
}
asort($files);
$key_file = array_search($this->file,$files);
$markdown = file_get_contents(DATA_PATH . '/docs/' . $this->file);
$my_html = MarkdownExtra::defaultTransform($markdown);
$this->templateData['page_title'] = 'Foo';
$this->templateData['description'] = 'DocConduit';
$this->templateData['page_title'] = 'Documentation du Framework';
$this->templateData['description'] = 'Documentation, SAND, Framework';
$this->templateData['data'] = $my_html;
if(isset($files[$key_file - 1])) {
$this->templateData['previous'] = $files[$key_file - 1];
}
if(isset($files[$key_file + 1])) {
$this->templateData['next'] = $files[$key_file + 1];
}
return $this->render('docs', $this->templateData);

View File

@ -2,7 +2,7 @@ name : index
page_title : Accueil de l'application
description : zatou stra bracadabla
engine : blade
engine : twig
authentification : yes
ariane : {acceuil}

View File

@ -1,3 +1,4 @@
{% extends "system.html.twig" %}
{% block body %}
<!-- Body Inner -->
@ -7,11 +8,12 @@
style="background: rgba(0, 0, 0, 0.59);">
<div class="container">
<ul class="top-menu">
<li {% if name == 'docs_route' || name == 'docs_name_route' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', []) }}">Documentation</a></li>
<li {% if name == 'depots' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'gitlist/SAND-FrameWork', []) }}">Dépot</a></li>
<li {% if name == 'donate' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Donate', []) }}">Donate</a></li>
<li {% if name == 'cgu' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'CGU', []) }}"> CGU Terms</a></li>
<li {% if name == 'policy' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Policy', []) }}">Policy</a></li>
{{call('\\MVC\\Object\\Environment','getTextEnvironment',[]) | raw}}
<li {% if name == 'docs_route' or name == 'docs_name_route' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'docs', []]) }}">Documentation</a></li>
<li {% if name == 'depots' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'gitlist/SAND-FrameWork', []]) }}">Dépot</a></li>
<li {% if name == 'donate' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Donate', []]) }}">Donate</a></li>
<li {% if name == 'cgu' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'CGU', []]) }}"> CGU Terms</a></li>
<li {% if name == 'policy' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Policy', []]) }}">Policy</a></li>
</ul>
</div>
</div>
@ -38,8 +40,8 @@
<!--end: logo-->
<nav>
<ul>
<li {% if name == 'index' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Index', []) }}">Index</a></li>
<li {% if name == 'admin' %} class="actual" {% endif %} ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Admin', []) }}">Admin</a></li>
<li {% if name == 'index' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[false, 'Index', []]) }}">Index</a></li>
<li {% if name == 'admin' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[false, 'Admin', []]) }}">Admin</a></li>
</ul>
</nav>
</div>
@ -52,24 +54,43 @@
<!-- Subbar -->
<div id="subbar" class="fullwidth">
<div class="container">
<span style="float:left;">Vous êtes connecté en tant que {{$_SESSION['user_login']}}</span>
<span style="float:right;"><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Logout', []) }}">Se Deconnecter</a></span>
<span style="float:left;">Vous êtes connecté en tant que {{session('user_login')}}</span>
<span style="float:right;"><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Logout', []]) }}">Se Deconnecter</a></span>
</div>
</div>
<!-- end: Subbar -->
<!-- Breadcrumbs -->
{%if ariane is defined %}
<div id="breadcrumbs" class="fullwidth">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
{% for value in ariane %}
{% if value == ariane|last %}
<li class="breadcrumb-item active" aria-current="page">{{value}}</li>
{% else %}
<li class="breadcrumb-item"><a href="{{call("\\MVC\\Classe\\Url","link_rewrite",[false,arianelink[value.index],[] ])}}">{{value}}</a></li>
{% endif %}
{% endfor %}
</ol>
</nav>
</div>
</div>
{% endif %}
<section id="page-content">
<div class="container">
<!--Alerts-->
{% if $_SESSION['alerts'] is defined %}
{% foreach $_SESSION['alerts'] as alert %}
{% if not session('alerts') == null %}
{% for alert in session('alerts') %}
<div class="alert alert-{{alert.type}} alert-dismissible fade show" role="alert">
<strong>{{alert.title}}</strong> {{alert.message}}.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endforeach %}
{% endfor %}
{% endif %}
<!--end: Alerts-->
{% block content %}{% endblock %}
</div>
@ -84,7 +105,7 @@
<div class="widget">
<div class="widget-title"></div>
<p class="mb-5">
<img src="{{ \MVC\Classe\Url::asset_rewrite('assets/img/1007698-ffeb3b.svg') }}" width="150">
<img src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/img/1007698-ffeb3b.svg']) }}" width="150">
</p>
</div>
</div>
@ -116,4 +137,4 @@
</div>
<!-- end: Body Inner -->
{% endblock %}}
{% endblock %}

View File

@ -27,29 +27,29 @@
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
{% block top-css %}
<link rel="stylesheet" href="{{ \MVC\Classe\Url::asset_rewrite('assets/bootstrap-5.0.0-beta1-dist/css/bootstrap.min.css')}}">
<link rel="stylesheet" href="{{ \MVC\Classe\Url::asset_rewrite('assets/css/custom.css')}}">
{% block topCss %}
<link rel="stylesheet" href="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/bootstrap-5.0.0-beta1-dist/css/bootstrap.min.css'])}}">
<link rel="stylesheet" href="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/css/custom.css'])}}">
{% endblock %}
{% endblock %}
</head>
<body>
{% block top-javascript %}{% endblock %}
{% block topJavascript %}{% endblock %}
{% block body %}{% endblock %}
{% block bottom-javascript %}
<script src="{{ \MVC\Classe\Url::asset_rewrite('assets/bootstrap-5.0.0-beta1-dist/js/bootstrap.min.js')}}"></script>
<script src="{{ \MVC\Classe\Url::asset_rewrite('assets/js/custom.js')}}"></script>
{% block bottomJavascript %}
<script src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/bootstrap-5.0.0-beta1-dist/js/bootstrap.min.js'])}}"></script>
<script src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/js/custom.js'])}}"></script>
/*
{#
SCRIPT JS permettant de ne valider qu'une seule fois un formulaire
ATTENTION tous les formulaires sont affecté
Lors d'une validation bootstrap personnalisé veuillez utilisé
la class do-resubmit sur le formulaire afin de permettre
l'activation supplémentaire du bouton.
*/
#}
<script>
window.onload = function() {
let PreventAllforms = document.querySelectorAll("form");

View File

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

View File

@ -6,14 +6,22 @@
@section('content')
@if (isset($files))
<h1>Sommaire:</h1>
@foreach( $files as $file)
<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', ['file'=>$file]) }}">{{ $file }}</a> <br/>
@endforeach
@endif
@if (isset($data))
<div style="display:block;position:relative;width:450px;margin:auto;">
@if (isset($previous))<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', ['file'=>$previous]) }}" class="btn btn-outline-info"> &laquo; Précedent</a>@endif
<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', []) }}" class="btn btn-info">Sommaire</a>
@if (isset($next))<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', ['file'=>$next]) }}" class="btn btn-outline-info">Suivant &raquo; </a>@endif
</div>
{{$data}}
<div style="display:block;position:relative;width:450px;margin:auto;">
@if (isset($previous))<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', ['file'=>$previous]) }}" class="btn btn-outline-info"> &laquo; Précedent</a>@endif
<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', []) }}" class="btn btn-info">Sommaire</a>
@if (isset($next))<a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', ['file'=>$next]) }}" class="btn btn-outline-info">Suivant &raquo; </a>@endif
</div>
@endif
@endsection

View File

@ -14,7 +14,7 @@
{{$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.defaultBlade',[4,5,6])}}
{{\MVC\Classe\ControlleurAction::inserer('default.variableSlug',['var1','var2','var3'])}}
@endsection

View File

@ -1 +1,10 @@
INDEX
{% extends "body.html.twig" %}
{% block content %}
<h1>Accueil de l'url</h1>
<h2> {{server('SERVER_NAME')}}</h2>
<br /><br /><br />
<hr/>
{{templating_a}}::{{templating_b}}::{{templating_c}}
{{ action('default.defaultTwig',[4,5,6]) }}
{% endblock %}

View File

@ -0,0 +1,8 @@
<?php
\MVC\Object\Session::createAndTestSession();
\MVC\Object\Alert::addAlert('OK','This is an alert !','info');
header('location:'.\MVC\Classe\Url::link_rewrite(false, "index", []));

View File

@ -22,16 +22,30 @@ class Module
public static function add()
{
print "adding module...\n\n";
print "Quel est le module a ajouter ?\n1.Symfony\n2.Wordpress\n3.Prestashop\n4.PhpList\n5.Wanewsletter\n6.PHPmyNewletter\n>";
print "Quel est le module a ajouter ?\n0.Laravel\n1.Symfony\n2.Wordpress\n3.Prestashop\n4.PhpList\n5.Wanewsletter\n6.PHPmyNewletter\n>";
$module = trim(fgets(STDIN));
switch ($module) {
case 0:
print "Quel est le nom du module laravel à ajouter (default : laravel) ? ";
$name = trim(fgets(STDIN));
if ($name !== '' && preg_match('#(.)+#', $name)) {
Module::addLaravel($name);
} else {
Module::addLaravel('symfony');
}
break;
case 1:
print "Quel est le nom du module symfony à ajouter (default : symfony) ? ";
$name = trim(fgets(STDIN));
print "Quel est la version de Symfony à ajouter (default : 4.4) ? ";
$version = trim(fgets(STDIN));
if ($version == '' && !preg_match('#(.)\.(.)\.(.)\.(.)#', $version)) {
$version = "4.4";
}
if ($name !== '' && preg_match('#(.)+#', $name)) {
Module::addSymfony($name);
Module::addSymfony($name,$version);
} else {
Module::addSymfony('symfony');
Module::addSymfony('symfony',$version);
}
break;
case 2:
@ -117,33 +131,86 @@ class Module
}
}
private static function addSymfony($name = 'symfony')
private static function addLaravel($name = 'laravel')
{
$git_clone = shell_exec('cd '.MODULES_PATH.' && composer create-project symfony/website-skeleton '.$name);
$git_clone = shell_exec('cd '.MODULES_PATH.' && composer create-project laravel/laravel '.$name);
print $git_clone;
$git_chmod = shell_exec('sudo chmod 775 '.MODULES_PATH.'/'.$name.' -R');
$git_chmod = shell_exec('chmod 775 '.MODULES_PATH.'/'.$name.' -R');
print $git_chmod;
$git_chown = shell_exec('sudo chown acksop:www-data '.MODULES_PATH.'/'.$name.' -R');
$git_chown = shell_exec('chown acksop:www-data '.MODULES_PATH.'/'.$name.' -R');
print $git_chown;
$git_controlleur = shell_exec('cp '.CONSOLE_PATH.'/skel/module_symfony.php '.CONTROLLERS_PATH.'/'.$name.'.php');
$git_controlleur = shell_exec('cp '.CONSOLE_PATH.'/skel/module.laravel.php '.CONTROLLERS_PATH.'/'.$name.'.php');
$controlleur = file_get_contents(CONTROLLERS_PATH.'/'.$name.'.php');
$controlleur = preg_replace('%MODULE%', $name, $controlleur);
$controlleur = preg_replace('/%%MODULE_NAME%%/', $name, $controlleur);
$controlleur = preg_replace('/%%MODULE%%/', 'laravel', $controlleur);
file_put_contents(CONTROLLERS_PATH.'/'.$name.'.php', $controlleur);
print $git_controlleur;
$git_modele = shell_exec('cp '.CONSOLE_PATH.'/skel/module.model '.MODELS_PATH.'/'.$name.'.model');
$git_modele = shell_exec('cp '.CONSOLE_PATH.'/skel/module.laravel.model '.MODELS_PATH.'/'.$name.'.model');
$modele = file_get_contents(MODELS_PATH.'/'.$name.'.model');
$modele = preg_replace('%MODULE%', $name, $modele);
$modele = preg_replace('/%%MODULE_NAME%%/', $name, $modele);
$modele = preg_replace('/%%MODULE%%/', 'laravel', $modele);
file_put_contents(MODELS_PATH.'/'.$name.'.model', $modele);
print $git_modele;
$git_view = shell_exec('cp '.CONSOLE_PATH.'/skel/module.blade.php '.VIEW_PATH.'/view/'.$name.'.blade.php');
$git_view = shell_exec('cp '.CONSOLE_PATH.'/skel/module.laravel.html.twig '.VIEW_PATH.'/view/'.$name.'.blade.php');
$vue = file_get_contents(VIEW_PATH.'/view/'.$name.'.html.twig');
$vue = preg_replace('/%%MODULE_NAME%%/', $name, $vue);
$vue = preg_replace('/%%MODULE%%/', 'laravel', $vue);
file_put_contents(VIEW_PATH.'/view/'.$name.'.html.twig', $vue);
print $git_view;
//stabilize symfony application
//print "stabilize symfony module...\n\n";
//$symfony_module = shell_exec('cp '.CONSOLE_PATH.'/skel/symfony-app/* '.MODULES_PATH.'/'.$name.' -Rf');
//$symfony_composer = shell_exec('cd '.MODULES_PATH.'/'.$name.' && composer update');
print "\n\nN'oubliez pas d'ajouter au fichier '/application/modules/setup/registre.model' :"
."\n'.$name.' : Application permettant d'intégrer un module avec symfony"
."\n "
."\n et de créer la base de données!\n";
}
public static function removeLaravel($name = 'laravel')
{
$git_clone = system('rm -Rf '.MODULES_PATH.'/'.$name, $git_clone_retval);
print $git_clone_retval;
$git_controlleur = system('rm -f '.CONTROLLERS_PATH.'/'.$name.'.php', $git_controlleur_retval);
print $git_controlleur_retval;
$git_modele = system('rm -f '.MODELS_PATH.'/'.$name.'.model', $git_modele_retval);
print $git_modele_retval;
$git_view = system('rm -f '.VIEW_PATH.'/view/'.$name.'.html.twig', $git_view_retval);
print $git_view_retval;
}
private static function addSymfony($name = 'symfony',$version="4.4")
{
$git_clone = shell_exec('cd '.MODULES_PATH.' && composer create-project symfony/website-skeleton:"^'.$version.'" '.$name);
print $git_clone;
$git_chmod = shell_exec('chmod 775 '.MODULES_PATH.'/'.$name.' -R');
print $git_chmod;
$git_chown = shell_exec('chown acksop:www-data '.MODULES_PATH.'/'.$name.' -R');
print $git_chown;
$git_controlleur = shell_exec('cp '.CONSOLE_PATH.'/skel/module.symfony.php '.CONTROLLERS_PATH.'/'.$name.'.php');
$controlleur = file_get_contents(CONTROLLERS_PATH.'/'.$name.'.php');
$controlleur = preg_replace('/%%MODULE_NAME%%/', $name, $controlleur);
$controlleur = preg_replace('/%%MODULE%%/', 'symfony', $controlleur);
file_put_contents(CONTROLLERS_PATH.'/'.$name.'.php', $controlleur);
print $git_controlleur;
$git_modele = shell_exec('cp '.CONSOLE_PATH.'/skel/module.symfony.model '.MODELS_PATH.'/'.$name.'.model');
$modele = file_get_contents(MODELS_PATH.'/'.$name.'.model');
$modele = preg_replace('/%%MODULE_NAME%%/', $name, $modele);
$modele = preg_replace('/%%MODULE%%/', 'symfony', $modele);
file_put_contents(MODELS_PATH.'/'.$name.'.model', $modele);
print $git_modele;
$git_view = shell_exec('cp '.CONSOLE_PATH.'/skel/module.symfony.blade.php '.VIEW_PATH.'/view/'.$name.'.blade.php');
$vue = file_get_contents(VIEW_PATH.'/view/'.$name.'.blade.php');
$vue = preg_replace('%MODULE%', 'symfony', $vue);
$vue = preg_replace('/%%MODULE_NAME%%/', $name, $vue);
$vue = preg_replace('/%%MODULE%%/', 'symfony', $vue);
file_put_contents(VIEW_PATH.'/view/'.$name.'.blade.php', $vue);
print $git_view;
//stabilize symfony application
include dirname(__FILE__) . DIRECTORY_SEPARATOR . 'Symfony.php';
$symfony_composer = shell_exec('cd '.MODULES_PATH.'/'.$name.' && composer update');
//print "stabilize symfony module...\n\n";
//$symfony_module = shell_exec('cp '.CONSOLE_PATH.'/skel/symfony-app/* '.MODULES_PATH.'/'.$name.' -Rf');
//$symfony_composer = shell_exec('cd '.MODULES_PATH.'/'.$name.' && composer update');
print "\n\nN'oubliez pas d'ajouter au fichier '/application/modules/setup/registre.model' :"
."\n'.$name.' : Application permettant d'intégrer un module avec symfony"

View File

@ -0,0 +1 @@
{{ subcall( app, 'load', ['%%MODULE%%'] ) | raw }}

View File

@ -0,0 +1,7 @@
{% extends "body.html.twig" %}
{% block content %}
{{ subcall( app, 'load', ['%%MODULE%%'] ) | raw }}
{% endblock %}

View File

@ -0,0 +1,8 @@
name : %%MODULE_NAME%%
page_title : module_title
description : module_description
engine : twig
authentification : no
ariane : {%%MODULE%%}
arianelink : {%%MODULE_NAME%%}

View File

@ -0,0 +1,3 @@
<?php
$app = new MVC\Classe\Modular($name, '%%MODULE%%', $url_params);
$templateData = array('app' => $app);

View File

@ -1,6 +1,6 @@
name : %%MODULE%%
name : %%MODULE_NAME%%
page_title : module_title
description : module_description
ariane : {%%MODULE%%}
arianelink : {%%MODULE%%}
arianelink : {%%MODULE_NAME%%}

View File

@ -0,0 +1,5 @@
@extends('body')
@section('content')
{{$app->load('%%MODULE%%')}}
@endsection

View File

@ -0,0 +1,8 @@
name : %%MODULE_NAME%%
page_title : module_title
description : module_description
engine : blade
authentification : no
ariane : {%%MODULE%%}
arianelink : {%%MODULE_NAME%%}

View File

@ -0,0 +1,3 @@
<?php
$app = new MVC\Classe\Modular($name, '%%MODULE%%', $url_params);
$templateData = array('app' => $app);

View File

@ -1,4 +1,4 @@
{% extends "base.html" %}
{% extends "body.html.twig" %}
{% block top-css %}
{{ parent() }}

View File

@ -1,10 +1,16 @@
#Les étapes de configurations de SAND
il vous faut modifier quelques valeurs dans des fichiers de configuration
- `application/config/app-parameters.php`
- `application/config/bdd-parameters.php`
il vous faut modifier quelques valeurs dans les fichiers de configuration suivant
- `application/config/app-parameters.php.skel`
- `application/config/bdd-parameters.php.skel`
Les autres fichiers contenus dans config servent pour la branche dev
et enlever l'extension `.skel` afin que l'autoload de composer puisse le prendre en compte
Dans le cas où vous voudriez utiliser les conduits vous devrez modifier le fichier `application/config/files/routing.yml`.
Vous pouvez tester une application de base simple en générant le dossier vendor en vous mettant à la racine de l'application et en lançant
`composer update`. Si votre serveur est correctement configurer pour pointer dans le dossier public sur l'index, vous devriez obtenir une application de test avec les fonctionnalités de base. En triturant un peu les fichier contenus dans le dossier `application/include` vous devriez comprendre comment se contruit une application faites avec SAND.
Les autres fichiers contenus dans config servent pour la branche dev, mais peuvent aussi servir pour votre application.
Dans le cas où vous choissisez d'utiliser les conduits lors du développement de votre application,
vous devrez modifier le fichier `application/config/files/routing.yml`.

View File

@ -12,6 +12,6 @@ où {page} est le nom :
- Du modèle contenu dans `/application/include/modeles/{page}.model`
- De la vue contenue dans `/application/include/vues/view/{page}.blade.php` ou `/application/include/vues/view/{page}.html.twig` suivant le moteur de rendu
...
Vous pouvez ainsi récupérer les variables passées en GET dans le contrôlleur depuis `$url_params['varname1']`
Dautres types durls peuvent être mises en place par la configuration du routing symfony et des conduits, il faut alors renseigner les informations de routage dans le fichier `/application/config/files/routing.yml` et faire correspondre lurl daccès au Conduit.

View File

@ -1 +1,18 @@
#Comment bien utiliser les commandes dans le framework SAND
#Comment bien utiliser les commandes dans le framework SAND
Les commandes console du framework sont toutes documentée par l'appel de la méthode help
Par exemple pour voir les méthodes associés à la commande page vous pourvez lancer la commande suivante depuis le dossier console:
`php bin.php page:help`
et vous verrez les différentes méthodes qui y sont associées.
Typiquement sur un projet on peut soit ajouter les fichiers manuellement quand on a l'habitude, soit aussi profiter des commandes:
`action`,`conduit`,`module` et `page`
Si vous avez a videz le cache des vues et des logs vous pouvez utiliser la commande
`php bin.php cache:clear`
quand a
`php bin.php cache:stabilize`
vous permet de vider le cache des vues blade et/ou twig

View File

@ -0,0 +1,14 @@
# Comment fonctionnent les objets de sessions
le dossier `application/objets` contient les classes qui sont utilisés par les sessions, vous trouverez dans ce dossier les classes suivantes:
- `Session.php` qui contient les méthodes permettant de créer les sessions, dans une application moderne il est courant de définir des droits sur les pages par un système d'authentification, ici SAND ne déroge pas à la règle et dans les fichiers .model possèdent une variable `authentification` qui peut prendre les valeurs `yes` ou `no`, ainsi le framework appelera automatiquement la méthode `createAndTestSession()` dans les controlleurs, si cette variable est défini à `no`, alors seule la méthode `sessionStart()` sera appelée, ceci afin que les alertes et l'historique puissent fonctionner.
Malheureusement les conduits et les traitements ne disposent pas d'un tel garde d'authentification, mais vous comprendrez qu'il est simple d'ajouter cette méthode au début d'un code de traitement ou de conduit.
- `Alert.php` contient quelques méthodes simples qui utilise la variable `$_SESSION`, elle est vidée a chaque génération de page sauf dans le cas des traitements, ainsi automatiquement une alerte peut être définie à afficher sur la page de redirection
- `History.php` permet d'obtenir à tout moment la page précédente de l'application, ainsi il est plus simple de rediriger les pages de traitement vers la page qui demande le traitement. Souvent dans les applications modernes vous avez un traitement qui doit être effectué depuis plusieurs pages cela permet de connaitre celle dont on provient sans passer par la variable serveur `$_SERVER["HTTP_REFERER"]` qui n'est pas toujours accessible.
- `XssToken.php` permet de définir un token dans la variable `$_SESSION` afin de protéger les formulaires de l'application contre la faille XSS.
Néanmoins il est possible que ce dossier contienne d'autres classes qui peuvent être utile, à vous de le fournir suivant les demandes de votre application.

View File

@ -0,0 +1,7 @@
#Comment faire évoluer une application écrite avec le framework SAND ?
Tout dabord, une fois lapplication créé, toutes les ressources sont téléchargée par composer et le fichier composer.lock est garant de la stabilité des dépôts auxquels lapplication fait appel. Donc normalement il ne sera pas nécessaire de faire évoluer ces ressources.
Néanmoins passer vers une nouvelle version de php par exemple de la 5.6 à la 8 nécessite des connaissances évolué des fonctions dépréciées entre les versions de PHP. SAND framework est php 8 ready, néanmoins certaines lib ne fonctionne que sur php7.3, mais celles-ci une fois installée ne changeront pas au cours du temps car elles sont directement accessibles depuis le dossier vendor.
Si vous utilisez les SPA vues.js, pensez à télécharger la version que vous utilisez afin de stabiliser votre application dans le temps, afin qu'elle ne consomme pas des ressources inutiles depuis le web.

View File

@ -8,6 +8,9 @@ name : name
page_title : Page de l'application
description : Description de la page
engine : blade
authentification : no
ariane : {acceuil, name}
arianelink : {index, name}
params1 : {val1,val2}
params2 : val
```

View File

@ -8,7 +8,222 @@ Elles sont chargées dans cette ordre:
ainsi la vue standard peut étendre de `application/include/vues/layout/body.html.twig`
```php
{% extends "system.html.twig" %}
{% block body %}
<!-- Body Inner -->
<div class="body-inner">
<!-- Topbar -->
<div id="topbar" class="d-none d-xl-block d-lg-block topbar-transparent topbar-fullwidth dark"
style="background: rgba(0, 0, 0, 0.59);">
<div class="container">
<ul class="top-menu">
{{call('\\MVC\\Object\\Environment','getTextEnvironment',[]) | raw}}
<li {% if name == 'docs_route' or name == 'docs_name_route' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'docs', []]) }}">Documentation</a></li>
<li {% if name == 'depots' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'gitlist/SAND-FrameWork', []]) }}">Dépot</a></li>
<li {% if name == 'donate' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Donate', []]) }}">Donate</a></li>
<li {% if name == 'cgu' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'CGU', []]) }}"> CGU Terms</a></li>
<li {% if name == 'policy' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Policy', []]) }}">Policy</a></li>
</ul>
</div>
</div>
<!-- end: Topbar -->
<!-- Header -->
<header id="header" class="dark" data-transparent="true" data-fullwidth="true"
style="background: rgba(0, 0, 0, 0.59);">
<div class="header-inner">
<div class="container">
<!--Navigation Resposnive Trigger-->
<div id="mainMenu-trigger">
<a class="lines-button x"><span class="lines"></span></a>
</div>
<!--end: Navigation Resposnive Trigger-->
<!--Navigation-->
<div id="mainMenu">
<div class="container">
<!--Logo-->
<div id="logo">
<a href="#">
SAND Framework
</a>
</div>
<!--end: logo-->
<nav>
<ul>
<li {% if name == 'index' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[false, 'Index', []]) }}">Index</a></li>
<li {% if name == 'admin' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[false, 'Admin', []]) }}">Admin</a></li>
<li {% if name == 'laravel' %} class="actual" {% endif %} ><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[false, 'Laravel', []]) }}">Module Laravel</a></li>
</ul>
</nav>
</div>
</div>
<!--end: Navigation-->
</div>
</div>
</header>
<!-- end: Header -->
<!-- Subbar -->
<div id="subbar" class="fullwidth">
<div class="container">
<span style="float:left;">Vous êtes connecté en tant que {{session('user_login')}}</span>
<span style="float:right;"><a href="{{ call("\\MVC\\Classe\\Url","link_rewrite",[ false, 'Logout', []]) }}">Se Deconnecter</a></span>
</div>
</div>
<!-- end: Subbar -->
<!-- Breadcrumbs -->
{%if ariane is defined %}
<div id="breadcrumbs" class="fullwidth">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
{% for value in ariane %}
{% if value == ariane|last %}
<li class="breadcrumb-item active" aria-current="page">{{value}}</li>
{% else %}
<li class="breadcrumb-item"><a href="{{call("\\MVC\\Classe\\Url","link_rewrite",[false,arianelink[value.index],[] ])}}">{{value}}</a></li>
{% endif %}
{% endfor %}
</ol>
</nav>
</div>
</div>
{% endif %}
<section id="page-content">
<div class="container">
<!--Alerts-->
{% if not session('alerts') == null %}
{% for alert in session('alerts') %}
<div class="alert alert-{{alert.type}} alert-dismissible fade show" role="alert">
<strong>{{alert.title}}</strong> {{alert.message}}.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
{% endif %}
<!--end: Alerts-->
{% block content %}{% endblock %}
</div>
</section>
<!-- Footer -->
<footer id="footer">
<div class="footer-content">
<div class="container">
<div class="row">
<div class="col-lg-3">
<div class="widget">
<div class="widget-title"></div>
<p class="mb-5">
<img src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/img/1007698-ffeb3b.svg']) }}" width="150">
</p>
</div>
</div>
<div class="col-lg-9">
<p>
SAND FrameWork is an CC-licensed or MIT-licenced open source project and completely free to use.
</p>
<p>
However, the amount of effort needed to maintain and develop new features for the project is not
sustainable without proper financial backing.
You can support its ongoing development by being a backer or a sponsor on
<a href="https://www.patreon.com/">Patreon campaign</a>
(recurring, with perks for different tiers), and get your company logo here.
</p>
<p>
Also, you can make a <a href="https://www.paypal.me/">one time donation via PayPal</a>.
</p>
</div>
</div>
</div>
<div class="copyright-content">
<div class="container">
<div class="copyright-text text-center">&copy; 2020-2021 Built with SAND Framework - Responsive SAND Template.</div>
</div>
</div>
</div>
</footer>
<!-- end: Footer -->
</div>
<!-- end: Body Inner -->
{% endblock %}
```
qui étends de `application/include/vues/system/system.html.twig`
```php
<!DOCTYPE html>
<html>
<head>
{% block head %}
<title>{{page_title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" lang="fr" content="{{description}}"/>
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
{% block topCss %}
<link rel="stylesheet" href="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/bootstrap-5.0.0-beta1-dist/css/bootstrap.min.css'])}}">
<link rel="stylesheet" href="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/css/custom.css'])}}">
{% endblock %}
{% endblock %}
</head>
<body>
{% block topJavascript %}{% endblock %}
{% block body %}{% endblock %}
{% block bottomJavascript %}
<script src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/bootstrap-5.0.0-beta1-dist/js/bootstrap.min.js'])}}"></script>
<script src="{{ call("\\MVC\\Classe\\Url","asset_rewrite",['assets/js/custom.js'])}}"></script>
{#
SCRIPT JS permettant de ne valider qu'une seule fois un formulaire
ATTENTION tous les formulaires sont affecté
Lors d'une validation bootstrap personnalisé veuillez utilisé
la class do-resubmit sur le formulaire afin de permettre
l'activation supplémentaire du bouton.
#}
<script>
window.onload = function() {
let PreventAllforms = document.querySelectorAll("form");
Array.prototype.slice.call(PreventAllforms)
.forEach(function (PreventForm) {
PreventForm.onsubmit = submitted.bind(PreventForm);
});
}
function submitted(event) {
if (event.target.classList.contains('do-resubmit')) {
event.submitter.disabled = false;
}else{
event.submitter.disabled = true;
}
}
</script>
{% endblock %}
</body>
</html>
```

View File

@ -8,43 +8,250 @@ Elles sont chargées dans cette ordre:
ainsi la vue standard peut étendre de `application/include/vues/layout/body.blade.php`
```php
@extends('system')
@section('body')
@section('sidebar')
This is the master sidebar.
@show
<div class="container">
@yield('content')
</div>
@extends('system')
@section('body')
<!-- Body Inner -->
<div class="body-inner">
<!-- Topbar -->
<div id="topbar" class="d-none d-xl-block d-lg-block topbar-transparent topbar-fullwidth dark"
style="background: rgba(0, 0, 0, 0.59);">
<div class="container">
<ul class="top-menu">
{{\MVC\Object\Environment::getTextEnvironment()}}
<li @if($name == 'docs_route' || $name == 'docs_name_route') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'docs', []) }}">Documentation</a></li>
<li @if($name == 'depots') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'gitlist/SAND-FrameWork', []) }}">Dépot</a></li>
<li @if($name == 'donate') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Donate', []) }}">Donate</a></li>
<li @if($name == 'cgu') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'CGU', []) }}"> CGU Terms</a></li>
<li @if($name == 'policy') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Policy', []) }}">Policy</a></li>
<li @if($name == 'feedback') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Feedback', []) }}">Feedback</a></li>
</ul>
</div>
</div>
<!-- end: Topbar -->
<!-- Header -->
<header id="header" class="dark" data-transparent="true" data-fullwidth="true"
style="background: rgba(0, 0, 0, 0.59);">
<div class="header-inner">
<div class="container">
<!--Navigation Resposnive Trigger-->
<div id="mainMenu-trigger">
<a class="lines-button x"><span class="lines"></span></a>
</div>
<!--end: Navigation Resposnive Trigger-->
<!--Navigation-->
<div id="mainMenu">
<div class="container">
<!--Logo-->
<div id="logo">
<a href="#">
SAND Framework
</a>
</div>
<!--end: logo-->
<nav>
<ul>
<li @if($name == 'index') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Index', []) }}">Index</a></li>
<li @if($name == 'admin') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Admin', []) }}">Admin</a></li>
<li @if($name == 'symfony4_4') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Symfony4_4', []) }}"> Module Symfony 4.4</a></li>
<li @if($name == 'symfony5_1') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Symfony5_1', []) }}"> Module Symfony 5.1</a></li>
<li @if($name == 'symfony5_2') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Symfony5_2', []) }}"> Module Symfony 5.2</a></li>
<li @if($name == 'symfony5_3') class="actual" @endif ><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Symfony5_3', []) }}"> Module Symfony 5.3</a></li>
</ul>
</nav>
</div>
</div>
<!--end: Navigation-->
</div>
</div>
</header>
<!-- end: Header -->
<!-- Subbar -->
@if(isset($authentification) && $authentification == 'yes')
<div id="subbar" class="fullwidth">
<div class="container">
<span style="float:left;">Vous êtes connecté en tant que {{$_SESSION['user_login']}}</span>
<span style="float:right;"><a href="{{ \MVC\Classe\Url::link_rewrite( false, 'Logout', []) }}">Se Deconnecter</a></span>
</div>
</div>
@endif
<!-- end: Subbar -->
<!-- Breadcrumbs -->
@if (isset($ariane))
<div id="breadcrumbs" class="fullwidth">
<div class="container">
<nav aria-label="breadcrumb">
<ol class="breadcrumb-sand">
@foreach($ariane as $value)
@if($value == end($ariane))
<li class="breadcrumb-item active" aria-current="page">{{$value}}</li>
@else
<li class="breadcrumb-item"><a href="{{\MVC\Classe\Url::link_rewrite(false,$arianelink[array_search($value,$ariane)])}}">{{$value}}</a></li>
@endif
@endforeach
</ol>
</nav>
</div>
</div>
@endif
<!-- end: BreadCrumbs -->
<section id="page-content">
<div class="container">
<!--Alerts-->
@if(isset($_SESSION['alerts']))
@foreach($_SESSION['alerts'] as $alert)
<div class="alert alert-{{$alert['type']}} alert-dismissible fade show" role="alert">
<strong>{{$alert['title']}}</strong> {{$alert['message']}}.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
@endforeach
@endif
<!--end: Alerts-->
@yield('content')
</div>
</section>
<!-- Footer -->
<footer id="footer">
<div class="footer-content">
<div class="container">
<div class="row">
<div class="col-lg-3">
<div class="widget">
<div class="widget-title"></div>
<p class="mb-5">
<img src="{{ \MVC\Classe\Url::asset_rewrite('assets/img/1007698-ffeb3b.svg') }}" width="150">
</p>
</div>
</div>
<div class="col-lg-9">
<p>
SAND FrameWork is an CC-licensed or MIT-licenced open source project and completely free to use.
</p>
<p>
However, the amount of effort needed to maintain and develop new features for the project is not
sustainable without proper financial backing.
You can support its ongoing development by being a backer or a sponsor on
<a href="https://www.patreon.com/">Patreon campaign</a>
(recurring, with perks for different tiers), and get your company logo here.
</p>
<p>
Also, you can make a <a href="https://www.paypal.me/">one time donation via PayPal</a>.
</p>
</div>
</div>
</div>
<div class="copyright-content">
<div class="container">
<div class="copyright-text text-center">&copy; 2020-2021 Built with SAND Framework - Responsive SAND Template.</div>
</div>
</div>
</div>
</footer>
<!-- end: Footer -->
</div>
<!-- end: Body Inner -->
@endsection
```
qui étends de `application/include/vues/system/system.blade.php`
```php
<html>
<head>
<title>{{$page_title}}</title>
<meta name="description" lang="fr" content="{{$description}}"/>
@section('top-css')
@endsection
</head>
<body>
@section('top-javascript')
@endsection
@yield('body')
@section('bottom-javascript')
@endsection
</body>
<!DOCTYPE html>
<html>
<head>
<title>{{$page_title}}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta name="author" content="" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="description" lang="fr" content="{{$description}}"/>
<link rel="apple-touch-icon" sizes="57x57" href="/apple-icon-57x57.png">
<link rel="apple-touch-icon" sizes="60x60" href="/apple-icon-60x60.png">
<link rel="apple-touch-icon" sizes="72x72" href="/apple-icon-72x72.png">
<link rel="apple-touch-icon" sizes="76x76" href="/apple-icon-76x76.png">
<link rel="apple-touch-icon" sizes="114x114" href="/apple-icon-114x114.png">
<link rel="apple-touch-icon" sizes="120x120" href="/apple-icon-120x120.png">
<link rel="apple-touch-icon" sizes="144x144" href="/apple-icon-144x144.png">
<link rel="apple-touch-icon" sizes="152x152" href="/apple-icon-152x152.png">
<link rel="apple-touch-icon" sizes="180x180" href="/apple-icon-180x180.png">
<link rel="icon" type="image/png" sizes="192x192" href="/android-icon-192x192.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="96x96" href="/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/manifest.json">
<meta name="msapplication-TileColor" content="#ffffff">
<meta name="msapplication-TileImage" content="/ms-icon-144x144.png">
<meta name="theme-color" content="#ffffff">
@section('top-css')
<link rel="stylesheet" href="{{ \MVC\Classe\Url::asset_rewrite('assets/bootstrap-5.0.0-beta1-dist/css/bootstrap.min.css')}}">
<link rel="stylesheet" href="{{ \MVC\Classe\Url::asset_rewrite('assets/css/custom.css')}}">
@if(\MVC\Classe\Browser::get() == 'Internet Explorer')
<link rel="stylesheet" href="{{\MVC\Classe\Url::asset_rewrite('assets/html5-simple-date-input-polyfill-master/html5-simple-date-input-polyfill.css')}}">
<!--<link rel="stylesheet" href="{{\MVC\Classe\Url::asset_rewrite('assets/hyperform-0.12.0/css/hyperform.css')}}">-->
@endif
@show
</head>
<body>
@section('top-javascript')
@if(\MVC\Classe\Browser::get() == 'Internet Explorer')
<!-- Polyfill.io will load polyfills your browser needs -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=default%2CNumber.parseInt%2CNumber.parseFloat%2CArray.prototype.find%2CArray.prototype.includes"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js" integrity="sha512-uzOpZ74myvXTYZ+mXUsPhDF+/iL/n32GDxdryI2SJronkEyKC8FBFRLiBQ7l7U/PTYebDbgTtbqTa6/vGtU23A==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/promise-polyfill@8/dist/polyfill.min.js"></script>
<script src="{{\MVC\Classe\Url::asset_rewrite('assets/html5-simple-date-input-polyfill-master/html5-simple-date-input-polyfill.js')}}"></script>
<script src="{{\MVC\Classe\Url::asset_rewrite('assets/hyperform-0.12.0/dist/hyperform.js')}}"></script>
<script>hyperform(window);</script>
@endif
@show
@yield('body')
@section('bottom-javascript')
<script src="{{ \MVC\Classe\Url::asset_rewrite('assets/bootstrap-5.0.0-beta1-dist/js/bootstrap.min.js')}}"></script>
<script src="{{ \MVC\Classe\Url::asset_rewrite('assets/js/custom.js')}}"></script>
@if(\MVC\Classe\Browser::get() !== 'Internet Explorer')
<script>
/*
SCRIPT JS permettant de ne valider qu'une seule fois un formulaire
ATTENTION tous les formulaires sont affecté
Lors d'une validation bootstrap personnalisé veuillez utilisé
la class do-resubmit sur le formulaire afin de permettre
l'activation supplémentaire du bouton.
*/
window.onload = function() {
let PreventAllforms = document.querySelectorAll("form");
Array.prototype.slice.call(PreventAllforms)
.forEach(function (PreventForm) {
PreventForm.onsubmit = submitted.bind(PreventForm);
});
}
function submitted(event) {
if (event.target.classList.contains('do-resubmit')) {
event.submitter.disabled = false;
}else{
event.submitter.disabled = true;
}
}
</script>
@endif
@show
</body>
</html>
```

View File

@ -6,4 +6,83 @@ Elles sont chargées dans le même ordre que les vues Blade normale:
* application/include/vues/layout
* application/include/vues/view
Cependant il faut inclure les biblitohèques Vue.js dans la page et coder à la mimine la SPA
Cependant il faut inclure les biblitohèques Vue.js dans la page et coder à la mimine la SPA
par exemple:
```php
@section('top-javascript')
@parent
<script src="https://unpkg.com/vue@2.6.12/dist/vue.js"></script>
<script src="https://unpkg.com/axios@0.21.1/dist/axios.min.js"></script>
@endsection
@section('content')
<h1>%PAGE% - VUE.js Controlleur</h1>
<br/><br/><br/>
<div id="app">
<div>
<input v-model="searchText" placeholder="Search...">
</div>
<div v-if="items" >
<a href="#" v-for="item in itemsSearched" :key="item.id">
<div>
<div>
<h2>
@{{ item.title }}
</h2>
</div>
</div>
<div>
<p>
@{{ item.description.slice(0, 300) + "..." }}
</p>
</div>
<div>
<span>Year : @{{ item.release_date }}</span>
<span>Director : @{{ item.director }}</span>
<span>Producer : @{{ item.producer }}</span>
</div>
</a>
</div>
</div>
@endsection
@section('bottom-javascript')
@parent
<script>
const vue = new Vue({
el: '#app',
data: {
items: [],
searchText: ''
},
mounted() {
axios
.get('https://ghibliapi.herokuapp.com/films')
.then(response => {
this.items = response.data;
})
.catch(error => console.log(error))
},
computed : {
itemsSearched : function(){
var self = this;
if( this.searchText == ''){
return this.items;
}
return this.items.filter(function(item){
// https://www.reddit.com/r/vuejs/comments/62kfae/how_do_i_create_very_simple_instant_search_filter/
// Must be of string type
return item.title.toLowerCase().indexOf(self.searchText) >= 0 ||
item.producer.toLowerCase().indexOf(self.searchText) >= 0 ||
item.director.toLowerCase().indexOf(self.searchText) >= 0 ||
item.release_date.toString().indexOf(self.searchText) >= 0;
});
}
}
});
</script>
@endsection
```

View File

@ -53,14 +53,17 @@ class DefaultAction extends Action
}
```
avec cet accès dans la vue:
avec cet accès dans une vue blade:
```php
{{\MVC\Classe\ControlleurAction::inserer('default',[])}}
{{\MVC\Classe\ControlleurAction::inserer('default.default',[4,5,6])}}
{{\MVC\Classe\ControlleurAction::inserer('default.variableSlug',['var1','var2'])}}
{{\MVC\Classe\ControlleurAction::inserer('default.makeHttp11',[])}}
```
ou avec cet accès dans une vue twig:
```php
{{ action('default.defaultTwig',[4,5,6]) }}
{{ action('default.makeHttp11',[]) }}
```
il faut absolument que l'action retourne du texte soit par la la méthode `render` soit par un `système de tampon`

View File

@ -5,6 +5,8 @@ un controlleur similaire a Symfony qui est dénomé ici Conduit car il prend
en paramètre une route défini dans le fichier routing.yml.
Cette fonctionnalité permet de choisir la route indépendamment du moteur.
Elle est utlie aussi pour créer des appels Curl et Ajax.
il faut instancier le fichier `application/config/files/routing.yml`
avec la route de base et les routes que vous voulez conduire, par exemple:
```yml
@ -48,3 +50,4 @@ class FooConduit extends Conduit
}
}
```
Vous remarquerez que les variables passé en GET sont obtenu dans le conduit par `$this->varname`.

View File

@ -1,29 +1,37 @@
#Comment Configurer un module Symfony ou tout autre application php
#Comment Configurer un module ou tout autre application php
il vous faut instancier trois fichiers:
le modèle (.model) contenant le nom de la page qui porte le model
ici : `application/include/modeles/syf51.model`
ici : `application/include/modeles/my_module.model`
```yaml
name : syf51
name : my_module
page_title : Accueil de l'application modulaire
description : zatou stra bracadabla
params : params
engine : blade
ariane : {my_module_name}
arianelink : {my_module}
```
le controlleur (.php) contenant ce code qui doit être automatisé
ici: `application/include/controlleurs/syf51.php`
le controlleur (.php) contenant ce code
ici: `application/include/controlleurs/my_module.php`
```php
<?php
\MVC\Classe\Session::start();
$app = new MVC\Classe\Modular($name);
$templateData = array('app' => $app);
```
et déclarer le module dans `\application\modules\setup\registre.model`
le template (.blade.php) contenant ce code
ici: `application/include/vues/view/my_module.php`
```php
{{$app->load('module_type')}}
```
aussi il vous faudra déclarer le module dans `\application\modules\setup\registre.model`
par une ligne suplémentaire:
```yaml
syf51 : Application permettant de tester l'intégration d'un module avec symfony5.0.99
my_module : Application permettant de tester l'intégration d'un module
```
si besoin et que le module n'existe pas il vous faudras coder et modifier
le fichier `/application/class/Modular.php` voir peut-être `/application/class/ModularRegister.php`
ainsi que le dossier `\application\module\my_module`
si besoin et que le type du module n'existe pas il vous faudra ajouter le type du module en modifiant le fichier `/application/class/Modular.php` et les méthodes `__construct` et `load`
Good Luck !

View File

@ -1 +1,10 @@
#Comment bien utiliser les modules
#Comment bien utiliser les modules
Simplement vous pouvez tester les intégrations prévues dans le FrameWork avec la commande `php bin.php module:add` ainsi vous aurez le choix d'intégrer en quelques modifications à la mimine un module Symfony ou Laravel. Pour cela choisissez les paramètres de base afin que l'installation se passe bien.
Il faut comprendre qu'un module Symfony ne peut fonctionner qu'avec un template `blade`, de même manière un module Laravel ne peut fonctionner qu'avec un template `twig`.
Basiquement toute application utilisant le système de randu `twig` doit être intégré avec un template-sand `blade` et l'inverse.
Au niveau du sysème de routage, il faut absolument inclure le path du module, par exemple pour un module nommé 'SciFi', il faudra inclure dans les routes des controlleurs la chaine de caractères `\SciFi` devant toutes les routes de vos controlleurs.
Il en est de même pour les autres modules : Wordpress, GitList, PhpList, Pretashop, ... ainsi que pour tous les autres modules que vous voudriez intégrer par vous-même.

View File

@ -0,0 +1 @@
#Comment ajouter un module Symfony

3
switch2LaravelModule.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
composer remove illuminate/view
composer require twig/twig 1.*

3
switch2SymfonyModule.sh Normal file
View File

@ -0,0 +1,3 @@
#!/usr/bin/env bash
composer require illuminate/view 4.*
composer remove twig/twig

View File

@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Tests;
use MVC\Classe\Caracter;
use PHPUnit\Framework\TestCase;
/**
* Exemple de test sur un cas simple
* @package Tests
*/
final class StrToUpperTest extends TestCase
{
public function testCaracteres(): void
{
$string = array(
"pere",
"pére",
"père",
"paîres",
"noël",
);
$string_value_upper = array();
$string_upper = array(
"PERE",
"PERE",
"PERE",
"PAIRES",
"NOEL",
);
foreach($string as $value){
//$string_value_upper[] = Caracter::mettreEnMajusculeAccents(strtoupper($value),true);
$string_value_upper[] = strtoupper($value);
}
for($i=0;$i<count($string_upper);$i++){
$this->assertEquals($string_value_upper[$i], $string_upper[$i]);
}
}
}