From a3f75da134717d7ccdd04d3f971521d82b635d31 Mon Sep 17 00:00:00 2001 From: Nicolas Boisselier Date: Sun, 27 Mar 2016 04:32:39 +0100 Subject: [PATCH] Bed --- lib/php/db.php | 109 +++++++++++++++++++++------- lib/php/db/index.php | 5 +- lib/php/db/table.php | 164 +++++++++++++++++++----------------------- lib/php/functions.php | 1 + lib/php/nb.php | 10 +-- lib/php/out.php | 104 ++++++++++++++++++++++----- lib/php/page.php | 30 ++++++-- 7 files changed, 282 insertions(+), 141 deletions(-) diff --git a/lib/php/db.php b/lib/php/db.php index 04b491e1..914f41ed 100644 --- a/lib/php/db.php +++ b/lib/php/db.php @@ -33,6 +33,67 @@ $DB_TYPES = array( , 'sqlite' => "SELECT name,type FROM sqlite_master WHERE type IN('table','view') AND name NOT LIKE 'sqlite_%' ORDER BY name", ), + 'table.fields' => array( + 'pgsql' => "SELECT +a.attname AS name, +pg_catalog.format_type(a.atttypid, a.atttypmod) AS type, +CASE a.attnotnull WHEN 't' then 1 ELSE 0 END AS notnull, +(SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) AS pg_default, +(SELECT 1 FROM pg_index i WHERE a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) AND i.indrelid = ''::regclass AND i.indisprimary) as pk +FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname='' AND pg_catalog.pg_table_is_visible(c.oid) ) AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum", + 'mysql' => "SHOW COLUMNS FROM ``", + 'sqlite' => "PRAGMA table_info('')", + ), + 'table.sql' => array( + 'pgsql' => " +SELECT + 'CREATE TABLE '||sql.table||'(' + ||array_to_string(array_agg(sql),', ') + ||')' as sql +FROM ( + ( + SELECT -- FIELDS + c.oid AS id + ,c.relname as table + ,9 as prio + ,'' + || f.attname + || ' ' || pg_catalog.format_type(f.atttypid,f.atttypmod) + ||CASE WHEN f.attnotnull THEN ' NOT NULL' ELSE '' END + ||CASE WHEN f.atthasdef = 't' AND d.adsrc !=''THEN ' DEFAULT '||d.adsrc ELSE '' END + AS sql + FROM pg_attribute f + JOIN pg_class c ON c.oid = f.attrelid + LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum + WHERE c.relkind = 'r'::char + AND f.attnum > 0 + ORDER BY f.attnum + ) UNION ( + SELECT -- CONSTRAINTS + c.oid as id + ,c.relname as table + ,0 as prio + ,CASE + WHEN p.contype = 'p' THEN 'PRIMARY KEY' + WHEN p.contype = 'u' THEN 'UNIQ' + ELSE '' END + ||'('||array_to_string(array_agg(f.attname),', ')||')' AS sql + FROM pg_attribute f + JOIN pg_class c ON c.oid = f.attrelid + LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) + WHERE c.relkind = 'r'::char + AND f.attnum > 0 + AND p.contype IN ('u','p') + GROUP BY c.oid,p.contype,f.attrelid,c.relname + ORDER BY c.oid,f.attrelid + ) +ORDER BY prio DESC) sql +WHERE sql.table='' +GROUP BY sql.id,sql.table +", + 'mysql' => "SHOW CREATE TABLE ``", + 'sqlite' => "SELECT sql FROM sqlite_master WHERE name=''", + ), ); #die($DB_TYPES['tables']['mysql']); @@ -284,10 +345,9 @@ class Db extends nb { } public function config() { - #bye($this->types('config')); - if (!($config = $this->types('config'))) - self::bye("db.config(): Unknow db type: ".$this->type." from ".print_r($GLOBALS['DB_TYPES'],1)) - ; + + $config = $this->type('config',true); + $config[1] = str_replace('',$this->name,$config[1]); if (!file_exists($config[0])) return array(); @@ -305,7 +365,7 @@ class Db extends nb { return $return; } - public function types($key=false,$die=false) { + public function type($key=false,$die=false) { #if (!isset($DB_TYPES[$key][$this->type])) return; global $DB_TYPES; @@ -326,12 +386,12 @@ class Db extends nb { !isset($DB_TYPES[$key]) or !isset($DB_TYPES[$key][$this->type]) or empty($DB_TYPES[$key][$this->type]) - ) - # ??? not working ??? - #self::bye("db.types(): Unknow key `$key` for type `".$this->type."`".print_r($DB_TYPES,1)); - #if ($die) self::bye("db.types(): Unknow key `$key` for type `".$this->type."`"); + ) { + #self::bye("db.type(): Unknow key `$key` for type `".$this->type."`".print_r($DB_TYPES,1)); + #nb::msg(">>>".$DB_TYPES[$key][$this->type]); + if ($die) self::bye("db.type(): Unknow key `$key` for type `".$this->type."`"); return; - ; + } return $DB_TYPES[$key][$this->type]; } @@ -340,9 +400,7 @@ class Db extends nb { if (isset($this->_tables) and $this->_tables) return ($return_hash ? $this->tables : $this->_tables); if (!isset($this->_tables)) $this->_tables = array(); - if (!($sql = $this->types('tables'))) - self::bye("db.types(): Unknow db type: ".$this->type." from ".print_r($GLOBALS['DB_TYPES'],1)) - ; + $sql = $this->type('tables',true); $rows = $this->conn->query($sql,PDO::FETCH_ASSOC); foreach ($rows as $row) { @@ -487,8 +545,6 @@ EOF; public function out2($rows,$head=array()) { #if (is_scalar($head)) bye(var_dump($head,true)); - if ($this->p('header') === '0' ) $head = false; - elseif (is_scalar($head)) $head = array($head); # NB 09.03.16 elseif (count($rows)) { # NB 09.03.16 $first = self::ar_first($row); # NB 09.03.16 #if (self::is_hash($first)) @@ -555,17 +611,15 @@ EOF; echo $this->html_menu(); $return = true; - } elseif (preg_match('/db\.(\w+)/',$action,$m)) { + } elseif (preg_match('/^db\.(\w+)/',$action,$m)) { $meth = $m[1]; $rows = $this->$meth(); - #$return = $this->out2($rows); - if ($rows) $return = - out::rows($this->p('format',out::php_cli() ? 'csv' : 'csv'),$rows) - ; + if ($rows) $return = $this->out2($rows,self::is_hash($rows) ? true : array($meth)); $return = true; } elseif($table) { if ($r=$table->action($action)) $return = $r; + #if (!is_scalar($return)) $return = $this->out2($return); } } @@ -689,15 +743,22 @@ EOF; } - public function dump() { + public function sql() { $this->pset('orderby',null); + $r = array(); foreach ($this->tables() as $t) { $t = $this->table($t); #$this->pset('format','sql'); - echo preg_replace('/\s+/',' ',$t->sql()).";\n"; - $t->rows(); + #$r[] = preg_replace('/\s+/',' ',$t->sql()).";"; + #if (0) + #$r[] = preg_replace('/ +/',' ',$t->sql()).";"; + $r[] = preg_replace('/\s+/',' ', + # Filter comment to generate one sql per line + join(' ',preg_grep('/^ *--/',explode("\n",$t->sql()),true)) + ).";"; + #$t->rows(); } - return array(); + return $r; } } # < Class diff --git a/lib/php/db/index.php b/lib/php/db/index.php index ee8c0c07..3a38e9d6 100755 --- a/lib/php/db/index.php +++ b/lib/php/db/index.php @@ -9,13 +9,16 @@ require_once(dirname(__FILE__).'/../config.php'); require_once(dirname(__FILE__).'/../db.php'); -if($format = out::client_type()) Db::pdef('format',$format); +#bye(out::client_type()); +Db::pdef('format',out::client_type()); +#if($format = out::client_type()) Db::pset('format',$format); # Param - Extract dbname from table if (preg_match('/^(\w+)\.(.*?)$/',Db::p('table'),$m)) { Db::pset('db',$m[1]); Db::pset('table',$m[2]); } +#$conf = Db::conf_dbs(array( Db::$root_dir.'/etc/dbs.yaml','/etc/dbs.yaml' )); Db::init($conf); Db::init(array( Db::$root_dir.'/etc/dbs.yaml','/etc/dbs.yaml' )); if( defined('DB_JUST_INIT')) return true; diff --git a/lib/php/db/table.php b/lib/php/db/table.php index 04b9c288..33d359c3 100644 --- a/lib/php/db/table.php +++ b/lib/php/db/table.php @@ -23,7 +23,7 @@ if (!defined('DB_HTML_EDIT')) define('DB_HTML_EDIT','Edit'); if (!defined('DB_HTML_DELETE')) define('DB_HTML_DELETE','Delete'); if (!defined('DB_TABLE_QUERY_NAME')) define('DB_TABLE_QUERY_NAME','_query_'); -class Table extends nb { +Class Table extends nb { public $name; public $db; @@ -41,14 +41,19 @@ class Table extends nb { function __construct($name,$opt=array()) { + if (!is_scalar($name)) { + $opt = $name; + $name = null; + } + foreach ($opt as $k => $v) { $this->$k = $v; } #unset($opt['db']); bye($opt); // Connection if (isset($opt['db'])) { - $this->db = $opt['db']; + $this->db = is_object($opt['db']) ? $opt['db'] : new Db($opt['db']); } else { - $this->db = new db(); + $this->db = new Db(); } // Name, could be a select @@ -102,62 +107,10 @@ class Table extends nb { return $this->sql; } - if ($this->db->type == 'sqlite') { - $sql = "SELECT sql FROM sqlite_master WHERE name='$this->name'"; - } elseif ($this->db->type == 'mysql') { - $sql = "SHOW CREATE TABLE `$this->name`"; - } elseif ($this->db->type == 'pgsql') { - $sql = "SELECT show_create_table('$this->name')"; - $sql = " -SELECT - 'CREATE TABLE '||sql.table||'(' - ||array_to_string(array_agg(sql),', ') - ||')' as sql -FROM ( - ( - SELECT -- FIELDS - c.oid AS id - ,c.relname as table - ,9 as prio - ,'' - || f.attname - || ' ' || pg_catalog.format_type(f.atttypid,f.atttypmod) - ||CASE WHEN f.attnotnull THEN ' NOT NULL' ELSE '' END - ||CASE WHEN f.atthasdef = 't' AND d.adsrc !=''THEN ' DEFAULT '||d.adsrc ELSE '' END - AS sql - FROM pg_attribute f - JOIN pg_class c ON c.oid = f.attrelid - LEFT JOIN pg_attrdef d ON d.adrelid = c.oid AND d.adnum = f.attnum - WHERE c.relkind = 'r'::char - AND f.attnum > 0 - ORDER BY f.attnum - ) UNION ( - SELECT -- CONSTRAINTS - c.oid as id - ,c.relname as table - ,0 as prio - ,CASE - WHEN p.contype = 'p' THEN 'PRIMARY KEY' - WHEN p.contype = 'u' THEN 'UNIQ' - ELSE '' END - ||'('||array_to_string(array_agg(f.attname),', ')||')' AS sql - FROM pg_attribute f - JOIN pg_class c ON c.oid = f.attrelid - LEFT JOIN pg_constraint p ON p.conrelid = c.oid AND f.attnum = ANY (p.conkey) - WHERE c.relkind = 'r'::char - AND f.attnum > 0 - AND p.contype IN ('u','p') - GROUP BY c.oid,p.contype,f.attrelid,c.relname - ORDER BY c.oid,f.attrelid - ) -ORDER BY prio DESC) sql -WHERE sql.table='$this->name' -GROUP BY sql.id,sql.table -"; - } else { - err('table.sql(): Unknow db type: '.$this->db->type); - } + $sql = str_replace('',$this->name,$this->db->type('table.sql',true)); $this->sql = $this->db->row($sql); + $this->sql = preg_replace("/^\w+\s+(CREATE)/i",'$1',$this->sql); # for mysql + #$this->sql = trim($this->sql); #bye($this->sql); return $this->sql; } @@ -174,28 +127,7 @@ GROUP BY sql.id,sql.table if ($this->fields === null) { $this->fields = array(); - - if ($this->db->type == 'sqlite') { - $sql = "PRAGMA table_info('$this->name')"; - - } elseif ($this->db->type == 'pgsql') { - $sql = "SELECT -a.attname AS name, -pg_catalog.format_type(a.atttypid, a.atttypmod) AS type, -CASE a.attnotnull WHEN 't' then 1 ELSE 0 END AS notnull, -(SELECT substring(pg_catalog.pg_get_expr(d.adbin, d.adrelid) for 128) FROM pg_catalog.pg_attrdef d WHERE d.adrelid = a.attrelid AND d.adnum = a.attnum AND a.atthasdef) AS pg_default, -(SELECT 1 FROM pg_index i WHERE a.attrelid = i.indrelid AND a.attnum = ANY(i.indkey) AND i.indrelid = '$this->name'::regclass AND i.indisprimary) as pk -FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog.pg_class c LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace WHERE c.relname='$this->name' AND pg_catalog.pg_table_is_visible(c.oid) ) AND a.attnum > 0 AND NOT a.attisdropped ORDER BY a.attnum"; - - } elseif ($this->db->type == 'mysql') { - $sql = "SHOW COLUMNS FROM `$this->name`"; - - } else { - err('table.fields(): Unknow db type: '.$this->db->type); - return array(); - - } - + $sql = str_replace('',$this->name,$this->db->type('table.fields',true)); $rows = $this->db->conn->query($sql); $rows->setFetchMode(PDO::FETCH_ASSOC); @@ -233,7 +165,7 @@ FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog. if (isset($row['extra']) and $row['extra'] == 'auto_increment') { $field['autoincrement'] = true; - # sqlite autoincrement + # sqlite autoincrement only in sql } elseif ($this->db->type == 'sqlite' and preg_match('/[\(,]'.$row['name'].' [^\),]+ AUTOINCREMENT/',$this->sql()) ) { @@ -668,7 +600,7 @@ FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog. if ($opt['is_html']) echo $this->html_nav_top(); if ($out_conf) { - out::begin($out_conf,$this->fields(),array($row)); + out::head($out_conf,$this->fields(),array($row)); } else { echo $this->{"rows_begin_$format"}($this->fields()); @@ -1127,13 +1059,14 @@ FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog. $this->db->print_header($this->p('format')); $this->rows(); return true; -# NB 06.03.16 } elseif ($action == 'table') { -# NB 06.03.16 return $this->out(array( -# NB 06.03.16 #"count" => $this->count(), -# NB 06.03.16 "sql_name" => $this->sql_name(), -# NB 06.03.16 "sql" => $this->sql(), -# NB 06.03.16 "fields" => $this->object2array($this->fields()), -# NB 06.03.16 ),true); + } elseif ($action == 'table') { + return $this->out2(array( + #"count" => $this->count(), + #"sql_name" => $this->sql_name(), + "name" => $this->name, + "sql" => $this->sql(), + #"fields" => $this->object2array($this->fields()), + )); } elseif ($action == 'table.delete' or $action == 'delete') { if (!$this->delete($this->p(),$e)) bye($e); @@ -1163,6 +1096,12 @@ FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog. $this->out2($out); return $r; + } elseif (preg_match('/^table\.(\w+)/',$action,$m)) { + $meth = $m[1]; + $rows = $this->$meth(); + if ($rows) $return = $this->out2($rows,self::is_hash($rows) ? true : array($meth)); + return true; + } elseif ($this->p('format') and !preg_match('/^(table|div)$/',$this->p('format'))) { $this->rows(array( 'format' => $this->p('format'))); @@ -1318,6 +1257,51 @@ FROM pg_catalog.pg_attribute a WHERE a.attrelid = (SELECT c.oid FROM pg_catalog. return $r; } + public function unserialize() { + $o = unserialize($this->serialize()); + if (empty($o->db)) { + global $Db; $o->db = $Db; + } + #var_export($o->db); + return($o->sql_name()); + debug($o->sql_name()); + return var_export($o,true); + } + + public function __sleep() { + if (1) return array( + 'name', + 'sql', + 'type', + 'fields', + 'fields_keys', + 'replace', + 'extras', + 'params', + 'order_by', + ); + + $vars = array(); + #foreach (get_class_vars(get_class($this)) as $k=>$v) { if ($k=!'db') $vars[]=$k; }; + foreach (get_class_vars(get_class($this)) as $k=>$v) { if ($k=!'db') $vars[]=$k; }; + #foreach (get_class_vars(__CLASS__) as $k=>$v) { if ($k=!'db') $vars[]=$k; }; + debug($vars); + #$vars = get_object_vars($this); + return $vars; + } + + public function serialize() { + #$o = new self(null,$this); + $clone = clone($this); + #foreach (get_object_vars($clone) as $k=>$v) { if (is_object($v)) unset($clone->$k); }; + #var_export($clone->db); + #unset($clone->db); + #$clone->db = array(); + #foreach (get_object_vars($this->db) as $k=>$v) { if (!is_object($v)) $clone->db[$k] = $v; }; + #debug($clone->db); + #foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); }; + return serialize($clone); + } -} +} # < Class ?> diff --git a/lib/php/functions.php b/lib/php/functions.php index bf13f2c4..a3e92f6b 100644 --- a/lib/php/functions.php +++ b/lib/php/functions.php @@ -99,6 +99,7 @@ function bye($msg='__bye__',$backtrace_deep=0) { if ($msg!=='__bye__') err($msg,'bye',( $backtrace_deep !== false ? (1+$backtrace_deep) : $backtrace_deep )); #if ($msg) err($msg,'bye',1+$backtrace_deep); exit; + #die("Can't exit from BYE!!!"); } function warn ($msg) { diff --git a/lib/php/nb.php b/lib/php/nb.php index 421ea072..fa36bb24 100644 --- a/lib/php/nb.php +++ b/lib/php/nb.php @@ -33,10 +33,12 @@ class nb { function __destruct() { #foreach (get_object_vars($this) as $k=>$v) { echo ("$k: $v\n"); } #if (is_object($this)) - try { - foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); }; - } catch(Exception $e) { - } + foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); }; + #foreach (get_class_vars($this) as $k=>$v) { unset($this->$k); }; +# NB 27.03.16 try { +# NB 27.03.16 foreach (get_object_vars($this) as $k=>$v) { unset($this->$k); }; +# NB 27.03.16 } catch(Exception $e) { +# NB 27.03.16 } } /* diff --git a/lib/php/out.php b/lib/php/out.php index 1b6844c5..d6ee7e1d 100644 --- a/lib/php/out.php +++ b/lib/php/out.php @@ -6,9 +6,12 @@ require_once('nb.php'); # NB 07.03.16 define('OUT_BRACE2','}'); # NB 07.03.16 define('OUT_COMA',','.NB_EOL); -class Out extends Nb { +Class Out extends Nb { - public static $types; public static function types() { + public static $charset = 'utf-8'; + public static $types; + public static $type; + public static function init() { self::$types = array( 'sql' => array( ), @@ -61,20 +64,43 @@ class Out extends Nb { 'rec' => ',', ), ); + self::$type = self::client_type(); } public function __construct($type,&$data,$head=array()) { if (!empty($type) and !empty($data)) return $this->rows($type,$data,$head); } - public static function begin($o,$head,$data=array()) { + public static function scalar($v) { + if (is_scalar($v)) return $v; + #if (is_array($v) and !self::is_hash($v)) return join(', ',$v); + #return var_export($v,true); + return trim(preg_replace(array( + '/^\s*\'(.*?)\' => \'?(.*?)\'?,$/m', # hash + '/^\s*(array \(|\),?)$/m', # sub array + '/ *\'(.*?)\' =>\s*$\r?\n/m', # sub hash + '/\s*\d+ => \'(.*?)\'(,)?\r?\n/m', # aray + '/$(\r?\n)+$/m', # blank lines + '/,\s*$/m', # last , + ),array( + '$1=$2', + '', + '$1=', + '$1$2 ', + '', + '', + ),var_export($v,true))); + return var_export($v,true); + return is_scalar($v) ? $v : json_encode($v); + } + + public static function head($o,$head,$data=array()) { #if (self::p('header')==="0") return; if (isset($o['enclose'])) echo $o['enclose'][0]; if (!isset($o['head'])) return; #var_dump($head); return; - if ($head === false) return; - if (empty($head)) { + if (empty($head) and $head!== false) { if (self::is_hash($data[0])) { $head = array_keys($data[0]); } else { @@ -82,6 +108,8 @@ class Out extends Nb { } } + if (self::p('header') === '0' ) return; + if ($head === false) return; echo $o['head']($head,$o) . empty($o['eol']) ? '' : $o['eol']; } @@ -112,14 +140,16 @@ class Out extends Nb { public static function rows_get($type,$data,$head=array()) { ob_start(); self::rows($type,$data,$head); + $contents = ob_get_contents(); + ob_end_clean(); + return $contents; return ob_get_flush(); } public static function rows($type,&$data,$head=array()) { # Ex: for action=tables when header=0 + if (is_scalar($data)) $data = array(array($data)); - #bye($data); - #if (empty($head)) $head = array_fill(0,count($data[0]),'?'); if (!isset(self::$types[$type])) self::bye("Unknow type: `$type`"); $conf = self::$types[$type]; @@ -130,13 +160,13 @@ class Out extends Nb { if (self::is_hash($data)) $data = array($data); if (is_scalar($data)) $data = array($data); - if (is_scalar($head) and !is_bool($head)) $head = array($head); - $tot = count($data); $count = 0; # Function head - self::begin($conf,$head,$data); + #elseif (is_scalar($head)) $head = array($head); + if (is_scalar($head) and !is_bool($head)) $head = array($head); + self::head($conf,$head,$data); foreach ($data as $row) { if ($count>0) out::concat($conf); @@ -173,13 +203,51 @@ class Out extends Nb { public static function client_type() { foreach (array_keys(self::$types) as $t) { if (preg_match("@^\w+/$t@",self::client_header('Accept'))) return $t; - #if (preg_match("@^\w+/$t@",self::client_header('Accept'),$m)) bye( $m ); - #if (self::client_header('Accept',$t)) return $t; } return; } -} Out::types() ; # < Class + public static function escape($v,$type=null) { + static $replace_flags = null; + + $is_scalar = is_scalar($v); + $v = out::scalar($v); + + if ($replace_flags === null) { + + #$replace_flags = ENT_COMPAT | ENT_DISALLOWED; + $replace_flags = ENT_COMPAT; + + if ($type === null) $type = self::$type; + if (!$type) { + return $v; + + } elseif ($type=='xhtml' or ( + !empty(self::$types[$type]['is_html']) + and !empty(self::$types[$type]['is_xml']) + )) { + $replace_flags = $replace_flags | ENT_XHTML; + + } elseif ($type=='xml' or !empty(self::$types[$type]['is_xml'])) { + $replace_flags = $replace_flags | ENT_XML1; + + } elseif ($type=='html' or !empty(self::$types[$type]['is_html'])) { + $replace_flags = $replace_flags | ENT_HTML5; + + } else { # text + return $v; + return preg_replace('/\n/','',$v); + + } + + } + + $v = htmlspecialchars($v,$replace_flags,strtoupper(self::$charset)); + if (!$is_scalar) $v = '
'.NB_EOL.$v.NB_EOL.'
'; + return $v; + } + +} Out::init() ; # < Class /****************************************************************************/ function out_yaml(&$row,$o) { @@ -195,12 +263,13 @@ function out_yaml(&$row,$o) { } function out_csv(&$row,$o) { + $values = array(); foreach (array_values($row) as $k=>$v) { #if (!is_scalar($v)) $v = join('',$v); - if (!is_scalar($v)) $v = json_encode($v); - $values[] = $v; + $values[] = preg_replace('/zAZA/','',out::scalar($v)); + #$values[] = preg_replace('/\r?\n/','',out::scalar($v)); } #echo join($o['sep'],array_values($row)); @@ -249,12 +318,13 @@ function out_tag(&$row,&$o) { # Tag = o[tag] or key if (isset($o['tag'])) { - $class = ' class="'.$k.'"'; + $class = is_numeric($k) ? '' : ' class="'.$k.'"'; $k = $o['tag']; } else { $class = ''; } + $v = out::escape($v); echo '' .(NB_EOL ? ' ' : '') ."<$k$class>$v" @@ -268,7 +338,7 @@ function out_tag(&$row,&$o) { function out_xml(&$row,$o) { echo (NB_EOL ? ' ' : '')."".NB_EOL; foreach ($row as $k => $v) { - echo (NB_EOL ? ' ' : '')."<$k>".NB_EOL; + echo (NB_EOL ? ' ' : '')."<$k>".NB_EOL; } echo (NB_EOL ? ' ' : '')."".NB_EOL; } diff --git a/lib/php/page.php b/lib/php/page.php index 0df3e42d..28ee2157 100644 --- a/lib/php/page.php +++ b/lib/php/page.php @@ -166,7 +166,7 @@ class Page extends nb { } if ($content===null) { - $this->end_tag($tag); + $this->tag_end($tag); return '<' . $tag . ($attrs ? " $attrs" : "") . '>'; } @@ -250,12 +250,12 @@ class Page extends nb { } - function end_tag($tag=null) { + function tag_end($tag=null) { static $tags = array(); if ($tag !== null) return array_unshift($tags,$tag); foreach ($tags as $t) echo "".NB_EOL; $tags = array(); - return false; + return $tags; return join('',self::ar_map('',$tags)); if ($tag === null) return $tags; array_unshift($tags,$tag); @@ -264,8 +264,8 @@ class Page extends nb { function end() { if (preg_match('/ml$/',$this->content_type)) { - #foreach ($this->end_tag() as $t) echo "".NB_EOL; - $this->end_tag(); + #foreach ($this->tag_end() as $t) echo "".NB_EOL; + $this->tag_end(); echo '' . NB_EOL; echo '' . NB_EOL; } @@ -444,6 +444,26 @@ class Page extends nb { $Page->h1 = join(' / ',$nav); $Page->title = join(' / ',$title); + + return $Page; + } + + public function action() { + $action = self::p('action'); + $format = self::p('format',self::php_cli() ? 'csv' : 'table'); + + if ($action == 'page.info') { + $out = array('path' => $this->path()); + foreach (get_object_vars($this) as $k=>$v) { if (!empty($this->$k)) $out[$k] = $this->$k; } + $out['p'] = self::p(); + $out['_SERVER'] = $_SERVER; + + $out = array_map(function($k, $v) { return array("name"=>$k,"value"=>$v); },array_keys($out),$out); + out::rows($format,$out); + return true; + } + + return false; } public static function html_embed($iframe,$mime='text/html') { -- 2.47.3