305 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			305 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| namespace nur\v;
 | |
| 
 | |
| use nur\A;
 | |
| use nur\c;
 | |
| use nur\config;
 | |
| use nur\func;
 | |
| use nur\interp;
 | |
| use nur\str;
 | |
| 
 | |
| /**
 | |
|  * Class v: méthodes outils pour produire du contenu pour le web
 | |
|  *
 | |
|  * NB: si on ajoute des méthodes ici, les ajouter aussi dans {@link vo}
 | |
|  * et {@link ly}
 | |
|  */
 | |
| class v {
 | |
|   /** retourner [$attr => $attr] si $cond est vrai */
 | |
|   static final function attrif(string $attr, ?bool $cond): ?array {
 | |
|     return $cond? [$attr => $attr]: null;
 | |
|   }
 | |
|   static final function selectedif($cond): ?array { return self::attrif("selected", $cond); }
 | |
|   static final function checkedif($cond): ?array { return self::attrif("checked", $cond); }
 | |
|   static final function requiredif($cond): ?array { return self::attrif("required", $cond); }
 | |
|   static final function disabledif($cond): ?array { return self::attrif("disabled", $cond); }
 | |
| 
 | |
|   private static function _start_tag_attrs(string $tag, ?array $attrs): array {
 | |
|     $parts = ["<$tag"];
 | |
|     if ($attrs !== null) {
 | |
|       foreach ($attrs as $key => $value) {
 | |
|         if ($value === null || $value === false) continue;
 | |
|         if (is_array($value)) {
 | |
|           $value = str::join3($value);
 | |
|           if (!$value) continue;
 | |
|         }
 | |
|         $parts[] = " ";
 | |
|         $parts[] = $key;
 | |
|         $parts[] = "=\"";
 | |
|         $parts[] = htmlspecialchars($value);
 | |
|         $parts[] = "\"";
 | |
|       }
 | |
|     }
 | |
|     return $parts;
 | |
|   }
 | |
|   /** retourner un tag ouvrant avec ses attributs et son texte */
 | |
|   static final function _start(string $tag, $vs=null): array {
 | |
|     if ($vs === null || $vs === false) return ["<$tag>"];
 | |
| 
 | |
|     list($seq, $attrs) = A::split_assoc(A::with(c::q($vs)));
 | |
|     # tout d'abord les attributs
 | |
|     $parts = self::_start_tag_attrs($tag, $attrs);
 | |
|     $parts[] = ">";
 | |
|     # puis rajouter le contenu
 | |
|     if ($seq !== null) $parts = [$parts, $seq];
 | |
|     return $parts;
 | |
|   }
 | |
| 
 | |
|   /** retourner un tag fermant */
 | |
|   static final function _end(string $tag): array {
 | |
|     return ["</$tag>"];
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * retourner un tag avec ses attributs et son texte
 | |
|    * toujours retourner un tag ouvrant et fermant
 | |
|    *
 | |
|    * si $require_content==true et que tous les contenus du tag sont null, ne pas
 | |
|    * afficher le tag
 | |
|    */
 | |
|   static final function _tag(string $tag, $vs=null, bool $require_content=false): array {
 | |
|     if ($vs === null || $vs === false) {
 | |
|       return $require_content? []: ["<$tag></$tag>"];
 | |
|     }
 | |
| 
 | |
|     list($seq, $attrs) = A::split_assoc(A::with(c::q($vs)));
 | |
|     $count = $seq !== null? count($seq): 0;
 | |
|     if ($require_content && $count > 0 && A::all_n($seq)) {
 | |
|       # si tous les contenus sont null, ne pas afficher le tag
 | |
|       return [];
 | |
|     } else {
 | |
|       # sinon tag normal
 | |
|       $parts = self::_start_tag_attrs($tag, $attrs);
 | |
|       $parts[] = ">";
 | |
|       if ($seq !== null) $parts[] = $seq;
 | |
|       $parts[] = "</$tag>";
 | |
|       return $parts;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * retourner un tag avec ses attributs et son texte.
 | |
|    * si le tag n'a pas de contenu, faire un tag simple <tag/>
 | |
|    *
 | |
|    * si $require_content==true et que tous les contenus du tag sont null, ne pas
 | |
|    * afficher le tag
 | |
|    */
 | |
|   static final function _tag1(string $tag, $vs=null, bool $require_content=false): array {
 | |
|     if ($vs === null || $vs === false) {
 | |
|       return $require_content? []: ["<$tag/>"];
 | |
|     }
 | |
| 
 | |
|     list($seq, $attrs) = A::split_assoc(A::with(c::q($vs)));
 | |
|     $count = A::count($seq);
 | |
|     if ($require_content && $count > 0 && A::all_n($seq)) {
 | |
|       # si tous les contenus sont null, ne pas afficher le tag
 | |
|       return [];
 | |
|     } elseif ($count == 0 || A::all_n($seq)) {
 | |
|       # si pas de contenu, faire un tag simple
 | |
|       $parts = self::_start_tag_attrs($tag, $attrs);
 | |
|       $parts[] = "/>";
 | |
|       return $parts;
 | |
|     } else {
 | |
|       # sinon tag normal
 | |
|       $parts = self::_start_tag_attrs($tag, $attrs);
 | |
|       $parts[] = ">";
 | |
|       if ($seq !== null) $parts[] = $seq;
 | |
|       $parts[] = "</$tag>";
 | |
|       return $parts;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   /** retourner un tag ouvrant avec ses attributs et son texte */
 | |
|   static final function start(string $tag, $vs=null): array {
 | |
|     if ($vs !== null) $vs = c::fq($vs);
 | |
|     return self::_start($tag, $vs);
 | |
|   }
 | |
| 
 | |
|   /** retourner un tag fermant */
 | |
|   static final function end(string $tag): array {
 | |
|     return self::_end($tag);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * retourner un tag avec ses attributs et son texte
 | |
|    * toujours retourner un tag ouvrant et fermant
 | |
|    *
 | |
|    * si $require_content==true et que tous les contenus du tag sont null, ne pas
 | |
|    * afficher le tag
 | |
|    */
 | |
|   static final function tag(string $tag, $vs=null, bool $require_content=false): array {
 | |
|     if ($vs !== null) $vs = c::fq($vs);
 | |
|     return self::_tag($tag, $vs, $require_content);
 | |
|   }
 | |
| 
 | |
|   /**
 | |
|    * retourner un tag avec ses attributs et son texte.
 | |
|    * si le tag n'a pas de contenu, faire un tag simple <tag/>
 | |
|    *
 | |
|    * si $require_content==true et que tous les contenus du tag sont null, ne pas
 | |
|    * afficher le tag
 | |
|    */
 | |
|   static final function tag1(string $tag, $vs=null, bool $require_content=false): array {
 | |
|     if ($vs !== null) $vs = c::fq($vs);
 | |
|     return self::_tag1($tag, $vs, $require_content);
 | |
|   }
 | |
| 
 | |
|   /** le tag h1 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h1($vs): array { return self::tag("h1", $vs, true); }
 | |
|   /** le tag h2 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h2($vs): array { return self::tag("h2", $vs, true); }
 | |
|   /** le tag h3 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h3($vs): array { return self::tag("h3", $vs, true); }
 | |
|   /** le tag h4 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h4($vs): array { return self::tag("h4", $vs, true); }
 | |
|   /** le tag h5 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h5($vs): array { return self::tag("h5", $vs, true); }
 | |
|   /** le tag h6 n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function h6($vs): array { return self::tag("h6", $vs, true); }
 | |
| 
 | |
|   static final function hr($vs=null): array { return self::tag1("hr", $vs); }
 | |
| 
 | |
|   static final function div($vs): array { return self::tag("div", $vs); }
 | |
|   static final function sdiv($vs=null): array { return self::start("div", $vs); }
 | |
|   static final function ediv(): array { return self::end("div"); }
 | |
|   static final function mdiv($key, ?array $data=null, $vs=null): array {
 | |
|     $class = "m-".str_replace(".", "-", $key);
 | |
|     $text = interp::string(config::m($key), $data);
 | |
|     return self::div([$text, "class" => $class, $vs]);
 | |
|   }
 | |
| 
 | |
|   /** le tag pre n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function pre($vs): array { return self::tag("pre", $vs, true); }
 | |
|   static final function spre($vs=null): array { return self::start("pre", $vs); }
 | |
|   static final function epre(): array { return self::end("pre"); }
 | |
| 
 | |
|   /** le tag p n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function p($vs): array { return self::tag("p", $vs, true); }
 | |
|   static final function sp($vs=null): array { return self::start("p", $vs); }
 | |
|   static final function ep(): array { return self::end("p"); }
 | |
| 
 | |
|   static final function br($vs=null): array { return self::tag1("br", $vs); }
 | |
| 
 | |
|   /** le tag span n'est pas généré s'il n'y a pas de contenu */
 | |
|   static final function span($vs): array { return self::tag("span", $vs, true); }
 | |
|   static final function mspan(string $key, ?array $data=null, $vs=null): array {
 | |
|     $class = "m-".str_replace(".", "-", $key);
 | |
|     $text = interp::string(config::m($key), $data);
 | |
|     return self::span([$text, "class" => $class, $vs]);
 | |
|   }
 | |
|   static final function a($vs, ?string $url=null): array {
 | |
|     if ($url !== null) $vs = ["href" => page::bu($url), c::q($vs)];
 | |
|     return self::tag("a", $vs);
 | |
|   }
 | |
|   static final function b($vs): array { return self::tag("b", $vs); }
 | |
|   static final function i($vs): array { return self::tag("i", $vs); }
 | |
|   static final function em($vs): array { return self::tag("em", $vs); }
 | |
|   static final function strong($vs): array { return self::tag("strong", $vs); }
 | |
| 
 | |
|   static final function ul($vs): array { return self::tag("ul", $vs); }
 | |
|   static final function sul($vs=null): array { return self::start("ul", $vs); }
 | |
|   static final function eul(): array { return self::end("ul"); }
 | |
| 
 | |
|   static final function ol($vs): array { return self::tag("ol", $vs); }
 | |
|   static final function sol($vs=null): array { return self::start("ol", $vs); }
 | |
|   static final function eol(): array { return self::end("ol"); }
 | |
| 
 | |
|   static final function li($vs): array { return self::tag("li", $vs); }
 | |
|   static final function sli($vs=null): array { return self::start("li", $vs); }
 | |
|   static final function eli(): array { return self::end("li"); }
 | |
| 
 | |
|   static final function table($vs): array { return self::tag("table", $vs); }
 | |
|   static final function stable($vs=null): array { return self::start("table", $vs); }
 | |
|   static final function etable(): array { return self::end("table"); }
 | |
| 
 | |
|   static final function thead($vs): array { return self::tag("thead", $vs); }
 | |
|   static final function sthead($vs=null): array { return self::start("thead", $vs); }
 | |
|   static final function ethead(): array { return self::end("thead"); }
 | |
| 
 | |
|   static final function tbody($vs): array { return self::tag("tbody", $vs); }
 | |
|   static final function stbody($vs=null): array { return self::start("tbody", $vs); }
 | |
|   static final function etbody(): array { return self::end("tbody"); }
 | |
| 
 | |
|   static final function tr($vs): array { return self::tag("tr", $vs); }
 | |
|   static final function str($vs=null): array { return self::start("tr", $vs); }
 | |
|   static final function etr(): array { return self::end("tr"); }
 | |
| 
 | |
|   static final function th($vs): array { return self::tag("th", $vs); }
 | |
|   static final function td($vs): array { return self::tag("td", $vs); }
 | |
| 
 | |
|   static final function if($cond, $vs): iterable { return $cond? c::q($vs) : []; }
 | |
|   static final function unless($cond, $vs): iterable { return !$cond? c::q($vs) : []; }
 | |
|   static final function callif($cond, ?callable $function, ...$args): iterable {
 | |
|     if (!$cond || $function === null) return [];
 | |
|     return c::q(func::call($function, ...$args));
 | |
|   }
 | |
| 
 | |
|   static final function foreach(?iterable $values, ?callable $function): array {
 | |
|     $pieces = [];
 | |
|     if ($values !== null) {
 | |
|       if ($function !== null) {
 | |
|         $index = 0;
 | |
|         foreach ($values as $key => $value) {
 | |
|           $pieces[] = func::call($function, $value, $key, $index++);
 | |
|         }
 | |
|       } else {
 | |
|         foreach ($values as $value) {
 | |
|           $pieces[] = $value;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     return $pieces;
 | |
|   }
 | |
| 
 | |
|   private static function _list(?iterable $values, ?string $sep=", ", ?string $prefix=null, ?string $suffix=null, ?callable $function): array {
 | |
|     $vs = [];
 | |
|     if ($values !== null) {
 | |
|       $functx = $function !== null? func::_prepare($function): null;
 | |
|       $first = true;
 | |
|       $index = 0;
 | |
|       foreach ($values as $key => $value) {
 | |
|         if ($first) {
 | |
|           $first = false;
 | |
|           $vs[] = $prefix;
 | |
|         } else {
 | |
|           $vs[] = $sep;
 | |
|         }
 | |
|         if ($functx !== null) {
 | |
|           $value = func::_call($functx, [$value, $key, $index++]);
 | |
|         }
 | |
|         $vs[] = $value;
 | |
|       }
 | |
|       if (!$first) $vs[] = $suffix;
 | |
|     }
 | |
|     return $vs;
 | |
|   }
 | |
| 
 | |
|   static final function simple_list(?iterable $values, ?string $sep=", ", ?string $prefix=null, ?string $suffix=null): array {
 | |
|     return self::_list($values, $sep, $prefix, $suffix, null);
 | |
|   }
 | |
| 
 | |
|   const LIST_SCHEMA = [
 | |
|     "sep" => ["?string", ", ", "séparateur entre les valeur"],
 | |
|     "prefix" => ["?array", null, "préfixe à rajouter s'il y a des valeurs"],
 | |
|     "suffix" => ["?array", null, "suffixe à rajouter s'il y a des valeurs"],
 | |
|     "function" => ["?callable", null, "fonction qui calcule la valeur à ajouter"],
 | |
|   ];
 | |
|   static final function list(?iterable $values, ?array $params): array {
 | |
|     $sep = A::get($params, "sep", ", ");
 | |
|     $prefix = A::get($params, "prefix");
 | |
|     $suffix = A::get($params, "suffix");
 | |
|     $function = A::get($params, "function");
 | |
|     return self::_list($values, $sep, $prefix, $suffix, $function);
 | |
|   }
 | |
| }
 |