<?php
/*****************************************************************************
- Class DB
- Render different output format example: html, xml, yaml, csv
- from any database
+ Class DB
+ Render different output format example: html, xml, yaml, csv
+ from any database
*****************************************************************************/
require_once(realpath(dirname(__FILE__).'/nb.php'));
#if (!empty($argv) and $argv[1] == 'zaza') bye($arr);
if (defined('PRODUCTION') and PRODUCTION) {
- define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_SILENT);
+ define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_SILENT);
} else {
- define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_EXCEPTION);
- #define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_WARNING);
+ define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_EXCEPTION);
+ #define('DB_DEFAUL_ERRMODE',PDO::ERRMODE_WARNING);
}
#const DB::ERRMODE='';
class Db extends nb {
- # PDO Connection
+ # PDO Connection
# NB 22.09.16 public static $encoding = 'utf-8';
# NB 22.09.16: TODO
- public static $table_rows_dump = [
- 'praser' => false,
- ];
-
- public $conn;
- public $pdo;
- public $options = [ # See: http://php.net/manual/en/pdo.error-handling.php
- PDO::ATTR_ERRMODE => DB_DEFAUL_ERRMODE,
+ public static $table_rows_dump = [
+ 'praser' => false,
+ ];
+
+ public $conn;
+ public $pdo;
+ public $options = [ # See: http://php.net/manual/en/pdo.error-handling.php
+ PDO::ATTR_ERRMODE => DB_DEFAUL_ERRMODE,
PDO::ATTR_TIMEOUT => 0,
- ];
- public $host = null;
- public $port = null;
- public $user = null;
- public $password = null;
- public $charset = 'utf8';
-
- # Database infos
- public $id;
- public $name;
- public $title;
- public $notice;
- public $type;
- public $tables = [];
- public $types = [];
- public $conf = [];
- public $attach = []; # for sqlite
- public $row_parse_pre; # Function to call in table.rows()
- public $row_parse_post; # Function to call in table.rows()
-
- # Encryption
- public $encrypt = [
+ ];
+ public $host = null;
+ public $port = null;
+ public $user = null;
+ public $password = null;
+ public $charset = 'utf8';
+
+ # Database infos
+ public $id;
+ public $name;
+ public $title;
+ public $notice;
+ public $type;
+ public $tables = [];
+ public $types = [];
+ public $conf = [];
+ public $attach = []; # for sqlite
+ public $row_parse_pre; # Function to call in table.rows()
+ public $row_parse_post; # Function to call in table.rows()
+
+ # Encryption
+ public $encrypt = [
# 'secret' => '32_CHAR_KEY',
# 'tables' => [
# 'TABLE1' => [
# ],
# ...,
# ],
- ];
-
- # Params
- protected $default_params = [
- ];
-
- protected static $paliases = [
- 'd' => 'db',
- 't' => 'table',
- 'l' => 'limit',
- 'a' => 'action',
- 'h' => 'header',
-
- 'f' => 'format',
- 'out' => 'format',
- 'o' => 'format',
- ];
-
- protected static $action_aliases = [
- 'help' => 'db.help',
- 'ls' => 'db.ls',
- 'exec' => 'db.exec',
- 'databases' => 'db.databases',
-
- 'tables' => 'db.tables',
- 'fields' => 'table.fields',
- 'rows' => 'table.rows',
- 'insert' => 'table.insert',
- 'replace' => 'table.replace',
- 'update' => 'table.update',
- 'delete' => 'table.delete',
- ];
-
- protected static $action_help = [
- ['db.help','This help'],
- ['db.ls','List databases from conf'],
- ['db.database','List other databases on the same server'],
- ['db.tables','List tables (name=* type=* count=1 engine=*)'],
-
- ['table.rows','Dump one table, use format='],
- ['table.fields','List fields'],
- ['table.status','Table status (count= maxlen= max=)'],
- ['table.sql','Sql source to create the table'],
-
- ['table.insert','Insert a record'],
- ['table.update','Update a record'],
- ['table.delete','Delete a record'],
-
- ];
- # Web
- public $default_table;
- public $sort;
- public $extras;
- public $format = 'json';
- public $formats = [ 'table','div','csv','xml','json','yaml','sh','sql','php' ];
- public $limits = ['20','50','100','500','1000'];
- public $limit; # Here not in Table becouse of Db::out()
-
- # Classes
- public $out;
-
- function __construct($opt = []) {
-
- # Args defaults
- if ($opt==='') $opt = [];
- $opt = is_scalar($opt) ? ['pdo' => $opt] : $opt;
-
- # Options
- if (isset($opt['options'])) {
- foreach ($opt['options'] as $k=>$v) $this->options[$k] = $v;
- unset($opt['options']);
- }
-
- # Charset
- if (!empty($opt['charset'])) $opt['charset']
- = preg_replace('/^ *utf-8 *$/','utf8',$opt['charset'])
- ;
-
- # Tables
- if (isset($opt['tables'])) {
- foreach ($opt['tables'] as $name=>$param) {
- $this->table($name,$param);
- }
- unset($opt['tables']);
- }
-
- # connect
- $connect = false;
- if (isset($opt['connect'])) {
- $connect = (bool) $opt['connect'];
- unset($opt['connect']);
- }
-
- # Args into this
- foreach ($opt as $k=>$v) $this->$k = $v;
- #parent::__construct($opt);
-
- # Out Class
- if (empty($this->out)) $this->out = new Out(['charset'=>$this->charset]);
-
- # Format
- # Set format from client Accept if != html
- if (!isset($opt['format'])) {
- if ($this->out->client_type()) $this->format = $this->out->client_type();
- if (self::p('format')) $this->format = self::p('format');
- }
-
- # Pdo
- $this->connect_init();
- if ($connect) $this->connect();
-
- # Extras must disapear - NB 29.03.16
- if (!empty($this->extras)) self::bye($this->extras);
- return true;
- }
-
- public function __destruct() {
- $this->disconnect();
- foreach (array_keys((array)$this) as $k) { if (isset($this->$k)) unset($this->$k); };
- }
+ ];
+
+ # Params
+ protected $default_params = [
+ ];
+
+ protected static $paliases = [
+ 'd' => 'db',
+ 't' => 'table',
+ 'l' => 'limit',
+ 'a' => 'action',
+ 'h' => 'header',
+
+ 'f' => 'format',
+ 'out' => 'format',
+ 'o' => 'format',
+ ];
+
+ protected static $action_aliases = [
+ 'help' => 'db.help',
+ 'ls' => 'db.ls',
+ 'exec' => 'db.exec',
+ 'databases' => 'db.databases',
+
+ 'tables' => 'db.tables',
+ 'fields' => 'table.fields',
+ 'rows' => 'table.rows',
+ 'insert' => 'table.insert',
+ 'replace' => 'table.replace',
+ 'update' => 'table.update',
+ 'delete' => 'table.delete',
+ ];
+
+ protected static $action_help = [
+ ['db.help','This help'],
+ ['db.ls','List databases from conf'],
+ ['db.database','List other databases on the same server'],
+ ['db.tables','List tables (name=* type=* count=1 engine=*)'],
+
+ ['table.rows','Dump one table, use format='],
+ ['table.fields','List fields'],
+ ['table.status','Table status (count= maxlen= max=)'],
+ ['table.sql','Sql source to create the table'],
+
+ ['table.insert','Insert a record'],
+ ['table.update','Update a record'],
+ ['table.delete','Delete a record'],
+
+ ];
+ # Web
+ public $default_table;
+ public $sort;
+ public $extras;
+ public $format = 'json';
+ public $formats = [ 'table','div','csv','xml','json','yaml','sh','sql','php' ];
+ public $limits = ['20','50','100','500','1000'];
+ public $limit; # Here not in Table becouse of Db::out()
+
+ # Classes
+ public $out;
+
+ function __construct($opt = []) {
+
+ # Args defaults
+ if ($opt==='') $opt = [];
+ $opt = is_scalar($opt) ? ['pdo' => $opt] : $opt;
+
+ # Options
+ if (isset($opt['options'])) {
+ foreach ($opt['options'] as $k=>$v) $this->options[$k] = $v;
+ unset($opt['options']);
+ }
+
+ # Charset
+ if (!empty($opt['charset'])) $opt['charset']
+ = preg_replace('/^ *utf-8 *$/','utf8',$opt['charset'])
+ ;
+
+ # Tables
+ if (isset($opt['tables'])) {
+ foreach ($opt['tables'] as $name=>$param) {
+ $this->table($name,$param);
+ }
+ unset($opt['tables']);
+ }
+
+ # connect
+ $connect = false;
+ if (isset($opt['connect'])) {
+ $connect = (bool) $opt['connect'];
+ unset($opt['connect']);
+ }
+
+ # Args into this
+ foreach ($opt as $k=>$v) $this->$k = $v;
+ #parent::__construct($opt);
+
+ # Out Class
+ if (empty($this->out)) $this->out = new Out(['charset'=>$this->charset]);
+
+ # Format
+ # Set format from client Accept if != html
+ if (!isset($opt['format'])) {
+ if ($this->out->client_type()) $this->format = $this->out->client_type();
+ if (self::p('format')) $this->format = self::p('format');
+ }
+
+ # Pdo
+ $this->connect_init();
+ if ($connect) $this->connect();
+
+ # Extras must disapear - NB 29.03.16
+ if (!empty($this->extras)) self::bye($this->extras);
+ return true;
+ }
+
+ public function __destruct() {
+ $this->disconnect();
+ foreach (array_keys((array)$this) as $k) { if (isset($this->$k)) unset($this->$k); };
+ }
function connect_init() {
- if (empty($this->pdo) and $this->type) $this->pdo = $this->type.':';
- # Extract args from pdo
- foreach ($this->pdo2h($this->pdo) as $k=>$v) {
- $this->$k = $v;
- }
+ if (empty($this->pdo) and $this->type) $this->pdo = $this->type.':';
+ # Extract args from pdo
+ foreach ($this->pdo2h($this->pdo) as $k=>$v) {
+ $this->$k = $v;
+ }
- if (empty($this->type)) $this->type = strtolower(preg_replace('/^([^:]+):.*$/','\1',$this->pdo));
- if (!$this->type) return false;
+ if (empty($this->type)) $this->type = strtolower(preg_replace('/^([^:]+):.*$/','\1',$this->pdo));
+ if (!$this->type) return false;
- if ($v = $this->p('db_host')) $this->host = $v;
- if ($this->conf_type('use_path')) {
+ if ($v = $this->p('db_host')) $this->host = $v;
+ if ($this->conf_type('use_path')) {
- if (empty($this->host)) $this->host = preg_replace('/^\w+:/','',$this->pdo);
+ if (empty($this->host)) $this->host = preg_replace('/^\w+:/','',$this->pdo);
- # Add file
- if (trim($this->pdo,'pdo:'.$this->type)=='') $this->pdo .= $this->host;
+ # Add file
+ if (trim($this->pdo,'pdo:'.$this->type)=='') $this->pdo .= $this->host;
- } else {
+ } else {
- # Add args to pdo
- foreach ([
- 'host' => 'host',
- 'port' => 'port',
- 'user' => 'user',
- 'password' => 'password',
- 'name' => 'dbname',
- 'charset' => 'charset',
- ] as $k => $v) {
- if ($v=='charset' and $this->type=='pgsql') continue;
- if (empty($this->$k)) continue;
- $this->pdo = preg_replace("/\b$v=[^;]*(;|$)/","",$this->pdo);
- $this->pdo .= (preg_match('/[:;]$/',$this->pdo) ? '' : ';') . "$v=".$this->$k;
- }
+ # Add args to pdo
+ foreach ([
+ 'host' => 'host',
+ 'port' => 'port',
+ 'user' => 'user',
+ 'password' => 'password',
+ 'name' => 'dbname',
+ 'charset' => 'charset',
+ ] as $k => $v) {
+ if ($v=='charset' and $this->type=='pgsql') continue;
+ if (empty($this->$k)) continue;
+ $this->pdo = preg_replace("/\b$v=[^;]*(;|$)/","",$this->pdo);
+ $this->pdo .= (preg_match('/[:;]$/',$this->pdo) ? '' : ';') . "$v=".$this->$k;
+ }
- if (strpos($this->host,'/') === 0) {
- $this->pdo = preg_replace("/\b(host|port)=[^;]*(;|$)/","",$this->pdo).';unix_socket='.$this->host;
- }
+ if (strpos($this->host,'/') === 0) {
+ $this->pdo = preg_replace("/\b(host|port)=[^;]*(;|$)/","",$this->pdo).';unix_socket='.$this->host;
+ }
- }
+ }
- # Defaults
- if (empty($this->title)) $this->title = prettyText($this->name);
- if (empty($this->id) and !empty($this->name)) $this->id = preg_replace('/\W+/','',$this->name);
+ # Defaults
+ if (empty($this->title)) $this->title = prettyText($this->name);
+ if (empty($this->id) and !empty($this->name)) $this->id = preg_replace('/\W+/','',$this->name);
- # Row parser
- if (empty($this->row_parse_pre) and $this->conf_type('row_parse')) {
- $this->row_parse_pre = $this->conf_type('row_parse');
- }
+ # Row parser
+ if (empty($this->row_parse_pre) and $this->conf_type('row_parse')) {
+ $this->row_parse_pre = $this->conf_type('row_parse');
+ }
- } # < if else 'use_path'
+ } # < if else 'use_path'
public function connect() {
- if (!empty($this->conn)) return false;
+ if (!empty($this->conn)) return false;
- # Pdo
- if (empty($this->pdo)) $this->bye("db: `".$this->id."`: Missing pdo: check host, name, user, password");
- if (empty($this->pdo)) return false;
+ # Pdo
+ if (empty($this->pdo)) $this->bye("db: `".$this->id."`: Missing pdo: check host, name, user, password");
+ if (empty($this->pdo)) return false;
- # Type
- $this->conf_type_load();
+ # Type
+ $this->conf_type_load();
- # Connect
- try {
- $this->conn = new PDO($this->pdo,$this->user,$this->password,$this->options);
- #if (isset($this->pdo_error)) $this->conn->setAttribute($this->pdo_error[0], $this->pdo_error[1]);
+ # Connect
+ try {
+ $this->conn = new PDO($this->pdo,$this->user,$this->password,$this->options);
+ #if (isset($this->pdo_error)) $this->conn->setAttribute($this->pdo_error[0], $this->pdo_error[1]);
- } catch (PDOException $e) {
- $msg = 'Connection failed:';
+ } catch (PDOException $e) {
+ $msg = 'Connection failed:';
- foreach(['name','host','file'] as $p) {
- if (!empty($this->$p)) $msg .= " $p=".$this->$p;
- }
+ foreach(['name','host','file'] as $p) {
+ if (!empty($this->$p)) $msg .= " $p=".$this->$p;
+ }
- $msg .= "\n ".$e->getMessage();
- #throw new Exception($msg, (int)$e->getCode());
- self::bye($msg);
- }
+ $msg .= "\n ".$e->getMessage();
+ #throw new Exception($msg, (int)$e->getCode());
+ self::bye($msg);
+ }
- if (empty($this->conn)) {
- $this->bye("Connection failed: ".$this->pdo_info());
- return false;
- }
+ if (empty($this->conn)) {
+ $this->bye("Connection failed: ".$this->pdo_info());
+ return false;
+ }
- # Create functions
- foreach ((array)$this->conf_type('sqliteCreateFunction') as $name => $fct) {
- if (is_array($fct)) {
- $this->conn->sqliteCreateFunction($name,$fct[0],$fct[1]);
- } else {
- $this->conn->sqliteCreateFunction($name,$fct);
- }
- }
+ # Create functions
+ foreach ((array)$this->conf_type('sqliteCreateFunction') as $name => $fct) {
+ if (is_array($fct)) {
+ $this->conn->sqliteCreateFunction($name,$fct[0],$fct[1]);
+ } else {
+ $this->conn->sqliteCreateFunction($name,$fct);
+ }
+ }
- $this->method('connect');
+ $this->method('connect');
- return true;
- }
+ return true;
+ }
public function disconnect() {
- if (empty($this->conn)) return null;
- $this->method('disconnect');
- }
-
- function exec($sql) {
-
- try {
- #$r = $this->conn->exec($sql,$params);
- $r = $this->conn->exec($sql);
- } catch (PDOException $e) {
- err(join(': ',[$e->getMessage(),"Db.exec()",$sql]));
- $r = null;
- }
-
- return $r;
- }
-
- public function query($sql) {
- # See: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
-
- try {
- $r = $this->conn->query($sql);
- } catch (PDOException $e) {
- err(join(': ',[$e->getMessage(),"Db.query()",$sql]));
- $r = null;
- }
-
- return $r;
-
- }
-
- public function row($sql,$sep=' ') {
- $query = $this->query($sql);
- $result = $query->fetch(PDO::FETCH_NUM);
- if (!is_array($result)) return $result;
- return join($sep,$result);
- return join($sep,$query->fetch(PDO::FETCH_NUM));
- }
-
- private function rows($sql,$style=PDO::FETCH_BOTH) {
- return $this->query($sql)->fetchAll($style);
- $sth = $this->conn->prepare($sql);
- $sth->execute();
- return $sth->fetchAll($style);
- }
-
- function query2a($sql) {
- $r = $this->conn->query($sql,PDO::FETCH_COLUMN);
- return $r ? $r->fetch() : $r;
- }
-
- function query2aa($sql) {
- return $this->conn->query($sql,PDO::FETCH_COLUMN);
- }
-
- function query2h($sql) {
- $r = $this->conn->query($sql,PDO::FETCH_ASSOC);
- return $r ? $r->fetch() : $r;
- }
-
- function query2ah($sql) {
- return $this->conn->query($sql,PDO::FETCH_ASSOC);
- }
-
- function quote($v) {
- static $fct = false; if ($fct === false) $fct = $this->conf_type('quote');
- if ($fct) return $fct($v);
- return $this->conn->quote($v);
- }
-
- /**
- * @author NB 12.08.16
- * Return a table instance
- */
- public function table($name='',$params=[]) {
- if ( !is_array($params) ) $this->bye('Usage: table($name,[type=>, sql=>, ...])');
- if (!$name and !empty($this->default_table)) $name = $this->default_table;
- if (!$name) $this->bye('table(): Missing table');
-
- if (empty($params) or empty($params['db'])) $params['db'] = $this;
-
- if (empty($this->tables[$name])) {
- $this->tables[$name] = new Table($name,$params);
- } elseif ($params) {
- $this->tables[$name]->__construct($name,$params);
- }
-
- return $this->tables[$name];
- }
-
- public static function localFile($name='') {
-
- if (!($config = self::type('localFile'))) return [];
-
- $config[1] = str_replace('<NAME>',($name ? $name : $this->name),$config[1]);
-
- if (!file_exists($config[0])) return [];
-
- $return = [];
- foreach (explode("\n",file_get_contents($config[0])) as $line) {
- if (!preg_match('/'.($config[1]).'/',$line,$m)) continue;
- foreach ($m as $k=>$v) if (preg_match('/^\d+$/',$k)) unset($m[$k]);
- $return = array_replace_recursive($return,$m);
- }
+ if (empty($this->conn)) return null;
+ $this->method('disconnect');
+ }
+
+ function exec($sql) {
+
+ try {
+ #$r = $this->conn->exec($sql,$params);
+ $r = $this->conn->exec($sql);
+ } catch (PDOException $e) {
+ err(join(': ',[$e->getMessage(),"Db.exec()",$sql]));
+ $r = null;
+ }
+
+ return $r;
+ }
+
+ public function query($sql) {
+ # See: http://wiki.hashphp.org/PDO_Tutorial_for_MySQL_Developers
+
+ try {
+ $r = $this->conn->query($sql);
+ } catch (PDOException $e) {
+ err(join(': ',[$e->getMessage(),"Db.query()",$sql]));
+ $r = null;
+ }
+
+ return $r;
+
+ }
+
+ public function row($sql,$sep=' ') {
+ $query = $this->query($sql);
+ $result = $query->fetch(PDO::FETCH_NUM);
+ if (!is_array($result)) return $result;
+ return join($sep,$result);
+ return join($sep,$query->fetch(PDO::FETCH_NUM));
+ }
+
+ private function rows($sql,$style=PDO::FETCH_BOTH) {
+ return $this->query($sql)->fetchAll($style);
+ $sth = $this->conn->prepare($sql);
+ $sth->execute();
+ return $sth->fetchAll($style);
+ }
+
+ function query2a($sql) {
+ $r = $this->conn->query($sql,PDO::FETCH_COLUMN);
+ return $r ? $r->fetch() : $r;
+ }
+
+ function query2aa($sql) {
+ return $this->conn->query($sql,PDO::FETCH_COLUMN);
+ }
+
+ function query2h($sql) {
+ $r = $this->conn->query($sql,PDO::FETCH_ASSOC);
+ return $r ? $r->fetch() : $r;
+ }
+
+ function query2ah($sql) {
+ return $this->conn->query($sql,PDO::FETCH_ASSOC);
+ }
+
+ function quote($v) {
+ static $fct = false; if ($fct === false) $fct = $this->conf_type('quote');
+ if ($fct) return $fct($v);
+ return $this->conn->quote($v);
+ }
+
+ /**
+ * @author NB 12.08.16
+ * Return a table instance
+ */
+ public function table($name='',$params=[]) {
+ if ( !is_array($params) ) $this->bye('Usage: table($name,[type=>, sql=>, ...])');
+ if (!$name and !empty($this->default_table)) $name = $this->default_table;
+ if (!$name) $this->bye('table(): Missing table');
+
+ if (empty($params) or empty($params['db'])) $params['db'] = $this;
+
+ if (empty($this->tables[$name])) {
+ $this->tables[$name] = new Table($name,$params);
+ } elseif ($params) {
+ $this->tables[$name]->__construct($name,$params);
+ }
+
+ return $this->tables[$name];
+ }
+
+ public static function localFile($name='') {
+
+ if (!($config = self::type('localFile'))) return [];
+
+ $config[1] = str_replace('<NAME>',($name ? $name : $this->name),$config[1]);
+
+ if (!file_exists($config[0])) return [];
+
+ $return = [];
+ foreach (explode("\n",file_get_contents($config[0])) as $line) {
+ if (!preg_match('/'.($config[1]).'/',$line,$m)) continue;
+ foreach ($m as $k=>$v) if (preg_match('/^\d+$/',$k)) unset($m[$k]);
+ $return = array_replace_recursive($return,$m);
+ }
#debug(self::ar_map('$a == null ? "" : $a',$return));
#debug($return);
- if (empty($return['user']) and !empty($_SERVER['USER'])) $return['user'] = $_SERVER['USER'];
- return $return;
- }
-
- public function unvar($value) {
- #return $value;
- if (empty($value)) return $value;
- if (!is_scalar($value)) {
- foreach ($value as $k=>$v) {
- if (is_scalar($v)) $value[$k] = $this->unvar($v);
- }
- return $value;
- }
- $replace = [
- '<D.NAME>' => $this->name,
- '<D.CHARSET>' => $this->charset,
- ];
- #debug( str_replace(array_keys($replace),array_values($replace),$value) );
- return str_replace(array_keys($replace),array_values($replace),$value);
- }
-
- public function method($key=null) {
- $method = $this->conf_type($key);
- if (is_callable($method)) return $this->unvar($method($this));
- 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]);
- }
+ if (empty($return['user']) and !empty($_SERVER['USER'])) $return['user'] = $_SERVER['USER'];
+ return $return;
+ }
+
+ public function unvar($value) {
+ #return $value;
+ if (empty($value)) return $value;
+ if (!is_scalar($value)) {
+ foreach ($value as $k=>$v) {
+ if (is_scalar($v)) $value[$k] = $this->unvar($v);
+ }
+ return $value;
+ }
+ $replace = [
+ '<D.NAME>' => $this->name,
+ '<D.CHARSET>' => $this->charset,
+ ];
+ #debug( str_replace(array_keys($replace),array_values($replace),$value) );
+ return str_replace(array_keys($replace),array_values($replace),$value);
+ }
+
+ public function method($key=null) {
+ $method = $this->conf_type($key);
+ if (is_callable($method)) return $this->unvar($method($this));
+ 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 = [];
+ public function conf_type_load($type=null) {
+ global $DB_TYPES;
+ static $require = [];
- if (empty($type)) $type = $this->type;
- if (empty($type)) self::bye('Db type is required');
+ if (empty($type)) $type = $this->type;
+ if (empty($type)) self::bye('Db type is required');
- if (empty($require[$type])) {
- $require[$type] = NB_ROOT.'/lib/php/db/types/'.$type.'.php';
- if (!file_exists($require[$type])) self::bye("Unknown type `$type`");
+ if (empty($require[$type])) {
+ $require[$type] = NB_ROOT.'/lib/php/db/types/'.$type.'.php';
+ if (!file_exists($require[$type])) self::bye("Unknown type `$type`");
# NB 10.01.18 $require[$type] = dirname(__FILE__).'/db/types/'.$type.'.php';
- require_once($require[$type]);
- }
+ require_once($require[$type]);
+ }
- return $DB_TYPES[$type];
- }
+ return $DB_TYPES[$type];
+ }
- public function conf_type($key=null,$die_if_empty=false) {
+ public function conf_type($key=null,$die_if_empty=false) {
- # Load php file
- $db_type = $this->conf_type_load();
+ # Load php file
+ $db_type = $this->conf_type_load();
- # Dump all array
- if ($key === null) return $db_type;
+ # Dump all array
+ if ($key === null) return $db_type;
- # Search for specifics from types
- if (!empty($this->types) and !empty($this->types[$key])) {
- $db_type[$key] = array_merge((empty($db_type[$key]) ? [] : $db_type[$key]),$this->types[$key]);
- }
+ # Search for specifics from types
+ if (!empty($this->types) and !empty($this->types[$key])) {
+ $db_type[$key] = array_merge((empty($db_type[$key]) ? [] : $db_type[$key]),$this->types[$key]);
+ }
- # Check key exists
- if (empty($db_type[$key])) {
- if ($die_if_empty) self::bye("db_type(): Unknown key `$key` for type `".$this->type."`");#.' - '.print_r($db_type,true));
- return;
- }
+ # Check key exists
+ if (empty($db_type[$key])) {
+ if ($die_if_empty) self::bye("db_type(): Unknown key `$key` for type `".$this->type."`");#.' - '.print_r($db_type,true));
+ return;
+ }
- return $this->unvar($db_type[$key]);
- }
+ return $this->unvar($db_type[$key]);
+ }
# NB 12.12.17 public function type($key=null,$die=false,$type=null) {
# NB 12.12.17 if (empty($type)) $type = $this->type;
# NB 12.12.17 return $this->conf_type($key,$die);
# NB 12.12.17 }
- public function table_exist($table) {
- # NB 02.11.16: TODO NEVEW USED
- $table = is_object($table) ? $table->name : $table;
+ public function table_exist($table) {
+ # NB 02.11.16: TODO NEVEW USED
+ $table = is_object($table) ? $table->name : $table;
- if ($this->_tables === true) {
- if (array_key_exists($table)) return 1;
- } else {
- }
+ if ($this->_tables === true) {
+ if (array_key_exists($table)) return 1;
+ } else {
+ }
- return null;
+ return null;
- }
+ }
- public function tables() {
+ public function tables() {
- if (!isset($this->_tables)) {
- #if (!isset($this->tables)) {
- $this->_tables = true;
+ if (!isset($this->_tables)) {
+ #if (!isset($this->tables)) {
+ $this->_tables = true;
- $sql = $this->method('tables');
+ $sql = $this->method('tables');
- if ($sql and !empty($this->conn)) {
- foreach ($this->conn->query($sql,PDO::FETCH_ASSOC) as $row) {
- $name = current($row);
+ if ($sql and !empty($this->conn)) {
+ foreach ($this->conn->query($sql,PDO::FETCH_ASSOC) as $row) {
+ $name = current($row);
- # add to this->tables !!!
- $t = $this->table($name,$row+['status'=>$row]);
- }
- }
+ # add to this->tables !!!
+ $t = $this->table($name,$row+['status'=>$row]);
+ }
+ }
- }
+ }
- return $this->tables;
- }
+ return $this->tables;
+ }
- public static function print_header($format,$value=null) {
- if (empty($_SERVER['DOCUMENT_ROOT'])) return null;
+ public static function print_header($format,$value=null) {
+ if (empty($_SERVER['DOCUMENT_ROOT'])) return null;
- if ($value!==null) return header("$format: $value");
+ if ($value!==null) return header("$format: $value");
- if (!$mime=mime::get($format)) return false;
- header('Content-type: '.$mime);
+ if (!$mime=mime::get($format)) return false;
+ header('Content-type: '.$mime);
- return $mime;
- }
+ return $mime;
+ }
- public function sql_name($value) {
- # no quote if contain comma for db
- if (strpos($value,'.') !== false) return $value;
+ public function sql_name($value) {
+ # no quote if contain comma for db
+ if (strpos($value,'.') !== false) return $value;
- # specific quote
- if ($q=$this->conf_type('quote_name')) return $q.$value.$q;
+ # specific quote
+ if ($q=$this->conf_type('quote_name')) return $q.$value.$q;
- # default quote
- return '"'.$value.'"';
- }
+ # default quote
+ return '"'.$value.'"';
+ }
- public function out($rows,$head=[],$conf=[]) {
+ public function out($rows,$head=[],$conf=[]) {
# NB 19.12.17 See www/dbq/dbq.php: $this->db->out($rows,$head,$conf);
if (empty($rows)) return false;
- if ($this->format) {
- $format = $this->format;
-
- } elseif ($this->format == 'null') {
- return true;
+ if ($this->format) {
+ $format = $this->format;
- } elseif ($format=$this->format) {
+ } elseif ($this->format == 'null') {
+ return true;
- } else {
- # NB 04.12.16: TODEL one day !
- $format = $this->out->php_cli() ? 'csv' : 'table';
- }
+ } elseif ($format=$this->format) {
- // Handle limit
- if ($this->limit) {
+ } else {
+ # NB 04.12.16: TODEL one day !
+ $format = $this->out->php_cli() ? 'csv' : 'table';
+ }
- $limit = (int)$this->limit;
- $i = empty($head) ? 1 : 0;
+ // Handle limit
+ if ($this->limit) {
- foreach ($rows as $k=>$v) {
- if ($i>$limit) unset($rows[$k]);
- $i++;
- }
+ $limit = (int)$this->limit;
+ $i = empty($head) ? 1 : 0;
- }
+ foreach ($rows as $k=>$v) {
+ if ($i>$limit) unset($rows[$k]);
+ $i++;
+ }
- $this->out->rows($format,$rows,$head,$conf);
- return true;
- }
+ }
- public function tables_rows($o=[]) {
- # Options
- # Filters
- $type = empty($o['type']) ? '' : $o['type'];
- $name = empty($o['name']) ? '' : $o['name'];
- $engine = empty($o['engine']) ? '' : $o['engine'];
- $database = empty($o['database']) ? '' : $o['database'];
- $count = empty($o['count']) ? '' : $o['count'];
- $fields = empty($o['fields']) ? '' : $o['fields'];
+ $this->out->rows($format,$rows,$head,$conf);
+ return true;
+ }
- #var_dump ($this->tables());
+ public function tables_rows($o=[]) {
+ # Options
+ # Filters
+ $type = empty($o['type']) ? '' : $o['type'];
+ $name = empty($o['name']) ? '' : $o['name'];
+ $engine = empty($o['engine']) ? '' : $o['engine'];
+ $database = empty($o['database']) ? '' : $o['database'];
+ $count = empty($o['count']) ? '' : $o['count'];
+ $fields = empty($o['fields']) ? '' : $o['fields'];
+
+ #var_dump ($this->tables());
#foreach($this->tables as $t) debug($t->name.'='.$t->type);
#bye($this->tables);
- $rows = [];
- foreach ($this->tables() as $t) {
- #debug($t->name.'='.$t->type);
-
- if ($name and !$this->str_match($t->name,$name)) continue;
- if ($type and !$this->str_match($t->type,$type)) continue;
- if ($count and !$this->str_match($t->count,$count)) continue;
- if ($engine and !$this->str_match($t->engine,$engine)) continue;
- if ($database and isset($t->database) and !$this->str_match($t->database,$database)) continue;
-
- $row = $t->status();
- if ($count) $row['count'] = $t->status('count');
- #if ($fields) $row['fields'] = $t->status('fields');
- if ($fields) $row['fields'] = join(',',array_keys($t->fields()));
-
- #debug($t->name.'='.$t->database);
- $rows[] = $row;
- }
-
- $rows = self::array_fill_assoc($rows);
- usort($rows,function($a,$b) { return strcmp($a['name'],$b['name']); });
-
- return $rows;
- }
-
- public function action($action,$table=null) {
- #debug(($this->tables));
- $actions = explode(',',$action);
+ $rows = [];
+ foreach ($this->tables() as $t) {
+ #debug($t->name.'='.$t->type);
+
+ if ($name and !$this->str_match($t->name,$name)) continue;
+ if ($type and !$this->str_match($t->type,$type)) continue;
+ if ($count and !$this->str_match($t->count,$count)) continue;
+ if ($engine and !$this->str_match($t->engine,$engine)) continue;
+ if ($database and isset($t->database) and !$this->str_match($t->database,$database)) continue;
+
+ $row = $t->status();
+ if ($count) $row['count'] = $t->status('count');
+ #if ($fields) $row['fields'] = $t->status('fields');
+ if ($fields) $row['fields'] = join(',',array_keys($t->fields()));
+
+ #debug($t->name.'='.$t->database);
+ $rows[] = $row;
+ }
+
+ $rows = self::array_fill_assoc($rows);
+ usort($rows,function($a,$b) { return strcmp($a['name'],$b['name']); });
+
+ return $rows;
+ }
+
+ public function action($action,$table=null) {
+ #debug(($this->tables));
+ $actions = explode(',',$action);
# NB 02.12.16 $this->pdef('format',($this->php_cli() ? 'csv' : ''));
- $rows = [];
- $return = false;
+ $rows = [];
+ $return = false;
- foreach ($actions as $action) {
+ foreach ($actions as $action) {
- if ($action == 'db.help') {
- $this->out(self::$action_help,['action','description']);
- $return = true;
+ if ($action == 'db.help') {
+ $this->out(self::$action_help,['action','description']);
+ $return = true;
- } elseif ($action == 'db.cryptkey') {
- echo $this->out($this->cryptkey(),['key']);
+ } elseif ($action == 'db.cryptkey') {
+ echo $this->out($this->cryptkey(),['key']);
- } elseif ($action == 'db.exec') {
+ } elseif ($action == 'db.exec') {
- $count = 0;
- $sql = '';
+ $count = 0;
+ $sql = '';
- while (($line = fgets(STDIN)) !== false and !feof(STDIN)) {
+ while (($line = fgets(STDIN)) !== false and !feof(STDIN)) {
- if (strpos($line,'--') === 0) continue;
+ if (strpos($line,'--') === 0) continue;
- $line = preg_replace('/[\r\n]+$/','',$line);
- if ($line == 'db.exec') break;
+ $line = preg_replace('/[\r\n]+$/','',$line);
+ if ($line == 'db.exec') break;
- $sql .= $line;
+ $sql .= $line;
- if (!preg_match('/;$/',$sql)) continue;
- #$line = preg_replace('/^\s*(.*?)\s*;?\s*$/','$1',$line);
- #if (!$line or strpos($line,'--') === 0) continue;
+ if (!preg_match('/;$/',$sql)) continue;
+ #$line = preg_replace('/^\s*(.*?)\s*;?\s*$/','$1',$line);
+ #if (!$line or strpos($line,'--') === 0) continue;
- $count++;
- #echo "$count> $line\n";
- $this->conn->exec($sql);
- $sql = '';
- }
- $return = $this->out([
- 'count' => $count,
- ]);
+ $count++;
+ #echo "$count> $line\n";
+ $this->conn->exec($sql);
+ $sql = '';
+ }
+ $return = $this->out([
+ 'count' => $count,
+ ]);
- } elseif ($action == 'db.tables') {
+ } elseif ($action == 'db.tables') {
- $rows = $this->tables_rows($this->p());
- $return = $this->out($rows);
+ $rows = $this->tables_rows($this->p());
+ $return = $this->out($rows);
- } elseif ($action == 'db.conf') {
- $return = $this->out(array_values($this->conf));
+ } elseif ($action == 'db.conf') {
+ $return = $this->out(array_values($this->conf));
- } elseif ($action == 'db.ls') {
- $return = $this->out($this->ls());
+ } elseif ($action == 'db.ls') {
+ $return = $this->out($this->ls());
- } elseif ($r=self::class_action_out($this,$action) !== null) {
- return $r;
+ } elseif ($r=self::class_action_out($this,$action) !== null) {
+ return $r;
- } elseif($table) {
- if ($r=$table->action($action)) $return = $r;
+ } elseif($table) {
+ if ($r=$table->action($action)) $return = $r;
- }
- }
+ }
+ }
- return $return;
- }
+ return $return;
+ }
- /**
- * @copyright NB 05.03.16
- * @param [FILES] $files Files to load
- * @return ARRAY the new/existing value of $this->db
- */
- public static function ar_merge($a,$b) {
+ /**
+ * @copyright NB 05.03.16
+ * @param [FILES] $files Files to load
+ * @return ARRAY the new/existing value of $this->db
+ */
+ public static function ar_merge($a,$b) {
return array_replace_recursive($a,$b);
#return array_combine($a,$b);
$n = $a;
return $n;
}
- public static function conf_load($files=[],&$first=false) {
- if (empty($files)) return [];
+ public static function conf_load($files=[],&$first=false) {
+ if (empty($files)) return [];
- #
- # Load all files into a $dbs if #files is not a hash
- #
+ #
+ # Load all files into a $dbs if #files is not a hash
+ #
- $DBQ = [];
- $dbs = [];
- $done = [];
- foreach ((array)$files as $file) {
+ $DBQ = [];
+ $dbs = [];
+ $done = [];
+ foreach ((array)$files as $file) {
- $file = self::untilde(realpath($file));
- if (isset($done[$file])) continue;
- else $done[$file] = 1;
+ $file = self::untilde(realpath($file));
+ if (isset($done[$file])) continue;
+ else $done[$file] = 1;
- if (!is_readable($file)) continue;
- if (preg_match('/\.(yaml|yml)$/i',$file) and ($yaml = self::yaml_parse_file($file))) {
- $dbs = self::ar_merge($dbs,$yaml);
+ if (!is_readable($file)) continue;
+ if (preg_match('/\.(yaml|yml)$/i',$file) and ($yaml = self::yaml_parse_file($file))) {
+ $dbs = self::ar_merge($dbs,$yaml);
- } elseif (preg_match('/\.php$/i',$file)) {
+ } elseif (preg_match('/\.php$/i',$file)) {
$DBQ = [];
- require($file);
- if (!empty($DBQ)) $dbs = self::ar_merge($dbs,$DBQ);
+ require($file);
+ if (!empty($DBQ)) $dbs = self::ar_merge($dbs,$DBQ);
- }
+ }
- }
+ }
- unset($yaml,$DBQ);
- if (!$dbs) return false;
+ unset($yaml,$DBQ);
+ if (!$dbs) return false;
- #
- # First iteration: Import database conf with key _import
- #
- foreach ($dbs as $id=>$params) {
- $params = (array)$params;
+ #
+ # First iteration: Import database conf with key _import
+ #
+ foreach ($dbs as $id=>$params) {
+ $params = (array)$params;
- foreach ($params as $k => $v) {
- if ($k != '_import') continue;
+ foreach ($params as $k => $v) {
+ if ($k != '_import') continue;
- $import = is_array($v) ? $v : explode(',',$v);
- foreach ($import as $v) {
- if ($id == $v) self::bye("Infinite loop: _import $id = $v");
- if (empty($dbs[$v])) continue;
+ $import = is_array($v) ? $v : explode(',',$v);
+ foreach ($import as $v) {
+ if ($id == $v) self::bye("Infinite loop: _import $id = $v");
+ if (empty($dbs[$v])) continue;
- foreach ($dbs[$v] as $kk => $vv) {
- if (!isset($params[$kk])) $dbs[$id][$kk] = $vv;
- }
- }
+ foreach ($dbs[$v] as $kk => $vv) {
+ if (!isset($params[$kk])) $dbs[$id][$kk] = $vv;
+ }
+ }
- unset($dbs[$id][$k]);
- }
- }
+ unset($dbs[$id][$k]);
+ }
+ }
- $default = isset($dbs['_default']) ? $dbs['_default'] : [];
+ $default = isset($dbs['_default']) ? $dbs['_default'] : [];
- #
- # Second iteration: Remove db starting with _
- #
- foreach ($dbs as $db=>$params) { if (preg_match('/^_/',$db)) unset($dbs[$db]); }
+ #
+ # Second iteration: Remove db starting with _
+ #
+ foreach ($dbs as $db=>$params) { if (preg_match('/^_/',$db)) unset($dbs[$db]); }
- if (!$dbs) return false;
+ if (!$dbs) return false;
- #
- # Third iteration: Add missing and default
- #
- foreach ($dbs as $db=>$params) {
- if (empty($params['name'])) $dbs[$db]['name'] = $db;
- if (empty($params['id'])) $dbs[$db]['id'] = $db;
+ #
+ # Third iteration: Add missing and default
+ #
+ foreach ($dbs as $db=>$params) {
+ if (empty($params['name'])) $dbs[$db]['name'] = $db;
+ if (empty($params['id'])) $dbs[$db]['id'] = $db;
# Ignore incomplete
- if (empty($params['type'])) {
+ if (empty($params['type'])) {
unset($dbs[$db]);
continue;
}
- foreach ($default as $k=>$v) if (!isset($params[$k])) $dbs[$db][$k] = $v;
- }
-
- #
- # Sort by `order`, min first
- #
- uasort($dbs,function($a,$b){
- if (empty($a['order']) and empty($b['order'])) return strcmp($a['id'],$b['id']);
- $a_ = !empty($a['order']) ? $a['order'] : 9999999;
- $b_ = !empty($b['order']) ? $b['order'] : 9999999;
- return($a_-$b_);
- });
-
- #
- # Return
- #
- if (!$dbs) return false;
- if ($first !== false) $first = self::ar_first($dbs);
- return $dbs;
- }
-
- /**
- * @copyright NB 19.11.16
- * Return a db hash to create a new instance from $conf
- */
- public static function conf_param_db($id) {
- if (!isset($id)) $id = self::p('db');
-
- if (!$id or !preg_match('/^(\w+):(.*)/',$id,$m)) return [];
- $conf = [$id => []];
-
- $conf[$id] = $conf[$id] + self::pdo2h($id);
- # NB 10.12.16: NEW
- if (empty($conf['id'])) $conf['id'] = $id;
-
- return $conf;
- }
-
- /**
- * @copyright NB 12.08.16
- * Return a db hash to create a new instance from $conf
- */
- public static function conf_search_db($conf,$id=null) {
-
- if (empty($id)) $id = self::p('db');
-
- # Load databases
- $conf = self::is_hash($conf) ? $conf : self::conf_load($conf);
-
- $conf += self::conf_param_db($id);
-
- if (!$conf) return false;
-
- # Param - Default base on order hight num value
- if (!$id) {
- $id = self::ar_first($conf,true);
- self::pset('db',$id);
- }
-
- if (!isset($conf[$id])) {
- self::bye("Can't find db: `".$id."` in `".join(",",array_keys($conf))."`",false);
- }
-
- if (empty($conf[$id])) return [];
-
- # Construct assoc array
- $db = array_merge($conf[$id],[
- 'conf' => $conf,
- ]);
-
- return $db;
- }
-
- /**
- * @copyright NB 12.08.16
- * Create globals Db and Table
- */
- public static function init($conf) {
-
- #
- # Params
- self::pinit();
-
- #
- # Load conf
- $db = self::conf_search_db($conf);
- if (self::p('localFile')) {
- foreach (self::localFile($db['name']) as $k=>$v) {
- if (empty($db[$k])) $db[$k] = $v;
- }
- }
-
- #
- # Db
- #
- global $Db, $Table;
- if (isset($Table)) self::bye("Table.init(): GLOBALS['Table'] already exists !");
- if (isset($Db)) self::bye("Db.init(): GLOBALS['Db'] already exists !");
- $Db = new self();
- #
- # Connection
- $Db->__construct($db);
- $Db->connect();
-
- #
- # Table
- #
- if (self::p('action') and
- !self::p('table') and
- !preg_match('/^(table\.\w+|rows|insert|edit|delete|update)$/',self::p('action'))
- ) {
-
- } else {
-
- # Search default_table
- if (!self::p('table') and isset($Db->default_table)) self::pset('table',$Db->default_table);
-
- # Choose first table
- if (!self::p('table') and ($v = array_keys($Db->tables()))) self::pset('table',$Db->ar_first($v));
-
- if (self::p('table')) $Table = $Db->table(self::p('table'),
- ( empty($db['tables'][$Db->p('table')]) ? [] : $db['tables'][$Db->p('table')] )
- );
-
- }
-
- return true;
- }
-
- /**
- * @copyright NB 12.08.16
- * Transform pdo string into assoc array
- */
- public static function pdo2h($pdo) {
- $hash = [];
-
- if (preg_match('/^(\w+):(.*)/',$pdo,$m)) {
- $hash['type'] = $m[1];
- $pdo = $m[2];
- }
-
- # YES - 'use_path'
- while (preg_match('/^(\w+)=([^;]*)(?:;?)(.*?)$/',$pdo,$m)) {
- if ($m[1] == 'dbname') $m[1] = 'name';
- $hash[$m[1]] = $m[2];
- $pdo = $m[3];
- }
-
- # NO - 'use_path'
- if ($pdo) {
- $hash['host'] = $pdo;
- unset($pdo);
- }
-
- return $hash;
- }
-
- public function pdo_info() {#$pdo) {
- $infos = [];
-
- foreach (self::pdo2h($this->pdo) as $k=>$v) {
- if (!preg_match('/^(host|port|dbname|name|user)/',$k)) continue;
- $infos[] = "$k=$v";
- }
-
- return join(' ',$infos);
- }
-
- public function dump2csv() {
-
- $this->pset('format','csv');
-
- # Filters
- $name = self::p('name',self::p('table',''));
- $sep = self::p('sep',"\t");
-
- foreach ($this->tables() as $t) {
- if (
- ($t->type == 'table')
- and (empty($name) or $this->str_match($t->name,$name))
- ) {
- $o = [
- 'preffix' => $t->name.$sep
- ]; $t->rows($o);
- }
- }
-
- }
-
- public function dump($db_type='') {
- return $this->sql(true,$db_type);
- }
-
- public function sql($insert=null,$db_type='') {
- if ($insert === null) $insert = self::p('insert');
- if (empty($db_type)) $db_type = self::p('db-type');
-
- # Params ! dirty !
+ foreach ($default as $k=>$v) if (!isset($params[$k])) $dbs[$db][$k] = $v;
+ }
+
+ #
+ # Sort by `order`, min first
+ #
+ uasort($dbs,function($a,$b){
+ if (empty($a['order']) and empty($b['order'])) return strcmp($a['id'],$b['id']);
+ $a_ = !empty($a['order']) ? $a['order'] : 9999999;
+ $b_ = !empty($b['order']) ? $b['order'] : 9999999;
+ return($a_-$b_);
+ });
+
+ #
+ # Return
+ #
+ if (!$dbs) return false;
+ if ($first !== false) $first = self::ar_first($dbs);
+ return $dbs;
+ }
+
+ /**
+ * @copyright NB 19.11.16
+ * Return a db hash to create a new instance from $conf
+ */
+ public static function conf_param_db($id) {
+ if (!isset($id)) $id = self::p('db');
+
+ if (!$id or !preg_match('/^(\w+):(.*)/',$id,$m)) return [];
+ $conf = [$id => []];
+
+ $conf[$id] = $conf[$id] + self::pdo2h($id);
+ # NB 10.12.16: NEW
+ if (empty($conf['id'])) $conf['id'] = $id;
+
+ return $conf;
+ }
+
+ /**
+ * @copyright NB 12.08.16
+ * Return a db hash to create a new instance from $conf
+ */
+ public static function conf_search_db($conf,$id=null) {
+
+ if (empty($id)) $id = self::p('db');
+
+ # Load databases
+ $conf = self::is_hash($conf) ? $conf : self::conf_load($conf);
+
+ $conf += self::conf_param_db($id);
+
+ if (!$conf) return false;
+
+ # Param - Default base on order hight num value
+ if (!$id) {
+ $id = self::ar_first($conf,true);
+ self::pset('db',$id);
+ }
+
+ if (!isset($conf[$id])) {
+ self::bye("Can't find db: `".$id."` in `".join(",",array_keys($conf))."`",false);
+ }
+
+ if (empty($conf[$id])) return [];
+
+ # Construct assoc array
+ $db = array_merge($conf[$id],[
+ 'conf' => $conf,
+ ]);
+
+ return $db;
+ }
+
+ /**
+ * @copyright NB 12.08.16
+ * Create globals Db and Table
+ */
+ public static function init($conf) {
+
+ #
+ # Params
+ self::pinit();
+
+ #
+ # Load conf
+ $db = self::conf_search_db($conf);
+ if (self::p('localFile')) {
+ foreach (self::localFile($db['name']) as $k=>$v) {
+ if (empty($db[$k])) $db[$k] = $v;
+ }
+ }
+
+ #
+ # Db
+ #
+ global $Db, $Table;
+ if (isset($Table)) self::bye("Table.init(): GLOBALS['Table'] already exists !");
+ if (isset($Db)) self::bye("Db.init(): GLOBALS['Db'] already exists !");
+ $Db = new self();
+ #
+ # Connection
+ $Db->__construct($db);
+ $Db->connect();
+
+ #
+ # Table
+ #
+ if (self::p('action') and
+ !self::p('table') and
+ !preg_match('/^(table\.\w+|rows|insert|edit|delete|update)$/',self::p('action'))
+ ) {
+
+ } else {
+
+ # Search default_table
+ if (!self::p('table') and isset($Db->default_table)) self::pset('table',$Db->default_table);
+
+ # Choose first table
+ if (!self::p('table') and ($v = array_keys($Db->tables()))) self::pset('table',$Db->ar_first($v));
+
+ if (self::p('table')) $Table = $Db->table(self::p('table'),
+ ( empty($db['tables'][$Db->p('table')]) ? [] : $db['tables'][$Db->p('table')] )
+ );
+
+ }
+
+ return true;
+ }
+
+ /**
+ * @copyright NB 12.08.16
+ * Transform pdo string into assoc array
+ */
+ public static function pdo2h($pdo) {
+ $hash = [];
+
+ if (preg_match('/^(\w+):(.*)/',$pdo,$m)) {
+ $hash['type'] = $m[1];
+ $pdo = $m[2];
+ }
+
+ # YES - 'use_path'
+ while (preg_match('/^(\w+)=([^;]*)(?:;?)(.*?)$/',$pdo,$m)) {
+ if ($m[1] == 'dbname') $m[1] = 'name';
+ $hash[$m[1]] = $m[2];
+ $pdo = $m[3];
+ }
+
+ # NO - 'use_path'
+ if ($pdo) {
+ $hash['host'] = $pdo;
+ unset($pdo);
+ }
+
+ return $hash;
+ }
+
+ public function pdo_info() {#$pdo) {
+ $infos = [];
+
+ foreach (self::pdo2h($this->pdo) as $k=>$v) {
+ if (!preg_match('/^(host|port|dbname|name|user)/',$k)) continue;
+ $infos[] = "$k=$v";
+ }
+
+ return join(' ',$infos);
+ }
+
+ public function dump2csv() {
+
+ $this->pset('format','csv');
+
+ # Filters
+ $name = self::p('name',self::p('table',''));
+ $sep = self::p('sep',"\t");
+
+ foreach ($this->tables() as $t) {
+ if (
+ ($t->type == 'table')
+ and (empty($name) or $this->str_match($t->name,$name))
+ ) {
+ $o = [
+ 'preffix' => $t->name.$sep
+ ]; $t->rows($o);
+ }
+ }
+
+ }
+
+ public function dump($db_type='') {
+ return $this->sql(true,$db_type);
+ }
+
+ public function sql($insert=null,$db_type='') {
+ if ($insert === null) $insert = self::p('insert');
+ if (empty($db_type)) $db_type = self::p('db-type');
+
+ # 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('table-type',''); $type = $type ? explode(',',$type) : $type;
- $name = self::p('table-name',''); $name = $name ? explode(',',$name) : $name;
-
- # Tables param filter
- $tables = $this->tables();
-
- # Caching before changing db type
- $views = [];
- foreach ($tables as $k=>$t) {
-
- if (
- ($t->type != 'table' and $t->type != 'view')
- or (!empty($name) and !$this->str_match($t->name,$name))
- or (!empty($type) and !$this->str_match($t->type,$type))
- ) {
- unset($tables[$k]);
- continue;
- }
-
- if ($t->type == 'view') {
- $views[$k] = $t;
- unset($tables[$k]);
- }
- unset($t->orderby);
-
- $t->fields();
- $t->sql();
- }
-
- # HEADER
- echo ''
- #."-- Database : ".$this->name."\n"
- ."-- Date : ".strftime('%F %T')."\n"
+ # Filters
+ $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();
+
+ # Caching before changing db type
+ $views = [];
+ foreach ($tables as $k=>$t) {
+
+ if (
+ ($t->type != 'table' and $t->type != 'view')
+ or (!empty($name) and !$this->str_match($t->name,$name))
+ or (!empty($type) and !$this->str_match($t->type,$type))
+ ) {
+ unset($tables[$k]);
+ continue;
+ }
+
+ if ($t->type == 'view') {
+ $views[$k] = $t;
+ unset($tables[$k]);
+ }
+ unset($t->orderby);
+
+ $t->fields();
+ $t->sql();
+ }
+
+ # HEADER
+ echo ''
+ #."-- Database : ".$this->name."\n"
+ ."-- Date : ".strftime('%F %T')."\n"
# NB 07.01.18 ."-- Pdo : ".$this->pdo_info()."\n"
- ;
+ ;
- # Change db type if needed
- $type_from = $type_to = '';
- if ($db_type) {
- echo "-- Type : ".$db_type."\n";
- echo "-- Type from: ".$this->type."\n";
- $type_from = $this->type;
- $type_to = $db_type;
- $this->type = $type_to;
+ # Change db type if needed
+ $type_from = $type_to = '';
+ if ($db_type) {
+ echo "-- Type : ".$db_type."\n";
+ echo "-- Type from: ".$this->type."\n";
+ $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,
- ];
-
- # SQL_PRE
- $i = 0; foreach ((array)$this->method('schema.pre') as $s) {
- if (($i++) == 0) echo "\n-- SQL.PRE\n";
- echo rtrim($s,';').";\n";
- }
-
- if ($type_from == 'mysql') $views = []; # Mysql store sql create view in mysql format wich only works with mysql
- echo "\n-- SQL\n";
- foreach (array_merge($tables,$views) as $t) {
-
- # DROP / CREATE
- $create = rtrim($t->create(false),';');
- $create = str_replace(';CREATE',";\nCREATE",$create);
-
- if (!($drop = $this->method('sql.drop'))) $drop =
- 'DROP '.strtoupper($t->type).' IF EXISTS '.$t->sql_name()
- ;
-
- $t->sql_create = $drop.';'.NB_EOL
- .$create.';'.NB_EOL
- ;
-
- if ($insert) $t->sql_create =
- "\n-- ".strtoupper($t->type).": ".$t->name."\n".$t->sql_create
- ;
- echo $t->sql_create;
-
- # INSERT
- if ($insert and $t->type == 'table') {
+ echo "-- Type : ".$this->type."\n";
+
+ }
+
+ # Specific function
+ $row_opt = [
+ 'parser' => false,
+ 'format' => 'sql',
+ 'db_type_from' => $type_from,
+ ];
+
+ # SQL_PRE
+ $i = 0; foreach ((array)$this->method('schema.pre') as $s) {
+ if (($i++) == 0) echo "\n-- SQL.PRE\n";
+ echo rtrim($s,';').";\n";
+ }
+
+ if ($type_from == 'mysql') $views = []; # Mysql store sql create view in mysql format wich only works with mysql
+ echo "\n-- SQL\n";
+ foreach (array_merge($tables,$views) as $t) {
+
+ # DROP / CREATE
+ $create = rtrim($t->create(false),';');
+ $create = str_replace(';CREATE',";\nCREATE",$create);
+
+ if (!($drop = $this->method('sql.drop'))) $drop =
+ 'DROP '.strtoupper($t->type).' IF EXISTS '.$t->sql_name()
+ ;
+
+ $t->sql_create = $drop.';'.NB_EOL
+ .$create.';'.NB_EOL
+ ;
+
+ if ($insert) $t->sql_create =
+ "\n-- ".strtoupper($t->type).": ".$t->name."\n".$t->sql_create
+ ;
+ echo $t->sql_create;
+
+ # INSERT
+ if ($insert and $t->type == 'table') {
$o = $row_opt;
- $t->rows($o);
- }
+ $t->rows($o);
+ }
- }
+ }
- $i = 0; foreach ((array)$this->method('schema.post') as $s) {
- if (($i++) == 0) echo "\n-- SQL.POST\n";
- echo rtrim($s,';').";\n";
- }
+ $i = 0; foreach ((array)$this->method('schema.post') as $s) {
+ if (($i++) == 0) echo "\n-- SQL.POST\n";
+ echo rtrim($s,';').";\n";
+ }
- return true;
- }
+ return true;
+ }
- public function status() {
+ public function status() {
- $status = $new = [];
+ $status = $new = [];
#debug(array_keys($this->tables()));
- $new = []
- +[
- 'id' => (empty($this->id) ? '' : $this->id),
- 'name' => $this->name,
- 'type' => $this->type,
- 'host' => $this->host,
- 'tables' => count($this->tables()),
- ]
- +($this->conf_type('use_path') ? [] : [
- 'port' => $this->port,
- 'user' => $this->user,
- ])
- +[
- 'title' => $this->title,
- 'default_table' => $this->default_table,
- ]
- +$new;
-
- if (($sqls=$this->conf_type('status'))) {
-
- foreach ($sqls as $sql => $fct) {
-
- try {
- $sth = $this->conn->prepare($sql);
- $sth->execute();
- } catch(PDOException $e){
- continue;
- }
-
- $rows = $sth->fetchAll(PDO::FETCH_BOTH);
- foreach ($rows as $i=>$r) {
- if ($v = $fct($r)) $new += $v;
- }
- #$sqls = $new;
- #debug($rows);
- }
-
- } # << type.status
-
- if (($call=$this->conf_type('status_callback'))) {
- $call($new);
- }
-
- #debug($new);
- foreach ($new as $k=>$v) {
- $status[] = [
- 'name' => $k,
- 'value' => $v,
- ];
- }
-
- return $status;
- }
-
- public function fields($st) {
- # See: http://php.net/manual/en/pdostatement.getcolumnmeta.php
- $fields = [];
- #debug($st->columnCount());
- #debug($st->getColumnMeta(0));
-
- for ($i = 0; $i < $st->columnCount(); $i++) {
- $col = $st->getColumnMeta($i);
-
- $f = new Field();
- $col['type'] = $f->pdo2type($col['pdo_type']);
- unset($col['pdo_type']);
-
- if (!empty($col['flags'])) {
- $col['null'] = in_array('not_null',$col['flags']) ? false : true;
- $col['key'] = in_array('primary_key',$col['flags']) ? true : false;
- }
- unset($col['flags']);
-
- unset($col['len']); # never right !
- unset($col['precision']); # ???
-
- $f->__construct($col);
- $fields[] = $f;
- }
-
- return $fields;
- }
-
- public function sql_pre() {
- $return = [];
-
- foreach ((array)$this->conf_type('sql_pre') as $s) {
- if (!empty($s)) $return[] = $s;
- }
-
- if (!empty($this->sql_pre)) {
- foreach ((array)$this->sql_pre as $s) {
- if (!empty($s)) $return[] = $s;
- }
- }
-
- return $return;
- }
-
- public function sql_post() {
- $return = [];
-
- foreach ((array)$this->conf_type('sql_post') as $s) {
- if (!empty($s)) $return[] = $s;
- }
-
- if (!empty($this->sql_post)) {
- foreach ((array)$this->sql_post as $s) {
- if (!empty($s)) $return[] = $s;
- }
- }
+ $new = []
+ +[
+ 'id' => (empty($this->id) ? '' : $this->id),
+ 'name' => $this->name,
+ 'type' => $this->type,
+ 'host' => $this->host,
+ 'tables' => count($this->tables()),
+ ]
+ +($this->conf_type('use_path') ? [] : [
+ 'port' => $this->port,
+ 'user' => $this->user,
+ ])
+ +[
+ 'title' => $this->title,
+ 'default_table' => $this->default_table,
+ ]
+ +$new;
+
+ if (($sqls=$this->conf_type('status'))) {
+
+ foreach ($sqls as $sql => $fct) {
+
+ try {
+ $sth = $this->conn->prepare($sql);
+ $sth->execute();
+ } catch(PDOException $e){
+ continue;
+ }
+
+ $rows = $sth->fetchAll(PDO::FETCH_BOTH);
+ foreach ($rows as $i=>$r) {
+ if ($v = $fct($r)) $new += $v;
+ }
+ #$sqls = $new;
+ #debug($rows);
+ }
- return $return;
- }
+ } # << type.status
- public function databases() {
+ if (($call=$this->conf_type('status_callback'))) {
+ $call($new);
+ }
- if (!isset($this->databases)) {
+ #debug($new);
+ foreach ($new as $k=>$v) {
+ $status[] = [
+ 'name' => $k,
+ 'value' => $v,
+ ];
+ }
- $this->databases = [];
- $name = self::p('name','');
+ return $status;
+ }
- if ($sql = $this->conf_type('databases') and !empty($this->conn)) {
- $fct = '';
- if (is_array($sql)) list($sql,$fct) = count($sql)>1 ? $sql : [$sql[0],''];
+ public function fields($st) {
+ # See: http://php.net/manual/en/pdostatement.getcolumnmeta.php
+ $fields = [];
+ #debug($st->columnCount());
+ #debug($st->getColumnMeta(0));
- $st = $this->conn->prepare($sql);
- $st->execute();
- $this->databases = [];
+ for ($i = 0; $i < $st->columnCount(); $i++) {
+ $col = $st->getColumnMeta($i);
- while ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
- if ($fct) $fct($row,$this);
- if ($row) $this->databases[] = $row;
- }
+ $f = new Field();
+ $col['type'] = $f->pdo2type($col['pdo_type']);
+ unset($col['pdo_type']);
- }
+ if (!empty($col['flags'])) {
+ $col['null'] = in_array('not_null',$col['flags']) ? false : true;
+ $col['key'] = in_array('primary_key',$col['flags']) ? true : false;
+ }
+ unset($col['flags']);
- }
+ unset($col['len']); # never right !
+ unset($col['precision']); # ???
- return $this->databases;
- }
+ $f->__construct($col);
+ $fields[] = $f;
+ }
- public static function pinit(&$changed=[]) {
- if (!empty(self::$paliases)) self::paliases(self::$paliases,$changed);
+ return $fields;
+ }
- if ($action=self::p('action') and !empty(self::$action_aliases)) {
- foreach (self::$action_aliases as $src => $dest) {
- if ($action === $src) self::pset('action',$dest);
- }
- }
+ public function sql_pre() {
+ $return = [];
- # Param - Extract dbname from table
+ foreach ((array)$this->conf_type('sql_pre') as $s) {
+ if (!empty($s)) $return[] = $s;
+ }
+
+ if (!empty($this->sql_pre)) {
+ foreach ((array)$this->sql_pre as $s) {
+ if (!empty($s)) $return[] = $s;
+ }
+ }
+
+ return $return;
+ }
+
+ public function sql_post() {
+ $return = [];
+
+ foreach ((array)$this->conf_type('sql_post') as $s) {
+ if (!empty($s)) $return[] = $s;
+ }
+
+ if (!empty($this->sql_post)) {
+ foreach ((array)$this->sql_post as $s) {
+ if (!empty($s)) $return[] = $s;
+ }
+ }
+
+ return $return;
+ }
+
+ public function databases() {
+
+ if (!isset($this->databases)) {
+
+ $this->databases = [];
+ $name = self::p('name','');
+
+ if ($sql = $this->conf_type('databases') and !empty($this->conn)) {
+ $fct = '';
+ if (is_array($sql)) list($sql,$fct) = count($sql)>1 ? $sql : [$sql[0],''];
+
+ $st = $this->conn->prepare($sql);
+ $st->execute();
+ $this->databases = [];
+
+ while ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
+ if ($fct) $fct($row,$this);
+ if ($row) $this->databases[] = $row;
+ }
+
+ }
+
+ }
+
+ return $this->databases;
+ }
+
+ public static function pinit(&$changed=[]) {
+ if (!empty(self::$paliases)) self::paliases(self::$paliases,$changed);
+
+ if ($action=self::p('action') and !empty(self::$action_aliases)) {
+ foreach (self::$action_aliases as $src => $dest) {
+ if ($action === $src) self::pset('action',$dest);
+ }
+ }
+
+ # Param - Extract dbname from table
# NB 12.11.16 if (false and preg_match('/^(\w+)\.(.*?)$/',self::p('table'),$m)) {
# NB 12.11.16 self::pset('db',$m[1]);
# NB 12.11.16 self::pset('table',$m[2]);
# NB 12.11.16 }
- # Select param
- if (Db::p('table') and Db::p('select')) {
- Db::pset('table','SELECT '.(Db::p('select')).' FROM '.Db::p('table'));
- Db::pset('select','');
- }
-
- }
-
- public function ls(&$fields=[]) {
-
- $fields = ['id','name','title','type','host' ]; #,'order'];
- $dbs = [];
- $name = self::p('name','');
- $type = self::p('type','');
-
- if (empty($this->conf)) return null;
-
- foreach ($this->conf as $id => $attr) {
- $attr['id'] = $id;
- $d = new Db($attr);
- $db = [];
-
- foreach ($fields as $k) {
- $db[$k] = isset($d->$k) ? $d->$k : '';
- }
-
- if (!empty($name) and !$this->str_match($db['name'],$name)) continue;
- if (!empty($type) and !$this->str_match($db['type'],$type)) continue;
-
- $dbs[] = $db;
- }
-
- return $dbs;
- }
-
- public function table_row_encrypt(&$table,&$row) {
- if (!empty($table->update_parse)) {
- $fct = $table->update_parse;
- $fct($row,$table);
- }
-
- if (0
- or empty($this->encrypt)
- or empty($this->encrypt['secret'])
- or empty($this->encrypt['tables'])
- or empty($this->encrypt['tables'][$table->name])
- ) return $row;
-
- foreach ($row as $k => $v) {
- if (!in_array($k,$this->encrypt['tables'][$table->name])) continue;
- $row[$k] = $this->encrypt($this->encrypt['secret'],$v);
- }
-
- return $row;
- }
-
- public function table_row_decrypt(&$table,&$row) {
- if (0
- or empty($this->encrypt)
- or empty($this->encrypt['secret'])
- or empty($this->encrypt['tables'])
- or empty($this->encrypt['tables'][$table->name])
- ) return $row;
-
- foreach ($row as $k => $v) {
- if (!in_array($k,$this->encrypt['tables'][$table->name])) continue;
- $row[$k] = $this->decrypt($this->encrypt['secret'],$v);
- }
-
- return $row;
- }
-
- public static function content_type2format($content_type=null) {
- if (empty($content_type)) $content_type = self::client_content_type();
- switch (mime::ext($content_type)) {
- case "html":
- return 'table';
- default:
- return 'csv';
- }
- }
-
- public function page($opt=[]) {
- require_once(NB_ROOT.'/lib/php/page.php');
- return new Page(array_merge([
- 'title' => ($this->title ? $this->title : this::prettyText($this->name)),
- 'css' => [
- 'css/*.css',
- '/*.css',
- ],
- 'js' => [
- 'js/*.js',
- '/*.js',
- ],
- 'content_type' => Page::content_type_and_set_format(),
- 'nav' => [
- [ (!empty($this) and !empty($this->title)) ? $this->title : 'Home', '/'],
- ( (!empty($this->table()) and !empty($this->table()->name)) ? [Page::prettyText($this->table()->name),Page::path().'?table='.urlencode($this->table()->name)] : '' ),
- ( Page::p('action') ? Page::prettyText(preg_replace('/^\w+\./','',Page::p('action'))) : '' ),
- ],
- ],$opt));
- }
-
- public function ssha512_password($password='',$salt='') {
- if (empty($password)) return $password;
- if ($salt === '') $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4);
- $password = '{SSHA512}' . base64_encode(hash('sha512', $password . $salt). $salt);
- return $password;
- }
-
- public function ssha_password($password='') {
- if (empty($password)) return $password;
- $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4);
- $password = '{SSHA}' . base64_encode(sha1( $password.$salt, TRUE ). $salt);
- return $password;
- }
-
- public function cast_text($str) {
- if ($fct = $this->conf_type('cast_text')) $str = $fct($str);
+ # Select param
+ if (Db::p('table') and Db::p('select')) {
+ Db::pset('table','SELECT '.(Db::p('select')).' FROM '.Db::p('table'));
+ Db::pset('select','');
+ }
+
+ }
+
+ public function ls(&$fields=[]) {
+
+ $fields = ['id','name','title','type','host' ]; #,'order'];
+ $dbs = [];
+ $name = self::p('name','');
+ $type = self::p('type','');
+
+ if (empty($this->conf)) return null;
+
+ foreach ($this->conf as $id => $attr) {
+ $attr['id'] = $id;
+ $d = new Db($attr);
+ $db = [];
+
+ foreach ($fields as $k) {
+ $db[$k] = isset($d->$k) ? $d->$k : '';
+ }
+
+ if (!empty($name) and !$this->str_match($db['name'],$name)) continue;
+ if (!empty($type) and !$this->str_match($db['type'],$type)) continue;
+
+ $dbs[] = $db;
+ }
+
+ return $dbs;
+ }
+
+ public function table_row_encrypt(&$table,&$row) {
+ if (!empty($table->update_parse)) {
+ $fct = $table->update_parse;
+ $fct($row,$table);
+ }
+
+ if (0
+ or empty($this->encrypt)
+ or empty($this->encrypt['secret'])
+ or empty($this->encrypt['tables'])
+ or empty($this->encrypt['tables'][$table->name])
+ ) return $row;
+
+ foreach ($row as $k => $v) {
+ if (!in_array($k,$this->encrypt['tables'][$table->name])) continue;
+ $row[$k] = $this->encrypt($this->encrypt['secret'],$v);
+ }
+
+ return $row;
+ }
+
+ public function table_row_decrypt(&$table,&$row) {
+ if (0
+ or empty($this->encrypt)
+ or empty($this->encrypt['secret'])
+ or empty($this->encrypt['tables'])
+ or empty($this->encrypt['tables'][$table->name])
+ ) return $row;
+
+ foreach ($row as $k => $v) {
+ if (!in_array($k,$this->encrypt['tables'][$table->name])) continue;
+ $row[$k] = $this->decrypt($this->encrypt['secret'],$v);
+ }
+
+ return $row;
+ }
+
+ public static function content_type2format($content_type=null) {
+ if (empty($content_type)) $content_type = self::client_content_type();
+ switch (mime::ext($content_type)) {
+ case "html":
+ return 'table';
+ default:
+ return 'csv';
+ }
+ }
+
+ public function page($opt=[]) {
+ require_once(NB_ROOT.'/lib/php/page.php');
+ return new Page(array_merge([
+ 'title' => ($this->title ? $this->title : this::prettyText($this->name)),
+ 'css' => [
+ 'css/*.css',
+ '/*.css',
+ ],
+ 'js' => [
+ 'js/*.js',
+ '/*.js',
+ ],
+ 'content_type' => Page::content_type_and_set_format(),
+ 'nav' => [
+ [ (!empty($this) and !empty($this->title)) ? $this->title : 'Home', '/'],
+ ( (!empty($this->table()) and !empty($this->table()->name)) ? [Page::prettyText($this->table()->name),Page::path().'?table='.urlencode($this->table()->name)] : '' ),
+ ( Page::p('action') ? Page::prettyText(preg_replace('/^\w+\./','',Page::p('action'))) : '' ),
+ ],
+ ],$opt));
+ }
+
+ public function ssha512_password($password='',$salt='') {
+ if (empty($password)) return $password;
+ if ($salt === '') $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4);
+ $password = '{SSHA512}' . base64_encode(hash('sha512', $password . $salt). $salt);
+ return $password;
+ }
+
+ public function ssha_password($password='') {
+ if (empty($password)) return $password;
+ $salt = substr(str_shuffle(str_repeat('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789',4)),0,4);
+ $password = '{SSHA}' . base64_encode(sha1( $password.$salt, TRUE ). $salt);
+ return $password;
+ }
+
+ public function cast_text($str) {
+ if ($fct = $this->conf_type('cast_text')) $str = $fct($str);
return $str;
- }
+ }
- public function like_nocase() {
- if ($v = $this->conf_type('like_nocase')) return $v;
+ public function like_nocase() {
+ if ($v = $this->conf_type('like_nocase')) return $v;
return 'LIKE';
- }
+ }
} # < Class
require_once(realpath(NB_ROOT.'/lib/php/db/field.php'));
require_once(realpath(NB_ROOT.'/lib/php/out.php'));
$DB_TABLE_QUERY_ID = 0;
-function __table_define() {
- define('TABLE_INDENT',NB_EOL ? "\t" : "");
- define('TABLE_CSV_SEP',Table::p('sep',"\t"));
- if (!defined('TABLE_TEMPLATE')) define('TABLE_TEMPLATE',dirname(__FILE__).'/../../../share/templates');
+// >> Define
+define('TABLE_INDENT',NB_EOL ? "\t" : "");
+define('TABLE_CSV_SEP',Table::p('sep',"\t"));
- if (!defined('DB_HTML_EDIT')) define('DB_HTML_EDIT','Edit');
- if (!defined('DB_HTML_DELETE')) define('DB_HTML_DELETE','Delete');
+if (!defined('TABLE_TEMPLATE')) define('TABLE_TEMPLATE',dirname(__FILE__).'/../../../share/templates');
- # Create a temporary table when table is a SELECT
- #if (!defined('DB_TABLE_QUERY_NAME'))
- define('DB_TABLE_QUERY_NAME','_query_');
-}
+if (!defined('DB_HTML_EDIT')) define('DB_HTML_EDIT','Edit');
+if (!defined('DB_HTML_DELETE')) define('DB_HTML_DELETE','Delete');
+// << Define
+
+# Create a temporary table when table is a SELECT
+#if (!defined('DB_TABLE_QUERY_NAME'))
+define('DB_TABLE_QUERY_NAME','_query_');
Class Table extends nb {
- public $name;
- public $type; # table, view, sql
- public $sql;
- public $replace = []; # to be process by by javascript (id="db-table-replace")
- public $extras = [];
- public $rows = []; # array inserted into temporary table
- public $row_parse_pre; # Function to call in rows()
- public $row_parse_post; # Function to call in rows()
- public $update_parse; # Function to call in update, replace, insert
- public $count;
- public $engine;
- public $created;
- public static $is_admin = true;
- public $key_preff = '_key_';
+ public $name;
+ public $type; # table, view, sql
+ public $sql;
+ public $replace = []; # to be process by by javascript (id="db-table-replace")
+ public $extras = [];
+ public $rows = []; # array inserted into temporary table
+ public $row_parse_pre; # Function to call in rows()
+ public $row_parse_post; # Function to call in rows()
+ public $update_parse; # Function to call in update, replace, insert
+ public $count;
+ public $engine;
+ public $created;
+ public static $is_admin = true;
+ public $key_preff = '_key_';
# NB 19.10.17 TODO
- public $field_preff = '';
-
- public $fields = [];
- public $fields_only = [];
- public $indexes = [];
-
- public $idtemplate;
-
- # hidden, sort, ... fields
- public $show_hidden_params = true;
- public $show_buttons = true;
- public $show_url_sort = true;
- public $show_header = true;
- public static $params = [
- 'db', 'table', 'limit', 'debug', 'action',
- 'page', 'paged', # wordpress
- ];
-
- function __construct($name,$opt=[]) {
-
- if (!is_scalar($name)) {
- $opt = $name;
- #$name = $opt['name'];
- $name = isset($opt['name']) ? $opt['name'] : '';
-
- }
-
- if(!empty($name)) $opt['name'] = $this->name = $name;
- #debug($opt);
-
- #unset($opt['db']); bye($opt);
-
- // Type
- if (isset($opt['sql'])) {
- $this->type = 'sql'; unset($opt['type']);
- $this->sql = $opt['sql']; unset($opt['sql']);
- }
-
- // Params
- if (isset($opt['params'])) {
- self::$params = $opt['params']; unset($opt['params']);
- }
-
- // Db / Connection
- if (isset($opt['db'])) {
- $this->db(is_object($opt['db']) ? $opt['db'] : new Db($opt['db']));
- unset($opt['db']);
-
- } elseif(isset($GLOBALS['Db'])) {
- $this->db($GLOBALS['Db']);
-
- } else {
- $this->db(new Db());
-
- }
-
- // Extras
- if (isset($opt['extras'])) {
- $this->add_extras($opt['extras']);
- unset($opt['extras']);
- }
-
- // Add others
- foreach ($opt as $k => $v) { $this->$k = $v; }
-
- if (empty($this->db()->limit)) {
- if ($this->p('paged')) {
- $this->db()->limit = ($this->db()->limit * $this->p('paged')).','.$this->db()->limit;
- } elseif ($this->db()->limit=$this->p('limit')) {
- }
- }
-
- if (isset($_GET['rows.header'])) $this->show_header = $_GET['rows.header'];
- if (isset($_GET['rows.fields'])) $this->fields_only = explode(',',$_GET['rows.fields']);
-
- }
-
- public function create_temporary_rows() {
- // For static rows
- if(empty($this->rows)) return null;
- if(!empty($this->rows) and empty($this->type)) $this->type = 'rows';
-
- $fields = array_keys($this->rows[0]);
- $sql_names = $this->sql_names($fields);
-
- $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE $this->name ("
- .join(',',$this->ar_map('"$a text"',$sql_names))
- .')');
- $sql = 'INSERT INTO '. $this->sql_name("$this->name")
- . ' (' . join(',',array_values($sql_names)).')'
- .' VALUES (' . join(',',$this->ar_map('":$a"',$fields)) . ')'
- ;
-
- #debug($sql);
- if (!($query = $this->db()->conn->prepare($sql))) {
- $this->err_sql($sql);
- return false;
- }
-
- $this->fields = [];
- foreach ($fields as $name) {
- $this->fields[$name] = new Field([
- 'name' => $name,
- 'table' => $this,
- ]);
- }
- $this->_fields = 1;
-
- foreach ($this->rows as $row) {
-
- foreach ($row as $k=>$v) {
- $field = $this->field($k);
- $field->bindParam($query,$v,":$k");
- }
-
- if (!($execute = $query->execute())) {
- $this->err_sql($sql);
- return false;
- }
-
- }
-
- return true;
- }
-
- private function sql_temporary() {
- if ($this->db()->type == 'sqlite') return 'TEMP';
- return 'TEMPORARY';
- }
-
- /*
- * Function create_temporary
- *
- * Create temporary if needed
- *
- */
- public function create_temporary() {
- if (!empty($this->_create_temporary)) return;
- $this->_create_temporary = true;
-
- $this->create_temporary_rows();
-
- // Name, could be a select
- if (DB_TABLE_QUERY_NAME and stripos($this->name,'SELECT ')===0) {
- $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE ".DB_TABLE_QUERY_NAME." AS $this->name");
- $this->name = DB_TABLE_QUERY_NAME;
-
- // Virtual Table
- } elseif (DB_TABLE_QUERY_NAME and !empty($this->sql)) {
+ public $field_preff = '';
+
+ public $fields = [];
+ public $fields_only = [];
+ public $indexes = [];
+
+ public $idtemplate;
+
+ # hidden, sort, ... fields
+ public $show_hidden_params = true;
+ public $show_buttons = true;
+ public $show_url_sort = true;
+ public $show_header = true;
+ public static $params = [
+ 'db', 'table', 'limit', 'debug', 'action',
+ 'page', 'paged', # wordpress
+ ];
+
+ function __construct($name,$opt=[]) {
+
+ if (!is_scalar($name)) {
+ $opt = $name;
+ #$name = $opt['name'];
+ $name = isset($opt['name']) ? $opt['name'] : '';
+
+ }
+
+ if(!empty($name)) $opt['name'] = $this->name = $name;
+ #debug($opt);
+
+ #unset($opt['db']); bye($opt);
+
+ // Type
+ if (isset($opt['sql'])) {
+ $this->type = 'sql'; unset($opt['type']);
+ $this->sql = $opt['sql']; unset($opt['sql']);
+ }
+
+ // Params
+ if (isset($opt['params'])) {
+ self::$params = $opt['params']; unset($opt['params']);
+ }
+
+ // Db / Connection
+ if (isset($opt['db'])) {
+ $this->db(is_object($opt['db']) ? $opt['db'] : new Db($opt['db']));
+ unset($opt['db']);
+
+ } elseif(isset($GLOBALS['Db'])) {
+ $this->db($GLOBALS['Db']);
+
+ } else {
+ $this->db(new Db());
+
+ }
+
+ // Extras
+ if (isset($opt['extras'])) {
+ $this->add_extras($opt['extras']);
+ unset($opt['extras']);
+ }
+
+ // Add others
+ foreach ($opt as $k => $v) { $this->$k = $v; }
+
+ if (empty($this->db()->limit)) {
+ if ($this->p('paged')) {
+ $this->db()->limit = ($this->db()->limit * $this->p('paged')).','.$this->db()->limit;
+ } elseif ($this->db()->limit=$this->p('limit')) {
+ }
+ }
+
+ if (isset($_GET['rows.header'])) $this->show_header = $_GET['rows.header'];
+ if (isset($_GET['rows.fields'])) $this->fields_only = explode(',',$_GET['rows.fields']);
+
+ }
+
+ public function create_temporary_rows() {
+ // For static rows
+ if(empty($this->rows)) return null;
+ if(!empty($this->rows) and empty($this->type)) $this->type = 'rows';
+
+ $fields = array_keys($this->rows[0]);
+ $sql_names = $this->sql_names($fields);
+
+ $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE $this->name ("
+ .join(',',$this->ar_map('"$a text"',$sql_names))
+ .')');
+ $sql = 'INSERT INTO '. $this->sql_name("$this->name")
+ . ' (' . join(',',array_values($sql_names)).')'
+ .' VALUES (' . join(',',$this->ar_map('":$a"',$fields)) . ')'
+ ;
+
+ #debug($sql);
+ if (!($query = $this->db()->conn->prepare($sql))) {
+ $this->err_sql($sql);
+ return false;
+ }
+
+ $this->fields = [];
+ foreach ($fields as $name) {
+ $this->fields[$name] = new Field([
+ 'name' => $name,
+ 'table' => $this,
+ ]);
+ }
+ $this->_fields = 1;
+
+ foreach ($this->rows as $row) {
+
+ foreach ($row as $k=>$v) {
+ $field = $this->field($k);
+ $field->bindParam($query,$v,":$k");
+ }
+
+ if (!($execute = $query->execute())) {
+ $this->err_sql($sql);
+ return false;
+ }
+
+ }
+
+ return true;
+ }
+
+ private function sql_temporary() {
+ if ($this->db()->type == 'sqlite') return 'TEMP';
+ return 'TEMPORARY';
+ }
+
+ /*
+ * Function create_temporary
+ *
+ * Create temporary if needed
+ *
+ */
+ public function create_temporary() {
+ if (!empty($this->_create_temporary)) return;
+ $this->_create_temporary = true;
+
+ $this->create_temporary_rows();
+
+ // Name, could be a select
+ if (DB_TABLE_QUERY_NAME and stripos($this->name,'SELECT ')===0) {
+ $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE ".DB_TABLE_QUERY_NAME." AS $this->name");
+ $this->name = DB_TABLE_QUERY_NAME;
+
+ // Virtual Table
+ } elseif (DB_TABLE_QUERY_NAME and !empty($this->sql)) {
# NB 29.12.16 table already exists !!! if ($this->name) $this->name = DB_TABLE_QUERY_NAME;
- $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE $this->name AS $this->sql");
-
- } elseif (preg_match('/\b(\.import|LOAD DATA|COPY|INSERT|REPLACE|DELETE|TRUNCATE|CREATE|DROP|ALERT)\b/',$this->name)) {
- bye("Query not Allowed !");
-
- } else {
- return false;
-
- }
-
- return true;
- }
-
- /*
- * Function db
- *
- * return the db object or init it
- *
- */
- public function db($set=null) {
- static $db = null;
- #if ($set !== null) debug($set->name);
- if ($set !== null) $db = $set;
- return $db;
- }
-
- /*
- * Function create
- *
- * return the sql to create the table build internaly
- *
- */
- public function create($from_engine=true,$db_type='') {
-
- // String replace function
- $sql_replace_fct = $this->db()->conf_type('table.sql.create');
- $db_sql_replace_fct = empty($this->db()->sql_replace) ? '' : $this->db()->sql_replace;
- $sql_replace = function($sql) use ($sql_replace_fct,$db_sql_replace_fct) {
- if ($db_sql_replace_fct) $sql = $db_sql_replace_fct($sql);
- return $sql_replace_fct ? $sql_replace_fct($sql,$this) : $sql;
- };
-
- if ($from_engine) return $sql_replace($this->sql());
-
- if ($this->type() == 'view') {
- return $sql_replace('CREATE VIEW '.$this->sql_name().' AS '.preg_replace('/^CREATE\s+.*?\s+AS\s+.*?SELECT/i','SELECT',$this->sql()));
- }
-
- $indexes = [];
- foreach ($this->indexes() as $i) {
- if (!empty($i['unique']) or !empty($i['key'])) continue;
- $indexes[] = 'CREATE INDEX '.$i['name'].' ON '.$this->sql_name().' ('.$i['field'].')';
- }
-
- # Get all fields
- $fields = [];
- foreach ($this->fields() as $f) {
- if (!empty($f->extras)) continue;
- $fields[] = $f;
- }
-
- $type = $this->db()->type;
- if (!empty($db_type)) $this->db()->type = $db_type;
-
- // Specific function for fields if return something use it instead of default
- $_create_fct = $this->db()->conf_type('field.create',false);
- $_create = function(&$field) use ($_create_fct) {
- if ($_create_fct and ($sql=$_create_fct($field))) return $sql;
-
- // Default
- return $field->sql_name().' '.$field->type
- .($field->null ? '' : ' NOT NULL')
- .($field->default !== null ? ' DEFAULT '.$field->quote($field->default,true) : '')
- .($field->key ? ' PRIMARY KEY' : '')
- .($field->uniq ? ' UNIQUE' : '')
- ;
- };
-
- $sql = 'CREATE '.strtoupper($this->type()).' '.$this->sql_name()
- .' ('
- .join(",",array_map(function($f) use ($_create) {return $_create($f);},$fields))
- # done at the end for primary keys .')'
- ;
-
- // Handle multiple primary keys syntaxe
- if (substr_count(strtoupper($sql),'PRIMARY KEY')>1) {
- $sql = str_ireplace(' PRIMARY KEY','',$sql)
- .', PRIMARY KEY ('.join(',',array_map(function($f){return $f->sql_name();},$this->fields_keys())).')'
- ;
- }
-
- $this->db()->type = $type;
- return $sql_replace($sql.')'.($indexes ? ';'.join(';',$indexes) : ''));
- }
-
- /*
- * Function indexes
- *
- * return indexes
- *
- */
- public function indexes() {
- if (!isset($this->indexes)) {
- $sql = $this->db()->conf_type('table.sql.index');
- $fct = '';
-
- if (is_array($sql)) list($sql,$fct) = (count($sql)==1 ? [$sql[0],null] : $sql);
- if (!$sql) return [];
-
- $sql = str_replace('<T.NAME>',$this->name,$sql);
- $sql = str_replace('<D.NAME>',$this->db()->name,$sql);
- $st = $this->db()->conn->prepare($sql);
- $st->execute();
- $this->indexes = [];
- while ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
-
- if (!$fct) $this->indexes[] = $row;
- elseif ($r = $fct($row)) $this->indexes[] = $r;
-
- }
- }
- return $this->indexes;
- }
-
- /*
- * Function sql
- *
- * return the sql used create the table
- *
- */
- public function sql() {
- if (isset($this->sql)) return $this->sql;
-
- if (!preg_match('/^[\w_-]+$/',$this->name) ) {
- $this->sql = $this->name;
- return $this->sql;
- }
-
- #$sql = str_replace('<T.NAME>',$this->name,$this->db()->conf_type('table.sql',true));
- $sql = $this->unvar($this->db()->conf_type('table.sql',true));
-
- # Noise before CREATE like MySql
- $this->sql = explode('\0',$this->db()->row($sql,'\0'));
- if (count($this->sql) > 1) {
- $this->sql = $this->sql[1];
- } else {
- $this->sql = $this->sql[0];
- }
-
- # Remove comments
- $this->sql = join(' ',preg_grep('/^ *--/',explode("\n",$this->sql),true));
-
- # Delete new line and trim for line output
- $this->sql = trim(preg_replace('/\s\s+/',' ',$this->sql));
-
- if (self::p('ansi')) {
- $this->sql = preg_replace("/\s*COLLATE NOCASE/i",'',$this->sql);
- }
-
- #bye($this->sql);
- return $this->sql;
- }
-
- public function field($name) { return $this->fields($name); }
-# NB 14.12.17 public function field_del($name) { unset($this->fields[$name]); }
+ $this->db()->conn->query("CREATE ".$this->sql_temporary()." TABLE $this->name AS $this->sql");
+
+ } elseif (preg_match('/\b(\.import|LOAD DATA|COPY|INSERT|REPLACE|DELETE|TRUNCATE|CREATE|DROP|ALERT)\b/',$this->name)) {
+ bye("Query not Allowed !");
+
+ } else {
+ return false;
+
+ }
+
+ return true;
+ }
+
+ /*
+ * Function db
+ *
+ * return the db object or init it
+ *
+ */
+ public function db($set=null) {
+ static $db = null;
+ #if ($set !== null) debug($set->name);
+ if ($set !== null) $db = $set;
+ return $db;
+ }
+
+ /*
+ * Function create
+ *
+ * return the sql to create the table build internaly
+ *
+ */
+ public function create($from_engine=true,$db_type='') {
+
+ // String replace function
+ $sql_replace_fct = $this->db()->conf_type('table.sql.create');
+ $db_sql_replace_fct = empty($this->db()->sql_replace) ? '' : $this->db()->sql_replace;
+ $sql_replace = function($sql) use ($sql_replace_fct,$db_sql_replace_fct) {
+ if ($db_sql_replace_fct) $sql = $db_sql_replace_fct($sql);
+ return $sql_replace_fct ? $sql_replace_fct($sql,$this) : $sql;
+ };
+
+ if ($from_engine) return $sql_replace($this->sql());
+
+ if ($this->type() == 'view') {
+ return $sql_replace('CREATE VIEW '.$this->sql_name().' AS '.preg_replace('/^CREATE\s+.*?\s+AS\s+.*?SELECT/i','SELECT',$this->sql()));
+ }
+
+ $indexes = [];
+ foreach ($this->indexes() as $i) {
+ if (!empty($i['unique']) or !empty($i['key'])) continue;
+ $indexes[] = 'CREATE INDEX '.$i['name'].' ON '.$this->sql_name().' ('.$i['field'].')';
+ }
+
+ # Get all fields
+ $fields = [];
+ foreach ($this->fields() as $f) {
+ if (!empty($f->extras)) continue;
+ $fields[] = $f;
+ }
+
+ $type = $this->db()->type;
+ if (!empty($db_type)) $this->db()->type = $db_type;
+
+ // Specific function for fields if return something use it instead of default
+ $_create_fct = $this->db()->conf_type('field.create',false);
+ $_create = function(&$field) use ($_create_fct) {
+ if ($_create_fct and ($sql=$_create_fct($field))) return $sql;
+
+ // Default
+ return $field->sql_name().' '.$field->type
+ .($field->null ? '' : ' NOT NULL')
+ .($field->default !== null ? ' DEFAULT '.$field->quote($field->default,true) : '')
+ .($field->key ? ' PRIMARY KEY' : '')
+ .($field->uniq ? ' UNIQUE' : '')
+ ;
+ };
+
+ $sql = 'CREATE '.strtoupper($this->type()).' '.$this->sql_name()
+ .' ('
+ .join(",",array_map(function($f) use ($_create) {return $_create($f);},$fields))
+ # done at the end for primary keys .')'
+ ;
+
+ // Handle multiple primary keys syntaxe
+ if (substr_count(strtoupper($sql),'PRIMARY KEY')>1) {
+ $sql = str_ireplace(' PRIMARY KEY','',$sql)
+ .', PRIMARY KEY ('.join(',',array_map(function($f){return $f->sql_name();},$this->fields_keys())).')'
+ ;
+ }
+
+ $this->db()->type = $type;
+ return $sql_replace($sql.')'.($indexes ? ';'.join(';',$indexes) : ''));
+ }
+
+ /*
+ * Function indexes
+ *
+ * return indexes
+ *
+ */
+ public function indexes() {
+ if (!isset($this->indexes)) {
+ $sql = $this->db()->conf_type('table.sql.index');
+ $fct = '';
+
+ if (is_array($sql)) list($sql,$fct) = (count($sql)==1 ? [$sql[0],null] : $sql);
+ if (!$sql) return [];
+
+ $sql = str_replace('<T.NAME>',$this->name,$sql);
+ $sql = str_replace('<D.NAME>',$this->db()->name,$sql);
+ $st = $this->db()->conn->prepare($sql);
+ $st->execute();
+ $this->indexes = [];
+ while ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
+
+ if (!$fct) $this->indexes[] = $row;
+ elseif ($r = $fct($row)) $this->indexes[] = $r;
- /*
- * Function db.fields
- *
- * return all or one fields from a table
- *
- * @name (string) name of the field to return. Default: null
- * @return (array) return null where name does not exsts
- */
- public function fields($name=null) {
+ }
+ }
+ return $this->indexes;
+ }
- $this->create_temporary();
+ /*
+ * Function sql
+ *
+ * return the sql used create the table
+ *
+ */
+ public function sql() {
+ if (isset($this->sql)) return $this->sql;
+
+ if (!preg_match('/^[\w_-]+$/',$this->name) ) {
+ $this->sql = $this->name;
+ return $this->sql;
+ }
- if (!isset($this->_fields)) {
- $this->_fields = true;
+ #$sql = str_replace('<T.NAME>',$this->name,$this->db()->conf_type('table.sql',true));
+ $sql = $this->unvar($this->db()->conf_type('table.sql',true));
- # Extras fields at the end
- $save_fields = $this->fields;
- $this->fields = [];
+ # Noise before CREATE like MySql
+ $this->sql = explode('\0',$this->db()->row($sql,'\0'));
+ if (count($this->sql) > 1) {
+ $this->sql = $this->sql[1];
+ } else {
+ $this->sql = $this->sql[0];
+ }
+
+ # Remove comments
+ $this->sql = join(' ',preg_grep('/^ *--/',explode("\n",$this->sql),true));
+
+ # Delete new line and trim for line output
+ $this->sql = trim(preg_replace('/\s\s+/',' ',$this->sql));
+
+ if (self::p('ansi')) {
+ $this->sql = preg_replace("/\s*COLLATE NOCASE/i",'',$this->sql);
+ }
+
+ #bye($this->sql);
+ return $this->sql;
+ }
- $conf = $this->unvar($this->db()->conf_type('table.fields',true));
- if (is_scalar($conf)) $conf = ['sql'=>$conf];
- # NB 25.09.17: dirty fixed for sqlite4 attache db
- $conf['sql'] = preg_replace("/^PRAGMA table_info\('([^'\.]+)\./","PRAGMA ".'$1'.".table_info('",$conf['sql']);
- $rows = $this->db()->conn->query($conf['sql']);
+ public function field($name) { return $this->fields($name); }
+# NB 14.12.17 public function field_del($name) { unset($this->fields[$name]); }
- if (!is_object($rows)) {
- $this->bye("Can't get fields from table $this->name ");
- }
+ /*
+ * Function db.fields
+ *
+ * return all or one fields from a table
+ *
+ * @name (string) name of the field to return. Default: null
+ * @return (array) return null where name does not exsts
+ */
+ public function fields($name=null) {
+
+ $this->create_temporary();
+
+ if (!isset($this->_fields)) {
+ $this->_fields = true;
+
+ # Extras fields at the end
+ $save_fields = $this->fields;
+ $this->fields = [];
+
+ $conf = $this->unvar($this->db()->conf_type('table.fields',true));
+ if (is_scalar($conf)) $conf = ['sql'=>$conf];
+ # NB 25.09.17: dirty fixed for sqlite4 attache db
+ $conf['sql'] = preg_replace("/^PRAGMA table_info\('([^'\.]+)\./","PRAGMA ".'$1'.".table_info('",$conf['sql']);
+ $rows = $this->db()->conn->query($conf['sql']);
+
+ if (!is_object($rows)) {
+ $this->bye("Can't get fields from table $this->name ");
+ }
- $rows->setFetchMode(PDO::FETCH_ASSOC);
+ $rows->setFetchMode(PDO::FETCH_ASSOC);
- // Get other indexes
- $indexes = [];
- foreach ($this->indexes() as $i) {
- if (empty($i['unique']) and empty($i['key'])) $indexes[$i['field']] = 1;
- }
+ // Get other indexes
+ $indexes = [];
+ foreach ($this->indexes() as $i) {
+ if (empty($i['unique']) and empty($i['key'])) $indexes[$i['field']] = 1;
+ }
- $count = 0;
- foreach ($rows as $row) {
+ $count = 0;
+ foreach ($rows as $row) {
- $count++;
- $row = array_change_key_case($row,CASE_LOWER);
+ $count++;
+ $row = array_change_key_case($row,CASE_LOWER);
- // From config
- $row['this'] = $this; # for use
- if (isset($conf['map'])) {
+ // From config
+ $row['this'] = $this; # for use
+ if (isset($conf['map'])) {
- foreach ($conf['map'] as $from => $to) {
- if (!isset($row[$from])) continue;
+ foreach ($conf['map'] as $from => $to) {
+ if (!isset($row[$from])) continue;
- $row[$to] = $row[$from];
- unset ($row[$from]);
- }
+ $row[$to] = $row[$from];
+ unset ($row[$from]);
+ }
- }
+ }
- if (isset($conf['fct'])) $conf['fct']($row);
+ if (isset($conf['fct'])) $conf['fct']($row);
- $field = [
- 'table' => $this,
- 'name' => $row['name'],
- 'type' => strtolower($row['type']),
- 'key' => (preg_match('/^(f.*|no|0)?\s*$/i',$row['key']) ? 0 : 1),
- 'index' => (empty($indexes[$row['name']]) ? 0 : $indexes[$row['name']]),
- 'null' => (preg_match('/^(f.*|no|0)?\s*$/i',$row['null']) ? 0 : 1),
- 'extra' => (isset($row['extra']) ? $row['extra'] : null), # !!! nothing todo with array $extra, this info from the sql server
- 'autoincrement' => (isset($row['autoincrement']) ? $row['autoincrement'] : 0),
- ];
+ $field = [
+ 'table' => $this,
+ 'name' => $row['name'],
+ 'type' => strtolower($row['type']),
+ 'key' => (preg_match('/^(f.*|no|0)?\s*$/i',$row['key']) ? 0 : 1),
+ 'index' => (empty($indexes[$row['name']]) ? 0 : $indexes[$row['name']]),
+ 'null' => (preg_match('/^(f.*|no|0)?\s*$/i',$row['null']) ? 0 : 1),
+ 'extra' => (isset($row['extra']) ? $row['extra'] : null), # !!! nothing todo with array $extra, this info from the sql server
+ 'autoincrement' => (isset($row['autoincrement']) ? $row['autoincrement'] : 0),
+ ];
- if (isset($row['uniq'])) $field['uniq'] = $row['uniq'];
- if (isset($row['default'])) $field['default'] = $row['default'];
+ if (isset($row['uniq'])) $field['uniq'] = $row['uniq'];
+ if (isset($row['default'])) $field['default'] = $row['default'];
- $this->fields[$field['name']] = new Field($field);
- $this->fields[$field['name']]->size = $this->fields[$field['name']]->size();
+ $this->fields[$field['name']] = new Field($field);
+ $this->fields[$field['name']]->size = $this->fields[$field['name']]->size();
- }
+ }
- # Extras fields at the end
- $this->fields = array_merge($this->fields,$save_fields);
- #if (empty($this->fields)) bye("Table `".$this->name."` does not exists");
+ # Extras fields at the end
+ $this->fields = array_merge($this->fields,$save_fields);
+ #if (empty($this->fields)) bye("Table `".$this->name."` does not exists");
- } # < $this->fields
+ } # < $this->fields
#bye($this->fields);
- if ($name !== null ) {
- if (!isset($this->fields[$name])) return null;
- return $this->fields[$name];
- }
-
- return $this->fields;
- }
-
- public function url_keys($values=null,$params=[],$preff='?',$sep='&') {
- if ($values === null) $values = $this->p();
- $url = is_array($params) ? $params : [$params];
-
- $keys = $this->fields_keys($others);
- if (empty($keys)) $keys = $others;
-
- foreach ($keys as $name => $field) {
- if (isset($values[$name]))
- $url[] = $this->field_preff.$name . '=' .urlencode($values[$name])
- ;
- }
-
- foreach (self::$params as $p) if ($v=self::p($p)) $url[] = $p.'='.urlencode($v);
- return $url ? $preff.join($sep,$url) : '';
- }
-
- public function fields_keys_values($values) {
- $keys = $this->fields_keys();
- if (empty($keys)) $keys = $this->fields();
-
- $ret = [];
- foreach ($keys as $name => $field) {
- if (isset($values[$name]))
- $ret[] = $values[$name];
- ;
- }
- return $ret;
- }
-
- public function fields_keys(&$others=[]) {
-
- $fields_keys = [];
-
- foreach ($this->fields() as $name => $f) {
- if ($f->key) {
- $fields_keys[$name] = $f;
- } else {
- $others[$name] = $f;
- }
- }
-
- return $fields_keys;
-
- }
-
- public static function params2hash($keys) {
- $params = [];
- foreach ($keys as $k) {
- $params[$k] = self::p($k);
- if (!isset($params[$k]) or (string)$params[$k] === '') unset($params[$k]);
- }
- return $params;
- }
-
- public static function form_hidden($ignore=[],$params=null) {
- $h = '';
- if (!isset($params)) {
- $params = self::params2hash(self::$params);
- }
+ if ($name !== null ) {
+ if (!isset($this->fields[$name])) return null;
+ return $this->fields[$name];
+ }
+
+ return $this->fields;
+ }
+
+ public function url_keys($values=null,$params=[],$preff='?',$sep='&') {
+ if ($values === null) $values = $this->p();
+ $url = is_array($params) ? $params : [$params];
+
+ $keys = $this->fields_keys($others);
+ if (empty($keys)) $keys = $others;
+
+ foreach ($keys as $name => $field) {
+ if (isset($values[$name]))
+ $url[] = $this->field_preff.$name . '=' .urlencode($values[$name])
+ ;
+ }
+
+ foreach (self::$params as $p) if ($v=self::p($p)) $url[] = $p.'='.urlencode($v);
+ return $url ? $preff.join($sep,$url) : '';
+ }
+
+ public function fields_keys_values($values) {
+ $keys = $this->fields_keys();
+ if (empty($keys)) $keys = $this->fields();
+
+ $ret = [];
+ foreach ($keys as $name => $field) {
+ if (isset($values[$name]))
+ $ret[] = $values[$name];
+ ;
+ }
+ return $ret;
+ }
+
+ public function fields_keys(&$others=[]) {
+
+ $fields_keys = [];
+
+ foreach ($this->fields() as $name => $f) {
+ if ($f->key) {
+ $fields_keys[$name] = $f;
+ } else {
+ $others[$name] = $f;
+ }
+ }
+
+ return $fields_keys;
+
+ }
+
+ public static function params2hash($keys) {
+ $params = [];
+ foreach ($keys as $k) {
+ $params[$k] = self::p($k);
+ if (!isset($params[$k]) or (string)$params[$k] === '') unset($params[$k]);
+ }
+ return $params;
+ }
+
+ public static function form_hidden($ignore=[],$params=null) {
+ $h = '';
+ if (!isset($params)) {
+ $params = self::params2hash(self::$params);
+ }
#debug([$params,array_diff($params,$ignore)]);
# NB 07.01.18 foreach (array_diff($params,$ignore) as $k=>$v) {
- foreach ($params as $k=>$v) {
+ foreach ($params as $k=>$v) {
if (!empty($ignore) and in_array($k,$ignore)) continue;
- if (isset($v) or $k=='action') {
- if (self::p('debug')) $h .= "<label>$k</label>";
- $h .= '<input type="'.(self::p('debug')?'text':'hidden').'" name="'.$k.'" value="'.$v.'"/>'.NB_EOL;
- }
- }
-
- return $h;
- }
-
- public function html_add($values = null,$form_action='?') {
- return html_edit($values,$form_action,true);
- }
-
- public function sql_edit($values = null,&$add=false) {
- $where = $this->where($this->fields(),$values);
- if (empty($where)) {
- $where = ' WHERE 1=0';
- $add = true;
- } else {
- $where .= " LIMIT 1";
- }
-
- $sql = "SELECT *" . $this->select_extras();
- $sql .= " FROM ".$this->sql_name().$where;
- if ($this->type == 'sql' and !empty($this->sql)) $sql = $this->sql.$where;
- $this->debug(preg_replace('/(,|FROM|WHERE|HAVING|GROUP|ORDER)/i',"\n\\1",$sql),1);
-
- return $sql;
- }
-
- public function html_edit($values = null,$form_action='?',$add=false) {
- if ($values === null) $values = $this->p();
- if (!is_array($values)) $values = [$values];
+ if (isset($v) or $k=='action') {
+ if (self::p('debug')) $h .= "<label>$k</label>";
+ $h .= '<input type="'.(self::p('debug')?'text':'hidden').'" name="'.$k.'" value="'.$v.'"/>'.NB_EOL;
+ }
+ }
+
+ return $h;
+ }
+
+ public function html_add($values = null,$form_action='?') {
+ return html_edit($values,$form_action,true);
+ }
+
+ public function sql_edit($values = null,&$add=false) {
+ $where = $this->where($this->fields(),$values);
+ if (empty($where)) {
+ $where = ' WHERE 1=0';
+ $add = true;
+ } else {
+ $where .= " LIMIT 1";
+ }
+
+ $sql = "SELECT *" . $this->select_extras();
+ $sql .= " FROM ".$this->sql_name().$where;
+ if ($this->type == 'sql' and !empty($this->sql)) $sql = $this->sql.$where;
+ $this->debug(preg_replace('/(,|FROM|WHERE|HAVING|GROUP|ORDER)/i',"\n\\1",$sql),1);
+
+ return $sql;
+ }
+
+ public function html_edit($values = null,$form_action='?',$add=false) {
+ if ($values === null) $values = $this->p();
+ if (!is_array($values)) $values = [$values];
# NB 23.11.17 $fields = $this->fields();
# NB 23.11.17 $keys = $this->fields_keys();
- $sql = $this->sql_edit($values,$add);
-
- $st = $this->db()->conn->prepare($sql);
- $st->execute();
-
- // Params
- $form_hidden = '';
- $url_params = [
- 'referer' => (!empty($_SERVER['HTTP_REFERER']) ? urlencode($_SERVER['HTTP_REFERER']) : ''),
- ];
- if ($this->show_hidden_params and !empty(self::$params)) {
- $ignore = ['limit'];
-
- $form_hidden = ''
- .self::form_hidden($ignore,array_merge($this->params2hash(self::$params),[
- 'action' => ($add ? 'insert' : 'update'),
- 'referer' => (!empty($_SERVER['HTTP_REFERER']) ? urlencode($_SERVER['HTTP_REFERER']) : ''),
- ]))
- ;
-
- foreach (array_diff(self::$params,$ignore) as $p) {
- if (!($v = self::p($p))) continue;
- $url_params[$p] = $v;
- }
-
- $url_params['action'] = ($add ? 'insert' : 'update');
-
- } else {
- $form_hidden = (!empty($_SERVER['HTTP_REFERER']) ? '<input type="hidden" name="referer" value="'.urlencode($_SERVER['HTTP_REFERER']).'" />' : '');
-
- }
-
- #debug($form_hidden);
- if ($url_params) {
- $flat = [];
- foreach ($url_params as $k=>$v) {
- if ((string)$v === '') continue;
- $flat[] = $k . '=' . urlencode($v);
- }
- if (NB_P_GET) {
- $form_action .= ( strpos('?',$form_action) === false ? '?' : '' ) . join('&',$flat);
- $form_hidden = '';
- }
- }
-
- // Form
- echo '<form class="db edit form-table" method="post" action="'.$form_action.'">'.NB_EOL;
- echo '<div class="fields">'.NB_EOL;
- $count = 0;
- if ( $add or ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT))) {
-
- if (!empty($row)) $this->db()->table_row_decrypt($this,$row);
- $count ++;
-
- foreach ($this->fields() as $name => $field) {
+ $sql = $this->sql_edit($values,$add);
+
+ $st = $this->db()->conn->prepare($sql);
+ $st->execute();
+
+ // Params
+ $form_hidden = '';
+ $url_params = [
+ 'referer' => (!empty($_SERVER['HTTP_REFERER']) ? urlencode($_SERVER['HTTP_REFERER']) : ''),
+ ];
+ if ($this->show_hidden_params and !empty(self::$params)) {
+ $ignore = ['limit'];
+
+ $form_hidden = ''
+ .self::form_hidden($ignore,array_merge($this->params2hash(self::$params),[
+ 'action' => ($add ? 'insert' : 'update'),
+ 'referer' => (!empty($_SERVER['HTTP_REFERER']) ? urlencode($_SERVER['HTTP_REFERER']) : ''),
+ ]))
+ ;
+
+ foreach (array_diff(self::$params,$ignore) as $p) {
+ if (!($v = self::p($p))) continue;
+ $url_params[$p] = $v;
+ }
+
+ $url_params['action'] = ($add ? 'insert' : 'update');
+
+ } else {
+ $form_hidden = (!empty($_SERVER['HTTP_REFERER']) ? '<input type="hidden" name="referer" value="'.urlencode($_SERVER['HTTP_REFERER']).'" />' : '');
+
+ }
+
+ #debug($form_hidden);
+ if ($url_params) {
+ $flat = [];
+ foreach ($url_params as $k=>$v) {
+ if ((string)$v === '') continue;
+ $flat[] = $k . '=' . urlencode($v);
+ }
+ if (NB_P_GET) {
+ $form_action .= ( strpos('?',$form_action) === false ? '?' : '' ) . join('&',$flat);
+ $form_hidden = '';
+ }
+ }
+
+ // Form
+ echo '<form class="db edit form-table" method="post" action="'.$form_action.'">'.NB_EOL;
+ echo '<div class="fields">'.NB_EOL;
+ $count = 0;
+ if ( $add or ($row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT))) {
+
+ if (!empty($row)) $this->db()->table_row_decrypt($this,$row);
+ $count ++;
+
+ foreach ($this->fields() as $name => $field) {
# NB 08.01.18 if ($add and !preg_match('/^(null|.*\(.*)?$/',strtolower($field->default))) {
# NB 08.01.18 $row[$name] = $field->default;
if ($add) {
- $row[$name] = $field->default2str($field->default);
+ $row[$name] = $field->default2str($field->default);
- } elseif(!isset($row[$name])) {
- $row[$name] = '';
+ } elseif(!isset($row[$name])) {
+ $row[$name] = '';
- }
+ }
- if (!$add and $field->key) {
- echo '<input name="'.$this->key_preff.$name.'" value="'.$row[$name].'" type="hidden" />'.NB_EOL;
- }
- echo $field->html_edit($row[$name]);
- }
+ if (!$add and $field->key) {
+ echo '<input name="'.$this->key_preff.$name.'" value="'.$row[$name].'" type="hidden" />'.NB_EOL;
+ }
+ echo $field->html_edit($row[$name]);
+ }
- }
- echo '</div>'.NB_EOL; # < fields
+ }
+ echo '</div>'.NB_EOL; # < fields
- echo ''
- .'<div class="db buttons">'
- .( empty($_SERVER['HTTP_REFERER']) ? '' : '<input type="button" onclick="document.location=document.referrer" value="Cancel" />')
- .'<input type="reset" />'
- .'<input type="submit" />'
- .'</div>'.NB_EOL
- ;
+ echo ''
+ .'<div class="db buttons">'
+ .( empty($_SERVER['HTTP_REFERER']) ? '' : '<input type="button" onclick="document.location=document.referrer" value="Cancel" />')
+ .'<input type="reset" />'
+ .'<input type="submit" />'
+ .'</div>'.NB_EOL
+ ;
- echo $form_hidden.'</form>'.NB_EOL;
+ echo $form_hidden.'</form>'.NB_EOL;
- }
+ }
- public function url_list($k='',$v='') {
+ public function url_list($k='',$v='') {
- $params = [];
- $fields = ($this->p('action') == 'delete') ? [] : $this->fields();
+ $params = [];
+ $fields = ($this->p('action') == 'delete') ? [] : $this->fields();
- foreach ( array_diff( array_merge(self::$params,array_keys($fields)), ['action'] ) as $f) {
+ foreach ( array_diff( array_merge(self::$params,array_keys($fields)), ['action'] ) as $f) {
- if (strcmp($this->p($f,''),'')==0) continue;
- $params[$f] = $this->p($f);
+ if (strcmp($this->p($f,''),'')==0) continue;
+ $params[$f] = $this->p($f);
- }
+ }
- if ($k) {
+ if ($k) {
- if (strcmp($v,'')==0) {
- unset($params[$k]);
- } else {
- $params[$k] = $v;
- }
+ if (strcmp($v,'')==0) {
+ unset($params[$k]);
+ } else {
+ $params[$k] = $v;
+ }
- }
+ }
- $flat = [];
- foreach ($params as $k=>$v) { $flat[] = $k.'='.urlencode($v); }
- return $flat ? '?'. join('&',$flat) : '';
+ $flat = [];
+ foreach ($params as $k=>$v) { $flat[] = $k.'='.urlencode($v); }
+ return $flat ? '?'. join('&',$flat) : '';
- }
+ }
- public function url_sort($name) {
+ public function url_sort($name) {
- if (!$this->show_url_sort or !($f=$this->field($name)) or !empty($f->dyn) or $f->is_encrypt()) return self::prettyText($name);
- #debug($f);
+ if (!$this->show_url_sort or !($f=$this->field($name)) or !empty($f->dyn) or $f->is_encrypt()) return self::prettyText($name);
+ #debug($f);
- # See: http://dev.w3.org/html5/html-author/charref
- $html = '';
+ # See: http://dev.w3.org/html5/html-author/charref
+ $html = '';
$title = $this->prettyText($name).': ';
- # Asc
- $sel = ( $this->p('orderby')=="$name asc") ? " sel" : "";
- $html .= '<a title="'.$title.'first In (asc)" class="sort asc'.$sel.'" href="'.$this->url_list('orderby',"$name asc").'">'
- .'<span class="asc">↓</span>'
- .'</a>';
- #$html .= ' ';
+ # Asc
+ $sel = ( $this->p('orderby')=="$name asc") ? " sel" : "";
+ $html .= '<a title="'.$title.'first In (asc)" class="sort asc'.$sel.'" href="'.$this->url_list('orderby',"$name asc").'">'
+ .'<span class="asc">↓</span>'
+ .'</a>';
+ #$html .= ' ';
- $html .= '<span class="name">'.$this->prettyText($name).'</span>';
+ $html .= '<span class="name">'.$this->prettyText($name).'</span>';
- #$html .= ' ';
+ #$html .= ' ';
- # Desc
- $sel = ( $this->p('orderby')=="$name desc") ? " sel" : "";
- $html .= '<a title="'.$title.'last In (desc)" class="sort desc'.$sel.'" href="'.$this->url_list('orderby',"$name desc").'">'
- .'<span class="desc">↑</span>'
- .'</a>';
+ # Desc
+ $sel = ( $this->p('orderby')=="$name desc") ? " sel" : "";
+ $html .= '<a title="'.$title.'last In (desc)" class="sort desc'.$sel.'" href="'.$this->url_list('orderby',"$name desc").'">'
+ .'<span class="desc">↑</span>'
+ .'</a>';
- return $html;
+ return $html;
- }
+ }
- public function nav($count,$tot,$limit) {
+ public function nav($count,$tot,$limit) {
- $html = '';
+ $html = '';
- if ($count<$tot) {
- list($x,$y) = strpos($limit,',')!==false
- ? preg_split('/\s*,\s*/',$limit)
- : [0,$limit]
- ;
+ if ($count<$tot) {
+ list($x,$y) = strpos($limit,',')!==false
+ ? preg_split('/\s*,\s*/',$limit)
+ : [0,$limit]
+ ;
- $prev = $x - $y;
- $next = $x + $y;
+ $prev = $x - $y;
+ $next = $x + $y;
- $this->debug("x=$x limit=$y prev=$prev next=$next tot=$tot",1);
+ $this->debug("x=$x limit=$y prev=$prev next=$next tot=$tot",1);
- } else {
- $x = 0;
- $y = $tot;
- $prev = -1;
- $next = 999999;
- }
+ } else {
+ $x = 0;
+ $y = $tot;
+ $prev = -1;
+ $next = 999999;
+ }
- if ($prev>=0) $html .= '<span class="prev"><a href="'.$this->url_list('limit',preg_replace('/^0,/','',"$prev,$y")).'"><<</a></span> ';
+ if ($prev>=0) $html .= '<span class="prev"><a href="'.$this->url_list('limit',preg_replace('/^0,/','',"$prev,$y")).'"><<</a></span> ';
- $html .= '<span class="count">'.($tot ? ($x+1) : 0).' - '.( $count<($x+$y) ? $count : ($x+$y) ).' / '.$tot.' results</span>';
+ $html .= '<span class="count">'.($tot ? ($x+1) : 0).' - '.( $count<($x+$y) ? $count : ($x+$y) ).' / '.$tot.' results</span>';
- if ($next<$tot) $html .= ' <span class="prev"><a href="'.$this->url_list('limit',"$next,$y").'">>></a></span>';
+ if ($next<$tot) $html .= ' <span class="prev"><a href="'.$this->url_list('limit',"$next,$y").'">>></a></span>';
- return $html;
+ return $html;
- }
+ }
- public function where($fields,$hvalues,$need_all_values=false) {
+ public function where($fields,$hvalues,$need_all_values=false) {
- // Construct where
- $where = [];
- foreach ($fields as $k => $field) {
- if (!isset($hvalues[$k])) {
- if ($need_all_values) return null;
- continue;
- }
- $where[] = $field->sql_name() . '=' . $field->quote($hvalues[$k]);
- }
+ // Construct where
+ $where = [];
+ foreach ($fields as $k => $field) {
+ if (!isset($hvalues[$k])) {
+ if ($need_all_values) return null;
+ continue;
+ }
+ $where[] = $field->sql_name() . '=' . $field->quote($hvalues[$k]);
+ }
- return empty($where) ? '' : ' WHERE ' . join(' AND ',$where);
+ return empty($where) ? '' : ' WHERE ' . join(' AND ',$where);
- }
+ }
- public function where_criterias($values,$logic='') {
- $having = $where = [];
- if (empty($logic)) $logic = 'AND';
+ public function where_criterias($values,$logic='') {
+ $having = $where = [];
+ if (empty($logic)) $logic = 'AND';
- $regexp = $this->db()->conf_type('regexp');
- if (empty($regexp)) $regexp = 'REGEXP';
+ $regexp = $this->db()->conf_type('regexp');
+ if (empty($regexp)) $regexp = 'REGEXP';
- foreach ($this->fields() as $k => $field) {
+ foreach ($this->fields() as $k => $field) {
- // No empty values
- $v = isset($values[$k]) ? $values[$k] : null;
- if (strcmp($v,'')==0 or $v=='!' or $v=='~') continue;
+ // No empty values
+ $v = isset($values[$k]) ? $values[$k] : null;
+ if (strcmp($v,'')==0 or $v=='!' or $v=='~') continue;
- // Equal / Not Equal
- $equal = '=';
- $not = strpos($v,'!')===0 ? 1 : 0;
- if ($not) $v = substr($v,1);
+ // Equal / Not Equal
+ $equal = '=';
+ $not = strpos($v,'!')===0 ? 1 : 0;
+ if ($not) $v = substr($v,1);
- // Superior / Inferior
- if (preg_match('/^(<|>|<=|>=)/',$v,$m)) {
- $v = substr($v,strlen($m[1]));
- $equal = $m[1];
- }
+ // Superior / Inferior
+ if (preg_match('/^(<|>|<=|>=)/',$v,$m)) {
+ $v = substr($v,strlen($m[1]));
+ $equal = $m[1];
+ }
$match = '';
- // Regex
- if (strpos($v,'~')===0) {
+ // Regex
+ if (strpos($v,'~')===0) {
$match = 'regexp';
- $v = substr($v,1);
- $v = $this->db()->quote($v);
- $equal = ' '.($not ? 'NOT ' : '').$regexp.' ';
+ $v = substr($v,1);
+ $v = $this->db()->quote($v);
+ $equal = ' '.($not ? 'NOT ' : '').$regexp.' ';
- } elseif ($field->string()) {
+ } elseif ($field->string()) {
- if (strtolower($v)=='null') $v = '';
+ if (strtolower($v)=='null') $v = '';
- // * -> %
- $v = str_replace('*','%',$v);
+ // * -> %
+ $v = str_replace('*','%',$v);
- $v = $this->db()->quote($v);
- if (preg_match('/[_%]/',$v)) {
+ $v = $this->db()->quote($v);
+ if (preg_match('/[_%]/',$v)) {
$match = 'like';
# NB 07.01.18 $equal = ' '.($not ? 'NOT ' : '').'LIKE ';
- $equal = ' '.($not ? 'NOT ' : '').$this->db()->like_nocase().' ';
- } else {
- $equal = ($not ? '<> ' : $equal);
- }
+ $equal = ' '.($not ? 'NOT ' : '').$this->db()->like_nocase().' ';
+ } else {
+ $equal = ($not ? '<> ' : $equal);
+ }
- // Others
- } else {
+ // Others
+ } else {
- // Integer
- if ($field->numeric()) {
- if (strtolower($v)=='null') $v = '0';
- #$k = "COLAESCE($k,0)";
+ // Integer
+ if ($field->numeric()) {
+ if (strtolower($v)=='null') $v = '0';
+ #$k = "COLAESCE($k,0)";
- // Date, Time according to field->string() behavior
- } else {
- $v = $this->db()->quote($v);
+ // Date, Time according to field->string() behavior
+ } else {
+ $v = $this->db()->quote($v);
- }
- $equal = $not ? '<>' : $equal;
+ }
+ $equal = $not ? '<>' : $equal;
- }
+ }
$name = $field->sql_name(true);
# NB 12.01.18 if (!$field->text()) $name = $field->sql_name_cast_text();
- if ($field->extras) {
- $k = $this->extras[$k]->sql_name();
+ if ($field->extras) {
+ $k = $this->extras[$k]->sql_name();
# NB 04.01.18 } elseif ($field->numeric() and $field->null) {
} elseif ($match) {
- if ($field->null) $k = 'COALESCE('.$name.','.$this->db()->quote('').")";
+ if ($field->null) $k = 'COALESCE('.$name.','.$this->db()->quote('').")";
- } elseif ($field->numeric()) {
+ } elseif ($field->numeric()) {
$name = $field->sql_name();
- if ($field->null) $k = 'COALESCE('.$name.",0)";
+ if ($field->null) $k = 'COALESCE('.$name.",0)";
- } elseif (!$field->numeric() and $field->null) {
- $k = 'COALESCE('.$name.",'')";
+ } elseif (!$field->numeric() and $field->null) {
+ $k = 'COALESCE('.$name.",'')";
- } else {
- $k = $name;
+ } else {
+ $k = $name;
- }
+ }
- # having, denorm, EMPTY
- if ($field->extras) {
- $extra_where = (string)$this->db()->conf_type('extra_where');
- #if ($_SERVER['REMOTE_USER'] == 'nico') debug($sql);
- $k = $field->extras;
+ # having, denorm, EMPTY
+ if ($field->extras) {
+ $extra_where = (string)$this->db()->conf_type('extra_where');
+ #if ($_SERVER['REMOTE_USER'] == 'nico') debug($sql);
+ $k = $field->extras;
- if ($extra_where == 'having') {
- $having[] = "$k$equal$v";
- } else {
- $where[] = "$k$equal$v";
- }
+ if ($extra_where == 'having') {
+ $having[] = "$k$equal$v";
+ } else {
+ $where[] = "$k$equal$v";
+ }
- } else {
- $where[] = "$k$equal$v";
+ } else {
+ $where[] = "$k$equal$v";
- }
+ }
- } #< foreach
+ } #< foreach
- $sql = '';
- if ($where) $sql .= ' WHERE '.join(" $logic ",$where);
- if ($having) $sql .= ' HAVING '.join(" $logic ",$having);
- return $sql;
+ $sql = '';
+ if ($where) $sql .= ' WHERE '.join(" $logic ",$where);
+ if ($having) $sql .= ' HAVING '.join(" $logic ",$having);
+ return $sql;
- }
+ }
- public function add_extras($extras) {
- if ($this->p('extras') === '0') return false;
+ public function add_extras($extras) {
+ if ($this->p('extras') === '0') return false;
- foreach ($extras as $k => $v) {
+ foreach ($extras as $k => $v) {
- if ($v === false or $v === null) {
- if (isset($this->fields[$k])) unset($this->fields[$k]);
- #if (isset($this->extras[$k])) unset($this->extras[$k]);
- $this->_rows_fields = true;
- continue;
- }
+ if ($v === false or $v === null) {
+ if (isset($this->fields[$k])) unset($this->fields[$k]);
+ #if (isset($this->extras[$k])) unset($this->extras[$k]);
+ $this->_rows_fields = true;
+ continue;
+ }
- $v = new Field( ( is_array($v) ? $v : [] ) + [
- 'name' => $k,
- 'type' => 'text',
- 'extras' => $v,
- 'table' => $this,
- ]);
+ $v = new Field( ( is_array($v) ? $v : [] ) + [
+ 'name' => $k,
+ 'type' => 'text',
+ 'extras' => $v,
+ 'table' => $this,
+ ]);
- $this->fields[$k] = $v;
- $this->extras[$k] = $v;
+ $this->fields[$k] = $v;
+ $this->extras[$k] = $v;
- }
+ }
- }
+ }
- public function select_extras() {
+ public function select_extras() {
- if (empty($this->extras)) return '';
+ if (empty($this->extras)) return '';
- $select = []; foreach ($this->extras as $name => $field) {
- $select[] = $field->extras." AS ".$field->sql_name();
- }
+ $select = []; foreach ($this->extras as $name => $field) {
+ $select[] = $field->extras." AS ".$field->sql_name();
+ }
- if (!$select) return '';
- return ','.join(',',$select);
- }
+ if (!$select) return '';
+ return ','.join(',',$select);
+ }
- public function rows_count() {
+ public function rows_count() {
$opt = [ 'count' => 1 ];
- return $this->db()->row($this->rows_sql($opt));
+ return $this->db()->row($this->rows_sql($opt));
}
- public function rows_sql(&$opt=[]) {
+ public function rows_sql(&$opt=[]) {
- if (isset($this->orderby)) self::pdef('orderby',$this->orderby);
- if (self::p('order')) self::pset('orderby',self::p('orderby').' '.self::p('order')); # from Wordpress
+ if (isset($this->orderby)) self::pdef('orderby',$this->orderby);
+ if (self::p('order')) self::pset('orderby',self::p('orderby').' '.self::p('order')); # from Wordpress
$count = empty($opt['count']) ? 0 : 1;
- //
- // Select
- //
- if (stripos($this->name,' ') !== false) {
- $sql = $this->name;
- $limit = $where = '';
+ //
+ // Select
+ //
+ if (stripos($this->name,' ') !== false) {
+ $sql = $this->name;
+ $limit = $where = '';
if ($count) $sql = "SELECT count(*) FROM ".$this->sql_name();
- } else {
+ } else {
- $where = $this->where_criterias($this->p(),$this->p('op'));
- $select_count = ( $where ? $this->db()->conf_type('select_count') : null );
- if (empty($select_count)) $select_count = ['',''];
+ $where = $this->where_criterias($this->p(),$this->p('op'));
+ $select_count = ( $where ? $this->db()->conf_type('select_count') : null );
+ if (empty($select_count)) $select_count = ['',''];
- if (!empty($this->_rows_fields)) {
- foreach ($this->fields() as $f) {
- if (empty($f->extra)) $select_fields[] = $f->sql_name();
- }
+ if (!empty($this->_rows_fields)) {
+ foreach ($this->fields() as $f) {
+ if (empty($f->extra)) $select_fields[] = $f->sql_name();
+ }
- } else {
- $select_fields = ['*'];
+ } else {
+ $select_fields = ['*'];
- }
+ }
- $sql = $count ? "SELECT count(*)" : "SELECT ".trim( $select_count[0].' '.join(',',$select_fields) ). $this->select_extras();
- $sql .= " FROM ".$this->sql_name();
- $sql .= $where;
+ $sql = $count ? "SELECT count(*)" : "SELECT ".trim( $select_count[0].' '.join(',',$select_fields) ). $this->select_extras();
+ $sql .= " FROM ".$this->sql_name();
+ $sql .= $where;
- if ($this->p('orderby') and !$count) $sql .= ' ORDER BY '.$this->p('orderby');
+ if ($this->p('orderby') and !$count) $sql .= ' ORDER BY '.$this->p('orderby');
- if ($limit = $this->db()->limit) {
- $limit = str_replace(',',' OFFSET ',$limit);
- $sql .= ' LIMIT '.$limit;
- } else {
- $limit = '';
- }
+ if ($limit = $this->db()->limit) {
+ $limit = str_replace(',',' OFFSET ',$limit);
+ $sql .= ' LIMIT '.$limit;
+ } else {
+ $limit = '';
+ }
- }
+ }
if ($count) return $sql;
- //
- // Get results
- //
- $this->debug(preg_replace('/[\r\n]+[ ]*/',' ',$sql),1);
+ //
+ // Get results
+ //
+ $this->debug(preg_replace('/[\r\n]+[ ]*/',' ',$sql),1);
# NB 03.09.16 $this->debug(preg_replace('/(,|FROM|WHERE|HAVING|GROUP|ORDER)/i',"\n\\1",$sql),1);
- return [$sql,$where,$limit,$select_count];
- }
-
- public function buttons() {
- if (!$this->show_buttons or empty(self::$params)) return false;
- if (!preg_match('/(table|view)/',$this->type())) return false;
- return true;
- }
-
- private function rows_parsers(&$row,&$opt=[]) {
- $parser = isset($opt['parser']) ? $opt['parser'] : true;
- $call = null;
-
- //
- // Decrypt
- //
- if ($parser) $this->db()->table_row_decrypt($this,$row);
-
- //
- // Pre
- //
- if ($parser and !empty($this->db()->row_parse_pre)) {
- $call = $this->db()->row_parse_pre; $call($row,$this,$opt);
- }
-
- if ($parser and !empty($this->row_parse_pre)) {
- $call = $this->row_parse_pre; $call($row,$this,$opt);
- }
-
- # Passed param on rows()
- if ($parser and !empty($opt['row_parse_pre'])) {
- $call = $opt['row_parse_pre']; $call($row,$this,$opt);
- }
-
- //
- // Format
- //
- if ($opt['is_html'] and !$opt['use_out']) {
- foreach ($row as $k=>$v) {
- if (!isset($this->extras[$k])) $row[$k] = $this->db()->out->format($v);
- }
-
- }
-
- //
- // Post
- //
- if ($parser and !empty($this->row_parse_post)) {
- $call = $this->row_parse_post; $call($row,$this,$opt);
- }
-
- if ($parser and !empty($this->db()->row_parse_post)) {
- $call = $this->db()->row_parse_post; $call($row,$this,$opt);
- }
-
- # Passed param on rows()
- if ($parser and !empty($opt['row_parse_post'])) {
- $call = $opt['row_parse_post']; $call($row,$this,$opt);
- }
-
- return $call;
- }
-
-
- public function fields_add_missing(&$fields,$row) {
- $new = [];
- foreach (array_keys($row) as $name) {
-
- #debug($name);
- $new[$name] = isset($fields[$name])
- ? $fields[$name]
- : new Field([
- 'name' => $name,
- 'dyn' => true,
- 'table' => $this,
- 'preffix' => $this->field_preff,
- ])
- ;
-
- }
-
- $fields = $new;
- return $fields;
- }
-
- public function rows(&$opt=[],$opt_by_val=null) {
-
- #
- # Db type change
- #
- $db_type = $this->db()->type;
- if (!empty($opt['db_type_from'])) {
- $this->db()->type = $opt['db_type_from'];
- }
-
- #
- # Fields
- #
- if (!DB_TABLE_QUERY_NAME) {
- $fields = [];
- foreach ($this->db()->fields() as $f) { $fields[$f->name] = $f; }
- $this->fields = $fields;
- }
-
- #
- # Fields filter
- #
- $fields = $this->fields();
- $fields_filter = [];
- if ($this->fields_only) {
- $fields_filter = $this->fields_only;
- $new_fields = [];
- foreach ($fields_filter as $k) {
- $new_fields[$k] = $fields[$k];
- }
- $fields = $new_fields;
- unset($new_fields);
- }
-
- #
- # Build query
- #
- $this->create_temporary();
-
- if ($opt_by_val !== null) $opt = $opt_by_val;
-
- if (isset($opt['format']) and $opt['format']==='') {
- $format = '';
- } else {
-
- $format = empty($opt['format']) ? $this->p('format') : $opt['format'];
- if (!$format and $this->db()->format) $format = $this->db()->format;
- if (!$format) $this->bye("Parameter `format` missing!");
- }
+ return [$sql,$where,$limit,$select_count];
+ }
+
+ public function buttons() {
+ if (!$this->show_buttons or empty(self::$params)) return false;
+ if (!preg_match('/(table|view)/',$this->type())) return false;
+ return true;
+ }
+
+ private function rows_parsers(&$row,&$opt=[]) {
+ $parser = isset($opt['parser']) ? $opt['parser'] : true;
+ $call = null;
+
+ //
+ // Decrypt
+ //
+ if ($parser) $this->db()->table_row_decrypt($this,$row);
+
+ //
+ // Pre
+ //
+ if ($parser and !empty($this->db()->row_parse_pre)) {
+ $call = $this->db()->row_parse_pre; $call($row,$this,$opt);
+ }
+
+ if ($parser and !empty($this->row_parse_pre)) {
+ $call = $this->row_parse_pre; $call($row,$this,$opt);
+ }
+
+ # Passed param on rows()
+ if ($parser and !empty($opt['row_parse_pre'])) {
+ $call = $opt['row_parse_pre']; $call($row,$this,$opt);
+ }
+
+ //
+ // Format
+ //
+ if ($opt['is_html'] and !$opt['use_out']) {
+ foreach ($row as $k=>$v) {
+ if (!isset($this->extras[$k])) $row[$k] = $this->db()->out->format($v);
+ }
+
+ }
+
+ //
+ // Post
+ //
+ if ($parser and !empty($this->row_parse_post)) {
+ $call = $this->row_parse_post; $call($row,$this,$opt);
+ }
+
+ if ($parser and !empty($this->db()->row_parse_post)) {
+ $call = $this->db()->row_parse_post; $call($row,$this,$opt);
+ }
+
+ # Passed param on rows()
+ if ($parser and !empty($opt['row_parse_post'])) {
+ $call = $opt['row_parse_post']; $call($row,$this,$opt);
+ }
+
+ return $call;
+ }
+
+
+ private function fields_add_missing(&$fields,$row) {
+ $new = [];
+ foreach (array_keys($row) as $name) {
+
+ #debug($name);
+ $new[$name] = isset($fields[$name])
+ ? $fields[$name]
+ : new Field([
+ 'name' => $name,
+ 'dyn' => true,
+ 'table' => $this,
+ 'preffix' => $this->field_preff,
+ ])
+ ;
+
+ }
+
+ $fields = $new;
+ return $fields;
+ }
+
+ public function rows(&$opt=[],$opt_by_val=null) {
+
+ #
+ # Db type change
+ #
+ $db_type = $this->db()->type;
+ if (!empty($opt['db_type_from'])) {
+ $this->db()->type = $opt['db_type_from'];
+ }
+
+ #
+ # Fields
+ #
+ $fields = $this->fields();
+
+ #
+ # Build query
+ #
+ $this->create_temporary();
+
+ if ($opt_by_val !== null) $opt = $opt_by_val;
+
+ if (isset($opt['format']) and $opt['format']==='') {
+ $format = '';
+ } else {
+
+ $format = empty($opt['format']) ? $this->p('format') : $opt['format'];
+ if (!$format and $this->db()->format) $format = $this->db()->format;
+ if (!$format) $this->bye("Parameter `format` missing!");
+ }
#debug($opt);
- list($sql,$where,$limit,$select_count) = $this->rows_sql($opt);
- $st = null;
- $cursor = null;
- $sql_orig = null;
+ list($sql,$where,$limit,$select_count) = $this->rows_sql($opt);
+ $st = null;
+ $cursor = null;
+ $sql_orig = null;
- $fct = function() { return true; };
- if ($this->db()->type == 'pgsql') {
+ $fct = function() { return true; };
+ if ($this->db()->type == 'pgsql') {
$sql_orig = $sql;
- $this->db()->conn->beginTransaction();
- $sql = "DECLARE table_rows CURSOR FOR $sql";
- $cursor = $this->db()->conn->prepare($sql);
- $cursor->execute();
- $sql = "FETCH 1 FROM table_rows";
-
- } else {
- $this->db()->conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
-
- }
-
- $st = $this->db()->conn->prepare($sql);#,[PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT]);
- if (empty($cursor)) {
- $st->execute();
- } else {
- $fct = function() use($st) { return $st->execute(); };
- }
- if (!empty($opt['query'])) return $st;
-
- #
- # Use the module out when format unknow
- #
- $out_conf = null;
- $opt['use_out'] = false;
-
- if ($this->p('out') or !preg_match('/^('.join('|',
- [ '','template','table','sql','_div','wp' ] # local
- ).')$/',$format))
- {
-
- $opt['use_out'] = true;
- if (!($out_conf = $this->db()->out->types($format))) $this->bye("Unknow format `$format`");
- $out_conf = array_merge($opt,$out_conf);
-
- # Function name should be format
- $this->db()->out->type($format); self::$params += array_values($this->db()->out->types());
-
- if (empty($out_conf['enclose'])) $out_conf['enclose'] = ['',''];
- debug('Using out module!',3);
-
- }
-
- #
- # Html
- #
- if (!isset($opt['is_html'])) $opt['is_html'] = preg_match('/^(table|div)$/',$format)
- ? ( $this->show_header )
- : false
- ;
-
- if ($opt['is_html'] and !empty(self::$params) and !$this->p('action') and !$this->p('inc')) {
- echo $this->html_menu($opt);
- }
-
- if ($opt['is_html']) {
- echo '<div class="results">'.NB_EOL;
+ $this->db()->conn->beginTransaction();
+ $sql = "DECLARE table_rows CURSOR FOR $sql";
+ $cursor = $this->db()->conn->prepare($sql);
+ $cursor->execute();
+ $sql = "FETCH 1 FROM table_rows";
+
+ } else {
+ $this->db()->conn->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, false);
+
+ }
+
+ $st = $this->db()->conn->prepare($sql);#,[PDO::ATTR_ERRMODE => PDO::ERRMODE_SILENT]);
+ if (empty($cursor)) {
+ $st->execute();
+ } else {
+ $fct = function() use($st) { return $st->execute(); };
+ }
+ if (!empty($opt['query'])) return $st;
+
+ #
+ # Use the module out when format unknow
+ #
+ $out_conf = null;
+ $opt['use_out'] = false;
+
+ if ($this->p('out') or !preg_match('/^('.join('|',
+ [ '','template','table','sql','_div','wp' ] # local
+ ).')$/',$format))
+ {
+
+ $opt['use_out'] = true;
+ if (!($out_conf = $this->db()->out->types($format))) $this->bye("Unknow format `$format`");
+ $out_conf = array_merge($opt,$out_conf);
+
+ # Function name should be format
+ $this->db()->out->type($format); self::$params += array_values($this->db()->out->types());
+
+ if (empty($out_conf['enclose'])) $out_conf['enclose'] = ['',''];
+ debug('Using out module!',3);
+
+ }
+
+ #
+ # Html
+ #
+ if (!isset($opt['is_html'])) $opt['is_html'] = preg_match('/^(table|div)$/',$format)
+ ? ( $this->show_header )
+ : false
+ ;
+
+ if ($opt['is_html'] and !empty(self::$params) and !$this->p('action') and !$this->p('inc')) {
+ echo $this->html_menu($opt);
+ }
+
+ if ($opt['is_html']) {
+ echo '<div class="results">'.NB_EOL;
# NB 07.01.18 if ($this->show_hidden_params and !$this->p('inc')) echo $this->form_hidden();
- }
+ }
- if ($opt['is_html']) $this->db()->out->type('html');
+ if ($opt['is_html']) $this->db()->out->type('html');
- #
- # Rows
- #
+ #
+ # Rows
+ #
- # Parser on/off (default: on)
- if (!isset($opt['parser'])) $opt['parser'] = true;
+ # Parser on/off (default: on)
+ if (!isset($opt['parser'])) $opt['parser'] = true;
- if (!empty($opt['db_type_from'])) {
- $this->db()->type = $db_type;
- }
+ if (!empty($opt['db_type_from'])) {
+ $this->db()->type = $db_type;
+ }
- $count = 0;
- while ($fct() and $row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
+ $count = 0;
+ while ($fct() and $row = $st->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT)) {
- $count++;
- $call = null;
+ $count++;
+ $call = null;
- $call = $this->rows_parsers($row,$opt);
+ $call = $this->rows_parsers($row,$opt);
- #
- # Fields filter
- #
- if ($fields_filter) {
- $new_row = [];
- foreach ($fields_filter as $k) {
- if (isset($row[$k])) $new_row[$k] = $row[$k];
- }
- $row = $new_row;
- }
+ #
+ # Fields filter
+ #
+ if ($this->fields_only) {
+ $new_row = [];
+ foreach ($this->fields_only as $k) {
+ if (isset($row[$k])) $new_row[$k] = $row[$k];
+ }
+ $row = $new_row;
+ }
- #
- # Preffix
- #
- if (!empty($opt['preffix'])) echo $opt['preffix'];
+ #
+ # Preffix
+ #
+ if (!empty($opt['preffix'])) echo $opt['preffix'];
- #
- # Head
- #
- if ($count === 1) {
- if ($opt['is_html']) echo $this->html_rows_top();
+ #
+ # Head
+ #
+ if ($count === 1) {
+ if ($opt['is_html']) echo $this->html_rows_top();
- if ($call) {
- $this->fields_add_missing($fields,$row);
- }
+ if ($call) {
+ $this->fields_add_missing($fields,$row);
+ }
- if ($out_conf) {
- $this->db()->out->head($out_conf,array_keys($fields),[$row]);
+ if ($out_conf) {
+ $this->db()->out->head($out_conf,array_keys($fields),[$row]);
- } else {
- echo $this->{"rows_begin_$format"}($fields,$opt);
+ } else {
+ echo $this->{"rows_begin_$format"}($fields,$opt);
- }
+ }
- }
+ }
- #
- # Row
- #
- $count_fields = 0;
+ #
+ # Row
+ #
+ $count_fields = 0;
- foreach ($fields as $f => $field) {
+ foreach ($fields as $f => $field) {
if (!$this->field($f)) continue;
- $row[$f] = $field->out(isset($row[$f]) ? $row[$f] : '');
- $count_fields++;
- }
+ $row[$f] = $field->out(isset($row[$f]) ? $row[$f] : '');
+ $count_fields++;
+ }
- if ($out_conf) {
- $this->db()->out->row($out_conf,$row);
+ if ($out_conf) {
+ $this->db()->out->row($out_conf,$row);
- } else {
- echo $this->{"rows_rec_$format"}($row,$opt);
- }
+ } else {
+ echo $this->{"rows_rec_$format"}($row,$opt);
+ }
- } # < while rows
+ } # < while rows
- $st->closeCursor();
- if (!empty($cursor)) $cursor->closeCursor();
- if (!$count) return;
+ $st->closeCursor();
+ if (!empty($cursor)) $cursor->closeCursor();
+ if (!$count) return;
- $this->count = $opt['count'] = $count;
- $this->limit = $opt['limit'] = $limit;
+ $this->count = $opt['count'] = $count;
+ $this->limit = $opt['limit'] = $limit;
- if ($opt['is_html'] or $format=='wp' or !empty($cursor)) {
+ if ($opt['is_html'] or $format=='wp' or !empty($cursor)) {
if (!empty($sql_orig)) $sql = $sql_orig;
- //
- // Tot
- //
- if (!$where and !$limit) {
- $debug = "Table.rows(): Not using count(*), use $count";
- $query = $this->db()->conn->query("SELECT $count");
-
- } elseif ($select_count[1]) {
- $debug = "Table.rows(): Using $select_count[1]";
- $query = $this->db()->conn->query($select_count[1]);
-
- } elseif ($where) {
- $sql_count = $sql;
- $sql_count = preg_replace('/ (ORDER|LIMIT) .*?$/s','',$sql_count);
- $sql_count = preg_replace('/^SELECT .*FROM/s','SELECT count(*) FROM ',$sql_count);
- $debug = "Table.rows(): Using $sql_count";
- $query = $this->db()->conn->query($sql_count);
-
- } else {
- $query = $this->db()->conn->query('SELECT count(*) FROM '.$this->sql_name());
-
- }
-
- if (!$query) $this->err_sql($sql);
-
- $tot = $query->fetch(PDO::FETCH_COLUMN);
- $this->tot = $opt['tot'] = $tot;
-
- } # < is_html
-
- if ($count === 0 and !$format) {
- echo $this->{"rows_begin_$format"}($fields,$opt);
- }
-
- if ($out_conf) {
- $this->db()->out->end($out_conf);
-
- } else {
- echo $this->{"rows_end_$format"}();
-
- if ($opt['is_html']) {
- echo '<div class="nav bottom">'
- .$this->nav($opt['count'],$opt['tot'],$opt['limit'])
- .'</div>'.NB_EOL
- ;
- }
-
- } # < out
-
- if ($opt['is_html']) {
- echo '</div>'.NB_EOL;
- }
-
- #return $count;
- }
-
- /*-----------------------------------------------------------------
- No Out
- -----------------------------------------------------------------*/
- public function rows_begin_($fields,&$o) {
- $o['sep'] = '';
- $o['var'] = [
- 'head' => array_keys($fields),
- 'rows' => [],
- ];
- }
-
- public function rows_rec_($row,&$o) {
- $o['var']['rows'][] = $row;
- }
-
- public function rows_end_() {
- }
-
- /*-----------------------------------------------------------------
- Template
- -----------------------------------------------------------------*/
- public function rows_begin_template($fields,&$o) {
- $id = $this->idtemplate();
-
- $id = preg_replace('/[^\w\._-]/','',$id);
-
- $file = TABLE_TEMPLATE.'/'.$id.'.php';
- if (!is_readable($file)) return false; #$this->bye("Wrong id `$id`");
+ //
+ // Tot
+ //
+ if (!$where and !$limit) {
+ $debug = "Table.rows(): Not using count(*), use $count";
+ $query = $this->db()->conn->query("SELECT $count");
+
+ } elseif ($select_count[1]) {
+ $debug = "Table.rows(): Using $select_count[1]";
+ $query = $this->db()->conn->query($select_count[1]);
+
+ } elseif ($where) {
+ $sql_count = $sql;
+ $sql_count = preg_replace('/ (ORDER|LIMIT) .*?$/s','',$sql_count);
+ $sql_count = preg_replace('/^SELECT .*FROM/s','SELECT count(*) FROM ',$sql_count);
+ $debug = "Table.rows(): Using $sql_count";
+ $query = $this->db()->conn->query($sql_count);
+
+ } else {
+ $query = $this->db()->conn->query('SELECT count(*) FROM '.$this->sql_name());
+
+ }
+
+ if (!$query) $this->err_sql($sql);
+
+ $tot = $query->fetch(PDO::FETCH_COLUMN);
+ $this->tot = $opt['tot'] = $tot;
+
+ } # < is_html
+
+ if ($count === 0 and !$format) {
+ echo $this->{"rows_begin_$format"}($fields,$opt);
+ }
+
+ if ($out_conf) {
+ $this->db()->out->end($out_conf);
+
+ } else {
+ echo $this->{"rows_end_$format"}();
+
+ if ($opt['is_html']) {
+ echo '<div class="nav bottom">'
+ .$this->nav($opt['count'],$opt['tot'],$opt['limit'])
+ .'</div>'.NB_EOL
+ ;
+ }
+
+ } # < out
+
+ if ($opt['is_html']) {
+ echo '</div>'.NB_EOL;
+ }
+
+ #return $count;
+ }
+
+ /*-----------------------------------------------------------------
+ No Out
+ -----------------------------------------------------------------*/
+ public function rows_begin_($fields,&$o) {
+ $o['sep'] = '';
+ $o['var'] = [
+ 'head' => array_keys($fields),
+ 'rows' => [],
+ ];
+ }
+
+ public function rows_rec_($row,&$o) {
+ $o['var']['rows'][] = $row;
+ }
+
+ public function rows_end_() {
+ }
+
+ /*-----------------------------------------------------------------
+ Template
+ -----------------------------------------------------------------*/
+ public function rows_begin_template($fields,&$o) {
+ $id = $this->idtemplate();
+
+ $id = preg_replace('/[^\w\._-]/','',$id);
+
+ $file = TABLE_TEMPLATE.'/'.$id.'.php';
+ if (!is_readable($file)) return false; #$this->bye("Wrong id `$id`");
# NB 02.12.16 $o['file'] = $file;
- $this->__file = $file;
- $this->__fields = array_keys($fields);
+ $this->__file = $file;
+ $this->__fields = array_keys($fields);
# NB 02.12.16 $HEAD = array_keys($fields);
# NB 02.12.16 $ROWS = [];
# NB 02.12.16 $ROW = [];
# NB 02.12.16 require $o['file'];
- }
-
- public function rows_rec_template($row,&$o) {
- $i = 0;
- foreach ($row as $k=>$v) {
- $row[$i] = $v;
- $i++;
- }
- $this->__rows[] = $row;
+ }
+
+ public function rows_rec_template($row,&$o) {
+ $i = 0;
+ foreach ($row as $k=>$v) {
+ $row[$i] = $v;
+ $i++;
+ }
+ $this->__rows[] = $row;
# NB 02.12.16 $HEAD = [];
# NB 02.12.16 $ROWS = [$row];
# NB 02.12.16 $ROW = $row;
- }
-
- public function rows_end_template() {
- $HEAD = &$this->__fields;
- $ROWS = &$this->__rows;
- $ROW = &$ROWS[0];;
- require $this->__file;
- unset($this->__file);
- unset($this->__fields);
- unset($this->__rows);
- }
-
- /*-----------------------------------------------------------------
- Wordpress
- -----------------------------------------------------------------*/
- public function rows_begin_wp() {
- require_once(NB_ROOT.'/lib/php/db/wp.php');
- $this->_html_table = new html_table($this);
- return '';
- }
-
- public function rows_rec_wp(&$row) {
- $this->_html_table->items[] = $row;
- return '';
- }
-
- public function rows_end_wp() {
-
- $limit = preg_replace('/^.*,\s*/','',$this->limit);
-
- $this->_html_table->set_pagination_args([
- 'total_items' => $this->tot, // total items defined above
- 'per_page' => $limit, // per page constant defined at top of method
- 'total_pages' => ceil($this->tot / $limit) // calculate pages count
- ]);
-
- #$this->_html_table->display_tablenav('top');
- $this->_html_table->display();
- #$this->_html_table->display_tablenav('bottom');
- unset($this->_html_table);
- return '';
- }
+ }
+
+ public function rows_end_template() {
+ $HEAD = &$this->__fields;
+ $ROWS = &$this->__rows;
+ $ROW = &$ROWS[0];;
+ require $this->__file;
+ unset($this->__file);
+ unset($this->__fields);
+ unset($this->__rows);
+ }
+
+ /*-----------------------------------------------------------------
+ Wordpress
+ -----------------------------------------------------------------*/
+ public function rows_begin_wp() {
+ require_once(NB_ROOT.'/lib/php/db/wp.php');
+ $this->_html_table = new html_table($this);
+ return '';
+ }
+
+ public function rows_rec_wp(&$row) {
+ $this->_html_table->items[] = $row;
+ return '';
+ }
+
+ public function rows_end_wp() {
+
+ $limit = preg_replace('/^.*,\s*/','',$this->limit);
+
+ $this->_html_table->set_pagination_args([
+ 'total_items' => $this->tot, // total items defined above
+ 'per_page' => $limit, // per page constant defined at top of method
+ 'total_pages' => ceil($this->tot / $limit) // calculate pages count
+ ]);
+
+ #$this->_html_table->display_tablenav('top');
+ $this->_html_table->display();
+ #$this->_html_table->display_tablenav('bottom');
+ unset($this->_html_table);
+ return '';
+ }
/*-----------------------------------------------------------------
- Sql
+ Sql
-----------------------------------------------------------------*/
public function rows_begin_sql() {
- return '';
- return "\n-- ".$this->name."\n";
+ return '';
+ return "\n-- ".$this->name."\n";
}
public function rows_rec_sql(&$row,&$opt) {
- $keys = $values = [];
+ $keys = $values = [];
- foreach ($row as $k=>$v) {
- if (isset($this->extras[$k])) continue;
- $f = $this->field($k);
+ foreach ($row as $k=>$v) {
+ if (isset($this->extras[$k])) continue;
+ $f = $this->field($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)).");";
- $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 '';
- }
-
- /*-----------------------------------------------------------------
- Text
- -----------------------------------------------------------------*/
- public function rows_begin_text() {
- $this->_row_text = null;
- return '';
- }
-
- public function rows_rec_text(&$row) {
- $text = '';
- if ($this->_row_text === null) {
- $this->_row_text = true;
- } else {
- $text .= "\t";
- }
- return $text.$row."\n";
- }
-
- public function rows_end_text() {
- unset($this->_row_text);
- return '';
- }
-
- /*-----------------------------------------------------------------
- Json
- -----------------------------------------------------------------*/
- public function rows_begin_json() {
- $this->_row_json = null;
- return '['.NB_EOL;
- return ''
- #."// database: ".$this->db()->name."\n"
- #."// table: $this->name\n"
- .'['.NB_EOL;
- }
-
- public function rows_rec_json(&$row) {
- if ($this->_row_json === null) {
- $json = '';
- $this->_row_json = true;
- } else {
- $json = ','.NB_EOL;
- }
- return $json . json_encode($row);
- }
-
- public function rows_end_json() {
- unset($this->_row_json);
- return NB_EOL.']'.NB_EOL;
- }
-
- /*-----------------------------------------------------------------
- Xml
- -----------------------------------------------------------------*/
- public function rows_begin_xml() {
- return ''
- .'<?xml version="1.0" encoding="utf-8"?>'.NB_EOL #<?
- .'<rows name="'.$this->name.'" database="'.$this->db()->name.'" database-type="'.$this->db()->conf_type('type').'">'.NB_EOL
- ;
- }
-
- public function rows_rec_xml(&$row) {
- $xml = '';
- $xml .= TABLE_INDENT."<row>".NB_EOL;
- foreach ($row as $k=>$v) {
- if ($v !== '') $xml .= ''
- . TABLE_INDENT.TABLE_INDENT."<".$k.">"
- .'<![CDATA['.$v.']]>'
- . '</'.$k.'>'
- . NB_EOL;
- }
- $xml .= TABLE_INDENT."</row>".NB_EOL;
- return $xml;
- }
-
- public function rows_end_xml() {
- return '</rows>'.NB_EOL;
- }
-
- public function zaza() { return [ ['A','B'], ['a','bb'] ]; }
-
- /*-----------------------------------------------------------------
- Csv
- -----------------------------------------------------------------*/
- public function rows_begin_csv($fields) {
-
- if (self::p('rows_head_char')!=='') echo self::p('rows_head_char');
- if (!$this->show_header) return '';
- return join(TABLE_CSV_SEP,array_keys($fields))."\n";
- }
-
- public function rows_rec_csv(&$row) {
- return str_replace("\n",'|',join(TABLE_CSV_SEP,array_values($row)))."\n";
- }
-
- public function rows_end_csv() {
- return '';
- }
-
- /*-----------------------------------------------------------------
- Html Table
- -----------------------------------------------------------------*/
- public function rows_begin_table($fields) {
-
- $html = '';
-
- $html .= '<table class="rows wp-list-table widefat striped">'.NB_EOL;
-
- $this->__rows_table_attr = [];
- foreach ($fields as $name => $f) {
- $this->__rows_table_attr[$name] = ''
- . ' class="' . $name
- . ($f->key ? ' key' : '')
- . (isset($this->extras[$name]) ? ' extra' : '')
- . ' ' . preg_replace('/\W.*$/','',$f->type)
- .'"'
- ;
- }
-
- if ($this->show_header) {
- $html .= '<thead>'.NB_EOL;
-
- // Columns names
- $html .= '<tr class="head">'.NB_EOL;
- if ($this->buttons() and DB_HTML_EDIT) $html .= '<th class="edit"></th>'.NB_EOL;
- foreach ($fields as $name => $f) {
- $html .= '<th'.$this->__rows_table_attr[$name].'>'.$this->url_sort($name).'</th>'.NB_EOL;
- }
- if ($this->buttons() and DB_HTML_DELETE) $html .= '<th class="delete"></th>'.NB_EOL;
- $html .= '</tr>'.NB_EOL;
- $html .= '</thead>'.NB_EOL;
- }
-
- $html .= '<tbody>'.NB_EOL;
- return $html;
- }
-
- public function rows_rec_table(&$row,&$opt) {
-
- $buttons = $this->html_row_buttons($row);
-
- $html = '<tr class="row">'.NB_EOL;
-
- if ($this->buttons() and !empty($buttons[0])) $html .= '<td class="action">'.$buttons[0].'</td>'.NB_EOL;
-
- foreach ($row as $k => $v) {
- if ( !empty($this) and !empty($this->field($k)) ) {
- $v = $this->field($k)->htmlValue($v);
- }
- $html .= '<td'.$this->__rows_table_attr[$k].'>'.$v.'</td>'.NB_EOL;
- }
-
- if ($this->buttons() and !empty($buttons[1])) $html .= '<td class="action">'.$buttons[1].'</td>'.NB_EOL;
-
- $html .= '</tr>'.NB_EOL;
+ return '';
+ }
- return $html;
- }
+ /*-----------------------------------------------------------------
+ Text
+ -----------------------------------------------------------------*/
+ public function rows_begin_text() {
+ $this->_row_text = null;
+ return '';
+ }
- public function rows_end_table() {
- unset($this->__rows_table_attr);
- $html = '';
- $html .= '</tbody>'.NB_EOL;
- $html .= '</table>'.NB_EOL;
- return $html;
- }
+ public function rows_rec_text(&$row) {
+ $text = '';
+ if ($this->_row_text === null) {
+ $this->_row_text = true;
+ } else {
+ $text .= "\t";
+ }
+ return $text.$row."\n";
+ }
- /*-----------------------------------------------------------------
- Html Div
- -----------------------------------------------------------------*/
- public function rows_begin_div() {
- return '<div class="rows search-results">'.NB_EOL;
- }
+ public function rows_end_text() {
+ unset($this->_row_text);
+ return '';
+ }
- public function rows_rec_div(&$row) {
+ /*-----------------------------------------------------------------
+ Json
+ -----------------------------------------------------------------*/
+ public function rows_begin_json() {
+ $this->_row_json = null;
+ return '['.NB_EOL;
+ return ''
+ #."// database: ".$this->db()->name."\n"
+ #."// table: $this->name\n"
+ .'['.NB_EOL;
+ }
- $html = '';
+ public function rows_rec_json(&$row) {
+ if ($this->_row_json === null) {
+ $json = '';
+ $this->_row_json = true;
+ } else {
+ $json = ','.NB_EOL;
+ }
+ return $json . json_encode($row);
+ }
- $html .= '<ul class="row">'.NB_EOL;
+ public function rows_end_json() {
+ unset($this->_row_json);
+ return NB_EOL.']'.NB_EOL;
+ }
- if ($this->buttons()) {
- $html .= '<li class="buttons">'.NB_EOL;
- $html .= join('',$this->html_row_buttons($row));
- $html .= '</li>'.NB_EOL;
- }
+ /*-----------------------------------------------------------------
+ Xml
+ -----------------------------------------------------------------*/
+ public function rows_begin_xml() {
+ return ''
+ .'<?xml version="1.0" encoding="utf-8"?>'.NB_EOL #<?
+ .'<rows name="'.$this->name.'" database="'.$this->db()->name.'" database-type="'.$this->db()->conf_type('type').'">'.NB_EOL
+ ;
+ }
- foreach ($row as $k => $v) {
- $html .= '<li>'
- .( $k == '0' ? '' : '<label>'.prettyText($k).'</label>')
- .'<span class="'.$k.'">'.$v.'</span>'
- .'</li>'.NB_EOL;
- }
+ public function rows_rec_xml(&$row) {
+ $xml = '';
+ $xml .= TABLE_INDENT."<row>".NB_EOL;
+ foreach ($row as $k=>$v) {
+ if ($v !== '') $xml .= ''
+ . TABLE_INDENT.TABLE_INDENT."<".$k.">"
+ .'<![CDATA['.$v.']]>'
+ . '</'.$k.'>'
+ . NB_EOL;
+ }
+ $xml .= TABLE_INDENT."</row>".NB_EOL;
+ return $xml;
+ }
- $html .= '</ul>'.NB_EOL;
+ public function rows_end_xml() {
+ return '</rows>'.NB_EOL;
+ }
- return $html;
- }
+ public function zaza() { return [ ['A','B'], ['a','bb'] ]; }
- public function rows_end_div() {
- return '</div>'.NB_EOL;
- }
+ /*-----------------------------------------------------------------
+ Csv
+ -----------------------------------------------------------------*/
+ public function rows_begin_csv($fields) {
+
+ if (self::p('rows_head_char')!=='') echo self::p('rows_head_char');
+ if (!$this->show_header) return '';
+ return join(TABLE_CSV_SEP,array_keys($fields))."\n";
+ }
+
+ public function rows_rec_csv(&$row) {
+ return str_replace("\n",'|',join(TABLE_CSV_SEP,array_values($row)))."\n";
+ }
+
+ public function rows_end_csv() {
+ return '';
+ }
+
+ /*-----------------------------------------------------------------
+ Html Table
+ -----------------------------------------------------------------*/
+ public function rows_begin_table($fields) {
+
+ $html = '';
+
+ $html .= '<table class="rows wp-list-table widefat striped">'.NB_EOL;
+
+ $this->__rows_table_attr = [];
+ foreach ($fields as $name => $f) {
+ $this->__rows_table_attr[$name] = ''
+ . ' class="' . $name
+ . ($f->key ? ' key' : '')
+ . (isset($this->extras[$name]) ? ' extra' : '')
+ . ' ' . preg_replace('/\W.*$/','',$f->type)
+ .'"'
+ ;
+ }
- public function sql_names($value) {
+ if ($this->show_header) {
+ $html .= '<thead>'.NB_EOL;
- $new = [];
- foreach ($value as $k=>$v) {
- $new[$k] = $this->sql_name($v);
- }
- return $new;
- }
+ // Columns names
+ $html .= '<tr class="head">'.NB_EOL;
+ if ($this->buttons() and DB_HTML_EDIT) $html .= '<th class="edit"></th>'.NB_EOL;
+ foreach ($fields as $name => $f) {
+ $html .= '<th'.$this->__rows_table_attr[$name].'>'.$this->url_sort($name).'</th>'.NB_EOL;
+ }
+ if ($this->buttons() and DB_HTML_DELETE) $html .= '<th class="delete"></th>'.NB_EOL;
+ $html .= '</tr>'.NB_EOL;
+ $html .= '</thead>'.NB_EOL;
+ }
- public function sql_name($value=null) {
+ $html .= '<tbody>'.NB_EOL;
+ return $html;
+ }
- return $this->db()->sql_name($value === null ? $this->name : $value);
- }
+ public function rows_rec_table(&$row,&$opt) {
- private function _post2sql($post) {
- $keys = [];
- $keys_values = [];
- $fields = [];
- $fields_values = [];
- foreach ($this->fields() as $name => $field) {
+ $buttons = $this->html_row_buttons($row);
- if ($field->extras) continue;
+ $html = '<tr class="row">'.NB_EOL;
- $value = $post[$this->field_preff.$name];
+ if ($this->buttons() and !empty($buttons[0])) $html .= '<td class="action">'.$buttons[0].'</td>'.NB_EOL;
- if ($field->key) {
- $keys[] = $name;
+ foreach ($row as $k => $v) {
+ if ( !empty($this) and !empty($this->field($k)) ) {
+ $v = $this->field($k)->htmlValue($v);
+ }
+ $html .= '<td'.$this->__rows_table_attr[$k].'>'.$v.'</td>'.NB_EOL;
+ }
- if (!isset($post[$this->key_preff.$name])) {
- if ($field->key) $this->bye("Missing `$name`!");
- continue;
- }
+ if ($this->buttons() and !empty($buttons[1])) $html .= '<td class="action">'.$buttons[1].'</td>'.NB_EOL;
- if (isset($post[$this->key_preff.$name])) {
- $keys_values[] = $post[$this->key_preff.$name];
+ $html .= '</tr>'.NB_EOL;
- } else {
- $keys_values[] = $value;
- }
+ return $html;
+ }
- } else {
+ public function rows_end_table() {
+ unset($this->__rows_table_attr);
+ $html = '';
+ $html .= '</tbody>'.NB_EOL;
+ $html .= '</table>'.NB_EOL;
+ return $html;
+ }
- $fields[] = $name;
- $fields_values[] = $value;
+ /*-----------------------------------------------------------------
+ Html Div
+ -----------------------------------------------------------------*/
+ public function rows_begin_div() {
+ return '<div class="rows search-results">'.NB_EOL;
+ }
+
+ public function rows_rec_div(&$row) {
+
+ $html = '';
+
+ $html .= '<ul class="row">'.NB_EOL;
+
+ if ($this->buttons()) {
+ $html .= '<li class="buttons">'.NB_EOL;
+ $html .= join('',$this->html_row_buttons($row));
+ $html .= '</li>'.NB_EOL;
+ }
- }
+ foreach ($row as $k => $v) {
+ $html .= '<li>'
+ .( $k == '0' ? '' : '<label>'.prettyText($k).'</label>')
+ .'<span class="'.$k.'">'.$v.'</span>'
+ .'</li>'.NB_EOL;
+ }
+
+ $html .= '</ul>'.NB_EOL;
+
+ return $html;
+ }
+
+ public function rows_end_div() {
+ return '</div>'.NB_EOL;
+ }
+
+ public function sql_names($value) {
+
+ $new = [];
+ foreach ($value as $k=>$v) {
+ $new[$k] = $this->sql_name($v);
+ }
+ return $new;
+ }
+
+ public function sql_name($value=null) {
+
+ return $this->db()->sql_name($value === null ? $this->name : $value);
+ }
+
+ private function _post2sql($post) {
+ $keys = [];
+ $keys_values = [];
+ $fields = [];
+ $fields_values = [];
+ foreach ($this->fields() as $name => $field) {
+
+ if ($field->extras) continue;
+
+ $value = $post[$this->field_preff.$name];
+
+ if ($field->key) {
+ $keys[] = $name;
+
+ if (!isset($post[$this->key_preff.$name])) {
+ if ($field->key) $this->bye("Missing `$name`!");
+ continue;
+ }
+
+ if (isset($post[$this->key_preff.$name])) {
+ $keys_values[] = $post[$this->key_preff.$name];
+
+ } else {
+ $keys_values[] = $value;
+ }
+
+ } else {
+
+ $fields[] = $name;
+ $fields_values[] = $value;
+
+ }
}
return [
- 'keys' => $keys,
- 'keys_values' => $keys_values,
- 'fields' => $fields,
- 'fields_values' => $fields_values,
- 'all_keys' => array_combine($keys,$keys_values),
- 'all_fields' => array_combine($fields,$fields_values),
+ 'keys' => $keys,
+ 'keys_values' => $keys_values,
+ 'fields' => $fields,
+ 'fields_values' => $fields_values,
+ 'all_keys' => array_combine($keys,$keys_values),
+ 'all_fields' => array_combine($fields,$fields_values),
];
- }
+ }
- public function replace($hvalues,&$info=[]) {
+ public function replace($hvalues,&$info=[]) {
# NB 12.12.17: When REPLACE is not supported where call a personalized function to modify $sql
$fct = $this->db()->conf_type('replace_insert');
if (!empty($fct)) {
$info['fct'] = $fct;
return $this->insert($hvalues,$info);
}
- return $this->insert($hvalues,$info,'REPLACE');
- }
+ return $this->insert($hvalues,$info,'REPLACE');
+ }
- public function insert($post,&$info=[],$insert_word='INSERT') {
+ public function insert($post,&$info=[],$insert_word='INSERT') {
- if (empty($info['values'])) $info['values'] = [];
- if (empty($post)) $this->bye('insert(): No values');
+ if (empty($info['values'])) $info['values'] = [];
+ if (empty($post)) $this->bye('insert(): No values');
- $sql_names = $fields = $values = [];
+ $sql_names = $fields = $values = [];
- foreach ($this->fields() as $name => $field) {
- if ($field->key and $field->autoincrement()) continue;
+ foreach ($this->fields() as $name => $field) {
+ if ($field->key and $field->autoincrement()) continue;
- if (!isset($post[$this->field_preff.$name])) {
+ if (!isset($post[$this->field_preff.$name])) {
# For postgres and replace mode, we want to update timestamp for example
if (!empty($info['fct']) and isset($field->default)) {
}
- $fields[$name] = $field;
- $sql_names[$name] = $field->sql_name();
- $values[] = $post[$this->field_preff.$name];
- }
+ $fields[$name] = $field;
+ $sql_names[$name] = $field->sql_name();
+ $values[] = $post[$this->field_preff.$name];
+ }
- if (empty($fields)) $this->bye('insert(): No fields for table');
+ if (empty($fields)) $this->bye('insert(): No fields for table');
- $sql =
- $insert_word.' INTO '. $this->sql_name() . ' (' . join(',',array_values($sql_names)).')'
- .' VALUES (' . join(',',ar_map('":$a"',array_keys($fields))) . ')'
- ;
+ $sql =
+ $insert_word.' INTO '. $this->sql_name() . ' (' . join(',',array_values($sql_names)).')'
+ .' VALUES (' . join(',',ar_map('":$a"',array_keys($fields))) . ')'
+ ;
if (!empty($info['fct'])) {
$fct = $info['fct'];
unset($info['fct']);
$fct($sql,$this,$fields);
}
- $info['sql'] = $sql;
+ $info['sql'] = $sql;
- if (!($query = $this->db()->conn->prepare($sql))) {
- $this->err_sql($sql);
- return false;
- }
+ if (!($query = $this->db()->conn->prepare($sql))) {
+ $this->err_sql($sql);
+ return false;
+ }
- $info['values'] = $post;
+ $info['values'] = $post;
- foreach ($fields as $name => $field) {
- $row = [ $name => $post[$name] ];
- $this->db()->table_row_encrypt($this,$row);
- #debug($name.': '.$row[$name]);
- if (!empty($info['values'][$name])) $info['values'][$name] = $row[$name];
- $field->bindParam($query,$row[$name],":$name");
- }
+ foreach ($fields as $name => $field) {
+ $row = [ $name => $post[$name] ];
+ $this->db()->table_row_encrypt($this,$row);
+ #debug($name.': '.$row[$name]);
+ if (!empty($info['values'][$name])) $info['values'][$name] = $row[$name];
+ $field->bindParam($query,$row[$name],":$name");
+ }
- if (self::p('debug')) {
- $this->debug($info,1);
- return true;
- }
+ if (self::p('debug')) {
+ $this->debug($info,1);
+ return true;
+ }
- if (!($execute = $query->execute())) {
- $this->err_sql($sql);
- return false;
- }
+ if (!($execute = $query->execute())) {
+ $this->err_sql($sql);
+ return false;
+ }
- $info['rowCount'] = $query->rowCount();
- return $query->rowCount();
- }
+ $info['rowCount'] = $query->rowCount();
+ return $query->rowCount();
+ }
- public function update($post,&$info=[]) {
+ public function update($post,&$info=[]) {
- $keys = [];
- $keys_values = [];
- $fields = [];
- $fields_values = [];
+ $keys = [];
+ $keys_values = [];
+ $fields = [];
+ $fields_values = [];
# NB 14.12.17 $bindParam = false; # NB 12.05.17: Not working ????
- $bindParam = true; # NB 12.05.17: Not working ????
+ $bindParam = true; # NB 12.05.17: Not working ????
- foreach ($this->fields() as $name => $field) {
+ foreach ($this->fields() as $name => $field) {
- if ($field->extras) continue;
+ if ($field->extras) continue;
- $value = $post[$this->field_preff.$name];
+ $value = $post[$this->field_preff.$name];
- if ($field->key) {
- $keys[] = $name;
+ if ($field->key) {
+ $keys[] = $name;
- if (!isset($post[$this->key_preff.$name])) {
- if ($field->key) $this->bye("Missing `$name`!");
- continue;
- }
+ if (!isset($post[$this->key_preff.$name])) {
+ if ($field->key) $this->bye("Missing `$name`!");
+ continue;
+ }
# NB 12.12.17 $_value = isset($post[$this->key_preff.$name]) ? $post[$this->key_preff.$name] : null;
- if (isset($post[$this->key_preff.$name])) {
- $fields[] = $name;
- $fields_values[] = $post[$this->key_preff.$name];
- $keys_values[] = $post[$this->key_preff.$name];
+ if (isset($post[$this->key_preff.$name])) {
+ $fields[] = $name;
+ $fields_values[] = $post[$this->key_preff.$name];
+ $keys_values[] = $post[$this->key_preff.$name];
- } else {
- $keys_values[] = $value;
- }
+ } else {
+ $keys_values[] = $value;
+ }
- } else {
+ } else {
- $fields[] = $name;
- $fields_values[] = $value;
+ $fields[] = $name;
+ $fields_values[] = $value;
- }
+ }
- }
+ }
- $info['keys'] = array_combine($keys,$keys_values);
- $info['fields'] = array_combine($fields,$fields_values);
- $info['post'] = $post;
+ $info['keys'] = array_combine($keys,$keys_values);
+ $info['fields'] = array_combine($fields,$fields_values);
+ $info['post'] = $post;
#bye([$keys,$keys_values]);
#debug([$post,$this->fields()]);
# $fields = $keys;
# $fields_values = $keys_values;
# }
- if (empty($fields)) $this->bye("Missing fields!");
-
- if (empty($keys)) {
- $this->bye("Missing keys!");
- $keys = $fields;
- $keys_values = $fields_values;
- }
-
- $sql = ''
- .'UPDATE ' . $this->sql_name()
- .' SET ' . join(',',$this->ar_map('"$a=:$a"',$fields))
- .' WHERE ' . join(' AND ',$this->ar_map('"$a=:key_$a"',$keys))
- ;
- #$info['sql'] = $sql;
- $info = [ 'sql' => $sql ] + $info;
-
- if ($bindParam and !($query = $this->db()->conn->prepare($sql))) {
- $this->err('PDO::errorInfo(): ' .join(' ', $this->db()->conn->errorInfo()) .NB_EOL);
- return false;
- }
-
- foreach ($fields as $name) {
- #debug("$name: ".$post[$name]);
- $row = [ $name => $post[$name] ];
- $this->db()->table_row_encrypt($this,$row);
- if ($bindParam) $field->bindParam($query,$row[$name],":$name");
- $sql = str_replace(":$name",$this->field($name)->quote($row[$name]),$sql);
- }
-
- foreach ($info['keys'] as $name => $value) {
- #debug("$name: ".$post[$name]);
- if ($bindParam) $field->bindParam($query,$value,":key_$name");
- $sql = str_replace(":key_$name",$this->field($name)->quote($value),$sql);
- }
-
- $info['sql'] = $sql;
- if (!$bindParam) {
- $query = $this->db()->conn->prepare($sql);
- }
- #return $sql;
- if (self::p('debug')) {
- $this->debug($info,1);
- return false;
- }
-
- if (!($ex = $query->execute())) {
- $this->err_sql($sql);
- return false;
- }
-
- $info = [ 'rowCount' => $query->rowCount()] + $info;
- #debug($info); return 0;
- return $info['rowCount'];
-
- }
-
- public function delete($post,&$info=[]) {
- if (empty($info['values'])) $info['values'] = [];
- $info['values'] = $post;
-
- $keys = $this->fields_keys();
-
- // If no primary keys, we use all field
- if (empty($keys)) $keys = $this->fields();
-
- if (!($where = $this->where($keys,$post,self::$is_admin ? false : true))) {
- err('Db.delete(): Missing keys values');
- return null;
- }
+ if (empty($fields)) $this->bye("Missing fields!");
+
+ if (empty($keys)) {
+ $this->bye("Missing keys!");
+ $keys = $fields;
+ $keys_values = $fields_values;
+ }
+
+ $sql = ''
+ .'UPDATE ' . $this->sql_name()
+ .' SET ' . join(',',$this->ar_map('"$a=:$a"',$fields))
+ .' WHERE ' . join(' AND ',$this->ar_map('"$a=:key_$a"',$keys))
+ ;
+ #$info['sql'] = $sql;
+ $info = [ 'sql' => $sql ] + $info;
+
+ if ($bindParam and !($query = $this->db()->conn->prepare($sql))) {
+ $this->err('PDO::errorInfo(): ' .join(' ', $this->db()->conn->errorInfo()) .NB_EOL);
+ return false;
+ }
+
+ foreach ($fields as $name) {
+ #debug("$name: ".$post[$name]);
+ $row = [ $name => $post[$name] ];
+ $this->db()->table_row_encrypt($this,$row);
+ if ($bindParam) $field->bindParam($query,$row[$name],":$name");
+ $sql = str_replace(":$name",$this->field($name)->quote($row[$name]),$sql);
+ }
+
+ foreach ($info['keys'] as $name => $value) {
+ #debug("$name: ".$post[$name]);
+ if ($bindParam) $field->bindParam($query,$value,":key_$name");
+ $sql = str_replace(":key_$name",$this->field($name)->quote($value),$sql);
+ }
+
+ $info['sql'] = $sql;
+ if (!$bindParam) {
+ $query = $this->db()->conn->prepare($sql);
+ }
+ #return $sql;
+ if (self::p('debug')) {
+ $this->debug($info,1);
+ return false;
+ }
+
+ if (!($ex = $query->execute())) {
+ $this->err_sql($sql);
+ return false;
+ }
+
+ $info = [ 'rowCount' => $query->rowCount()] + $info;
+ #debug($info); return 0;
+ return $info['rowCount'];
+
+ }
+
+ public function delete($post,&$info=[]) {
+ if (empty($info['values'])) $info['values'] = [];
+ $info['values'] = $post;
+
+ $keys = $this->fields_keys();
+
+ // If no primary keys, we use all field
+ if (empty($keys)) $keys = $this->fields();
+
+ if (!($where = $this->where($keys,$post,self::$is_admin ? false : true))) {
+ err('Db.delete(): Missing keys values');
+ return null;
+ }
# NB 07.12.17: Add LIMIT 1. If a table as not primary key when want to delete only on record
# NB 12.12.17 $sql = 'DELETE FROM ' . $this->sql_name() . $where . ($this->db()->type == 'pgsql' ? '' : ' LIMIT 1');
- $sql = 'DELETE FROM ' . $this->sql_name() . $where . ($this->db()->conf_type('delete_no_limit') ? '' : ' LIMIT 1');
- $info['sql'] = $sql;
+ $sql = 'DELETE FROM ' . $this->sql_name() . $where . ($this->db()->conf_type('delete_no_limit') ? '' : ' LIMIT 1');
+ $info['sql'] = $sql;
- if (self::p('debug')) {
- $this->debug($info,1);
- return false;
- }
+ if (self::p('debug')) {
+ $this->debug($info,1);
+ return false;
+ }
- $query = $this->db()->exec($sql);
- $info['rowCount'] = $query;
+ $query = $this->db()->exec($sql);
+ $info['rowCount'] = $query;
- return $info['rowCount'];
- }
+ return $info['rowCount'];
+ }
- public function out($v,$head=[],$conf=[]) { return $this->db()->out($v,$head,$conf); }
+ public function out($v,$head=[],$conf=[]) { return $this->db()->out($v,$head,$conf); }
- public function url_referer($default='') {
+ public function url_referer($default='') {
- if (self::p('referer')) {
- return urldecode($this->p('referer'));
+ if (self::p('referer')) {
+ return urldecode($this->p('referer'));
- } elseif(!empty($default)) {
- return $default;
+ } elseif(!empty($default)) {
+ return $default;
- } else {
- return '?table=' . urlencode($this->name) . (self::p('db') ? '&db='.self::p('db') : '');
+ } else {
+ return '?table=' . urlencode($this->name) . (self::p('db') ? '&db='.self::p('db') : '');
- }
+ }
- }
+ }
# NB 12.01.18 public function maxlengths() {
# NB 12.01.18 $sql = 'MAX(LENGTH('.$field->sql_name(true).'))';
# NB 12.01.18 }
- public function fields_rows() {
- $rows = array_values($this->object2array($this->fields()));
-
- list($sql,$where,$limit,$select_count) = $this->rows_sql();
- foreach ([
- 'maxlen' => 'MAX(LENGTH('.$this->db()->cast_text('<NAME>').'))',
- 'max' => 'MAX(<NAME>)',
- ] as $name => $select) {
- if (!$this->p($name)) continue;
- $sql = '';
+ public function fields_rows() {
+ $rows = array_values($this->object2array($this->fields()));
- foreach ($this->fields() as $f) {
- $sql .= ($sql == '' ? 'SELECT ' : ', ');
- $sql .= str_replace('<NAME>',$f->sql_name(),$select);
- }
+ list($sql,$where,$limit,$select_count) = $this->rows_sql();
+ foreach ([
+ 'maxlen' => 'MAX(LENGTH('.$this->db()->cast_text('<NAME>').'))',
+ 'max' => 'MAX(<NAME>)',
+ ] as $name => $select) {
+ if (!$this->p($name)) continue;
+ $sql = '';
- $sql .= ' FROM ' . $this->sql_name() . $where . ($limit ? " LIMIT ".$limit : '');
- $len = $this->db()->query($sql)->fetch(PDO::FETCH_NUM);
+ foreach ($this->fields() as $f) {
+ $sql .= ($sql == '' ? 'SELECT ' : ', ');
+ $sql .= str_replace('<NAME>',$f->sql_name(),$select);
+ }
- $i = 0;
- foreach ($rows as $k => $v) { $rows[$k][$name] = $len[$i]; $i++; }
+ $sql .= ' FROM ' . $this->sql_name() . $where . ($limit ? " LIMIT ".$limit : '');
+ $len = $this->db()->query($sql)->fetch(PDO::FETCH_NUM);
- }
+ $i = 0;
+ foreach ($rows as $k => $v) { $rows[$k][$name] = $len[$i]; $i++; }
- return $rows;
- }
+ }
- public function action($action=null) {
+ return $rows;
+ }
- if ($action == 'table.fields') {
- $rows = $this->fields_rows();
- return $this->out($rows);
+ public function action($action=null) {
- } elseif ($action == 'table.rows') {
- $this->db()->print_header($this->p('format'));
- $this->rows();
- return true;
+ if ($action == 'table.fields') {
+ $rows = $this->fields_rows();
+ return $this->out($rows);
- } elseif ($action == 'table.info') {
- return $this->out($this->info());
+ } elseif ($action == 'table.rows') {
+ $this->db()->print_header($this->p('format'));
+ $this->rows();
+ return true;
- } elseif ($action == 'table.delete') {
- if (!$this->delete($_POST,$e) and !isset($e['rowCount'])) bye($e);
- $this->db()->print_header('Location',$this->url_referer(str_replace('&','&',$this->url_list())));
- $this->out($e);
- return true;
+ } elseif ($action == 'table.info') {
+ return $this->out($this->info());
- } elseif ($action == 'table.replace') {
- if (!$this->replace($_POST,$e) and !isset($e['rowCount'])) bye($e);
- $this->db()->print_header('Location',$this->url_referer());
- $this->out($e);
- return true;
+ } elseif ($action == 'table.delete') {
+ if (!$this->delete($_POST,$e) and !isset($e['rowCount'])) bye($e);
+ $this->db()->print_header('Location',$this->url_referer(str_replace('&','&',$this->url_list())));
+ $this->out($e);
+ return true;
- } elseif ($action == 'table.insert') {
- if (!$this->insert($_POST,$e)) bye();
- $this->db()->print_header('Location',$this->url_referer());
- $this->out($e);
- return true;
+ } elseif ($action == 'table.replace') {
+ if (!$this->replace($_POST,$e) and !isset($e['rowCount'])) bye($e);
+ $this->db()->print_header('Location',$this->url_referer());
+ $this->out($e);
+ return true;
- } elseif ($action == 'table.update') {
- if ($this->update($_POST,$e) === false) bye($e);
- $this->db()->print_header('Location',$this->url_referer());
- $this->out($e);
- return true;
+ } elseif ($action == 'table.insert') {
+ if (!$this->insert($_POST,$e)) bye();
+ $this->db()->print_header('Location',$this->url_referer());
+ $this->out($e);
+ return true;
- } elseif ($action == 'table.truncate') {
- $this->db()->query('TRUNCATE '.$this->sql_name());
- return true;
+ } elseif ($action == 'table.update') {
+ if ($this->update($_POST,$e) === false) bye($e);
+ $this->db()->print_header('Location',$this->url_referer());
+ $this->out($e);
+ return true;
- } elseif (self::class_action_out($this,$action) !== null) {
- return true;
+ } elseif ($action == 'table.truncate') {
+ $this->db()->query('TRUNCATE '.$this->sql_name());
+ return true;
- } elseif ($this->p('format') and !preg_match('/^(table|div)$/',$this->p('format'))) {
+ } elseif (self::class_action_out($this,$action) !== null) {
+ return true;
- $opt = ['format' => $this->p('format')];
- $this->rows($opt);
- return true;
+ } elseif ($this->p('format') and !preg_match('/^(table|div)$/',$this->p('format'))) {
- } elseif ($action == 'edit') {
- return $this->html_edit();
+ $opt = ['format' => $this->p('format')];
+ $this->rows($opt);
+ return true;
- } elseif ($this->p('table')) {
- # NB 17.03.16 } else {
- $this->pdef('limit','20');
+ } elseif ($action == 'edit') {
+ return $this->html_edit();
- // Rows
- return $this->rows();
+ } elseif ($this->p('table')) {
+ # NB 17.03.16 } else {
+ $this->pdef('limit','20');
- }
+ // Rows
+ return $this->rows();
- return false;
- }
+ }
- public function html_row_buttons(&$row) {
- if (!$this->show_buttons or empty(self::$params)) return [];
- return [
- (!DB_HTML_EDIT ? '' : '<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>'.NB_EOL),
- (!DB_HTML_DELETE ? '' : '<a class="delete button" href="'.$this->url_keys($row,'action=delete')
- .'&referer='
- .( isset($_SERVER['REQUEST_URI']) ? urlencode($_SERVER['REQUEST_URI']) : '' )
- .'">'.DB_HTML_DELETE.'</a>'.NB_EOL),
- ];
- }
+ return false;
+ }
+
+ public function html_row_buttons(&$row) {
+ if (!$this->show_buttons or empty(self::$params)) return [];
+ return [
+ (!DB_HTML_EDIT ? '' : '<a class="edit button" href="'.$this->url_keys($row,'action=edit').'">'.DB_HTML_EDIT.'</a>'.NB_EOL),
+ (!DB_HTML_DELETE ? '' : '<a class="delete button" href="'.$this->url_keys($row,'action=delete')
+ .'&referer='
+ .( isset($_SERVER['REQUEST_URI']) ? urlencode($_SERVER['REQUEST_URI']) : '' )
+ .'">'.DB_HTML_DELETE.'</a>'.NB_EOL),
+ ];
+ }
- public function html_rows_top() {
- if (self::p('replace') === '0') return '';
- $html = '';
+ public function html_rows_top() {
+ if (self::p('replace') === '0') return '';
+ $html = '';
- if (!empty($this->replace)) {
+ if (!empty($this->replace)) {
- $replace = [];
- foreach ($this->replace as $k=>$v) { $replace[] = "$k.$v"; }
- $html .= '<span id="db-table-replace" style="display:none">'.join(' ',$replace).'</span>'.NB_EOL;
+ $replace = [];
+ foreach ($this->replace as $k=>$v) { $replace[] = "$k.$v"; }
+ $html .= '<span id="db-table-replace" style="display:none">'.join(' ',$replace).'</span>'.NB_EOL;
- }
+ }
- return $html;
+ return $html;
- }
+ }
- public function count() {
+ public function count() {
- if (isset($this->count)) return $this->count;
+ if (isset($this->count)) return $this->count;
- $sql_count = $this->name;
+ $sql_count = $this->name;
- # We could use it instead of query, but wont be cached ! $this->create_temporary();
- if ($this->type == 'sql' and $this->name !== DB_TABLE_QUERY_NAME) {
- if (!$this->sql) return;
+ # We could use it instead of query, but wont be cached ! $this->create_temporary();
+ if ($this->type == 'sql' and $this->name !== DB_TABLE_QUERY_NAME) {
+ if (!$this->sql) return;
- $sql_count = "SELECT COUNT(*) FROM ($this->sql) _table_count" ;
- #debug([$this->name,$sql_count]);
+ $sql_count = "SELECT COUNT(*) FROM ($this->sql) _table_count" ;
+ #debug([$this->name,$sql_count]);
# NB 08.08.17 if (preg_match('/SELECT.*SELECT|UNION/i',$this->sql)) {
# NB 08.08.17 $sql_count = "SELECT COUNT(*) FROM ($this->sql) _table_count" ;
# NB 08.08.17 } else {
# NB 08.08.17 bye($sql_count);
# NB 08.08.17 }
- } elseif (preg_match('/^[\w_-]+$/',$sql_count)) {
- $sql_count = "SELECT count(*) FROM ".$this->sql_name($sql_count);
-
- } else {
- $sql_count = preg_replace('/ (ORDER|LIMIT) .*?$/s','',$sql_count);
- $sql_count = preg_replace('/^SELECT .*FROM/s','SELECT count(*) FROM ',$sql_count);
-
- }
-
- $this->count = (int)$this->db()->row($sql_count);
- return $this->count;
-
- }
-
- public function err_sql($sql) {
- $err = $this->db()->conn->errorInfo();
- $err[] = $sql;
- $this->bye(join(' | ',$err));
- }
-
- public function html_menu($opt=[]) {
-
- $buttons = '<input type="submit" class="button button-small" value="Go"/>';
- if (!empty($opt['buttons'])) $buttons = $opt['buttons'];
-
- $r = '<form class="menu" method="get" action="?">'.NB_EOL;
- #$r = '<form class="menu" method="get" action="'.preg_replace('/\?.*$/','',$_SERVER["REQUEST_URI"]).'">'.NB_EOL;
-
- # See: http://html5doctor.com/html5-forms-input-types/
- #$r .= '<input id="skill" type="range" min="1" max="100" value="0" />';
- #$r .= '<input id="startdate" name="startdate" min="2012-01-01" max="2013-01-01" type="date" />';
-
- //
- // Options
- //
- if ($this->p('options')!=='0') {
-
- $r .= '<div class="options">';
-
- // Tables - see default.js if you change class
- $tables = array_keys($this->db()->tables());
- if (count($tables)>1) {
- $r .= '<span class="label">';
- $r .= '<label for="table">Tables</label>'.html_select_array($tables,[
- 'html' => 'class="tables" name="table" id="table"',
- 'selected' => $this->name,
- 'prettyText' => true,
- 'sort' => 'natcasesort',
- ]);
- $r .= '</span>';
- }
-
- // Dbs - see default.js if you change class
- if (!empty($this->db()->dbs) and count($this->db()->dbs)>1) {
- $r .= '<span class="label">';
- $r .= '<label for="db">Db</label>'.html_select_array($this->db()->dbs,[
- 'html' => 'class="dbs" id="db" name="db" onchange="document.location=\''.preg_replace('/\?.*$/','',$_SERVER['REQUEST_URI']).'?db=\'+this.value"',
- 'selected' => $this->db()->name,
- 'prettyText' => true,
- 'sort' => 'natcasesort',
- ]);
- $r .= '</span>';
- }
-
- // Format
- $r .= '<span class="label">';
- #debug($this->db()->formats);
- $r .= '<label for="format">Format</label>'.html_select_array($this->db()->formats,[
- 'html' => 'class="format" name="format" id="format"',
- 'selected' => $this->db()->format,
- 'prettyText' => true,
+ } elseif (preg_match('/^[\w_-]+$/',$sql_count)) {
+ $sql_count = "SELECT count(*) FROM ".$this->sql_name($sql_count);
+
+ } else {
+ $sql_count = preg_replace('/ (ORDER|LIMIT) .*?$/s','',$sql_count);
+ $sql_count = preg_replace('/^SELECT .*FROM/s','SELECT count(*) FROM ',$sql_count);
+
+ }
+
+ $this->count = (int)$this->db()->row($sql_count);
+ return $this->count;
+
+ }
+
+ public function err_sql($sql) {
+ $err = $this->db()->conn->errorInfo();
+ $err[] = $sql;
+ $this->bye(join(' | ',$err));
+ }
+
+ public function html_menu($opt=[]) {
+
+ $buttons = '<input type="submit" class="button button-small" value="Go"/>';
+ if (!empty($opt['buttons'])) $buttons = $opt['buttons'];
+
+ $r = '<form class="menu" method="get" action="?">'.NB_EOL;
+ #$r = '<form class="menu" method="get" action="'.preg_replace('/\?.*$/','',$_SERVER["REQUEST_URI"]).'">'.NB_EOL;
+
+ # See: http://html5doctor.com/html5-forms-input-types/
+ #$r .= '<input id="skill" type="range" min="1" max="100" value="0" />';
+ #$r .= '<input id="startdate" name="startdate" min="2012-01-01" max="2013-01-01" type="date" />';
+
+ //
+ // Options
+ //
+ if ($this->p('options')!=='0') {
+
+ $r .= '<div class="options">';
+
+ // Tables - see default.js if you change class
+ $tables = array_keys($this->db()->tables());
+ if (count($tables)>1) {
+ $r .= '<span class="label">';
+ $r .= '<label for="table">Tables</label>'.html_select_array($tables,[
+ 'html' => 'class="tables" name="table" id="table"',
+ 'selected' => $this->name,
+ 'prettyText' => true,
+ 'sort' => 'natcasesort',
+ ]);
+ $r .= '</span>';
+ }
+
+ // Dbs - see default.js if you change class
+ if (!empty($this->db()->dbs) and count($this->db()->dbs)>1) {
+ $r .= '<span class="label">';
+ $r .= '<label for="db">Db</label>'.html_select_array($this->db()->dbs,[
+ 'html' => 'class="dbs" id="db" name="db" onchange="document.location=\''.preg_replace('/\?.*$/','',$_SERVER['REQUEST_URI']).'?db=\'+this.value"',
+ 'selected' => $this->db()->name,
+ 'prettyText' => true,
+ 'sort' => 'natcasesort',
+ ]);
+ $r .= '</span>';
+ }
+
+ // Format
+ $r .= '<span class="label">';
+ #debug($this->db()->formats);
+ $r .= '<label for="format">Format</label>'.html_select_array($this->db()->formats,[
+ 'html' => 'class="format" name="format" id="format"',
+ 'selected' => $this->db()->format,
+ 'prettyText' => true,
# NB 26.12.16 'sort' => 'natcasesort',
- ]);
- $r .= '</span>';
-
- // Limit
- if (!empty($this->db()->limits) and count($this->db()->limits)>1) {
- $r .= '<span class="label">';
- $r .= '<label for="limit">Limit</label>'.html_select_array($this->db()->limits,[
- 'html' => 'class="limit" name="limit" id="limit"',
- 'selected' => $this->p('limit'),
- 'prettyText' => true,
- 'sort' => 'sort',
- 'default_value' => $this->db()->limits[0],
- ]);
- $r .= '</span>';
- }
-
- // Submit
- $r .= $buttons;
-
- // Order By
- /*
- $r .= '<span class="label">';
- $r .= '<label for="limit">OrderBy</label>'.html_select_array(array_keys($this->fields()),[
- 'html' => 'class="orderby" name="orderby" id="orderby"',
- 'selected' => $this->p('orderby'),
- 'prettyText' => true,
- ]);
- $r .= '</span>';
- */
-
- // Hiddens
- $form_hidden = ['db','table','format','limit','download'];
- if ($this->show_hidden_params) $r .= ''#.print_r(self::$params,true)
- .self::form_hidden($form_hidden)
- // Embed for no html format (rent)
- .'<input type="'.($this->p('debug') ? 'text' : 'hidden').'" name="download" value="0"/>';
- ;
-
- $r .= '</div>'; # < Options
-
- }
-
- //
- // Criterias
- //
- $r .= '<div class="criterias">';
- foreach ( $this->fields() as $k => $f) {
-
- if ($f->is_encrypt()) continue;
- $v = $this->p($k);
-
- $r .= ''
- .'<span class="label '.$k.'">'
- . '<label>'.prettyText($k).'</label>'
- . '<input type="text" id="'.$k.'" name="'.$this->field_preff.$k.'" value="'.$v.'" />'
- .'</span>'
- ;
-
- }
-
- if ($this->p('options')==='0') $r .= $buttons;
- $r .= '</div>'; # < Criterias
-
- ///
- // Bye
- ///
- $r .= '</form>'.NB_EOL;
- return $r;
- }
-
- public function __sleep() {
- return [
- 'name',
- 'sql',
- 'type',
- 'fields',
- 'extras',
- 'row_parse_pre',
- 'row_parse_post',
- 'count',
- 'engine',
- 'created',
- ];
- }
-
- public function serialize() {
- $this->fields();
- #$this->count();
- return serialize($this);
- }
-
- public function unserialize() {
- $o = unserialize($this->serialize());
- return var_export($o,true);
- }
-
- public function type() {
- if (isset($this->type)) return $this->type;
- return $this->type = $this->status('type');
- }
-
- public function unvar($value) {
- if (empty($value)) return $value;
- if (!is_scalar($value)) {
- foreach ($value as $k=>$v) {
- if (is_scalar($v)) $value[$k] = $this->unvar($v);
- }
- return $value;
- }
- $replace = [
- '<T.NAME>' => $this->name,
- '<T.TYPE>' => $this->type,
- ];
- return str_replace(array_keys($replace),array_values($replace),$value);
- }
-
- public function status($key=null) {
-
- if (!isset($this->status)) {
-
- if ($this->type == 'sql') {
-
- $this->status = [
- 'type' => $this->type,
- 'name' => $this->name,
- ];
-
- } else {
-
- $this->create_temporary();
- $sql = $this->db()->method('tables');
- if (!$this->p('count')) $sql .= " LIMIT 0";
- $sql = "SELECT * FROM ($sql) t WHERE name=".$this->db()->quote($this->name);
-
- $sth = $this->db()->conn->query($sql,PDO::FETCH_ASSOC);
- if (!empty($sth)) $this->status = $sth->fetch();
-
- } # if ($this->type == 'sql')
-
- if (empty($this->status)) $this->status = [];
-
- # Add to status array
- foreach ([
- 'name',
- 'type',
- ] as $k) {
- if (!empty($this->$k)) $this->status[$k] = $this->$k;
- }
-
- # Add from status array
- foreach ([
- 'engine',
- 'created',
- ] as $k) {
- if (empty($this->$k) and !empty($this->status[$k])) $this->$k = $this->status[$k];
- }
- }
-
- # Params
- foreach ([
- 'count',
- 'fields',
- 'sql',
- ] as $k) {
- if (isset($this->status[$k])) continue;
+ ]);
+ $r .= '</span>';
+
+ // Limit
+ if (!empty($this->db()->limits) and count($this->db()->limits)>1) {
+ $r .= '<span class="label">';
+ $r .= '<label for="limit">Limit</label>'.html_select_array($this->db()->limits,[
+ 'html' => 'class="limit" name="limit" id="limit"',
+ 'selected' => $this->p('limit'),
+ 'prettyText' => true,
+ 'sort' => 'sort',
+ 'default_value' => $this->db()->limits[0],
+ ]);
+ $r .= '</span>';
+ }
+
+ // Submit
+ $r .= $buttons;
+
+ // Order By
+ /*
+ $r .= '<span class="label">';
+ $r .= '<label for="limit">OrderBy</label>'.html_select_array(array_keys($this->fields()),[
+ 'html' => 'class="orderby" name="orderby" id="orderby"',
+ 'selected' => $this->p('orderby'),
+ 'prettyText' => true,
+ ]);
+ $r .= '</span>';
+ */
+
+ // Hiddens
+ $form_hidden = ['db','table','format','limit','download'];
+ if ($this->show_hidden_params) $r .= ''#.print_r(self::$params,true)
+ .self::form_hidden($form_hidden)
+ // Embed for no html format (rent)
+ .'<input type="'.($this->p('debug') ? 'text' : 'hidden').'" name="download" value="0"/>';
+ ;
+
+ $r .= '</div>'; # < Options
+
+ }
+
+ //
+ // Criterias
+ //
+ $r .= '<div class="criterias">';
+ foreach ( $this->fields() as $k => $f) {
+
+ if ($f->is_encrypt()) continue;
+ $v = $this->p($k);
+
+ $r .= ''
+ .'<span class="label '.$k.'">'
+ . '<label>'.prettyText($k).'</label>'
+ . '<input type="text" id="'.$k.'" name="'.$this->field_preff.$k.'" value="'.$v.'" />'
+ .'</span>'
+ ;
+
+ }
+
+ if ($this->p('options')==='0') $r .= $buttons;
+ $r .= '</div>'; # < Criterias
+
+ ///
+ // Bye
+ ///
+ $r .= '</form>'.NB_EOL;
+ return $r;
+ }
+
+ public function __sleep() {
+ return [
+ 'name',
+ 'sql',
+ 'type',
+ 'fields',
+ 'extras',
+ 'row_parse_pre',
+ 'row_parse_post',
+ 'count',
+ 'engine',
+ 'created',
+ ];
+ }
+
+ public function serialize() {
+ $this->fields();
+ #$this->count();
+ return serialize($this);
+ }
+
+ public function unserialize() {
+ $o = unserialize($this->serialize());
+ return var_export($o,true);
+ }
+
+ public function type() {
+ if (isset($this->type)) return $this->type;
+ return $this->type = $this->status('type');
+ }
+
+ public function unvar($value) {
+ if (empty($value)) return $value;
+ if (!is_scalar($value)) {
+ foreach ($value as $k=>$v) {
+ if (is_scalar($v)) $value[$k] = $this->unvar($v);
+ }
+ return $value;
+ }
+ $replace = [
+ '<T.NAME>' => $this->name,
+ '<T.TYPE>' => $this->type,
+ ];
+ return str_replace(array_keys($replace),array_values($replace),$value);
+ }
+
+ public function status($key=null) {
+
+ if (!isset($this->status)) {
+
+ if ($this->type == 'sql') {
+
+ $this->status = [
+ 'type' => $this->type,
+ 'name' => $this->name,
+ ];
+
+ } else {
+
+ $this->create_temporary();
+ $sql = $this->db()->method('tables');
+ if (!$this->p('count')) $sql .= " LIMIT 0";
+ $sql = "SELECT * FROM ($sql) t WHERE name=".$this->db()->quote($this->name);
+
+ $sth = $this->db()->conn->query($sql,PDO::FETCH_ASSOC);
+ if (!empty($sth)) $this->status = $sth->fetch();
+
+ } # if ($this->type == 'sql')
+
+ if (empty($this->status)) $this->status = [];
+
+ # Add to status array
+ foreach ([
+ 'name',
+ 'type',
+ ] as $k) {
+ if (!empty($this->$k)) $this->status[$k] = $this->$k;
+ }
+
+ # Add from status array
+ foreach ([
+ 'engine',
+ 'created',
+ ] as $k) {
+ if (empty($this->$k) and !empty($this->status[$k])) $this->$k = $this->status[$k];
+ }
+ }
+
+ # Params
+ foreach ([
+ 'count',
+ 'fields',
+ 'sql',
+ ] as $k) {
+ if (isset($this->status[$k])) continue;
# NB 08.08.17 if (!empty($this->status[$k])) continue;
- if (empty($key)) {
- if (!$this->p($k)) continue;
+ if (empty($key)) {
+ if (!$this->p($k)) continue;
- } elseif(is_array($key)) {
- if (!in_array($k,$key)) continue;
+ } elseif(is_array($key)) {
+ if (!in_array($k,$key)) continue;
- } else {
- if ($k!=$key) continue;
- }
+ } else {
+ if ($k!=$key) continue;
+ }
- $this->status[$k] = $this->$k();
- if (is_array($this->status[$k])) $this->status[$k] = count($this->status[$k]);
- }
+ $this->status[$k] = $this->$k();
+ if (is_array($this->status[$k])) $this->status[$k] = count($this->status[$k]);
+ }
- if (!empty($key) and is_scalar($key)) return ( empty($this->status[$key]) ? '' : $this->status[$key] );
- return $this->status;
- }
+ if (!empty($key) and is_scalar($key)) return ( empty($this->status[$key]) ? '' : $this->status[$key] );
+ return $this->status;
+ }
- private function idtemplate($id=null) {
- if (empty($id)
- and !( $id=$this->p('idtemplate') )
- and !( $id = $this->idtemplate )
- ) $this->bye('Wrong parameter!');
- return $id;
- }
+ private function idtemplate($id=null) {
+ if (empty($id)
+ and !( $id=$this->p('idtemplate') )
+ and !( $id = $this->idtemplate )
+ ) $this->bye('Wrong parameter!');
+ return $id;
+ }
- public function template($id=null) {
- $id = $this->idtemplate($id);
+ public function template($id=null) {
+ $id = $this->idtemplate($id);
- $id = preg_replace('/[^\w\._-]/','',$id);
+ $id = preg_replace('/[^\w\._-]/','',$id);
- $file = TABLE_TEMPLATE.'/'.$id.'.php';
- if (!is_readable($file)) return false; #$this->bye("Wrong id `$id`");
+ $file = TABLE_TEMPLATE.'/'.$id.'.php';
+ if (!is_readable($file)) return false; #$this->bye("Wrong id `$id`");
- $opt = [ 'format'=> '' ];
- $this->rows($opt);
+ $opt = [ 'format'=> '' ];
+ $this->rows($opt);
- $HEAD = &$opt['var']['head'];
- $ROWS = &$opt['var']['rows'];
- $ROW = &$opt['var']['rows'][0];
- foreach ($ROWS as $key=>$row) {
- $i=0;
- foreach ($row as $k=>$v) {
- $ROWS[$key][$i] = $v;
- $i++;
- }
- }
- #$opt['var']['rows']=[];
+ $HEAD = &$opt['var']['head'];
+ $ROWS = &$opt['var']['rows'];
+ $ROW = &$opt['var']['rows'][0];
+ foreach ($ROWS as $key=>$row) {
+ $i=0;
+ foreach ($row as $k=>$v) {
+ $ROWS[$key][$i] = $v;
+ $i++;
+ }
+ }
+ #$opt['var']['rows']=[];
- # Protect $_REQUEST !
- $_REQUEST_BAK = $_REQUEST;
- $_REQUEST = array_merge($_REQUEST,$ROW);
+ # Protect $_REQUEST !
+ $_REQUEST_BAK = $_REQUEST;
+ $_REQUEST = array_merge($_REQUEST,$ROW);
- $ex = require $file;
+ $ex = require $file;
- $_REQUEST = $_REQUEST_BAK;
+ $_REQUEST = $_REQUEST_BAK;
- #return $ex;
- }
+ #return $ex;
+ }
- public function ssha_password($password) {
- return $this->db()->ssha_password($password);
- }
+ public function ssha_password($password) {
+ return $this->db()->ssha_password($password);
+ }
- static public function _bye($msg = '__bye__', $backtrace_deep = 0) {
- die($msg);
- }
+ static public function _bye($msg = '__bye__', $backtrace_deep = 0) {
+ die($msg);
+ }
} # < Class
-__table_define();
?>