diff --git a/heaven.php b/heaven.php index dc776d3..b0dbdc0 100644 --- a/heaven.php +++ b/heaven.php @@ -7,8 +7,6 @@ ////////////////////////////////////////////////////////////////////////// class HEAVEN extends SKY { - private $referer = []; - public $jump = false; public $methods = ['POST', 'GET', 'PUT', 'PATCH', 'DELETE', 'OPTIONS', 'HEAD', 'TRACE', 'CONNECT']; public $method = false; @@ -19,12 +17,13 @@ class HEAVEN extends SKY public $admins = 1; # root only has admin access or list pids in array public $lg = false; # no languages initialy public $has_public = true; # web-site or CRM - public $adm_able = false; + public $page_p = 'p'; + public $adm_able = false; public $ajax = 0; public $surl = []; function __get($name) { - if (2 == strlen($name) && '_' == $name[0] && is_num($name[1])) { + if ('_' == $name[0] && 2 == strlen($name) && is_num($name[1])) { $v = (int)$name[1]; if ('' === URI) return $v ? '' : 'main'; @@ -58,9 +57,11 @@ private function extra_file($sn) { function load() { header('Content-Type: text/html; charset=' . ENC); + defined('DESIGN') or define('DESIGN', false); + define('DIR_V', DESIGN ? WWW . 'view' : 'view');///////// $this->method = array_search($_SERVER['REQUEST_METHOD'], $this->methods); if (false === $this->method) - throw new Err('Unknown method'); + throw new Err('Unknown request method'); define('PATH', preg_replace("|[^/]*$|", '', $_SERVER['SCRIPT_NAME'])); define('URI', (string)substr($_SERVER['REQUEST_URI'], strlen(PATH))); # (string) required! @@ -79,11 +80,12 @@ function load() { define('PROTO', @$_SERVER['HTTPS'] ? 'https' : 'http'); define('DOMAIN', $this->sname[3]); - $hook = parent::load(); # database connection start from here + parent::load(); # database connection start from here $this->ajax = isset($_SERVER['HTTP_X_REQUESTED_WITH']) && 'xmlhttprequest' == strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) ? 2 : 0; + //2do: fetch $this->is_front = true; - $this->origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : false; + $this->origin = $_SERVER['HTTP_ORIGIN'] ?? false; $this->orientation = 0; if (isset($_SERVER['HTTP_X_ORIENTATION'])) { in_array($wo = (int)$_SERVER['HTTP_X_ORIENTATION'], [0, 1, 2]) or $wo = 0; @@ -94,20 +96,20 @@ function load() { $this->s_statp = preg_match("/^\d{4}$/", $s) ? $s . 'p' : '1000p'; } - $referer = @$_SERVER['HTTP_REFERER']; + $referer = $_SERVER['HTTP_REFERER'] ?? ''; $this->re = "~^https?://$re" . preg_quote(DOMAIN . PATH); $this->lref = preg_match("$this->re(.*)$~", $referer, $m) ? $m[3] : false; $this->eref = !$m ? $referer : false; - $ajax_adm = false; + // $ajax_adm = false; if ('' !== URI) { # not main page $this->surl = explode('/', explode('?', URI)[0]); - $hook->h_rewrite($cnt_s = count($this->surl)); + common_c::rewrite_h($cnt_s = count($this->surl)); if (1 == $cnt_s && '' === $this->surl[0]) { $this->surl = []; - if ('AJAX' == key($_GET) && $this->ajax) { + if ($this->ajax && 'AJAX' == key($_GET)) { $this->ajax = 1; # j_ template - $ajax_adm = 'adm' == $_GET['AJAX']; + $this->ajaxv = $_GET['AJAX']; // 'adm' array_shift($_GET); } } @@ -116,63 +118,25 @@ function load() { if ($this->debug) $this->gpc = Debug::gpc(); - global $user; - $user = new USER; - $hook->h_load(); - if (12 == $this->error_no && !$this->ajax && '' !== URI) // 2do:check for api calls - jump(); - if ($this->error_no && '_exception' != URI) - throw new Exception(11); - - $adm = $this->admins && $user->allow($this->admins) ? Admin::access($ajax_adm) : false; - $type = in_array($this->_1, ['list', 'edit', 'new']); - $fn = ($this->style ? "$this->style/" : '') . ($this->is_mobile ? 'mobile' : 'desktop'); - $tz = !$user->vid || '' === $user->v_tz ? "''" : (float)('' === $user->u_tz ? $user->v_tz : $user->u_tz); + //if (12 == $this->error_no && !$this->ajax && '' !== URI) // 2do:check for api calls + // jump(); + //if ($this->error_no && '_exception' != URI) + // throw new Exception(11); SKY::$vars = [ - 'k_tkd' => [$this->s_title, $this->s_keywords, $this->s_description], - 'k_type' => $type = $type ? $this->_1 : ($this->_1 && 'p' != $this->_1 ? 'show' : 'list'), - 'k_list' => 'list' == $type, - 'k_static' => [[], ["~/$fn.js"], ["~/$fn.css"]], # default app meta_tags, js, css files - 'k_js' => "sky.tz=$tz; sky.is_debug=$this->debug; var addr='" . LINK . "';", + 'k_list' => 'list' == $this->_1 || in_array($this->page_p, [$this->_1, $this->_2, $this->_3]), + + // 'k_js' => "sky.is_debug=$this->debug; var addr='" . LINK . "';", ]; if (1 == $this->extra) is_file($fn = 'var/extra.txt') && in_array($this->fn_extra, array_map('trim', file($fn))) or $this->extra = 2; - - return $adm; - } - - function log($mode, $data) { - if (!in_array($this->s_test_mode, [$mode, 'all'])) - return; - sqlf('update $_memory set dt=' . SKY::$dd('dt') . ', tmemo=substr(' . SKY::$dd->f_cc('%s', 'tmemo') . ',1,15000) where id=10', date(DATE_DT) . " $mode $data\n"); } - function qs($url) { - return preg_match("$this->re(.*)$~", $url, $m) ? $m[3] : false; - } - - function flag($flag = 0, $val = null, $char = 'v') { - $storage =& SKY::$mem[$char][2]['flags']; - if ($val == null) - return $flag ? $storage & $flag : $storage; - SKY::$char(null, ['flags' => $val ? $flag | $storage : ~$flag & $storage]); + function adm() { + return $this->admins && $user->allow($this->admins) ? Admin::access($ajax_adm) : false; } - function csrf($skip = []) { - if (INPUT_POST != $this->method || in_array($this->_0, $skip) || $this->error_no) - return false; - $csrf = 1; - if (isset($_POST['_csrf'])) { - $csrf = $_POST['_csrf']; - unset($_POST['_csrf']); - } elseif (isset($_SERVER['HTTP_X_CSRF_TOKEN'])) { - $csrf = $_SERVER['HTTP_X_CSRF_TOKEN']; - } - return $csrf; - } - - function h_load() { # default processing + function h_load() { # default processing ////////////////// global $user; if ($this->is_mobile = $this->sname[2]) { @@ -184,6 +148,9 @@ function h_load() { # default processing define('LG', !$this->sname[1] ? ($user->id && $user->u_lang ? $user->u_lang : $user->v_lg) : substr(SNAME, 0, 2)); if (LG != $user->v_lg && !$this->sname[2]) $user->v_lg = LG; + require 'main/lng/' . LG . '.php'; + SKY::$reg['trans_late'] = $lgt ?? []; + SKY::$reg['trans_coll'] = []; } $link = PROTO . '://' . (DEFAULT_LG ? LG . '.' : '') . ($this->is_mobile ? 'm.' : '') . DOMAIN; define('LINK', $link . PATH); @@ -197,13 +164,30 @@ function h_load() { # default processing } } - function h_rewrite($cnt) { + function h_rewrite($cnt) {/////////////////////////// if (1 == $cnt && 'robots.txt' == $this->surl[0] && !$_GET) { $this->surl = ['']; $_GET = ['_etc' => 'robots.txt']; } } + function log($mode, $data) { + if (!in_array($this->s_test_mode, [$mode, 'all'])) + return; + sqlf('update $_memory set dt=' . SKY::$dd('dt') . ', tmemo=substr(' . SKY::$dd->f_cc('%s', 'tmemo') . ',1,15000) where id=10', date(DATE_DT) . " $mode $data\n"); + } + + function qs($url) { + return preg_match("$this->re(.*)$~", $url, $m) ? $m[3] : false; + } + + function flag($flag = 0, $val = null, $char = 'v') { + $storage =& SKY::$mem[$char][2]['flags']; + if ($val == null) + return $flag ? $storage & $flag : $storage; + SKY::$char(null, ['flags' => $val ? $flag | $storage : ~$flag & $storage]); + } + function tail_x($plus = '', $stdout = '') { if ($plus) # if not tailed correctly trace($this->except ? $this->except['title'] : 'Unexpected Exit', true, 3); @@ -341,8 +325,8 @@ function tracing($plus = '', $trace_x = false) { function shutdown() { chdir(DIR); # restore dir! - $dd = SQL::$dd = SKY::$dd; # main database driver - if (!$this->tailed) { + $dd = SQL::$dd = SKY::$dd; # set main database driver if SKY loaded + if (!$this->tailed) { # possible result of `die` function global $user; if (isset($user)) { $this->flag(USER::NOT_TAILED, 1); @@ -419,7 +403,8 @@ function pagination($ipp, $cnt = null, $ipl = 5, $current = null, $throw = true) } $sky->is_front or $throw = false; $e = function ($no) use ($throw, $cnt, $sky) { - if ($throw && (404 != $no || $sky->s_error_404)) throw new Exception("pagination error $no"); + if ($throw && (404 != $no || $sky->s_error_404)) + throw new Exception("pagination error $no"); return [0, $no, $cnt]; }; if ($cnt <= $ipp) { diff --git a/sky b/sky new file mode 100644 index 0000000..b1d2871 --- /dev/null +++ b/sky @@ -0,0 +1,49 @@ +#!/usr/bin/env php +load(); + +new Console($argv[1]); diff --git a/sky.bat b/sky.bat new file mode 100644 index 0000000..402d636 --- /dev/null +++ b/sky.bat @@ -0,0 +1,4 @@ +@ECHO OFF +setlocal DISABLEDELAYEDEXPANSION +SET BIN_TARGET=%~dp0/sky +php "%BIN_TARGET%" %* diff --git a/sky.php b/sky.php index 0044326..26741b2 100644 --- a/sky.php +++ b/sky.php @@ -12,6 +12,7 @@ class SKY public $error_prod = ''; public $errors = ''; public $error_no = 0; + public $error_last = 0; public $was_error = 0; public $cnt_error = 0; public $cli; @@ -39,26 +40,32 @@ function __construct() { spl_autoload_register(function ($name) { trace("autoload($name)"); + if (strpos($name, '\\')) # `vendor` folder autoloader + return; if (in_array(substr($name, 0, 2), ['m_', 'q_', 't_'])) { is_file($file = "main/app/$name.php") ? require $file : eval("class $name extends Model_$name[0] {}"); } elseif (is_file($file = DIR_S . '/w2/' . ($name = strtolower($name)) . '.php')) { require $file; # wing2 folder - } elseif (false === strpos($name, '\\')) { + } else { require "main/w3/$name.php"; - } # else `vendor` folder + } + return true; }, true, true); + set_error_handler(function ($no, $message, $file, $line, $context = null) { - if (error_reporting() & $no && ($this->debug || $this->s_prod_error)) { + $this->error_last = $no; + if (error_reporting() & $no && ($this->debug || !SKY::$dd || $this->s_prod_error)) { $this->error_title = 'PHP ' . ($err = Debug::error_name($no)); trace("$err: $message", true, $line, $file, $context); } return true; }); + set_exception_handler(function ($e) { preg_match("/^(\d{1,3}) ?(.*)$/", $mess = $e->getMessage(), $m); $this->except = [ 'name' => $name = get_class($e), - 'crash' => 'Stop' != $name && ('Exception' != $name || !$this->s_quiet_eerr), + 'crash' => $crash = 'Stop' != $name && ('Exception' != $name || !SKY::$dd || !$this->s_quiet_eerr), 'code' => $m ? $m[1] : 0, 'mess' => $m ? $m[2] : $mess, 'title' => $this->error_title = "Exception $name($mess)", @@ -66,22 +73,28 @@ function __construct() { if ('Stop' == $name && !$mess) $this->tailed = true; global $user; - $etc = $m && 22 == $m[1] ? implode("\n", $user->jump_path) : $e->getTraceAsString(); - trace("$this->error_title\n$etc", 'Err' == $name, $e->getLine(), $e->getFile()); + $etc = $m && 22 == $m[1] ? isset($user) && implode("\n", $user->jump_path) : $e->getTraceAsString(); + trace("$this->error_title\n$etc", $crash, $e->getLine(), $e->getFile()); $this->error_title = "Exception $name($mess)"; }); + register_shutdown_function([$this, 'shutdown']); } + function h_init($vendor = false) { + if ($vendor) + require 'vendor/autoload.php'; + } + function shutdown() { chdir(DIR); # restore dir! - if (SKY::$dd) - SQL::$dd = SKY::$dd; # switch main database driver + SQL::$dd = SKY::$dd; # set main database driver if SKY loaded foreach ($this->shutdown as $object) call_user_func([$object, 'shutdown']); $e = error_get_last(); - if ($e && $e['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR)) { + //if ($e && $e['type'] & (E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR)) { + if ($e && $e['type'] != $this->error_last) { $err = Debug::error_name($e['type']); trace("$err: $e[message]", true, $e['line'], $e['file']); $this->error_title = "PHP $err"; @@ -102,20 +115,27 @@ function shutdown() { function load() { global $argv; - require 'main/app/hook.php'; - SKY::$dd = SQL::open('', $hook = new hook); + SKY::$dd = SQL::open(); if (CLI) $this->gpc = '$argv = ' . html(var_export($argv, true)); if (DEV) Ext::init(); - list($this->imemo, $tmemo) = sqlf('-select imemo, tmemo from $_memory where id=3'); - SKY::ghost('s', $tmemo, 'update $_memory set dt=$now, tmemo=%s where id=3'); + $this->memory(3, 's'); $this->debug |= (int)$this->s_trace_single; if ($this->s_prod_error || $this->debug) ini_set('error_reporting', -1); $this->trace_cli = $this->s_trace_cli; - return $hook; + } + + function memory($id = 9, $char = 'n', $table = 'memory') { + if (!isset(SKY::$mem[$char])) { + SKY::$dd or $this->load(); + list($dt, $imemo, $tmemo) = sqlf('-select dt, imemo, tmemo from $_memory where id=' . $id); + SKY::ghost($char, $tmemo, 'update $_memory set dt=$now, tmemo=%s where id=' . $id); + if (9 == $id && defined('WWW') && 'n' == $char && 'memory' == $table) + Schedule::setWWW($this->n_www); + } } function tail_ghost($alt = false) { @@ -130,20 +150,22 @@ function tail_ghost($alt = false) { function __get($name) { $pre = substr($name, 0, 2); - if ('s_' == $pre) - return array_key_exists($name = substr($name, 2), SKY::$mem['s'][3]) ? SKY::$mem['s'][3][$name] : ''; - if ('k_' == $pre) + if ('k_' == $pre) { return array_key_exists($name, SKY::$vars) ? SKY::$vars[$name] : ''; + } elseif (2 == strlen($pre) && '_' == $pre[1] && isset(SKY::$mem[$char = $pre[0]])) { + $name = substr($name, 2); + return array_key_exists($name, SKY::$mem[$char][3]) ? SKY::$mem[$char][3][$name] : ''; + } return array_key_exists($name, SKY::$reg) ? SKY::$reg[$name] : ''; } function __set($name, $value) { $pre = substr($name, 0, 2); - if ('s_' == $pre) { - SKY::$mem['s'][0] = 1; # sqlf only, flag cannot be =2 - SKY::$mem['s'][3][substr($name, 2)] = $value; - } elseif ('k_' == $pre) { + if ('k_' == $pre) { SKY::$vars[$name] = $value; + } elseif (2 == strlen($pre) && '_' == $pre[1] && isset(SKY::$mem[$char = $pre[0]])) { + SKY::$mem[$char][0] = 1; # sqlf only, flag cannot be =2 + SKY::$mem[$char][3][substr($name, 2)] = $value; } else { SKY::$reg[$name] = $value; } @@ -268,7 +290,7 @@ function constants() { define('TPL_META', ''); } - const CORE = '0.114 2021-05-16T11:01:11+03:00 energy'; + const CORE = '0.115 2021-05-24T07:01:11+03:00 energy'; static function version() { global $sky; @@ -290,17 +312,6 @@ class Err extends Exception {} # Use when exception is caused by programmer acti class Stop extends Exception {} # Assume like stop and not a crash # use exception `Exception`, `die` when exceptional situation is caused by events of the outside world. Configure as crash or not. -////////////////////////////////////////////////////////////////////////// -class Hook_base { # use it in app/hook.php - function __call($name, $args) { - global $sky; - - if ('h_' == substr($name, 0, 2) && method_exists($sky, $name)) - return call_user_func_array([$sky, $name], $args); # call the default processing for the method - throw new Err("Hook `$name` not exists"); - } -} - ////////////////////////////////////////////////////////////////////////// class eVar implements Iterator { @@ -455,30 +466,29 @@ function trace($var, $is_error = false, $line = 0, $file = '', $context = null) } } -function sql() { - $in = func_get_args(); +function sql(...$in) { $sql = $in[0] instanceof SQL ? $in[0] : new SQL($in, 'parseT'); return $sql->exec(); } -function qp() { # Query Part, Query Parse - $in = func_get_args() or $in = ['']; +function qp(...$in) { # Query Part, Query Parse + $in or $in = ['']; return new SQL($in, 'parseT'); } -function table() { - $sql = new SQL(func_get_args(), 'init_qb'); +function table(...$in) { + $sql = new SQL($in, 'init_qb'); $sql->table($sql->qstr); $sql->qstr = ''; return $sql; } -function sqlf() { # just more quick parsing, using printf syntax. No SQL injection! +function sqlf(...$in) { # just more quick parsing, using printf syntax. No SQL injection! //$trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);//new Exception(); |DEBUG_BACKTRACE_PROVIDE_OBJECT //$trace = $e->getTrace(); //trace($trace[1]); - $sql = new SQL(func_get_args(), 'parseF'); + $sql = new SQL($in, 'parseF'); return $sql->exec(); } diff --git a/w2/azure.php b/w2/azure.php new file mode 100644 index 0000000..9dd9963 --- /dev/null +++ b/w2/azure.php @@ -0,0 +1,7 @@ +{"_$arg1"}(); + echo "\n"; + } + + function __call($name, $args) { + echo "Command `$name` not found"; + } + + function _m() { + $sky->debug = 0; + echo sqlf('+select tmemo from $_memory where id=%d', $argv[2] ?? 1); + } + + function _c() { + $list = Gate::controllers(); + echo "Reparsed:\n" . implode(' ', $list); + } + + function _cache() { + echo Admin::drop_all_cache() ? 'Drop all cache: OK' : 'Error when drop cache'; + } + + function _jet() { + echo '2do'; + } + + function _a() { + $list = Gate::controllers(true); + array_shift($list); + Gate::$cshow = true; + foreach ($list as $k => $v) { + if (1 != $v) + continue; + $e = new eVar(Gate::view($mc = '*' != $k ? "c_$k" : 'default_c')); + foreach ($e as $row) + echo "$mc::$row->func$row->pars -- " . strip_tags($row->url). "\n"; + } + + #$gate = new Gate; + #$gate->put_cache($argv[2]); + #$ary = $gate->contr(); + #echo count($ary) . " $gate->i\n";print_r($ary); + } + + function _t() { + //Gate::test("main/app/$argv[2]"); + } + + function _xxx() { + #Gate::test(__FILE__); + } +} diff --git a/w2/dd_ibase.php b/w2/dd_ibase.php index 078be84..2b283ca 100644 --- a/w2/dd_ibase.php +++ b/w2/dd_ibase.php @@ -83,8 +83,7 @@ static function begin($lock_table = false) { static function end($par = true) { } - function f_cc() { - $in = func_get_args(); + function f_cc(...$in) { return 'concat(' . implode(', ', $in) . ')'; } diff --git a/w2/dd_mysqli.php b/w2/dd_mysqli.php index c94aeff..bd6002a 100644 --- a/w2/dd_mysqli.php +++ b/w2/dd_mysqli.php @@ -160,8 +160,7 @@ function _rows_count($table) { return $row[4]; } - function f_cc() { - $in = func_get_args(); + function f_cc(...$in) { return 'concat(' . implode(', ', $in) . ')'; } diff --git a/w2/dd_oci.php b/w2/dd_oci.php index 9a26646..961f2cd 100644 --- a/w2/dd_oci.php +++ b/w2/dd_oci.php @@ -93,8 +93,7 @@ static function begin($lock_table = false) { static function end($par = true) { } - function f_cc() { - $in = func_get_args(); + function f_cc(...$in) { return implode(' || ', $in); } diff --git a/w2/dd_pg.php b/w2/dd_pg.php index 0b8705c..5a566ee 100644 --- a/w2/dd_pg.php +++ b/w2/dd_pg.php @@ -81,8 +81,8 @@ static function begin($lock_table = false) { static function end($par = true) { } - function f_cc() { - return implode(' || ', func_get_args()); + function f_cc(...$in) { + return implode(' || ', $in); } function f_dt($column = false, $sign = false, $n = 0, $period = 'day') { diff --git a/w2/dd_sqlite3.php b/w2/dd_sqlite3.php index 5118666..9e54b18 100644 --- a/w2/dd_sqlite3.php +++ b/w2/dd_sqlite3.php @@ -103,8 +103,8 @@ function _rows_count($table) { return sql('+select count(1) from $_`', $table); } - function f_cc() { - return implode(' || ', func_get_args()); + function f_cc(...$in) { + return implode(' || ', $in); } function tz() { diff --git a/w2/form.php b/w2/form.php index ab7a67d..393718b 100644 --- a/w2/form.php +++ b/w2/form.php @@ -58,8 +58,7 @@ static function A($row, $form) { # no validation return $me->tag($me->draw_form($row, $me->mk)); } - static function X() { - $in = func_get_args(); + static function X(...$in) { $cfg = array_shift($in); array_walk($in, function(&$ary) { is_array($ary) or $ary = [$ary]; diff --git a/w2/gate.php b/w2/gate.php index 6628d04..48824eb 100644 --- a/w2/gate.php +++ b/w2/gate.php @@ -4,32 +4,41 @@ class Gate { - private $gate_file; - private $url = ''; - static $cshow = 0; - static $contr_ary = false; # not loaded initialy - const GATE = 'main/app/gate.php'; + const ARRAY = 'main/app/gate.php'; + const HAS_T3 = 1; const RAW_INPUT = 2; const AUTHORIZED = 16; const OBJ_ADDR = 32; const OBJ_PFS = 64; + static $cshow = 0; + static $contr_ary = false; # not loaded initialy + + private $gate_file; + private $url = ''; + function __construct() { + global $sky; + $sky->memory(); $this->flags = [ - self::HAS_T3 => 'Address has semantic part', - self::RAW_INPUT => 'Use raw body input', - self::AUTHORIZED => 'User must be authorized', - self::OBJ_ADDR => 'Return address as object', - self::OBJ_PFS => 'Return postfields as object', + Gate::HAS_T3 => 'Address has semantic part', + Gate::RAW_INPUT => 'Use raw body input', + Gate::AUTHORIZED => 'User must be authorized', + Gate::OBJ_ADDR => 'Return address as object', + Gate::OBJ_PFS => 'Return postfields as object', ]; } - - static function post_data($me = false) { - global $user; - if ($me) - $me->argc($_POST['args']); - $user->v_sg_prod = isset($_POST['production']); + + static function instance() { + static $me; + return $me ? $me : ($me = new Gate); + } + + static function post_data($me) { + global $sky; + isset($_POST['args']) && $me->argc($_POST['args']);////////// + $sky->n_sg_prod = isset($_POST['production']); $addr = $pfs = []; $to =& $addr; if (isset($_POST['key'])) { @@ -48,9 +57,9 @@ static function post_data($me = false) { return [$flag, $method, $addr, $pfs]; } - static function load($class = false) { + static function load_array($class = false) { $sky_gate = []; - if (is_file($fn = self::GATE)) + if (is_file($fn = Gate::ARRAY)) require $fn; if (!$class) return $sky_gate; @@ -61,7 +70,7 @@ static function load($class = false) { } static function save($class, $func = false, $ary = false) { - $sky_gate = self::load(); + $sky_gate = Gate::load_array(); if (is_array($func)) { # save virtuals $found = []; foreach ($sky_gate as $k => $v) @@ -75,13 +84,13 @@ static function save($class, $func = false, $ary = false) { } elseif (!$ary) { # delete action unset($sky_gate[$class][$func]); } else { # update, add - $sky_gate[$class][$func] = true === $ary ? self::post_data() : $ary; + $sky_gate[$class][$func] = true === $ary ? Gate::post_data(Gate::instance()) : $ary; } if (is_file($fn = "var/gate/$class.php"))//--delete virtuals unlink($fn); $comment = '# this is autogenerated file, do not edit'; $file = " $v) { + foreach (Gate::load_array() as $k => $v) { $k = 'default_c' == $k ? '*' : substr($k, 2); if (!isset($list[$k])) { if (is_string($v)) { @@ -126,13 +135,13 @@ static function controllers($virtuals = false) { } static function real_src(&$class, &$fn_src, $test = true) { - $sky_gate = self::load(); + $sky_gate = Gate::load_array(); $set = isset($sky_gate[$class]); if (!$set && $test) return false; $set or $sky_gate[$class] = []; - if (is_string(self::$contr_ary = $sky_gate[$class])) { - self::$contr_ary = $sky_gate[$class = self::$contr_ary]; + if (is_string(Gate::$contr_ary = $sky_gate[$class])) { + Gate::$contr_ary = $sky_gate[$class = Gate::$contr_ary]; } elseif ($test) { return false; } @@ -142,10 +151,10 @@ static function real_src(&$class, &$fn_src, $test = true) { static function put_cache($class, $fn_src, $fn_dst) { $real = $class; - if (false === self::$contr_ary) - self::real_src($real, $fn_src, false); - $me = new Gate; - $me->parse($fn_src, self::$contr_ary, $class); + if (false === Gate::$contr_ary) + Gate::real_src($real, $fn_src, false); + $me = Gate::instance(); + $me->parse($fn_src, Gate::$contr_ary, $class); file_put_contents($fn_dst, $me->gate_file); } @@ -158,26 +167,26 @@ function view_code($ary, $class, $func) { } static function compile($class, $func) { - $me = new Gate; + $me = Gate::instance(); json([ - 'code' => $me->view_code(self::post_data($me), $class, $func), + 'code' => $me->view_code(Gate::post_data($me), $class, $func), 'url' => PROTO . '://' . $me->url, ]); } static function cshow() { - global $user; - Gate::$cshow = $user->v_sg_cshow; + global $sky; + Gate::$cshow = $sky->n_sg_cshow; if (isset($_POST['s'])) - Gate::$cshow = $user->v_sg_cshow = (int)('true' == $_POST['s']); + Gate::$cshow = $sky->n_sg_cshow = (int)('true' == $_POST['s']); return Gate::$cshow; } static function view($class, $func = null, $is_edit = true) { - list($real, $ary) = Gate::load($class); # virt class return real + list($real, $ary) = Gate::load_array($class); # virt class return real if ($real != $class) throw new Err("Cannot open virtual controller `$class`"); - $me = new Gate; + $me = Gate::instance(); $src = is_file($fn = "main/app/$class.php") ? $me->parse($fn) : []; if ($diff = array_diff_key($ary, $src)) $src = $diff + $src; @@ -188,7 +197,7 @@ static function view($class, $func = null, $is_edit = true) { $me->edit = $has_func && $is_edit; $return = [ 'row_c' => function($row = false) use (&$src, $ary, $me, $class) { - global $user; + global $sky; if ($row && $row->__i && !next($src) || !$src) return false; $name = key($src); @@ -212,7 +221,7 @@ static function view($class, $func = null, $is_edit = true) { 'c1' => $me->view_c1($flag, $meth, $is_j), 'c2' => $me->view_c23($flag, $addr, 1), 'c3' => $me->view_c23($flag, $pfs, 0), - 'prod' => $user->v_sg_prod ? ' checked' : '', + 'prod' => $sky->n_sg_prod ? ' checked' : '', ]; }, ]; @@ -237,7 +246,7 @@ function view_c1($flag, $meth, $is_j) { } $out .= sprintf('
', $this->edit ? '' : ';min-height:50px'); foreach ($this->flags as $k => $v) { - if ($is_j && $k & self::HAS_T3) + if ($is_j && $k & Gate::HAS_T3) continue; $ok = (bool)($flag & $k); $input = sprintf('', $k, $ok ? ' checked' : '', $this->edit ? '' : ' disabled'); @@ -381,20 +390,20 @@ function contr_mode($class, $func) { } function code($ary, $cmode, $is_view = true) { - global $user; + global $sky; list ($flag, $meth, $addr, $pfs) = $ary + [0, [], [], []]; if ($this->_j) $meth = [0]; if (!$meth && 'main' == $cmode[1] && '' === $cmode[2]) # for main page $meth = [1]; - $this->_e = !DEV || $is_view && $user->v_sg_prod ? 'die;' : 'e();'; + $this->_e = !DEV || $is_view && $sky->n_sg_prod ? 'die;' : 'e();'; $errors = $s0 = ''; if (!$cnt_meth = count($meth)) $errors .= "$this->_e # no HTTP methods defined\n"; $eq0 = 1 == $cnt_meth ? ["$meth[0] == \$sky->method"] : ['in_array($sky->method, [' . implode(', ', $meth) . '])']; - if (self::AUTHORIZED & $flag) + if (Gate::AUTHORIZED & $flag) $eq0[] = '$user->auth'; $is_post = in_array(0, $meth); if ($this->pfs_c = count($pfs)) @@ -459,25 +468,24 @@ function span($in, $c, $ns = 0) { } function process_addr($addr, $flag, $cmode, &$eq0) { - global $user; + global $sky; list($i, $p0, $p1) = $cmode; $this->i = $i; $ctrl = $p0 ? $this->span($p0, 2 == $i && !$p1 ? 'green' : 'blue', 2) : ''; $act = '' === $p1 ? '' : $this->span($p1, $this->_j ? 'red' : 'green', 2); - $this->url = $user->v_sg_prod ? _PUBLIC . '/' : SNAME . PATH; - + $this->url = $sky->n_sg_prod ? _PUBLIC . '/' : SNAME . PATH; $this->ends = []; $php = $this->ra = $this->ns = ''; $this->raw_input = $this->sz_surl = $this->sz_ary = 0; - $t3 = self::HAS_T3 & $flag; + $t3 = Gate::HAS_T3 & $flag; $this->start = $this->_j ? 1 : 0; if ($this->cnt_ary = $this->addr_c = count($addr)) { $this->current = $addr; foreach ($addr as $v) $v[4] or '' === $v[1] ? $this->sz_surl++ : $this->sz_ary++; - $this->ary_as_object = self::OBJ_ADDR & $flag; + $this->ary_as_object = Gate::OBJ_ADDR & $flag; foreach ($addr as $pos => $v) { $skip = 0; $key = isset($v[1]) ? $v[1] : ''; @@ -540,7 +548,7 @@ function process_pfs($pfs, $flag, $cnt_meth, &$eq0) { $this->ends = []; } $php = $this->ra = $this->ns = ''; - if ($this->raw_input = self::RAW_INPUT & $flag) + if ($this->raw_input = Gate::RAW_INPUT & $flag) $php .= "\$input = file_get_contents('php://input');\n"; if ($this->cnt_ary = $this->pfs_c) { $this->sz_ary = 0; @@ -549,7 +557,7 @@ function process_pfs($pfs, $flag, $cnt_meth, &$eq0) { if (!$this->raw_input) foreach ($pfs as $v) $v[4] or $this->sz_ary++; - $this->ary_as_object = self::OBJ_PFS & $flag; + $this->ary_as_object = Gate::OBJ_PFS & $flag; foreach ($pfs as $pos => $v) $php .= $this->each_row($pos, $v, true); if ($this->sz_ary) { diff --git a/w2/jet.php b/w2/jet.php index 4beffd1..a73cf6f 100644 --- a/w2/jet.php +++ b/w2/jet.php @@ -39,6 +39,8 @@ function __construct($layout, $name, $fn = false, $is_fire = false) { } if (!self::$directive) { MVC::handle('jet_c'); + if (is_file($fn_jet = 'main/app/jet.php')) + require $fn_jet; self::$directive = true; } $this->files[$name] = 1; diff --git a/w2/mvc.php b/w2/mvc.php index 98833b2..0e5860c 100644 --- a/w2/mvc.php +++ b/w2/mvc.php @@ -47,20 +47,19 @@ function view($in, $return = false, $param = null) { echo $mvc->echo; } -function t() { # situational translation - $ary = func_get_args(); +function t(...$in) { # situational translation global $sky; $sky->trans_i or $sky->trans_i = 0; - if ($args = $ary) { - $str = array_shift($ary); + if ($args = $in) { + $str = array_shift($in); } elseif ($sky->trans_i++ % 2) { $str = ob_get_clean(); } else { return ob_start(); } - if (is_array(@$ary[0])) - $ary = $ary[0]; + if (is_array(@$in[0])) + $in = $in[0]; if (isset($sky->trans_late[$str])) { DEFAULT_LG == LG or $str = $sky->trans_late[$str]; @@ -68,7 +67,7 @@ function t() { # situational translation SKY::$reg['trans_coll'][$str] = $sky->trans_i; } $args or print $str; - return $ary ? vsprintf($str, $ary) : $str; + return $in ? vsprintf($str, $in) : $str; } ////////////////////////////////////////////////////////////////////////// @@ -257,6 +256,30 @@ function __call($name, $args) { } } +abstract class HOOK extends Controller +{ + function mc(Array $in = null) { + $name = get_class(MVC::$mc); + if (!$in) + return $name; + if (is_int(key($in))) + return in_array($name, $in); + } + + //add named limits!!!!!! + + static function rewrite_h($cnt) { + global $sky; + if (1 == $cnt && 'robots.txt' == $sky->surl[0] && !$_GET) { + $sky->surl = ['']; + $_GET = ['_etc' => 'robots.txt']; + } + } + + static function dd_h($name, $dd) { + } +} + class MVC extends MVC_BASE { const dir_j = 'var/jet/'; @@ -374,11 +397,17 @@ static function head($plus = '') { if (isset($v['y_h1'])) $sky->k_title = $v['y_h1']; } + if (!$sky->k_tkd) + $sky->k_tkd = [$sky->s_title, $sky->s_keywords, $sky->s_description]; $sky->k_title = html($sky->k_title ? "$sky->k_title - {$sky->k_tkd[0]}" : $sky->k_tkd[0]); if ($sky->k_refresh) { list($secs, $link) = explode('!', $sky->k_refresh); $sky->k_head = $sky->k_head . sprintf('', $secs, $link ? ";url=$link" : ''); } + if (!$sky->k_static) { + $fn = ($sky->style ? "$sky->style/" : '') . ($sky->is_mobile ? 'mobile' : 'desktop'); + $sky->k_static = [[], ["~/$fn.js"], ["~/$fn.css"]]; # default app meta_tags, js, css files + } $plus = "$sky->k_title$plus"; $plus .= tag($sky->k_static[0] + ['csrf-token' => $user->v_csrf, 'surl-path' => PATH]); # meta tags $plus .= js([-2 => '~/jquery.min.js', -1 => '~/sky.js'] + $sky->k_static[1]); @@ -467,7 +496,7 @@ private function set($in, $is_common = false) { !$in or $this->body = ''; } elseif (is_int($in)) { # soft error $sky->error_no = $in; - if ($sky->s_error_404 || $user->jump_alt) + if ($sky->s_error_404)// || $user->jump_alt) throw new Stop($in); # terminate quick $sky->ajax or http_response_code($in); $this->body = '_std.404'; @@ -475,7 +504,7 @@ private function set($in, $is_common = false) { } private function gate($ex = false) { - global $sky, $user; + global $sky; $_0 = $sky->_0; $list = !$ex && $sky->s_contr ? explode(' ', $sky->s_contr) : Gate::controllers(); @@ -485,7 +514,7 @@ private function gate($ex = false) { if (!$dst || DEV) { $src = is_file($fn_src = "main/app/$class.php") or !$in_a or $src = Gate::real_src($real, $fn_src); if (!$src) - return $ex || !$in_a ? ['Controller', '_', [], ''] : $this->gate(true); + return $ex || !$in_a ? ['Controller', '_', false, ''] : $this->gate(true); if (!$dst || filemtime($fn_src) > filemtime($fn_dst)) Gate::put_cache($class, $fn_src, $fn_dst); } @@ -495,58 +524,55 @@ private function gate($ex = false) { : ($is_j ? 'j_' : 'a_') . $_0; require $fn_dst; if (!method_exists($gape = new Gape, $action)) - $action = 1 == $sky->ajax ? 'default_j' : 'default_a'; + $action = $is_j ? 'default_j' : 'default_a'; if (isset($gape->src)) $real = "c_$gape->src"; if ($in_a) MVC::$tpl = substr($real, 2); - return [$class, $action, call_user_func([$gape, $action], $sky, $user), $real]; + return [$class, $action, $gape, $real]; } static function top() { global $sky, $user; - if ((DEBUG || $user->root) && ($id = array_search(URI, [1 => '_x1', 15 => '_x2', 16 => '_x3']))) { - $sky->debug = false; - echo sqlf('+select tmemo from $_memory where id=%d', $id); # show X-trace - throw new Stop; - } MVC::$vars = ['sky' => $me = new MVC]; ob_start(); $param = []; if ('_' == $sky->_0[0]) { - require DIR_S . '/w2/standard_c.php'; - $real = $controller = 'standard_c'; + require DIR_S . '/w2/standard_c.php';//////////delete + if ($id = array_search(URI, [1 => '_x1', 15 => '_x2', 16 => '_x3'])) { + $param = [$id]; + $sky->surl[0] = '_trace'; + } + $real = $class = 'standard_c'; $action = (1 == $sky->ajax ? 'j' : 'a') . $sky->_0; MVC::$tpl = '_std'; $me->body = '_std.' . substr($sky->_0, 1); + $gape = false; } else { - list ($controller, $action, $param, $real) = $me->gate(); + list ($class, $action, $gape, $real) = $me->gate(); switch ($action[0]) { case 'd': $me->body = MVC::$tpl . ".default"; break; # default_X case 'e': $me->body = MVC::$tpl . ".empty"; break; # empty_X default: $me->body = MVC::$tpl . "." . substr($action, 2); break; # a_.. or j_.. } } - trace("$controller::$action()" . ($controller == $real ? '' : ' (virtual)'), 'TOP-VIEW'); - if (DEFAULT_LG) { - require 'main/lng/' . LG . '.php'; - SKY::$reg['trans_late'] = $lgt ?? []; - SKY::$reg['trans_coll'] = []; - } - require 'main/app/common_c.php'; + trace("$class::$action()" . ($class == $real ? '' : ' (virtual)'), 'TOP-VIEW'); + MVC::$mc = new $class; MVC::$cc = new common_c; - MVC::$mc = new $controller; $me->set(MVC::$mc->head_y($action), true); - if (DEV && 1 == $sky->error_no && $real) { # gate error - $me->body = 1 == $sky->ajax ? '' : '_std.lock'; - $sky->ca_path = ['ctrl' => $real, 'func' => $action]; + if ($gape) { + $param = (array)call_user_func([$gape, $action], $sky, $user); + if (DEV && 1 == $sky->error_no) { # gate error + $me->body = 1 == $sky->ajax ? '' : '_std.lock'; + $sky->ca_path = ['ctrl' => $real, 'func' => $action]; + } } if (!$sky->error_no || $sky->surl && '_exception' == $sky->surl[0]) - $me->set(call_user_func_array([MVC::$mc, $action], (array)$param)); + $me->set(call_user_func_array([MVC::$mc, $action], $param)); if ($sky->error_no > 400 && $sky->error_no < 501) $me->set(MVC::$mc->error_y($action)); - is_string($rett = MVC::$mc->tail_y()) ? (MVC::$layout = $rett) : $me->set($rett, true); + is_string($tail = MVC::$mc->tail_y()) ? (MVC::$layout = $tail) : $me->set($tail, true); $me->echo = ob_get_clean(); view($me); # visualize } diff --git a/w2/rare.php b/w2/rare.php index de83ca1..078d59c 100644 --- a/w2/rare.php +++ b/w2/rare.php @@ -4,7 +4,7 @@ class Rare { - static public $u_svn_skips = []; + static public $u_svn_skips = ['.git', '.svn']; static function list_path($dir, $func = '', $skip = [], $up = false) { if ('/' === $dir) diff --git a/w2/schedule.php b/w2/schedule.php index 9d99626..d5a6061 100644 --- a/w2/schedule.php +++ b/w2/schedule.php @@ -21,32 +21,6 @@ class Schedule public $dt; public $imemo; - function &load() { - global $sky; - SKY::$dd or $sky->load(); - if (!isset(SKY::$mem['n'])) { - list($this->dt, $this->imemo, $tmemo) = sqlf('-select dt, imemo, tmemo from $_memory where id=9'); - SKY::ghost('n', $tmemo, 'update $_memory set dt=$now, tmemo=%s where id=9'); - } - return SKY::$mem['n'][3]; - } - - function __get($name) { - $ary = $this->load(); - if ('www' == $name) { - $ary = explode('~', $ary['www']); - return DEV ? $ary[0] . '/' : $ary[1] . '/'; - } - return $ary[substr($name, 2)]; - } - - function __set($name, $value) { - if ('n_' == substr($name, 0, 2)) { - $this->load(); - SKY::n(substr($name, 2), $value); - } - } - function __construct($debug_level = 1, $single_thread = false) { global $argv, $sky; @@ -65,8 +39,36 @@ function __construct($debug_level = 1, $single_thread = false) { $this->single_thread = $sky->cli = true; } $sky->debug = $debug_level; - if (-1 == $this->arg) + if (-1 == $this->arg) { $sky->shutdown[] = $this; + //if ('' == $this->amp) + //echo "Multy-threads: " . ($this->single_thread ? "No\n" : "Yes\n"): + } + } + + function __get($name) { + global $sky; + $sky->memory(); + $ary =& SKY::$mem['n'][3]; + if ('www' == $name) { + $ary = explode('~', $ary['www']); + return DEV ? $ary[0] . '/' : $ary[1] . '/'; + } + return $ary[substr($name, 2)]; + } + + function __set($name, $value) { + global $sky; + if ('n_' == substr($name, 0, 2)) { + $sky->memory(); + SKY::n(substr($name, 2), $value); + } + } + + static function setWWW($www) { + $ary = explode('~', $www); + $ary[DEV ? 0 : 1] = rtrim(WWW, '/'); + SKY::n('www', implode('~', $ary)); } function mail_error() { @@ -150,11 +152,11 @@ function ok($schedule = '') { return true; } - function sql() { + function sql(...$in) { global $sky; SKY::$dd or $sky->load(); $start = microtime(true); - $sql = (string)call_user_func_array('qp', func_get_args()); + $sql = (string)call_user_func_array('qp', $in); $n = sql(SQL::NO_PARSE + 1, $sql); $this->write(sprintf("%01.3f sec <= %s <= %s", microtime(true) - $start, is_array($n) ? count($n) : $n, $sql)); return $n; diff --git a/w2/sql.php b/w2/sql.php index 52673ee..746e7cc 100644 --- a/w2/sql.php +++ b/w2/sql.php @@ -88,11 +88,11 @@ static function open($name = '', $p2 = false) { isset($cfg['pref']) or $cfg['pref'] = ''; $dd = SQL::$connections[$name] = new $driver($cfg['dsn'], $cfg['pref']); unset($cfg['dsn']); - static $hook = false; - $hook or $hook = $p2; # first call must set hook object - $hook->h_dd($name, $dd); + require_once DIR_S . '/w2/mvc.php'; + require_once 'main/app/common_c.php'; + common_c::dd_h($name, $dd); } - return $p2 ? (SQL::$dd = $dd) : $dd; + return $p2 || !SQL::$dd ? (SQL::$dd = $dd) : $dd; } static function close($name = false) { @@ -189,15 +189,15 @@ function exec() { return $this; } - function append() { + function append(...$in) { $tmp = $this->qstr; - $this->qstr = $tmp . $this->parseT(func_get_args()); + $this->qstr = $tmp . $this->parseT($in); return $this; } - function prepend() { + function prepend(...$in) { $tmp = $this->qstr; - $this->qstr = $this->parseT(func_get_args()) . $tmp; + $this->qstr = $this->parseT($in) . $tmp; return $this; } diff --git a/w2/standard_c.php b/w2/standard_c.php index 97b33f2..68e6d21 100644 --- a/w2/standard_c.php +++ b/w2/standard_c.php @@ -8,19 +8,20 @@ class standard_c extends Controller private $_a = ''; function head_y($action) { - $production = [ + $soft = [ + 'a_trace', + 'j_file', 'a_exception', 'j_init', 'j_crop_code', 'j_crop', 'j_file_tmp', 'j_file_delete', - 'j_file', ]; if ('a_etc' == $action || DEV && 'a_dev' == $action) # run MVC::$cc ! return parent::head_y($action); - if (in_array($action, $production)) # app's ::head_y() locked ! - return; + if (in_array($action, $soft)) # app's ::head_y() locked ! + return $this->soft(111); if (!DEV) return 404; global $sky; @@ -30,8 +31,33 @@ function head_y($action) { return ['y_1' => $v[0]]; } - function a_exception() { + private function soft($xxx) { global $sky, $user; + $user = new USER; + } + + function a_trace($id) { + global $sky, $user; + if (!$user->root && !DEBUG) + return 404; + $sky->debug = false; + echo sqlf('+select tmemo from $_memory where id=%d', $id); # show X-trace + throw new Stop; + } + + function j_file() { + global $user; + if (!$user->root && !DEV) + return 404; + $sky->debug = false; + list($file, $line) = explode('^', $_POST['name']); + $txt = file_get_contents($file); + echo Display::php($txt, str_pad('', $line - 1, '=') . ('true' == $_POST['c'] ? '-' : '+')); + throw new Stop; + } + + function a_exception() { + global $sky; $no = $sky->_1 or $no = $sky->error_no; $sky->error_no < 10000 or $no = 11; $no or jump(); @@ -101,17 +127,6 @@ function j_file_delete() { File_t::delete_one(); } - function j_file() { - global $user; - if (1 != $user->pid && !DEV) - return 404; - $sky->debug = false; - list($file, $line) = explode('^', $_POST['name']); - $txt = file_get_contents($file); - echo Display::php($txt, str_pad('', $line - 1, '=') . ('true' == $_POST['c'] ? '-' : '+')); - throw new Stop; - } - # functions below for DEV only function a_dev() { diff --git a/w2/user.php b/w2/user.php index 2cbea56..76d296d 100644 --- a/w2/user.php +++ b/w2/user.php @@ -175,6 +175,7 @@ function __construct() { ], 7), ]; } + if (START_TS - $sky->s_online_ts > 60) { $query = '+select 1 + count(1) from $_visitors where dt_l > now() - interval %d minute and id<>%d'; $sky->s_online = sqlf($query, $sky->s_visit, $this->vid); @@ -199,14 +200,30 @@ function cookize($cookie = false) { return $cookie; } - function deny() { - return !call_user_func_array([$this, 'allow'], func_get_args()); + function deny(...$in) { + return !call_user_func_array([$this, 'allow'], $in); } - function allow() { + function allow(...$in) { if (1 == $this->pid) # superuser can full access return true; - $args = func_get_args() or $args = [[]]; - return in_array($this->pid, is_array($args[0]) ? $args[0] : $args); + $in or $in = [[]]; + return in_array($this->pid, is_array($in[0]) ? $in[0] : $in); + } + + function guard_origin($skip = []) { + // if ($sky->origin && $sky->origin != $link) throw new Exception('Origin not allowed'); + } + + function guard_csrf($skip = []) { + global $sky; + if (INPUT_POST != $sky->method || in_array($sky->_0, $skip) || $sky->error_no) + return; + $csrf = $_POST['_csrf'] ?? $_SERVER['HTTP_X_CSRF_TOKEN'] ?? false; + unset($_POST['_csrf']); + if ($csrf !== $this->v_csrf) + throw new Exception('CSRF protection'); + // if ($sky->origin && $sky->origin != $link) throw new Exception('Origin not allowed'); + trace('CSRF is OK'); } }