Commit e03bb9ef authored by Sylvain's avatar Sylvain

Boostrap 5

parent a17067b9
<?php
namespace Goldenscarab\Modulus\Service\Template\Compose;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use \Illuminate\Support\HtmlString;
use Goldenscarab\Modulus\Helpers\Dynamik;
use Goldenscarab\Modulus\Helpers\Bootstrap4;
class Template
{
/**
* Prefixe des routes
*
* @var string
*/
protected $route_prefix;
/**
* Prefixe des permission
*
* @var string
*/
protected $can_prefix;
/**
* Source des données
*
* @var Collection
*/
protected $source;
/**
* Id de la table
*
* @var string
*/
protected $table_id;
/**
* Classe de la table
*
* @var string
*/
protected $table_class;
/**
* Menu de la liste
*
* @var array
*/
protected $_menu;
/**
* Configuration des lignes
*
* @var array
*/
protected $_rows;
/**
* Configuration des colonnes
*
* @var array
*/
protected $_columns;
public function __construct($attrs = [])
{
$this->setAttrs($attrs);
}
/**
* Replacement des tag de valeur par défaut par une action associée
*
* @param array $datas
* @return array
*/
protected function replaceDefaultsAction(array $datas)
{
$datas_default = [];
$models_action = array(
'[SHOW]' => [
'label' => '<i class="fa fa-eye mr-2"></i>' . __('Voir'),
'permission' => $this->can_prefix . '-read',
'href' => ['url' => [
'route' => $this->route_prefix . '.show',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[READ]' => [
'label' => '<i class="fa fa-eye mr-2"></i>' . __('Consulter'),
'permission' => $this->can_prefix . '-read',
'href' => ['url' => [
'route' => $this->route_prefix . '.read',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[CREATE]' => [
'label' => '<i class="fa fa-plus mr-2"></i>' . __('Ajouter'),
'permission' => $this->can_prefix . '-create',
'href' => ['url' => [
'route' => $this->route_prefix . '.create',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[UPDATE]' => [
'label' => '<i class="fa fa-pencil-square-o mr-2"></i>' . __('Modifier'),
'permission' => $this->can_prefix . '-update',
'href' => ['url' => [
'route' => $this->route_prefix . '.update',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[DUPLICATE]' => [
'label' => '<i class="fa fa-clone mr-2"></i>' . __('Dupliquer'),
'permission' => $this->can_prefix . '-create',
'href' => ['url' => [
'route' => $this->route_prefix . '.duplicate',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[DELETE]' => [
'label' => '<i class="fa fa-trash mr-2"></i>' . __('Supprimer'),
'permission' => $this->can_prefix . '-delete',
'href' => '#',
'class' => 'confirm text-danger',
'data-href' => ['url' => [
'route' => $this->route_prefix . '.delete',
'args' => [':id', ['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[EXPORT]' => [
'label' => '<i class="fa fa-file-excel-o mr-2"></i>' . __('Exporter'),
'permission' => $this->can_prefix . '-read',
'href' => ['url' => [
'route' => $this->route_prefix . '.export',
'args' => [['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[TRUNCATE]' => [
'label' => '<i class="fa fa-times mr-2"></i>' . __('Tout supprimer'),
'permission' => $this->can_prefix . '-delete',
'href' => '#',
'class' => 'confirm',
'data-href' => ['url' => [
'route' => $this->route_prefix . '.truncate',
'args' => [['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[RESET-POSITION]' => [
'label' => '<i class="fa fa-list-ol mr-2"></i>' . __('Reset position'),
'permission' => $this->can_prefix . '-update',
'href' => '#',
'class' => 'confirm',
'data-href' => ['url' => [
'route' => $this->route_prefix . '.reset-position',
'args' => [['callback' => ['function' => 'current_query_to_string()']]]
]],
],
'[SEPARATOR]' => '<div class="dropdown-divider"></div>'
);
// Recherche des tags de modèles à remplacer
foreach ($datas as $key => $data) {
if (is_array($data)) {
$datas_default[$key] = $this->replaceDefaultsAction($data);
} else {
if (array_key_exists($data, $models_action)) {
//throw new \InvalidArgumentException("Modèle d'action non reconnu : " . $data);
}
$datas_default[$key] = data_get($models_action, $data, $data);
}
}
return $datas_default;
}
/**
* Retire les élements d'un tableau lorsqu'une permission est spécifié et que l'utilisateur ne dispose pas des droits
*
* @param array $datas
* @return array
*/
protected function removeWithoutPermission(array $datas)
{
$datas_permission = [];
foreach ($datas as $key => $data) {
if ($key === 'permission' && !auth()->user()->can($data)) {
return null;
}
if (is_array($data)) {
$datas_permission[$key] = $this->removeWithoutPermission($data);
} else {
$datas_permission[$key] = $data;
}
}
// Filtre des éléments vides
$datas_permission = array_filter($datas_permission, function($item) {
return !is_null($item) && $item !== '';
});
return $datas_permission;
}
/**
* Retourne le rendu d'attributs avec leur valeur
* @param array $attrs Les attributs avec la colonne de l'object conteant la valeur
* @param Object $item Object contenant la valeur de l'attribut
* @return string Le rendu des attributs avec leur valeur
*/
protected function renderAttributes($attrs = [], $source = null): string
{
$render = '';
if (is_iterable($attrs)) {
$template = ' %s="%s"';
foreach ($attrs as $name => $data) {
$value = $this->getValue($data, $source);
$render .= vsprintf($template, [$name, $value]);
}
}
return $render;
}
/**
* Récupération d'une valeur en fonction de sa composition
* @param Mixed $value array pour une valeur dynamique ou string|int|float|bool pour une valeur statique
* @param Object $datas Objet dans lequel aller chercher la valeur si dynamique
* @param boolean $strip Supprimer les balises HTML dela valeur résultante
* @return Mixed La valeur
*/
protected function getValue($value, $datas = null)
{
$dynamik = new Dynamik($datas);
return $dynamik->getValue($value);
}
/**
* Retourne le rendu d'une chaine de caractère en HTML
* @param String $string La chains de caractères à traiter
* @return String Le rendu HTML
*/
public function renderHTML($string): string
{
return new HtmlString($string);
}
/**
* Retourne le rendu avec indentation d'un texte
* @param string $text Le texte à traiter
* @param Integer $nb Le nombre d'indentation à appliquer
* @return string Le rendu avec indentation
*/
protected function renderIndent($text, $nb): string
{
$indent = ' ';
$render = '';
$real_indent = '';
for ($i = 1; $i <= $nb; $i++) {
$real_indent .= $indent;
}
$lines = explode(PHP_EOL, $text);
foreach ($lines as $line) {
if (!empty($line)) {
$render .= $real_indent . $line . PHP_EOL;
}
}
return $render;
}
/**
* Mise à jour des attributs depuis le tableau passé en paramètre
* @param Array $attrs Liste des attributs à traiter
* @return void
*/
protected function setAttrs($attrs)
{
$this->resetAttrs();
if (is_null($attrs)) {
return ;
}
// Liste des attributs autorisés
$attrs_available = array_map(function ($val) {
return trim($val, '_');
}, array_keys(get_object_vars($this)));
// Traitement des attributs
if (is_array($attrs)) {
foreach ($attrs as $attr => $value) {
if (in_array($attr, $attrs_available)) {
if (is_array($value)) {
$this->{'_' . $attr} = $value;
} else {
$this->{$attr} = $value;
}
} else {
throw new \InvalidArgumentException("Le paramètre [" . $attr . "] n'est pas pris en charge");
}
}
} else {
throw new \InvalidArgumentException("Type de paramètre invalide. Attendu : Tableau");
}
}
/**
* Réinitialisation des attributs de constructions
* @return void
*/
protected function resetAttrs()
{
$attrs = array_keys(get_object_vars($this));
foreach ($attrs as $attr) {
if (preg_match('/^_.*/', $attr)) {
$this->{$attr} = [];
} else if (preg_match('/^is_.*/', $attr)) {
$this->{$attr} = false;
} else {
$this->{$attr} = null;
}
}
}
}
<?php
namespace Goldenscarab\Modulus\Service\Template\Compose;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Goldenscarab\Modulus\Helpers\Dynamik;
use Goldenscarab\Modulus\Helpers\Bootstrap5;
class TemplateBt5 extends Template
{
public function __construct($attrs = [])
{
$this->setAttrs($attrs);
}
/**
* Rendu des boutons d'action
*
* @param array $data
* @param Collection $source
* @return string
*/
public function renderAction($data, $source): string
{
$render = '';
$data = $this->replaceDefaultsAction($data);
$dynamik = new Dynamik($source);
$action_data = $dynamik->dynamikize($data);
if (Arr::has($action_data, 'dropdown')) {
$render = Bootstrap5::renderAButtonDropDown($action_data);
} else if (Arr::has($action_data, 'button')) {
$render = Bootstrap5::renderAButton(data_get($action_data, 'button', []));
}
return $render;
}
/**
* Retourne le rendu d'un tableau liste
* @return string le rendu du tableau liste
*/
public function renderList(): string
{
$template = '<div class="table-responsive-lg" style="min-height: 250px;">' . PHP_EOL;
$template .= ' <table id="%s" class="%s">' . PHP_EOL;
$template .= ' <thead>' . PHP_EOL;
$template .= ' <tr>' . PHP_EOL;
$template .= '%s';
$template .= ' </tr>' . PHP_EOL;
$template .= ' </thead>' . PHP_EOL;
$template .= ' <tbody>' . PHP_EOL;
$template .= '%s';
$template .= ' </tbody>' . PHP_EOL;
$template .= ' </table>';
$template .= '</div>';
$render = vsprintf($template, [
empty($this->table_id) ? 'table-' . Str::slug($this->route_prefix) : $this->table_id,
trim('table table-sm table-hover table-striped ' . $this->table_class),
$this->renderIndent($this->renderListHead(), 3),
$this->renderIndent($this->renderListBody(), 2),
]);
return $render;
}
/**
* Retourne le rendu des entêtes de colonnes d'un tableau liste
* @return string Le rendu des entêtes de colonnes
*/
public function renderListHead(): string
{
$template = '<th scope="col" class="text-nowrap%s">%s%s</th>' . PHP_EOL;
$render = '';
$columns = $this->_columns;
// Colonne titre
if (is_iterable($columns)) {
foreach ($columns as $column) {
$sortable = data_get($column, 'sortable');
$class = data_get($column, 'class');
// Pas de classe dynamique pour le header
if (is_array($class)) {
$class = '';
}
$render .= vsprintf($template, [
is_null($class) ? '' : ' ' . $class,
data_get($column, 'label'),
is_null($sortable) ? '' : col_sort($sortable)
]);
}
}
// Colonne menu
$render .= vsprintf($template, ['','', '']);
return $render;
}
/**
* Retourne le rendu des lignes d'un tableau liste
* @return string Le rendu des lignes du tableau
*/
public function renderListBody(): string
{
$template_row = '<tr scope="row"%s>' . PHP_EOL;
$template_row .= '%s';
$template_row .= '</tr>' . PHP_EOL;
$template_cel = '<td%s>%s</td>' . PHP_EOL;
$render = '';
$collection = $this->source;
$columns = $this->_columns;
$rows = $this->_rows;
if (is_iterable($collection)) {
if (count($collection) == 0) {
$render_cels_row = vsprintf($template_cel, [
' colspan="' . (count($columns) + 1) .'"',
__('Aucun élément disponible')
]);
$render .= vsprintf($template_row, [
null,
$this->renderIndent($render_cels_row, 1)
]);
} else {
foreach ($collection as $item) {
$render_cels_row = '';
if (is_iterable($columns)) {
foreach ($columns as $column) {
$attrs = collect($column)->except(['label', 'row', 'value', 'sortable', 'id']);
$attributes = $this->renderAttributes($attrs, $item);
$value = $this->getValue(data_get($column, 'value'), $item);
// Création de la cellule
$render_cels_row .= vsprintf($template_cel, [
$attributes,
$value
]);
}
// Ajout du menu en fin de ligne
$render_cels_row .= vsprintf($template_cel, [
' class="text-right"',
$this->renderAction($this->_menu, $item)
]);
}
$render .= vsprintf($template_row, [
$this->renderAttributes($rows, $item),
$this->renderIndent($render_cels_row, 1)
]);
}
}
}
return $render;
}
}
......@@ -2,6 +2,7 @@
namespace Goldenscarab\Modulus\Service\Template;
use Goldenscarab\Modulus\Service\Template\Compose\TemplateBt5;
use Goldenscarab\Modulus\Service\Template\Compose\Template1Bt4;
use Goldenscarab\Modulus\Service\Template\Compose\Template2Bt4;
use Goldenscarab\Modulus\Service\Template\Compose\Template3Bt4;
......@@ -45,6 +46,14 @@ class Template
$template = new Template4Bt4($attrs);
$render = $template->renderList();
return $template->renderHTML($render);
}
public function list5($attrs = []): string
{
$template = new TemplateBt5($attrs);
$render = $template->renderList();
return $template->renderHTML($render);
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment