]> git.nbdom.net Git - nb.git/commitdiff
lib/php/db.php
authorNicolas Boisselier <nicolas.boisselier@gmail.com>
Wed, 10 Jan 2018 02:48:05 +0000 (02:48 +0000)
committerNicolas Boisselier <nicolas.boisselier@gmail.com>
Wed, 10 Jan 2018 02:48:05 +0000 (02:48 +0000)
lib/php/db.php
lib/php/db/table.php
lib/php/nb.php

index 7039018f7dd32a3c1dbb5ea8a704b196c4b6f640..17b33b05577134e4a9234f7d3d83736ee37dd0cf 100644 (file)
@@ -431,6 +431,20 @@ class Db extends nb {
     return $this->unvar($method);
   }
 
+  public function loadPhp($name) {
+    static $require = [];
+
+    if (empty($name)) self::bye('Db file is required');
+
+    if (empty($require[$name])) {
+      $require[$name] = NB_ROOT.'/lib/php/db/'.$name.'.php';
+      if (!file_exists($require[$name])) return false;
+      require_once($require[$name]);
+    }
+
+               return true;
+  }
+
   public function conf_type_load($type=null) {
     global $DB_TYPES;
     static $require = [];
@@ -441,7 +455,7 @@ class Db extends nb {
     if (empty($require[$type])) {
       $require[$type] = NB_ROOT.'/lib/php/db/types/'.$type.'.php';
       if (!file_exists($require[$type])) self::bye("Unknown type `$type`");
-      $require[$type] = dirname(__FILE__).'/db/types/'.$type.'.php';
+# NB 10.01.18       $require[$type] = dirname(__FILE__).'/db/types/'.$type.'.php';
       require_once($require[$type]);
     }
 
@@ -614,7 +628,7 @@ class Db extends nb {
     $rows = [];
     $return = false;
 
-    foreach($actions as $action) {
+    foreach ($actions as $action) {
 
         if ($action == 'db.help') {
           $this->out(self::$action_help,['action','description']);
@@ -965,14 +979,14 @@ class Db extends nb {
     if ($insert === null) $insert = self::p('insert');
     if (empty($db_type)) $db_type = self::p('db_type');
 
-    # Params
-    $this->pset('orderby',null);
-    $this->pset('extras','0');
-    $this->pset('format','sql');
+    # Params ! dirty !
+# NB 10.01.18     $this->pset('orderby',null);
+# NB 10.01.18     $this->pset('extras','0');
+# NB 10.01.18     $this->pset('format','sql');
 
     # Filters
-    $type = self::p('type','');
-    $name = self::p('name',self::p('table',''));
+    $type = self::p('table-type',''); $type = $type ? explode(',',$type) : $type;
+    $name = self::p('table-name',''); $name = $name ? explode(',',$name) : $name;
 
     # Tables param filter
     $tables = $this->tables();
@@ -1015,13 +1029,16 @@ class Db extends nb {
       $type_from = $this->type;
       $type_to = $db_type;
       $this->type = $type_to;
+
                } else {
       echo "-- Type     : ".$this->type."\n";
+
     }
 
     # Specific function
     $row_opt = [
       'parser' => false,
+      'format' => 'sql',
       'db_type_from' => $type_from,
     ];
     if ($fct = $this->conf_type('table.sql.create')) {
index c4b9e2b53d54db34885859c4a0e752f0e68a0867..7bd421b9282c4f9e16271d766eda18da5c74aeb6 100644 (file)
@@ -1068,11 +1068,6 @@ Class Table extends nb {
       }
       $fields = $new_fields;
       unset($new_fields);
-      /*
-      foreach ($fields as $k => $field) {
-        if (!in_array($k,$fields_filter) and !isset($this->extras[$k])) unset($fields[$k]);
-      }
-      */
     }
 
     #
@@ -1167,11 +1162,6 @@ Class Table extends nb {
           if (isset($row[$k])) $new_row[$k] = $row[$k];
         }
         $row = $new_row;
-        /*
-        foreach (array_keys($row) as $k) {
-          if (!in_array($k,$fields_filter)) unset($row[$k]);
-        }
-        */
       }
 
       #
@@ -1194,6 +1184,7 @@ Class Table extends nb {
 
         } else {
           echo $this->{"rows_begin_$format"}($fields,$opt);
+
         }
 
       }
@@ -1372,38 +1363,37 @@ Class Table extends nb {
     return '';
   }
 
-  /*-----------------------------------------------------------------
-    Sql
-  -----------------------------------------------------------------*/
-  public function rows_begin_sql() {
-    return '';
-    return "\n-- ".$this->name."\n";
-  }
+       /*-----------------------------------------------------------------
+       Sql
+       -----------------------------------------------------------------*/
+       public function rows_begin_sql() {
+       return '';
+       return "\n-- ".$this->name."\n";
+       }
 
-  public function rows_rec_sql(&$row,&$opt) {
-    $keys = $values = [];
+       public function rows_rec_sql(&$row,&$opt) {
+       $keys = $values = [];
 
-    foreach ($row as $k=>$v) {
-      if (isset($this->extras[$k])) continue;
-      $f = $this->fields($k);
+       foreach ($row as $k=>$v) {
+       if (isset($this->extras[$k])) continue;
+       $f = $this->fields($k);
 
-      $values[] = $f->quote($v);
-      $keys[] = $f->sql_name();
-    }
+       $values[] = $f->quote($v);
+       $keys[] = $f->sql_name();
+       }
 
-    $fields = $this->fields_only ? ' ('.join(',',$keys).')' : '';
-    $sql = "INSERT INTO ".$this->sql_name().$fields." VALUES(".join(',',array_values($values)).");";
+       $fields = $this->fields_only ? ' ('.join(',',$keys).')' : '';
+       $sql = "INSERT INTO ".$this->sql_name().$fields." VALUES(".join(',',array_values($values)).");";
 
-    #if ($fct and $this->name=='place') debug($sql);
-    $fct = !empty($opt['fct']) ? $opt['fct'] : null;
-    if ($fct) $sql = $fct($sql,$this);
+       $fct = !empty($opt['fct']) ? $opt['fct'] : null;
+       if ($fct) $sql = $fct($sql,$this);
 
-    return $sql.NB_EOL;
-  }
+       return $sql.NB_EOL;
+       }
 
-  public function rows_end_sql() {
-    return '';
-  }
+       public function rows_end_sql() {
+       return '';
+       }
 
   /*-----------------------------------------------------------------
     Text
index 60700b65116d4b91cee65c4c7dc8903f7a75d380..f860724a0af5ea03d7392cc08e2dd42b1f6f0234 100644 (file)
@@ -11,554 +11,554 @@ require_once(NB_ROOT.'/lib/php/functions.php');
 if (class_exists('NB')) return; # protect against double include
 class NB {
 
-  const ROOT_DIR = NB_ROOT;
-  const NB_ROOT = NB_ROOT;
-
-  protected static $content_types_aliases = array(
-       #>_SHELL_REPLACE dbq db=$NB_DB table="SELECT type,ext FROM mime_type WHERE ext IN ('json','csv','txt','yaml','xml','html','doc','xls')"
-    'text' => 'txt',
-    'human' => 'txt',
-    'table' => 'html',
-    'div' => 'html',
-       #<_SHELL_REPLACE
-  );
-
-  protected static $content_types = array(
-    'json' => 'text/json',
-    'doc'  => 'application/msword',
-    'xls'  => 'application/vnd.ms-excel',
-    'xml'  => 'application/xml',
-    'txt'  => 'text/plain',
-    'csv'  => 'text/csv',
-    'html' => 'text/html',
-    'yaml' => 'text/yaml',
-    'php'  => 'text/x-php',
-  );
-
-  #public static function zaza() { return (is_object($this) ? 'TRUE' : 'FALSE'); }
-  #public static function test() { return 'TEST'; }
-  public function __construct($opt = array()) {
-
-    # Deep merge of vars
-    foreach ($opt as $k => $v) {
-      if ( ! array_key_exists($k,$this) ) self::bye("Unknown param $k = `$v`");
-
-      if ($v === null) continue;
-
-      if (is_array($this->$k)) {
-        $this->$k = array_merge_recursive((array)$this->$k, is_array($v) ? $v : [$v]);
-      } else {
-        $this->$k = $v;
-      }
-    }
-
-  }
-
-  #public function __set_state() { }
-
-  public function __sleep() {
-    return(get_class_vars(get_class($this))); # get all
+       const ROOT_DIR = NB_ROOT;
+       const NB_ROOT = NB_ROOT;
+
+       protected static $content_types_aliases = array(
+               #>_SHELL_REPLACE dbq db=$NB_DB table="SELECT type,ext FROM mime_type WHERE ext IN ('json','csv','txt','yaml','xml','html','doc','xls')"
+               'text' => 'txt',
+               'human' => 'txt',
+               'table' => 'html',
+               'div' => 'html',
+               #<_SHELL_REPLACE
+       );
+
+       protected static $content_types = array(
+               'json' => 'text/json',
+               'doc'  => 'application/msword',
+               'xls'  => 'application/vnd.ms-excel',
+               'xml'  => 'application/xml',
+               'txt'  => 'text/plain',
+               'csv'  => 'text/csv',
+               'html' => 'text/html',
+               'yaml' => 'text/yaml',
+               'php'  => 'text/x-php',
+       );
+
+       #public static function zaza() { return (is_object($this) ? 'TRUE' : 'FALSE'); }
+       #public static function test() { return 'TEST'; }
+       public function __construct($opt = array()) {
+
+               # Deep merge of vars
+               foreach ($opt as $k => $v) {
+                       if ( ! array_key_exists($k,$this) ) self::bye("Unknown param $k = `$v`");
+
+                       if ($v === null) continue;
+
+                       if (is_array($this->$k)) {
+                               $this->$k = array_merge_recursive((array)$this->$k, is_array($v) ? $v : [$v]);
+                       } else {
+                               $this->$k = $v;
+                       }
+               }
+
+       }
+
+       #public function __set_state() { }
+
+       public function __sleep() {
+               return(get_class_vars(get_class($this))); # get all
 # NB 09.04.16     return array_keys((array)$this);
-    #debug((array)$this); # publics + private in a weird way !
-    #debug(get_object_vars($this)); # non static
-  }
-  #public function __wakeup() { }
-
-  public function __destruct() {
-    #foreach (get_object_vars($this) as $k=>$v) { echo ("$k: $v\n"); }
-    #if (is_object($this))
-    #foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); };
-    foreach (array_keys((array)$this) as $k) { if (isset($this->$k)) unset($this->$k); };
-  }
-
-  /*
-   * Replace aliases by long name
-   */
-  public static function paliases($aliases,&$changed=[]) {
-    foreach ($aliases as $short=>$long) {
-      if (!preg_match('/^\s*$/',self::p($short))) {
-        self::pset($long,self::p($short));
-        $changed[$short] = $long;
-      }
-      #if (!preg_match('/^\s*$/',self::p($short))) echo ">$long => short=".self::p($short);
-      self::pset($short,null);
-    }
-  }
-
-  /*
-   * Set a default's param value, if not set
-   * Return the value set or existing
-   */
-  public static function pdef($name,$value) {
-    if (preg_match('/^\s*$/',self::p($name))) return self::pset($name,(!is_scalar($value) and is_callable($value)) ? $value() : $value);
-    return self::p($name);
-  }
-
-  /*
-   * Function: p
-   * Return a param
-   */
-  protected static function _p_get($name=null,$default=null) {
-    if ($name === null) return isset($_GET) ? $_GET : [];
-    return isset($_GET[$name]) ? $_GET[$name] : $default;
-  }
-
-  public static function p($name=null,$default=null) {
-    if(NB_P_GET) return self::_p_get($name,$default);
-    if ($name === null) return isset($_REQUEST) ? $_REQUEST : [];
-    return isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
-  }
-
-  /*
-   * Function: pset
-   * Set a value for param, delete it if null
-   */
-  protected static function _pset_get($name,$value=null) {
-    # Brutal !
-    if (is_array($name)) return ($_GET=$name);
-
-    # Delete key
-    if ($value === null or $value === '') {
-      unset ($_GET[$name]);
-      return null;
-    }
-
-    # Set value
-    return ($_GET[$name] = $value);
-  }
-
-  public static function pset($name,$value=null) {
-    if(NB_P_GET) return self::_pset_get($name,$value);
-
-    # Brutal !
-    if (is_array($name)) return ($_REQUEST=$name);
-
-    # Delete key
-    if ($value === null or $value === '') {
-      unset ($_REQUEST[$name]);
-      return null;
-    }
-
-    # Set value
-    return ($_REQUEST[$name] = $value);
-  }
-
-  /*
-   * Function: bye
-   * Set a value for param, delete it if null
-   */
+               #debug((array)$this); # publics + private in a weird way !
+               #debug(get_object_vars($this)); # non static
+       }
+       #public function __wakeup() { }
+
+       public function __destruct() {
+               #foreach (get_object_vars($this) as $k=>$v) { echo ("$k: $v\n"); }
+               #if (is_object($this))
+               #foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); };
+               foreach (array_keys((array)$this) as $k) { if (isset($this->$k)) unset($this->$k); };
+       }
+
+       /*
+        * Replace aliases by long name
+        */
+       public static function paliases($aliases,&$changed=[]) {
+               foreach ($aliases as $short=>$long) {
+                       if (!preg_match('/^\s*$/',self::p($short))) {
+                               self::pset($long,self::p($short));
+                               $changed[$short] = $long;
+                       }
+                       #if (!preg_match('/^\s*$/',self::p($short))) echo ">$long => short=".self::p($short);
+                       self::pset($short,null);
+               }
+       }
+
+       /*
+        * Set a default's param value, if not set
+        * Return the value set or existing
+        */
+       public static function pdef($name,$value) {
+               if (preg_match('/^\s*$/',self::p($name))) return self::pset($name,(!is_scalar($value) and is_callable($value)) ? $value() : $value);
+               return self::p($name);
+       }
+
+       /*
+        * Function: p
+        * Return a param
+        */
+       protected static function _p_get($name=null,$default=null) {
+               if ($name === null) return isset($_GET) ? $_GET : [];
+               return isset($_GET[$name]) ? $_GET[$name] : $default;
+       }
+
+       public static function p($name=null,$default=null) {
+               if(NB_P_GET) return self::_p_get($name,$default);
+               if ($name === null) return isset($_REQUEST) ? $_REQUEST : [];
+               return isset($_REQUEST[$name]) ? $_REQUEST[$name] : $default;
+       }
+
+       /*
+        * Function: pset
+        * Set a value for param, delete it if null
+        */
+       protected static function _pset_get($name,$value=null) {
+               # Brutal !
+               if (is_array($name)) return ($_GET=$name);
+
+               # Delete key
+               if ($value === null or $value === '') {
+                       unset ($_GET[$name]);
+                       return null;
+               }
+
+               # Set value
+               return ($_GET[$name] = $value);
+       }
+
+       public static function pset($name,$value=null) {
+               if(NB_P_GET) return self::_pset_get($name,$value);
+
+               # Brutal !
+               if (is_array($name)) return ($_REQUEST=$name);
+
+               # Delete key
+               if ($value === null or $value === '') {
+                       unset ($_REQUEST[$name]);
+                       return null;
+               }
+
+               # Set value
+               return ($_REQUEST[$name] = $value);
+       }
+
+       /*
+        * Function: bye
+        * Set a value for param, delete it if null
+        */
 # NB 30.10.17   public static function bye($msg='',$backtrace_deep=0) {
 # NB 30.10.17     #throw new Exception($msg);
 # NB 30.10.17     return bye($msg,$backtrace_deep+1);
 # NB 30.10.17   }
-  # # NB 30.10.17: From function.php 
-  public static function bye($msg='__bye__',$backtrace_deep=0) {
-    #if ($msg) err($msg,'bye',$backtrace_deep === 0 ? 1 : $backtrace_deep);
+       # # NB 30.10.17: From function.php 
+       public static function bye($msg='__bye__',$backtrace_deep=0) {
+               #if ($msg) err($msg,'bye',$backtrace_deep === 0 ? 1 : $backtrace_deep);
 
-    if ($msg!=='__bye__') {
-      #throw new Exception($msg);
-      header("HTTP/1.0 500 Internal Server Error");
+               if ($msg!=='__bye__') {
+                       #throw new Exception($msg);
+                       header("HTTP/1.0 500 Internal Server Error");
 # NB 15.11.17       err($msg,'bye',( $backtrace_deep !== false ? (1+-1+$backtrace_deep) : $backtrace_deep ));
-      err($msg,'bye',1+$backtrace_deep);
-      exit(1);
-    }
-
-    #if ($msg) err($msg,'bye',1+$backtrace_deep);
-    exit;
-    #die("Can't exit from BYE!!!");
-  }
-
-  public static function err($msg='__err__',$preff='err',$backtrace_deep=0) {
-    $msg = is_scalar($msg) ? $msg : print_r($msg,true);
-    $preff_msg = $preff ? strtoupper($preff).': ' : '';
-
-    if ($msg !== '__err__' and $backtrace_deep !== false) {
-      $msg = trim($preff_msg.$msg).' '
-        .self::debug_backtrace_msg(1+$backtrace_deep,NULL,$preff_msg)
-        #.self::debug_backtrace_msg(1+$backtrace_deep,NULL)
-      ;
-
-    } else { 
-      $msg = $preff_msg.$msg;
-
-    }
-
-    #self::msg( !self::php_cli()
-    self::msg( self::client_header('Accept','ml')
-      ? '<pre'
-          .' class="err'. ( ($preff and $preff!='err') ? " $preff" : '' ).'"'
-        .'>'.$msg.'</pre>'.NB_EOL
-      : $msg
-    ).NB_EOL;
-
-  }
-
-  /*
-   * Function: debug
-   * Does what it says
-   */
+                       err($msg,'bye',1+$backtrace_deep);
+                       exit(1);
+               }
+
+               #if ($msg) err($msg,'bye',1+$backtrace_deep);
+               exit;
+               #die("Can't exit from BYE!!!");
+       }
+
+       public static function err($msg='__err__',$preff='err',$backtrace_deep=0) {
+               $msg = is_scalar($msg) ? $msg : print_r($msg,true);
+               $preff_msg = $preff ? strtoupper($preff).': ' : '';
+
+               if ($msg !== '__err__' and $backtrace_deep !== false) {
+                       $msg = trim($preff_msg.$msg).' '
+                               .self::debug_backtrace_msg(1+$backtrace_deep,NULL,$preff_msg)
+                               #.self::debug_backtrace_msg(1+$backtrace_deep,NULL)
+                       ;
+
+               } else { 
+                       $msg = $preff_msg.$msg;
+
+               }
+
+               #self::msg( !self::php_cli()
+               self::msg( self::client_header('Accept','ml')
+                       ? '<pre'
+                                       .' class="err'. ( ($preff and $preff!='err') ? " $preff" : '' ).'"'
+                               .'>'.$msg.'</pre>'.NB_EOL
+                       : $msg
+               ).NB_EOL;
+
+       }
+
+       /*
+        * Function: debug
+        * Does what it says
+        */
 # NB 15.11.17   public static function debug($msg,$level=0) {
 # NB 15.11.17     return debug($msg,$level);
 # NB 15.11.17   }
-  public static function debug($msg,$level=0) {
-    if ($level and $level>self::p('debug')) return;
-    #$msg = is_scalar($msg) ? $msg : print_r($msg,true);
-    $msg = is_scalar($msg) ? $msg : print_r($msg,true);
-
-    if (self::client_header('Accept','ml')) {
-      $msg = '<pre class="debug">'
-        .(isset($_SERVER['HTTP_HOST']) ? htmlentities($msg) : $msg)
-  # NB 16.12.15       .(isset($_SERVER['HTTP_HOST']) ? htmlspecialchars($msg) : $msg)
-      .'</pre>'.NB_EOL;
-
-    } else {
-      $msg = "DEBUG: $msg\n";
-
-    }
-    self::msg($msg);
-
-  }
-
-  /*
-   * Function: ar_map
-   * Does what it says
-   */
-  public static function ar_map($return,$array,$as_hash=false) {
-    return ar_map($return,$array,$as_hash);
-  }
-
-  /*
-   * Function: prettyText
-   * Does what it says
-   */
-  public static function prettyText($text) {
-    return prettyText($text);
-  }
-
-  public static function mime2ext($mime) {
-
-    static $aliases = null;
-    if ($aliases === null) $aliases = array_combine(
-      array_values(self::$content_types_aliases),
-      array_keys(self::$content_types_aliases)
-    );
-
-    foreach (self::$content_types as $e => $c) {
-      if ($mime == $c) return $e;
-    }
-
-    // Aliases
-    if (isset($aliases[$mime])) return self::ext2mime($aliases[$mime]);
-
-  }
-
-  /*
-   * Function: ext2mime
-   * Does what it says
-   */
-  #public static function ext2content_type($ext) { return self::ext2mime($ext); }
-  public static function ext2mime($ext) {
-
-    foreach (self::$content_types as $e => $c) {
-      if ($ext == $e) return $c;
-    }
-
-    // Aliases
-    if (isset(self::$content_types_aliases[$ext])) return self::ext2mime(self::$content_types_aliases[$ext]);
-
-  }
-
-  /*
-   * Function: ar_first
-   * Does what it says
-   */
-  public static function ar_first(&$ar,$hkeys=false) {
-    # Strict Standards: Non-static method: if (self::is_hash($ar)) return ar_first(array_keys($ar));
-    #if (self::is_hash($ar)) return ar_first(array_keys($ar));
-    $is_hash = null;
+       public static function debug($msg,$level=0) {
+               if ($level and $level>self::p('debug')) return;
+               #$msg = is_scalar($msg) ? $msg : print_r($msg,true);
+               $msg = is_scalar($msg) ? $msg : print_r($msg,true);
+
+               if (self::client_header('Accept','ml')) {
+                       $msg = '<pre class="debug">'
+                               .(isset($_SERVER['HTTP_HOST']) ? htmlentities($msg) : $msg)
+       # NB 16.12.15       .(isset($_SERVER['HTTP_HOST']) ? htmlspecialchars($msg) : $msg)
+                       .'</pre>'.NB_EOL;
+
+               } else {
+                       $msg = "DEBUG: $msg\n";
+
+               }
+               self::msg($msg);
+
+       }
+
+       /*
+        * Function: ar_map
+        * Does what it says
+        */
+       public static function ar_map($return,$array,$as_hash=false) {
+               return ar_map($return,$array,$as_hash);
+       }
+
+       /*
+        * Function: prettyText
+        * Does what it says
+        */
+       public static function prettyText($text) {
+               return prettyText($text);
+       }
+
+       public static function mime2ext($mime) {
+
+               static $aliases = null;
+               if ($aliases === null) $aliases = array_combine(
+                       array_values(self::$content_types_aliases),
+                       array_keys(self::$content_types_aliases)
+               );
+
+               foreach (self::$content_types as $e => $c) {
+                       if ($mime == $c) return $e;
+               }
+
+               // Aliases
+               if (isset($aliases[$mime])) return self::ext2mime($aliases[$mime]);
+
+       }
+
+       /*
+        * Function: ext2mime
+        * Does what it says
+        */
+       #public static function ext2content_type($ext) { return self::ext2mime($ext); }
+       public static function ext2mime($ext) {
+
+               foreach (self::$content_types as $e => $c) {
+                       if ($ext == $e) return $c;
+               }
+
+               // Aliases
+               if (isset(self::$content_types_aliases[$ext])) return self::ext2mime(self::$content_types_aliases[$ext]);
+
+       }
+
+       /*
+        * Function: ar_first
+        * Does what it says
+        */
+       public static function ar_first(&$ar,$hkeys=false) {
+               # Strict Standards: Non-static method: if (self::is_hash($ar)) return ar_first(array_keys($ar));
+               #if (self::is_hash($ar)) return ar_first(array_keys($ar));
+               $is_hash = null;
                foreach ($ar as $k=>$v) {
-      $is_hash = ($k === 0) ? false : true;
-      break;
+                       $is_hash = ($k === 0) ? false : true;
+                       break;
                }
                #$is_hash = (array_values($ar) === $ar);
-    # Should return the first k => v - NB 06.03.16
-    if ($is_hash) return ar_first($hkeys ? array_keys($ar) : array_values($ar));
-    return ar_first($ar);
-  }
-
-  /*
-   * Function: server_header
-   */
-  public static function server_header($name=null,$match=null) {
-    static $header = null;
-    if ( $header === null ) {
-      $header = array();
-      foreach (headers_list() as $h) {
-        if ( preg_match("/^([^:]+)\s*:\s+(.*?)\s*$/",$h,$m) ) $header[$m[1]] = $m[2];
-      }
-    }
-
-    # Array
-    if ($name === null) return $header;
-
-    # Search
-    if ($match) {
-      foreach ($header as $k=>$v) { if (strpos($v,$match) !== false) return $v; }
-      return false;
-    }
-
-    # Key
-    return isset($header[$name]) ? $header[$name] : null;
-  }
-
-  /*
-   * Function: client_header
-   * Return a client header. Work only with apache !
-   */
-  public static function client_header($name=null,$match=null) {
-    static $header = null;
-    if ( $header === null ) {
-      $header = [];
+               # Should return the first k => v - NB 06.03.16
+               if ($is_hash) return ar_first($hkeys ? array_keys($ar) : array_values($ar));
+               return ar_first($ar);
+       }
+
+       /*
+        * Function: server_header
+        */
+       public static function server_header($name=null,$match=null) {
+               static $header = null;
+               if ( $header === null ) {
+                       $header = array();
+                       foreach (headers_list() as $h) {
+                               if ( preg_match("/^([^:]+)\s*:\s+(.*?)\s*$/",$h,$m) ) $header[$m[1]] = $m[2];
+                       }
+               }
+
+               # Array
+               if ($name === null) return $header;
+
+               # Search
+               if ($match) {
+                       foreach ($header as $k=>$v) { if (strpos($v,$match) !== false) return $v; }
+                       return false;
+               }
+
+               # Key
+               return isset($header[$name]) ? $header[$name] : null;
+       }
+
+       /*
+        * Function: client_header
+        * Return a client header. Work only with apache !
+        */
+       public static function client_header($name=null,$match=null) {
+               static $header = null;
+               if ( $header === null ) {
+                       $header = [];
 
                        if (function_exists('getallheaders')) {
-        $header = getallheaders();
+                               $header = getallheaders();
+
+                       } else {
+                               foreach ($_SERVER as $key => $value) {
+                                       if (substr($key, 0, 5) == 'HTTP_') {
+                                               $header[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))))] = $value;
+                                       }
+                               }
+               #bye( [$name,$header] ); # argcs ????
+
+                       }
+
+               }
+
+               # Array
+               if ($name === null) return $header;
+
+               # Search
+               if ($match) {
+                       foreach ($header as $k=>$v) { if (strpos($v,$match) !== false) return $v; }
+                       return false;
+               }
+
+               # Key
+               return isset($header[$name]) ? $header[$name] : null;
+       }
+
+       /*
+        * Function: argv2request
+        * Set $_REQUEST from argv
+        */
+       public static function argv2request($args=null) {
+
+               if (isset($args)) {
+                       $argv = $args;
+                       $args = [];
+               } else {
+                       global $argv;
+               }
+
+               $new_argv = array();
+               for ($i=1;$i<count($argv);$i++) {
+
+                       if (preg_match('/^([\w_\-\.]+)=(.+)\s*$/',$argv[$i],$f)) {
+                               $k = $f[1];
+                               $v = $f[2];
+
+                               // Array
+                               if (preg_match('/^(.*)\[\]$/',$k,$p)) {
+                                       #bye($p);
+                                       if (($_REQUEST[$p[1]]==NULL) or !in_array($v,$_REQUEST[$p[1]])) $_REQUEST[$p[1]][] = $v;
+
+                               } else {
+                                        $_REQUEST[$k] = $v;
+
+                               }
+
+                       } else {
+
+                               if (preg_match('/^-(h|-?help)$/',$argv[$i])) $_REQUEST['help'] = 1;
+                               else $new_argv[] = $argv[$i];
+
+                       }
 
-      } else {
-        foreach ($_SERVER as $key => $value) {
-          if (substr($key, 0, 5) == 'HTTP_') {
-            $header[str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($key, 5)))))] = $value;
-          }
-        }
-    #bye( [$name,$header] ); # argcs ????
+               }
+
+               if (!empty($_REQUEST)) {
+                       if (empty($_POST)) $_POST = $_REQUEST;
+                       if (empty($_GET)) $_GET = $_REQUEST;
+               }
+
+               return $new_argv;
+
+       }
+
+       /*
+        * Function: benchmark
+        * Call a function several times
+        * Usage: benchmark("f1"); benchmark("f2"); benchmark();
+        */
+       public static function benchmark($function=null,$limit=100000) {
+               global $_benchmark;
+
+               if ($_benchmark === null) {
+                       $_benchmark = array('.' => microtime(true));
+               }
 
+               if ($function === null) {
+                       $prev = $_benchmark['.'];
+                       echo "Results: $limit\n";
+                       foreach ($_benchmark as $lib => $sec) {
+                               if ($lib === '.') continue;
+                               printf("%-30s %s\n",$lib,($sec-$prev));
+                               $prev = $sec;
                        }
+                       return;
+               }
+
+               for ($i=0; $i<$limit; $i++) {
+                       $function();
+               }
+
+               echo "Completed: $function\n";
+               $_benchmark[$function] = microtime(true);
+       }
+
+       public static function json_decode($v) { return json_decode($v); }
+       public static function json_encode($v) { return json_encode($v); }
 
-    }
+       /*
+        * Function: object2array
+        */
+       public static function object2array($o) { return $array = json_decode(json_encode($o), true); }
 
-    # Array
-    if ($name === null) return $header;
+       private static function yaml_init() {
+               static $Spyc;
+               if (!isset($Spyc)) {
+
+                       if (!function_exists('yaml_emit')) {
+                               require_once(NB_ROOT.'/lib/php/Spyc.php');
+                               function yaml_emit($data) { return Spyc::YAMLDump($data, false, false, true); }
+                               function yaml_parse_file($file) { return Spyc::YAMLLoad($file); }
+                               function yaml_parse($str) { return Spyc::YAMLLoadString($str); }
+                       }
 
-    # Search
-    if ($match) {
-      foreach ($header as $k=>$v) { if (strpos($v,$match) !== false) return $v; }
-      return false;
-    }
-
-    # Key
-    return isset($header[$name]) ? $header[$name] : null;
-  }
-
-  /*
-   * Function: argv2request
-   * Set $_REQUEST from argv
-   */
-  public static function argv2request($args=null) {
-
-    if (isset($args)) {
-      $argv = $args;
-      $args = [];
-    } else {
-      global $argv;
-    }
-
-    $new_argv = array();
-    for ($i=1;$i<count($argv);$i++) {
-
-      if (preg_match('/^([\w_\-\.]+)=(.+)\s*$/',$argv[$i],$f)) {
-        $k = $f[1];
-        $v = $f[2];
-
-        // Array
-        if (preg_match('/^(.*)\[\]$/',$k,$p)) {
-          #bye($p);
-          if (($_REQUEST[$p[1]]==NULL) or !in_array($v,$_REQUEST[$p[1]])) $_REQUEST[$p[1]][] = $v;
-
-        } else {
-           $_REQUEST[$k] = $v;
-
-        }
-
-      } else {
-
-        if (preg_match('/^-(h|-?help)$/',$argv[$i])) $_REQUEST['help'] = 1;
-        else $new_argv[] = $argv[$i];
-
-      }
-
-    }
-
-    if (!empty($_REQUEST)) {
-      if (empty($_POST)) $_POST = $_REQUEST;
-      if (empty($_GET)) $_GET = $_REQUEST;
-    }
-
-    return $new_argv;
-
-  }
-
-  /*
-   * Function: benchmark
-   * Call a function several times
-   * Usage: benchmark("f1"); benchmark("f2"); benchmark();
-   */
-  public static function benchmark($function=null,$limit=100000) {
-    global $_benchmark;
-
-    if ($_benchmark === null) {
-      $_benchmark = array('.' => microtime(true));
-    }
-
-    if ($function === null) {
-      $prev = $_benchmark['.'];
-      echo "Results: $limit\n";
-      foreach ($_benchmark as $lib => $sec) {
-        if ($lib === '.') continue;
-        printf("%-30s %s\n",$lib,($sec-$prev));
-        $prev = $sec;
-      }
-      return;
-    }
-
-    for ($i=0; $i<$limit; $i++) {
-      $function();
-    }
-
-    echo "Completed: $function\n";
-    $_benchmark[$function] = microtime(true);
-  }
-
-  public static function json_decode($v) { return json_decode($v); }
-  public static function json_encode($v) { return json_encode($v); }
-
-  /*
-   * Function: object2array
-   */
-  public static function object2array($o) { return $array = json_decode(json_encode($o), true); }
-
-  private static function yaml_init() {
-    static $Spyc;
-    if (!isset($Spyc)) {
-
-      if (!function_exists('yaml_emit')) {
-        require_once(NB_ROOT.'/lib/php/Spyc.php');
-        function yaml_emit($data) { return Spyc::YAMLDump($data, false, false, true); }
-        function yaml_parse_file($file) { return Spyc::YAMLLoad($file); }
-        function yaml_parse($str) { return Spyc::YAMLLoadString($str); }
-      }
-
-      $Spyc = true;
-    }
-  }
-
-  public static function yaml_parse_file($file) {
-    self::yaml_init();
-    return yaml_parse_file($file);
-  }
-
-  /*
-   * Function: yaml_encode
-   */
-  public static function yaml_encode($row) {
-    self::yaml_init();
-    $yaml = yaml_emit($row);
-    $yaml = preg_replace('/^---\s*/','',$yaml);
-    $yaml = preg_replace('/\n\.\.\.$/','',$yaml);
-    $yaml = trim($yaml);
-    #if ($yaml === "---") return '' ;
-    return "$yaml\n";
-  }
-
-  public static function yaml_decode($str) {
-    self::yaml_init();
-    return yaml_parse($str);
-  }
-
-  /*
-  * Function: debug_backtrace_msg
-  * @copyright 13.07.11
-  * @author NB
+                       $Spyc = true;
+               }
+       }
+
+       public static function yaml_parse_file($file) {
+               self::yaml_init();
+               return yaml_parse_file($file);
+       }
+
+       /*
+        * Function: yaml_encode
+        */
+       public static function yaml_encode($row) {
+               self::yaml_init();
+               $yaml = yaml_emit($row);
+               $yaml = preg_replace('/^---\s*/','',$yaml);
+               $yaml = preg_replace('/\n\.\.\.$/','',$yaml);
+               $yaml = trim($yaml);
+               #if ($yaml === "---") return '' ;
+               return "$yaml\n";
+       }
+
+       public static function yaml_decode($str) {
+               self::yaml_init();
+               return yaml_parse($str);
+       }
+
+       /*
+       * Function: debug_backtrace_msg
+       * @copyright 13.07.11
+       * @author NB
        * Return backtrace message
-  */
+       */
        public static function debug_backtrace_msg($deep=NULL,$one_line=NULL,$preff='') {
 
-    $msg = '';
+               $msg = '';
                if (self::p('_debug_backtrace_msg')) $deep = self::p('_debug_backtrace_msg');
-    if ($deep < 0 or $deep === false) return $msg;
+               if ($deep < 0 or $deep === false) return $msg;
 
-    $debug = debug_backtrace(); array_shift($debug);
+               $debug = debug_backtrace(); array_shift($debug);
 
-    for ($i=0;$i<$deep;$i++) {
-      array_shift($debug);
-    }
+               for ($i=0;$i<$deep;$i++) {
+                       array_shift($debug);
+               }
 
-    foreach ($debug as $i=>$call_info) {
-      $msg .= ( $one_line ? ($preff !=='' ? $preff : ' | ') : "\n$preff " ) . self::debug_backtrace_info($call_info);
-    }
+               foreach ($debug as $i=>$call_info) {
+                       $msg .= ( $one_line ? ($preff !=='' ? $preff : ' | ') : "\n$preff " ) . self::debug_backtrace_info($call_info);
+               }
 
                return $msg."\n";
        }
 
-  /*
-  * Function: debug_backtrace_info
-  * @copyright 13.07.11
-  * @author NB
+       /*
+       * Function: debug_backtrace_info
+       * @copyright 13.07.11
+       * @author NB
        * Return backtrace message
-  */
-  public static function debug_backtrace_info($call_info) {
-
-    // Error into string
-    $errorType = array (
-      E_ERROR          => 'ERROR',
-      E_WARNING        => 'WARNING',
-      E_PARSE          => 'PARSING ERROR',
-      E_NOTICE         => 'NOTICE',
-
-      E_CORE_ERROR     => 'CORE ERROR',
-      E_CORE_WARNING   => 'CORE WARNING',
-      E_COMPILE_ERROR  => 'COMPILE ERROR',
-      E_COMPILE_WARNING => 'COMPILE WARNING',
-
-      E_USER_ERROR     => 'USER ERROR',
-      E_USER_WARNING   => 'USER WARNING',
-      E_USER_NOTICE    => 'USER NOTICE',
-
-      E_STRICT         => 'STRICT NOTICE',
-
-      E_RECOVERABLE_ERROR  => 'RECOVERABLE ERROR',
-      E_DEPRECATED  => 'E_DEPRECATED ERROR',
-      E_USER_DEPRECATED  => 'E_USER_DEPRECATED ERROR',
-    );
-
-    if (isset($call_info['type'])
-      and isset($errorType[$call_info['type']])
-    ) {
-      $call_info['type'] = $errorType[$call_info['type']].'='.$call_info['type'];
-    }
-
-    // Default values
-    if (isset($call_info['file']) and !empty($_SERVER['DOCUMENT_ROOT']))
-      $call_info['file'] = str_replace($_SERVER['DOCUMENT_ROOT'].'/','',$call_info['file'])
-    ;
-
-    // Get infos
-    $msg = [];
-    foreach ([
-      'file',
-      'line',
-      'function',
-      'type',
-      'message',
-      'code',
-    ] as $i) {
-
-      if (!array_key_exists($i,$call_info)) continue;
-      if ($i == 'type' and preg_match('/^\W\W/',$call_info[$i])) continue;
-      $msg[] = "$i=".$call_info[$i];
-
-    }
-
-    return join(' ',$msg);
-  }
+       */
+       public static function debug_backtrace_info($call_info) {
+
+               // Error into string
+               $errorType = array (
+                       E_ERROR          => 'ERROR',
+                       E_WARNING        => 'WARNING',
+                       E_PARSE          => 'PARSING ERROR',
+                       E_NOTICE         => 'NOTICE',
+
+                       E_CORE_ERROR     => 'CORE ERROR',
+                       E_CORE_WARNING   => 'CORE WARNING',
+                       E_COMPILE_ERROR  => 'COMPILE ERROR',
+                       E_COMPILE_WARNING => 'COMPILE WARNING',
+
+                       E_USER_ERROR     => 'USER ERROR',
+                       E_USER_WARNING   => 'USER WARNING',
+                       E_USER_NOTICE    => 'USER NOTICE',
+
+                       E_STRICT         => 'STRICT NOTICE',
+
+                       E_RECOVERABLE_ERROR  => 'RECOVERABLE ERROR',
+                       E_DEPRECATED  => 'E_DEPRECATED ERROR',
+                       E_USER_DEPRECATED  => 'E_USER_DEPRECATED ERROR',
+               );
+
+               if (isset($call_info['type'])
+                       and isset($errorType[$call_info['type']])
+               ) {
+                       $call_info['type'] = $errorType[$call_info['type']].'='.$call_info['type'];
+               }
+
+               // Default values
+               if (isset($call_info['file']) and !empty($_SERVER['DOCUMENT_ROOT']))
+                       $call_info['file'] = str_replace($_SERVER['DOCUMENT_ROOT'].'/','',$call_info['file'])
+               ;
+
+               // Get infos
+               $msg = [];
+               foreach ([
+                       'file',
+                       'line',
+                       'function',
+                       'type',
+                       'message',
+                       'code',
+               ] as $i) {
+
+                       if (!array_key_exists($i,$call_info)) continue;
+                       if ($i == 'type' and preg_match('/^\W\W/',$call_info[$i])) continue;
+                       $msg[] = "$i=".$call_info[$i];
+
+               }
+
+               return join(' ',$msg);
+       }
 
        /**
        * @copyright NB 05.03.16
@@ -569,500 +569,507 @@ class NB {
        * @return BOOL
        */
        public static function is_hash(&$arr) {
-    if (!is_array($arr)) return false;
+               if (!is_array($arr)) return false;
                foreach ($arr as $k=>$v) {
-      return ($k === 0) ? false : true;
+                       return ($k === 0) ? false : true;
                }
-    return null;
+               return null;
                return (array_values($arr) === $arr);
        }
 
-  public static function hksort(&$h,$k,$get_first=false) {
-    uasort($h,create_function('$a,$b','$a_=isset($a["'.$k.'"])?$a["'.$k.'"]:-1;$b_=isset($b["'.$k.'"])?$b["'.$k.'"]:-1; return($b_-$a_);'));
-    if ($get_first) {
-      $first = self::ar_first($h);
-      if ($get_first !== true) return $first[$get_first];
-      return $first;
-    }
-    return true;
-  }
-
-  /**
-  * @copyright NB 06.03.16
-  * Print message on stderr if php is in client mode
-  */
-  public static function msg($msg) {
-    if (self::php_cli()) return file_write("php://stderr",$msg);
-    echo($msg);
-  }
-  /*
-  public static function ar_sort(&$ary, $clause, $ascending = true) {
-    $clause = str_ireplace('order by', '', $clause);
-    $clause = preg_replace('/\s+/', ' ', $clause);
-    $keys = explode(',', $clause);
-    $dirMap = array('desc' => 1, 'asc' => -1);
-    $def = $ascending ? -1 : 1;
-
-    $keyAry = array();
-    $dirAry = array();
-    foreach($keys as $key) {
-        $key = explode(' ', trim($key));
-        $keyAry[] = trim($key[0]);
-        if(isset($key[1])) {
-            $dir = strtolower(trim($key[1]));
-            $dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
-        } else {
-            $dirAry[] = $def;
-        }
-    }
-
-    $fnBody = '';
-    for($i = count($keyAry) - 1; $i >= 0; $i--) {
-        $k = $keyAry[$i];
-        $t = $dirAry[$i];
-        $f = -1 * $t;
-        $aStr = '$a[\''.$k.'\']';
-        $bStr = '$b[\''.$k.'\']';
-        if(strpos($k, '(') !== false) {
-            $aStr = '$a->'.$k;
-            $bStr = '$b->'.$k;
-        }
-
-        if($fnBody == '') {
-            $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
-            $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";               
-        } else {
-            $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
-            $fnBody .= "}\n";
-            $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
-        }
-    }
-
-    if($fnBody) {
-        $sortFn = create_function('$a,$b', $fnBody);
-        usort($ary, $sortFn);       
-    }
-  }
-  */
-
-  public static function php_cli() {
+       public static function hksort(&$h,$k,$get_first=false) {
+               uasort($h,create_function('$a,$b','$a_=isset($a["'.$k.'"])?$a["'.$k.'"]:-1;$b_=isset($b["'.$k.'"])?$b["'.$k.'"]:-1; return($b_-$a_);'));
+               if ($get_first) {
+                       $first = self::ar_first($h);
+                       if ($get_first !== true) return $first[$get_first];
+                       return $first;
+               }
+               return true;
+       }
+
+       /**
+       * @copyright NB 06.03.16
+       * Print message on stderr if php is in client mode
+       */
+       public static function msg($msg) {
+               if (self::php_cli()) return file_write("php://stderr",$msg);
+               echo($msg);
+       }
+       /*
+       public static function ar_sort(&$ary, $clause, $ascending = true) {
+               $clause = str_ireplace('order by', '', $clause);
+               $clause = preg_replace('/\s+/', ' ', $clause);
+               $keys = explode(',', $clause);
+               $dirMap = array('desc' => 1, 'asc' => -1);
+               $def = $ascending ? -1 : 1;
+
+               $keyAry = array();
+               $dirAry = array();
+               foreach($keys as $key) {
+                               $key = explode(' ', trim($key));
+                               $keyAry[] = trim($key[0]);
+                               if(isset($key[1])) {
+                                               $dir = strtolower(trim($key[1]));
+                                               $dirAry[] = $dirMap[$dir] ? $dirMap[$dir] : $def;
+                               } else {
+                                               $dirAry[] = $def;
+                               }
+               }
+
+               $fnBody = '';
+               for($i = count($keyAry) - 1; $i >= 0; $i--) {
+                               $k = $keyAry[$i];
+                               $t = $dirAry[$i];
+                               $f = -1 * $t;
+                               $aStr = '$a[\''.$k.'\']';
+                               $bStr = '$b[\''.$k.'\']';
+                               if(strpos($k, '(') !== false) {
+                                               $aStr = '$a->'.$k;
+                                               $bStr = '$b->'.$k;
+                               }
+
+                               if($fnBody == '') {
+                                               $fnBody .= "if({$aStr} == {$bStr}) { return 0; }\n";
+                                               $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";               
+                               } else {
+                                               $fnBody = "if({$aStr} == {$bStr}) {\n" . $fnBody;
+                                               $fnBody .= "}\n";
+                                               $fnBody .= "return ({$aStr} < {$bStr}) ? {$t} : {$f};\n";
+                               }
+               }
+
+               if($fnBody) {
+                               $sortFn = create_function('$a,$b', $fnBody);
+                               usort($ary, $sortFn);       
+               }
+       }
+       */
+
+       public static function php_cli() {
 # NB 05.03.16 define('NB_CLI', PHP_SAPI === 'cli');
-    static $php_cli;
-    if ($php_cli===null or $php_cli==='') $php_cli= (
-      !isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0))
-    );
-    return $php_cli;
-  }
-
-  public static function no_accent($str){
-    return strtr($str,array(
-      'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'Ā' => 'A', 'ā' => 'a', 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a',
-      'Ç' => 'C', 'ç' => 'c', 'Ć' => 'C', 'ć' => 'c', 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c',
-      'Ð' => 'D', 'ð' => 'd', 'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd',
-      'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'Ē' => 'E', 'ē' => 'e', 'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 'Ě' => 'E', 'ě' => 'e',
-      'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G', 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g',
-      'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h',
-      'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I', 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 'ı' => 'i',
-      'Ĵ' => 'J', 'ĵ' => 'j',
-      'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k',
-      'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L', 'ł' => 'l',
-      'Ñ' => 'N', 'ñ' => 'n', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N', 'ň' => 'n', 'ʼn' => 'n', 'Ŋ' => 'N', 'ŋ' => 'n',
-      'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'Ō' => 'O', 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o',
-      'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 'ř' => 'r',
-      'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 'ş' => 's', 'Š' => 'S', 'š' => 's', 'ſ' => 's',
-      'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T', 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't',
-      'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U', 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U', 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u',
-      'Ŵ' => 'W', 'ŵ' => 'w',
-      'Ý' => 'Y', 'ý' => 'y', 'ÿ' => 'y', 'Ŷ' => 'Y', 'ŷ' => 'y', 'Ÿ' => 'Y',
-      'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 'Ž' => 'Z', 'ž' => 'z'
-    ));
-  }
-
-  /**
-  * If action on class, gener output
-  */
-  public static function class_action_out($class,$action) {
-    $class_name = strtolower(get_class($class));
-
-    if (!preg_match('/^'.$class_name.'\.(\w+)/',$action,$m)) return null;
-    $name = $m[1];
-
-    $rows = array();
-    if (in_array($name,get_class_methods($class))) $rows = $class->$name();
-    elseif (in_array($name,get_class_vars($class_name))) $rows = $class->$name;
-    else self::bye("Unknown action: `$action`");
-
-    if (is_array($rows) and !$rows) return $rows;
-    if (!$rows) return false;
-    if ($rows === true) return true;
-
-    if (is_scalar($rows)) {
-      $rows = array($name => $rows);
-    }
-    out::rows(self::p('format',self::php_cli() ? 'csv' : 'table'),$rows,(is_scalar($rows) ? $name : []));
-    return true;
-  }
-
-  public static function cidr_range( $cidr, $chkip=null ) {
-    // Assign IP / mask
-    if (empty($cidr)) return false;
-    list($ip,$mask) = explode("/",$cidr);
-
-    // Sanitize IP
-    $ip1 = preg_replace( '_(\d+\.\d+\.\d+\.\d+).*$_', '$1', "$ip.0.0.0" );
-
-    // Calculate range
-    $ip2 = long2ip( ip2long( $ip1 ) - 1 + ( 1 << ( 32 - $mask) ) );
-
-    // are we cidr range cheking?
-    if ( $chkip != null && ! filter_var( $chkip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false ) {
-      return ip2long( $ip1 ) <= ip2long( $chkip ) && ip2long( $ip2 ) >= ip2long( $chkip ) ? true : false;
-    } else {
-      return "$ip1 - $ip2";
-    }
-  }
-
-  public static function str_match($string,$pattern) {
-      $match = false;
-
-      // No empty values
-      if (strcmp($pattern,'')==0 or $pattern=='!' or $pattern=='~') return false;
-
-      // Equal / Not Equal
-      $equal = '=';
-      $not = strpos($pattern,'!')===0 ? true : false;
-      if ($not) $pattern = substr($pattern,1);
-
-      // Regex
-      if (strpos($pattern,'~')===0) {
-        $pattern = substr($pattern,1);
-        $match = preg_match('@'.str_replace('@','\@',$pattern).'@i',$string);
-
-      // Superior
-      } elseif (strpos($pattern,'>')===0) {
-        $pattern = substr($pattern,1);
-        $match = ($string > $pattern);
-      } elseif (strpos($pattern,'>=')===0) {
-        $pattern = substr($pattern,2);
-        $match = ($string >= $pattern);
-
-      // Inferior
-      } elseif (strpos($pattern,'<')===0) {
-        $pattern = substr($pattern,1);
-        $match = ($string < $pattern);
-      } elseif (strpos($pattern,'<=')===0) {
-        $pattern = substr($pattern,2);
-        $match = ($string <= $pattern);
-
-      // Match
-      } elseif(preg_match('/['.preg_quote('*?[]!').']/',$pattern)) {
-        $match = fnmatch($pattern,$string,FNM_CASEFOLD);
-
-      // Default
-      } else {
-
-        if (strtolower($pattern)=='null') {
-          $pattern = '';
-          if (!$string) $string = 0;
-        }
-
-        $match = (strtolower($pattern) == strtolower($string));
-
-      }
-
-      return (bool)($not ? !$match : $match);
-
-  }
-
-  public static function file_write($file,$data,$mode='w') {
-
-    if (!$ftmp = fopen($file,$mode)) {
-      bye("file_write(): Can't open $file in mode $mode");
-      return;
-    }
-
-    if (fwrite($ftmp,$data) === FALSE) {
-      bye("file_write(): Can't write $file in mode $mode");
-      return;
-    }
-
-    fclose($ftmp);
-    return 1;
-
-  }
-
-  public static function untilde($path) {
-    #if (!function_exists('posix_getuid')) return $path;
-    return preg_replace_callback('/^(~)([\w_-]+)?/',function($m){
-
-      $user = empty($m[2]) ? '' : $m[2];
-      $infos = self::user_infos($user);
-
-      if (empty($infos)) return $m[0];
-
-      return preg_replace("/^~".($user ? $infos['name'] : '')."/",$infos['dir'],$m[0]);
-    },$path);
-  }
-
-  public static function user_infos($user=null,$key=''){
-
-    if ($user === null) $user = '';
-    if ($key === null) $key = '';
-    $infos = [];
-    #bye((array)$infos);
-
-    #
-    # Linux standard
-    #
-    if (function_exists('posix_getuid')) {
-      if ($user==='') $user = posix_getuid();
-      if (preg_match('/^\d+$/',$user)) $infos = posix_getpwuid($user);
-      else $infos = posix_getpwnam($user);
-    }
-
-    #
-    # /etc/passwd
-    #
-    if (!$infos
-      and $user !== ''
-      and self::osname()!='darwin'
-      and is_readable('/etc/passwd')
-      and $handle = fopen("/etc/passwd", "r")
-    ) {
-      $i = preg_match('/^\d+$/',$user) ? 2 : 0; # uid or name
+               static $php_cli;
+               if ($php_cli===null or $php_cli==='') $php_cli= (
+                       !isset($_SERVER['SERVER_SOFTWARE']) && (php_sapi_name() == 'cli' || (is_numeric($_SERVER['argc']) && $_SERVER['argc'] > 0))
+               );
+               return $php_cli;
+       }
+
+       public static function no_accent($str){
+               return strtr($str,array(
+                       'À' => 'A', 'Á' => 'A', 'Â' => 'A', 'Ã' => 'A', 'Ä' => 'A', 'Å' => 'A', 'à' => 'a', 'á' => 'a', 'â' => 'a', 'ã' => 'a', 'ä' => 'a', 'å' => 'a', 'Ā' => 'A', 'ā' => 'a', 'Ă' => 'A', 'ă' => 'a', 'Ą' => 'A', 'ą' => 'a',
+                       'Ç' => 'C', 'ç' => 'c', 'Ć' => 'C', 'ć' => 'c', 'Ĉ' => 'C', 'ĉ' => 'c', 'Ċ' => 'C', 'ċ' => 'c', 'Č' => 'C', 'č' => 'c',
+                       'Ð' => 'D', 'ð' => 'd', 'Ď' => 'D', 'ď' => 'd', 'Đ' => 'D', 'đ' => 'd',
+                       'È' => 'E', 'É' => 'E', 'Ê' => 'E', 'Ë' => 'E', 'è' => 'e', 'é' => 'e', 'ê' => 'e', 'ë' => 'e', 'Ē' => 'E', 'ē' => 'e', 'Ĕ' => 'E', 'ĕ' => 'e', 'Ė' => 'E', 'ė' => 'e', 'Ę' => 'E', 'ę' => 'e', 'Ě' => 'E', 'ě' => 'e',
+                       'Ĝ' => 'G', 'ĝ' => 'g', 'Ğ' => 'G', 'ğ' => 'g', 'Ġ' => 'G', 'ġ' => 'g', 'Ģ' => 'G', 'ģ' => 'g',
+                       'Ĥ' => 'H', 'ĥ' => 'h', 'Ħ' => 'H', 'ħ' => 'h',
+                       'Ì' => 'I', 'Í' => 'I', 'Î' => 'I', 'Ï' => 'I', 'ì' => 'i', 'í' => 'i', 'î' => 'i', 'ï' => 'i', 'Ĩ' => 'I', 'ĩ' => 'i', 'Ī' => 'I', 'ī' => 'i', 'Ĭ' => 'I', 'ĭ' => 'i', 'Į' => 'I', 'į' => 'i', 'İ' => 'I', 'ı' => 'i',
+                       'Ĵ' => 'J', 'ĵ' => 'j',
+                       'Ķ' => 'K', 'ķ' => 'k', 'ĸ' => 'k',
+                       'Ĺ' => 'L', 'ĺ' => 'l', 'Ļ' => 'L', 'ļ' => 'l', 'Ľ' => 'L', 'ľ' => 'l', 'Ŀ' => 'L', 'ŀ' => 'l', 'Ł' => 'L', 'ł' => 'l',
+                       'Ñ' => 'N', 'ñ' => 'n', 'Ń' => 'N', 'ń' => 'n', 'Ņ' => 'N', 'ņ' => 'n', 'Ň' => 'N', 'ň' => 'n', 'ʼn' => 'n', 'Ŋ' => 'N', 'ŋ' => 'n',
+                       'Ò' => 'O', 'Ó' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'O', 'Ø' => 'O', 'ò' => 'o', 'ó' => 'o', 'ô' => 'o', 'õ' => 'o', 'ö' => 'o', 'ø' => 'o', 'Ō' => 'O', 'ō' => 'o', 'Ŏ' => 'O', 'ŏ' => 'o', 'Ő' => 'O', 'ő' => 'o',
+                       'Ŕ' => 'R', 'ŕ' => 'r', 'Ŗ' => 'R', 'ŗ' => 'r', 'Ř' => 'R', 'ř' => 'r',
+                       'Ś' => 'S', 'ś' => 's', 'Ŝ' => 'S', 'ŝ' => 's', 'Ş' => 'S', 'ş' => 's', 'Š' => 'S', 'š' => 's', 'ſ' => 's',
+                       'Ţ' => 'T', 'ţ' => 't', 'Ť' => 'T', 'ť' => 't', 'Ŧ' => 'T', 'ŧ' => 't',
+                       'Ù' => 'U', 'Ú' => 'U', 'Û' => 'U', 'Ü' => 'U', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'ü' => 'u', 'Ũ' => 'U', 'ũ' => 'u', 'Ū' => 'U', 'ū' => 'u', 'Ŭ' => 'U', 'ŭ' => 'u', 'Ů' => 'U', 'ů' => 'u', 'Ű' => 'U', 'ű' => 'u', 'Ų' => 'U', 'ų' => 'u',
+                       'Ŵ' => 'W', 'ŵ' => 'w',
+                       'Ý' => 'Y', 'ý' => 'y', 'ÿ' => 'y', 'Ŷ' => 'Y', 'ŷ' => 'y', 'Ÿ' => 'Y',
+                       'Ź' => 'Z', 'ź' => 'z', 'Ż' => 'Z', 'ż' => 'z', 'Ž' => 'Z', 'ž' => 'z'
+               ));
+       }
+
+       /**
+       * If action on class, gener output
+       */
+       public static function class_action_out($class,$action) {
+               $class_name = strtolower(get_class($class));
+
+               if (!preg_match('/^'.$class_name.'\.(\w+)/',$action,$m)) return null;
+               $name = $m[1];
+
+               $rows = array();
+               if (in_array($name,get_class_methods($class))) $rows = $class->$name();
+               elseif (in_array($name,get_class_vars($class_name))) $rows = $class->$name;
+               else self::bye("Unknown action: `$action`");
+
+               if (is_array($rows) and !$rows) return $rows;
+               if (!$rows) return false;
+               if ($rows === true) return true;
+
+               if (is_scalar($rows)) {
+                       $rows = array($name => $rows);
+               }
+               out::rows(self::p('format',self::php_cli() ? 'csv' : 'table'),$rows,(is_scalar($rows) ? $name : []));
+               return true;
+       }
+
+       public static function cidr_range( $cidr, $chkip=null ) {
+               // Assign IP / mask
+               if (empty($cidr)) return false;
+               list($ip,$mask) = explode("/",$cidr);
+
+               // Sanitize IP
+               $ip1 = preg_replace( '_(\d+\.\d+\.\d+\.\d+).*$_', '$1', "$ip.0.0.0" );
+
+               // Calculate range
+               $ip2 = long2ip( ip2long( $ip1 ) - 1 + ( 1 << ( 32 - $mask) ) );
+
+               // are we cidr range cheking?
+               if ( $chkip != null && ! filter_var( $chkip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) === false ) {
+                       return ip2long( $ip1 ) <= ip2long( $chkip ) && ip2long( $ip2 ) >= ip2long( $chkip ) ? true : false;
+               } else {
+                       return "$ip1 - $ip2";
+               }
+       }
+
+       public static function str_match($string,$patterns) {
+               $match = false;
+
+               foreach ((array)$patterns as $pattern) {
+
+                       // No empty values
+                       if (strcmp($pattern,'')==0 or $pattern=='!' or $pattern=='~') return false;
+
+                       // Equal / Not Equal
+                       $equal = '=';
+                       $not = strpos($pattern,'!')===0 ? true : false;
+                       if ($not) $pattern = substr($pattern,1);
+
+                       // Regex
+                       if (strpos($pattern,'~')===0) {
+                               $pattern = substr($pattern,1);
+                               $match = preg_match('@'.str_replace('@','\@',$pattern).'@i',$string);
+
+                       // Superior
+                       } elseif (strpos($pattern,'>')===0) {
+                               $pattern = substr($pattern,1);
+                               $match = ($string > $pattern);
+                       } elseif (strpos($pattern,'>=')===0) {
+                               $pattern = substr($pattern,2);
+                               $match = ($string >= $pattern);
+
+                       // Inferior
+                       } elseif (strpos($pattern,'<')===0) {
+                               $pattern = substr($pattern,1);
+                               $match = ($string < $pattern);
+                       } elseif (strpos($pattern,'<=')===0) {
+                               $pattern = substr($pattern,2);
+                               $match = ($string <= $pattern);
+
+                       // Match
+                       } elseif(preg_match('/['.preg_quote('*?[]!').']/',$pattern)) {
+                               $match = fnmatch($pattern,$string,FNM_CASEFOLD);
+
+                       // Default
+                       } else {
+
+                               if (strtolower($pattern)=='null') {
+                                       $pattern = '';
+                                       if (!$string) $string = 0;
+                               }
+
+                               $match = (strtolower($pattern) == strtolower($string));
+
+                       }
+
+                       $match = (bool)($not ? !$match : $match);
+                       if ($match) break;
+               }
+
+               return $match;
+               return (bool)($not ? !$match : $match);
+
+       }
+
+       public static function file_write($file,$data,$mode='w') {
+
+               if (!$ftmp = fopen($file,$mode)) {
+                       bye("file_write(): Can't open $file in mode $mode");
+                       return;
+               }
+
+               if (fwrite($ftmp,$data) === FALSE) {
+                       bye("file_write(): Can't write $file in mode $mode");
+                       return;
+               }
+
+               fclose($ftmp);
+               return 1;
+
+       }
+
+       public static function untilde($path) {
+               #if (!function_exists('posix_getuid')) return $path;
+               return preg_replace_callback('/^(~)([\w_-]+)?/',function($m){
+
+                       $user = empty($m[2]) ? '' : $m[2];
+                       $infos = self::user_infos($user);
+
+                       if (empty($infos)) return $m[0];
+
+                       return preg_replace("/^~".($user ? $infos['name'] : '')."/",$infos['dir'],$m[0]);
+               },$path);
+       }
+
+       public static function user_infos($user=null,$key=''){
+
+               if ($user === null) $user = '';
+               if ($key === null) $key = '';
+               $infos = [];
+               #bye((array)$infos);
+
+               #
+               # Linux standard
+               #
+               if (function_exists('posix_getuid')) {
+                       if ($user==='') $user = posix_getuid();
+                       if (preg_match('/^\d+$/',$user)) $infos = posix_getpwuid($user);
+                       else $infos = posix_getpwnam($user);
+               }
+
+               #
+               # /etc/passwd
+               #
+               if (!$infos
+                       and $user !== ''
+                       and self::osname()!='darwin'
+                       and is_readable('/etc/passwd')
+                       and $handle = fopen("/etc/passwd", "r")
+               ) {
+                       $i = preg_match('/^\d+$/',$user) ? 2 : 0; # uid or name
 
                        while (($line = fgets($handle)) !== false) {
-        // process the line read.
-        $line = explode(':',$line);
-        if ($user != $line[$i]) continue;
-        $infos = [
-          'name' => $line[0],
-          'uid' => $line[2],
-          'gid' => $line[3],
-          'dir' => $line[5],
-        ];
-        break;
-        #if ($user == (int)$user)
+                               // process the line read.
+                               $line = explode(':',$line);
+                               if ($user != $line[$i]) continue;
+                               $infos = [
+                                       'name' => $line[0],
+                                       'uid' => $line[2],
+                                       'gid' => $line[3],
+                                       'dir' => $line[5],
+                               ];
+                               break;
+                               #if ($user == (int)$user)
                        }
                        fclose($handle);
-    }
-
-    #
-    # Command
-    #
-    if (!$infos) {
-      $cmd = $user === '' ? 'id' : sprintf('id %s',$user);
-      $line = []; exec(escapeshellcmd($user === '' ? 'id' : 'id '.escapeshellarg($user)).' 2>/dev/null',$line);
-      if ($line and preg_match('/uid=(\d+)\((\S+)\) gid=(\d+)\((\S+)\)/',$line[0],$infos)) {
-        array_shift($infos);
-        $infos = [
-          'name' => $infos[1],
-          'uid' => $infos[0],
-          'gid' => $infos[2],
-          '_group' => $infos[3],
-        ];
-      }
-    }
-
-    if ((!$key or $key == 'dir') and empty($infos['dir']) and !empty($infos['name'])) {
-      $line = []; exec("echo ~".($infos['name']),$line);
-      $infos['dir'] = $line[0];
-      #debug ( `echo ~$cmd` );
-    }
-
-    if ($key) return (empty($infos[$key]) ? '' : $infos[$key] );
-    return $infos;
-  }
-
-  public static function osname(){
-    return strtolower(php_uname('s'));
-    return strtolower(preg_replace('/\s+.*$/','', php_uname()));
-  }
-
-  public static function ls_dir($path,$exp='',$recurse=false) {
-
-    if (!is_readable($path)) return [];
-
-    $ls = [];
-    $rep = opendir($path);
-
-    while($file = readdir($rep)) {
-
-      if ($file === '' or $file == '.' or $file == '..') continue;
+               }
+
+               #
+               # Command
+               #
+               if (!$infos) {
+                       $cmd = $user === '' ? 'id' : sprintf('id %s',$user);
+                       $line = []; exec(escapeshellcmd($user === '' ? 'id' : 'id '.escapeshellarg($user)).' 2>/dev/null',$line);
+                       if ($line and preg_match('/uid=(\d+)\((\S+)\) gid=(\d+)\((\S+)\)/',$line[0],$infos)) {
+                               array_shift($infos);
+                               $infos = [
+                                       'name' => $infos[1],
+                                       'uid' => $infos[0],
+                                       'gid' => $infos[2],
+                                       '_group' => $infos[3],
+                               ];
+                       }
+               }
+
+               if ((!$key or $key == 'dir') and empty($infos['dir']) and !empty($infos['name'])) {
+                       $line = []; exec("echo ~".($infos['name']),$line);
+                       $infos['dir'] = $line[0];
+                       #debug ( `echo ~$cmd` );
+               }
+
+               if ($key) return (empty($infos[$key]) ? '' : $infos[$key] );
+               return $infos;
+       }
+
+       public static function osname(){
+               return strtolower(php_uname('s'));
+               return strtolower(preg_replace('/\s+.*$/','', php_uname()));
+       }
+
+       public static function ls_dir($path,$exp='',$recurse=false) {
+
+               if (!is_readable($path)) return [];
+
+               $ls = [];
+               $rep = opendir($path);
+
+               while($file = readdir($rep)) {
+
+                       if ($file === '' or $file == '.' or $file == '..') continue;
 #die(">>>$file | $exp | $path");
 
-      if (empty($exp) or preg_match('#'.$exp.'#',$file)) {
-        $ls[] = $file;
-        #$ls[] = "$path/$file";
-      }
-
-      if ($recurse and is_dir("$path/$file")) {
-  #print ">>>$path/$file\n";
-
-        foreach (self::ls_dir("$path/$file",$recurse,$exp) as $l) {
-  #print ">>>$path/$file << $l\n";
-          $ls[] = "$file/$l";
-          #$ls[] = $l;
-        }
-
-      }
-
-      #echo "<div>$file</div>\n";
-
-    }
-
-    closedir($rep);
-
-  #print ">>>$path: ".print_r($ls,true)."\n";
-    return $ls;
-
-  }
-
-  /*
-   * Function client_content_type
-   * Return the head Accept from the client
-   */
-  public static function client_content_type($default='') {
-    $v = explode(',', self::client_header('Accept'));
-    return ( ($v and $v[0] != '*/*') ? $v[0] : $default );
-  }
-
-  public static function array_fill_assoc($rows,$keys=null) {
-    if ($keys === null) {
-      $keys = [];
-      foreach(array_reverse($rows) as $v) {
-        foreach ($v as $k=>$vv) $keys[$k] = 1;
-      }
-      $keys = array_keys($keys);
-    }
-
-    # NB 21.12.16: to keep order we need a new array 
-    $new = [];
-    foreach($rows as $k=>$v) {
-      foreach ($keys as $key) {
-        $new[$k][$key] = isset($v[$key]) ? $v[$key] : '';
-        if (!isset($v[$key])) $rows[$k][$key] = '';
-      }
-    }
-
-    return $new;
-    return $rows;
-  }
-
-  public static function strlen($v,$encoding='UTF-8') {
-    return mb_strlen($v,$encoding);
-  }
-
-  public static function mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){
-    $mb_diff=mb_strlen($input, $encoding)-strlen($input);
-    return str_pad($input,$pad_length-$mb_diff,$pad_string,$pad_type);
-  } 
-
-  public static function cryptkey($length=32) {
-    return bin2hex(mcrypt_create_iv($length/2, MCRYPT_DEV_URANDOM));
-  }
-
-  public static function encrypt($key,$value) {
-    static $iv = null;
-    if ($iv === null) {
-      $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
-      $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
-    }
-    return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_CBC, $iv));
-  }
-
-  public static function decrypt($key,$value) {
-    static $iv_size = null;
-    if ($iv_size === null) {
-      $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
-    }
-    $value = base64_decode($value);
-    return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($value, $iv_size), MCRYPT_MODE_CBC, substr($value, 0, $iv_size)));
-  }
-
-  public static function is_vm() {
-    return file_exists('/proc/cpuinfo') && preg_match('/^flags.* hypervisor/m',file_get_contents('/proc/cpuinfo'));
-  }
-
-  public static function html2txt($txt) {
-    return strip_tags($txt);
-  }
-
-  public static function md2html($txt) {
-    static $_txt2md = null;
-    if ($_txt2md === null) {
-      require_once(NB_ROOT.'/lib/php/parsedown/Parsedown.php');
-      $_txt2md = new Parsedown();
-    }
-    return $_txt2md->text($txt);
-  }
-
-  public static function minify_js($code) {
-    if (strpos($code,'/') === 0 and file_exists($code)) $code = file_get_contents($code);
-         require_once(NB_ROOT.'/lib/php/jsmin.php');
+                       if (empty($exp) or preg_match('#'.$exp.'#',$file)) {
+                               $ls[] = $file;
+                               #$ls[] = "$path/$file";
+                       }
+
+                       if ($recurse and is_dir("$path/$file")) {
+       #print ">>>$path/$file\n";
+
+                               foreach (self::ls_dir("$path/$file",$recurse,$exp) as $l) {
+       #print ">>>$path/$file << $l\n";
+                                       $ls[] = "$file/$l";
+                                       #$ls[] = $l;
+                               }
+
+                       }
+
+                       #echo "<div>$file</div>\n";
+
+               }
+
+               closedir($rep);
+
+       #print ">>>$path: ".print_r($ls,true)."\n";
+               return $ls;
+
+       }
+
+       /*
+        * Function client_content_type
+        * Return the head Accept from the client
+        */
+       public static function client_content_type($default='') {
+               $v = explode(',', self::client_header('Accept'));
+               return ( ($v and $v[0] != '*/*') ? $v[0] : $default );
+       }
+
+       public static function array_fill_assoc($rows,$keys=null) {
+               if ($keys === null) {
+                       $keys = [];
+                       foreach(array_reverse($rows) as $v) {
+                               foreach ($v as $k=>$vv) $keys[$k] = 1;
+                       }
+                       $keys = array_keys($keys);
+               }
+
+               # NB 21.12.16: to keep order we need a new array 
+               $new = [];
+               foreach($rows as $k=>$v) {
+                       foreach ($keys as $key) {
+                               $new[$k][$key] = isset($v[$key]) ? $v[$key] : '';
+                               if (!isset($v[$key])) $rows[$k][$key] = '';
+                       }
+               }
+
+               return $new;
+               return $rows;
+       }
+
+       public static function strlen($v,$encoding='UTF-8') {
+               return mb_strlen($v,$encoding);
+       }
+
+       public static function mb_str_pad($input, $pad_length, $pad_string=' ', $pad_type=STR_PAD_RIGHT,$encoding='UTF-8'){
+               $mb_diff=mb_strlen($input, $encoding)-strlen($input);
+               return str_pad($input,$pad_length-$mb_diff,$pad_string,$pad_type);
+       
+
+       public static function cryptkey($length=32) {
+               return bin2hex(mcrypt_create_iv($length/2, MCRYPT_DEV_URANDOM));
+       }
+
+       public static function encrypt($key,$value) {
+               static $iv = null;
+               if ($iv === null) {
+                       $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
+                       $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);
+               }
+               return base64_encode($iv . mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $key, $value, MCRYPT_MODE_CBC, $iv));
+       }
+
+       public static function decrypt($key,$value) {
+               static $iv_size = null;
+               if ($iv_size === null) {
+                       $iv_size = mcrypt_get_iv_size(MCRYPT_RIJNDAEL_256, MCRYPT_MODE_CBC);
+               }
+               $value = base64_decode($value);
+               return rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $key, substr($value, $iv_size), MCRYPT_MODE_CBC, substr($value, 0, $iv_size)));
+       }
+
+       public static function is_vm() {
+               return file_exists('/proc/cpuinfo') && preg_match('/^flags.* hypervisor/m',file_get_contents('/proc/cpuinfo'));
+       }
+
+       public static function html2txt($txt) {
+               return strip_tags($txt);
+       }
+
+       public static function md2html($txt) {
+               static $_txt2md = null;
+               if ($_txt2md === null) {
+                       require_once(NB_ROOT.'/lib/php/parsedown/Parsedown.php');
+                       $_txt2md = new Parsedown();
+               }
+               return $_txt2md->text($txt);
+       }
+
+       public static function minify_js($code) {
+               if (strpos($code,'/') === 0 and file_exists($code)) $code = file_get_contents($code);
+               require_once(NB_ROOT.'/lib/php/jsmin.php');
                return trim(JSMin::minify($code));
-  }
+       }
 
-  public static function minify_css($code) {
-    if (strpos($code,'/') === 0 and file_exists($code)) $code = file_get_contents($code);
+       public static function minify_css($code) {
+               if (strpos($code,'/') === 0 and file_exists($code)) $code = file_get_contents($code);
 
-    // comments /* */
+               // comments /* */
                $code = preg_replace(',/\*.*?\*/,s','',$code);
 
-    // new lines
+               // new lines
                $code = preg_replace('/[\r\n]+/','',$code);
 
-    // spaces
+               // spaces
                #$code = preg_replace('/\s*()\s*/','$1',$code);
 
-    // selectors spaces (eg: "a > p")
-    $code = preg_replace_callback('/(^|\s*\})\s*([^\}]+)\s*(\{)\s*/',function($m){
+               // selectors spaces (eg: "a > p")
+               $code = preg_replace_callback('/(^|\s*\})\s*([^\}]+)\s*(\{)\s*/',function($m){
 
-      array_shift($m);
-      foreach ($m as $k=>$v) {
-        #$v = str_replace(' ','',$v);
-        #$v = trim($v);
-        $v = preg_replace('/\s*(\W)\s*/','$1',$v);
-        #$v = ':'.$v.':';
-        $m[$k] = $v;
+                       array_shift($m);
+                       foreach ($m as $k=>$v) {
+                               #$v = str_replace(' ','',$v);
+                               #$v = trim($v);
+                               $v = preg_replace('/\s*(\W)\s*/','$1',$v);
+                               #$v = ':'.$v.':';
+                               $m[$k] = $v;
                                #debug($v);
-      }
-      #bye($m);
-      #debug($m);
-      return join('',$m);
-    },$code);
-
-    // Property
-    $code = preg_replace_callback('/\s*(\{|;)\s*([\w-]+)\s*(:)\s*/',function($m){
-
-      array_shift($m);
-      #bye($m);
-      #return join('',$m);
-      foreach ($m as $k=>$v) {
+                       }
+                       #bye($m);
+                       #debug($m);
+                       return join('',$m);
+               },$code);
+
+               // Property
+               $code = preg_replace_callback('/\s*(\{|;)\s*([\w-]+)\s*(:)\s*/',function($m){
+
+                       array_shift($m);
+                       #bye($m);
+                       #return join('',$m);
+                       foreach ($m as $k=>$v) {
                                #if (!$v) continue;
-        $v = trim($v);
-        #$v = preg_replace('/\s*,\s*/',',',$v);
-        $m[$k] = $v;
-      }
+                               $v = trim($v);
+                               #$v = preg_replace('/\s*,\s*/',',',$v);
+                               $m[$k] = $v;
+                       }
 
-      return join('',$m);
+                       return join('',$m);
 
-    },$code);
+               },$code);
 
-    // redudant
-    $code = str_replace(';}','}',$code);
+               // redudant
+               $code = str_replace(';}','}',$code);
 
-    return $code;
-  }
+               return $code;
+       }
 
-  public static function http_user() {
-    foreach ([
-      'PHP_AUTH_USER',
-      'REMOTE_USER',
-    ] as $k) {
-      if (!empty($_SERVER[$k])) return $_SERVER[$k];
-    }
-  }
+       public static function http_user() {
+               foreach ([
+                       'PHP_AUTH_USER',
+                       'REMOTE_USER',
+               ] as $k) {
+                       if (!empty($_SERVER[$k])) return $_SERVER[$k];
+               }
+       }
 
        private static function ar_filter_keys($ar,$keys) {
                $new = [];
@@ -1072,7 +1079,7 @@ class NB {
                return $new;
        }
 
-  public static function ldap_search($o=[]) {
+       public static function ldap_search($o=[]) {
                $host = '127.0.0.1';
                if (preg_match('/^.*?([^\.]+\.[^\.]+)$/',$_SERVER['HTTP_HOST'],$m)) {
                        $host = 'ldap.'.$m[1];
@@ -1154,9 +1161,9 @@ class NB {
 
                        for ($i=0; $i<$rec["count"]; $i++){
                                # Fields
-                       $key = $info[$r][$i];
+                               $key = $info[$r][$i];
                                if (!empty($o['attrs']) and !in_array($key,$o['attrs'])) continue;
-                       $recs[$r][$key] = [];
+                               $recs[$r][$key] = [];
 
                                # Values
                                if (isset($rec[$key]['count'])) for ($j=0; $j<$rec[$key]['count']; $j++){
@@ -1204,9 +1211,9 @@ $key = hash("MD5", '5587eeb68760aa0ed7d2d1212d0829c3'); //we want a 32 byte bina
 #$key = '76a553babab7a62b7935d9a10f73777bf57b043c9d0f1fc22ea51dd9484154bc91afafd0f92e773e590ad05ebca9aec3fac11ebada7e517c78d32790e5a8f3ed';
 $enc = nb::encrypt($key,$value);
 echo ''
-  ."key  : $key\n"
-  ."enc  : $enc\n"
-  ."value: ".nb::decrypt($key,$enc) ."\n"
+       ."key  : $key\n"
+       ."enc  : $enc\n"
+       ."value: ".nb::decrypt($key,$enc) ."\n"
 ;
 */
 ?>