+ add zin and zui3 files.

This commit is contained in:
sunhao
2023-07-25 17:42:27 +08:00
parent b92acecc1a
commit e97ab9686b
234 changed files with 82310 additions and 178 deletions
+100 -5
View File
@@ -394,19 +394,20 @@ class baseControl
*
* @param string $moduleName module name
* @param string $methodName method name
* @param string $viewDir
* @access public
* @return string the view file
*/
public function setViewFile($moduleName, $methodName)
public function setViewFile(string $moduleName, string $methodName, string $viewDir = 'view')
{
$moduleName = strtolower(trim($moduleName));
$methodName = strtolower(trim($methodName));
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
$viewExtPath = $this->app->getModuleExtPath($this->appName, $moduleName, 'view');
$viewExtPath = $this->app->getModuleExtPath($moduleName, $viewDir);
$viewType = $this->viewType == 'mhtml' ? 'html' : $this->viewType;
$mainViewFile = $modulePath . 'view' . DS . $this->devicePrefix . $methodName . '.' . $viewType . '.php';
$mainViewFile = $modulePath . $viewDir . DS . $this->devicePrefix . $methodName . '.' . $viewType . '.php';
$viewFile = $mainViewFile;
if(!empty($viewExtPath))
@@ -416,7 +417,7 @@ class baseControl
$viewFile = file_exists($commonExtViewFile) ? $commonExtViewFile : $mainViewFile;
$viewFile = (!empty($siteExtViewFile) and file_exists($siteExtViewFile)) ? $siteExtViewFile : $viewFile;
if(!is_file($viewFile)) $this->app->triggerError("the view file $viewFile not found", __FILE__, __LINE__, $exit = true);
if(!is_file($viewFile)) $this->app->triggerError("the view file $viewFile not found", __FILE__, __LINE__, true);
$commonExtHookFiles = glob($viewExtPath['common'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php");
$siteExtHookFiles = empty($viewExtPath['site']) ? '' : glob($viewExtPath['site'] . $this->devicePrefix . $methodName . ".*.{$viewType}.hook.php");
@@ -907,12 +908,106 @@ class baseControl
* @access public
* @return void
*/
public function display($moduleName = '', $methodName = '')
public function display(string $moduleName = '', string $methodName = '')
{
if($this->config->debug && $this->viewType === 'html' && (!isset($_GET['zin']) || $_GET['zin'] != '0'))
{
if(empty($moduleName)) $moduleName = $this->moduleName;
if(empty($methodName)) $methodName = $this->methodName;
$modulePath = $this->app->getModulePath($this->appName, $moduleName);
$viewType = $this->viewType == 'mhtml' ? 'html' : $this->viewType;
$mainViewFile = $modulePath . 'ui' . DS . $this->devicePrefix . $methodName . '.' . $viewType . '.php';
if(file_exists($mainViewFile)) return $this->render($moduleName, $methodName);
}
if(empty($this->output)) $this->parse($moduleName, $methodName);
echo $this->output;
}
/**
* 向浏览器输出内容。
* Print the content of the view.
*
* @param string $moduleName module name
* @param string $methodName method name
* @access public
* @return void
*/
public function render($moduleName = '', $methodName = '')
{
if(isset($_GET['zin']) && $_GET['zin'] == '0')
{
$this->display($moduleName, $methodName);
return;
}
if(empty($moduleName)) $moduleName = $this->moduleName;
if(empty($methodName)) $methodName = $this->methodName;
/* Load zin lib */
$this->app->loadClass('zin', true);
\zin\loadConfig();
/**
* 设置视图文件。(PHP7有一个bug,不能直接$viewFile = $this->setViewFile())。
* Set viewFile. (Can't assign $viewFile = $this->setViewFile() directly because one php7's bug.)
*/
$results = $this->setViewFile($moduleName, $methodName, 'ui');
$viewFile = $results;
if(is_array($results)) extract($results);
/**
* 获得当前页面的CSS和JS。
* Get css and js codes for current method.
*/
$css = $this->getCSS($moduleName, $methodName, '.ui');
$js = $this->getJS($moduleName, $methodName, '.ui');
if($css) $this->view->pageCSS = $css;
if($js) $this->view->pageJS = $js;
/**
* 切换到视图文件所在的目录,以保证视图文件里面的include语句能够正常运行。
* Change the dir to the view file to keep the relative paths work.
*/
$currentPWD = getcwd();
chdir(dirname($viewFile));
/**
* Set zin context data
*/
\zin\zin::$globalRenderList = array();
\zin\zin::$enabledGlobalRender = true;
\zin\zin::$rendered = false;
\zin\zin::$rawContentCalled = false;
\zin\zin::$data = (array)$this->view;
\zin\zin::$data['zinDebug'] = array();
if($this->config->debug && $this->config->debug >= 2)
{
\zin\zin::$data['zinDebug']['trace'] = $this->app->loadClass('trace')->getTrace();
}
/**
* 使用extract和ob方法渲染$viewFile里面的代码。
* Use extract and ob functions to eval the codes in $viewFile.
*/
extract(\zin\zin::$data);
ob_start();
include $viewFile;
if(!\zin\zin::$rendered) \zin\render();
$content = ob_get_clean();
ob_start();
echo $content;
/**
* 渲染完毕后,再切换回之前的路径。
* At the end, chang the dir to the previous.
*/
chdir($currentPWD);
}
/**
* 直接输出data数据,通常用于ajax请求中。
* Send data directly, for ajax requests.
+105 -4
View File
@@ -680,15 +680,21 @@ class baseHelper
* 检查是否是AJAX请求。
* Check is ajax request.
*
* @param ?string $type zin|modal|fetch
* @static
* @access public
* @return bool
*/
public static function isAjaxRequest()
public static function isAjaxRequest(?string $type = null): bool
{
if(isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') return true;
if(isset($_GET['HTTP_X_REQUESTED_WITH']) && $_GET['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest') return true;
return false;
$isAjax = (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest') || (isset($_GET['HTTP_X_REQUESTED_WITH']) && $_GET['HTTP_X_REQUESTED_WITH'] === 'XMLHttpRequest');
if($isAjax === false) return false;
if($type === 'zin') return array_key_exists('HTTP_X_ZIN_OPTIONS', $_SERVER);
if($type === 'modal') return isset($_SERVER['HTTP_X_ZUI_MODAL']) && $_SERVER['HTTP_X_ZUI_MODAL'] == true;
if($type === 'fetch') return !array_key_exists('HTTP_X_ZIN_OPTIONS', $_SERVER) && !(isset($_SERVER['HTTP_X_ZUI_MODAL']) && $_SERVER['HTTP_X_ZUI_MODAL'] == true);
return $isAjax;
}
/**
@@ -788,6 +794,101 @@ class baseHelper
return null;
}
/**
* Send a cookie.
*
* @param string $name
* @param string $value
* @param int|null $expire
* @param string|null $path
* @param string $domain
* @param bool|null $secure
* @param bool $httponly
* @static
* @access public
* @return bool
*/
public static function setcookie(string $name, string $value = '', int $expire = null, string $path = null, string $domain = '', bool $secure = null, bool $httponly = true)
{
global $config, $app;
if($expire === null) $expire = $config->cookieLife;
if($path === null) $path = $config->webRoot;
if($secure === null) $secure = $config->cookieSecure;
if(isset($app->worker))
{
$app->worker->response->setCookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
else
{
return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly);
}
}
/**
* 设置状态码。
* Set status code.
*
* @param int $code
* @static
* @access public
* @return void
*/
static public function setStatus(int $code)
{
global $app;
if(isset($app->worker))
{
$app->worker->response->setStatus($code);
}
else
{
$PHRASES = array(
100 => 'Continue', 101 => 'Switching Protocols', 102 => 'Processing',
200 => 'OK', 201 => 'Created', 202 => 'Accepted', 203 => 'Non-Authoritative Information', 204 => 'No Content', 205 => 'Reset Content', 206 => 'Partial Content', 207 => 'Multi-status', 208 => 'Already Reported',
300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 306 => 'Switch Proxy', 307 => 'Temporary Redirect',
400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed', 418 => 'I\'m a teapot', 422 => 'Unprocessable Entity', 423 => 'Locked', 424 => 'Failed Dependency', 425 => 'Unordered Collection', 426 => 'Upgrade Required', 428 => 'Precondition Required', 429 => 'Too Many Requests', 431 => 'Request Header Fields Too Large', 451 => 'Unavailable For Legal Reasons',
500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported', 506 => 'Variant Also Negotiates', 507 => 'Insufficient Storage', 508 => 'Loop Detected', 511 => 'Network Authentication Required',
);
header('HTTP/1.1 ' . (string)$code . ' ' . $PHRASES[$code], true, $code);
}
}
/**
* 发送HTTP头信息。
* Send http header.
*
* @param string $key
* @param string $value
* @param bool $replace
* @param int $response_code
* @static
* @access public
* @return void
*/
static public function header(string $key, string $value, bool $replace = true, int $response_code = 0)
{
global $app;
if(isset($app->worker))
{
$key = trim(strtolower($key));
$app->worker->response->setHeader($key, $value);
if($key == 'location')
{
$app->worker->response->setStatus(302);
helper::end();
}
}
else
{
header($key . ': ' . $value, $replace, $response_code);
}
}
/**
* 检查是否启用缓存。
* Check is enable cache.
+43 -17
View File
@@ -356,6 +356,14 @@ class baseRouter
*/
public $siteCode;
/**
* zin 请求时发生的错误信息。
* The errors occurred when zin request.
*
* @var array
*/
public $zinErrors = array();
/**
* 构造方法, 设置路径,类,超级变量等。注意:
* 1.应该使用createApp()方法实例化router类;
@@ -2891,7 +2899,7 @@ class baseRouter
* @access public
* @return void
*/
public function saveError($level, $message, $file, $line)
public function saveError(int $level, string $message, string $file, int $line)
{
if(empty($this->config->debug)) return true;
if(!is_dir($this->logRoot)) return true;
@@ -2901,9 +2909,9 @@ class baseRouter
* 删除设定时间之前的日志。
* Delete the log before the set time.
**/
if(mt_rand(0, 10) == 1)
if(random_int(0, 10) == 1)
{
$logDays = isset($this->config->framework->logDays) ? $this->config->framework->logDays : 14;
$logDays = $this->config->framework->logDays ?? 14;
$dayTime = time() - $logDays * 24 * 3600;
foreach(glob($this->getLogRoot() . '*') as $logFile)
{
@@ -2915,7 +2923,7 @@ class baseRouter
* 忽略该错误:Redefining already defined constructor。
* Skip the error: Redefining already defined constructor.
**/
if(strpos($message, 'Redefining') !== false) return true;
if(str_contains($message, 'Redefining')) return true;
/*
* 设置错误信息。
@@ -2924,8 +2932,8 @@ class baseRouter
if(preg_match('/[^\x00-\x80]/', $message)) $message = helper::convertEncoding($message, 'gbk');
$errorLog = "\n" . date('H:i:s') . " $message in <strong>$file</strong> on line <strong>$line</strong> ";
$URI = $this->getURI();
$errorLog .= "when visiting <strong>" . (empty($URI) ? '' : htmlspecialchars($URI)) . "</strong>\n";
$uri = $this->getURI();
$errorLog .= "when visiting <strong>" . (empty($uri) ? '' : htmlspecialchars($uri)) . "</strong>\n";
/*
* 为了安全起见,对公网环境隐藏脚本路径。
@@ -2942,18 +2950,29 @@ class baseRouter
if(!is_file($errorFile)) file_put_contents($errorFile, "<?php\n die();\n?" . ">\n");
$fh = fopen($errorFile, 'a');
if($fh) fwrite($fh, strip_tags($errorLog)) and fclose($fh);
if($fh) fwrite($fh, strip_tags(htmlspecialchars_decode($errorLog))) and fclose($fh);
/*
* 如果debug > 1,显示warning, notice级别的错误。
* If the debug > 1, show warning, notice error.
* 如果debug > 1,直接在页面显示非严重错误。
* If the debug > 1, show non-serious errors on page directly.
**/
if($level == E_NOTICE or $level == E_WARNING or $level == E_STRICT or $level == 8192) // 8192: E_DEPRECATED
if(!empty($this->config->debug) && $this->config->debug > 1)
{
if(!empty($this->config->debug) and $this->config->debug > 1)
/* Send non-serious errors to page in zin mode. */
$isZinRequest = isset($this->config->zin) || isset($_SERVER['HTTP_X_ZIN_OPTIONS']);
$isNonSeriousError = $level !== E_ERROR && $level !== E_PARSE && $level !== E_CORE_ERROR && $level !== E_COMPILE_ERROR;
if($isZinRequest && $isNonSeriousError)
{
$this->zinErrors[] = array('file' => $file, 'line' => $line, 'message' => $message, 'level' => $level);
return;
}
/* Show non-serious errors to classic page. */
if($level == E_NOTICE or $level == E_WARNING or $level == E_STRICT or $level == 8192)
{
$cmd = "vim +$line $file";
$size = strlen($cmd);
echo "<pre class='alert alert-danger'>$message: ";
echo "<input type='text' value='$cmd' size='$size' style='border:none; background:none;' onclick='this.select();' /></pre>";
}
@@ -2963,14 +2982,21 @@ class baseRouter
* 如果是严重错误,停止程序。
* If error level is serious, die.
* */
if($level == E_ERROR or $level == E_PARSE or $level == E_CORE_ERROR or $level == E_COMPILE_ERROR or $level == E_USER_ERROR)
if(in_array($level, array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR)))
{
if(empty($this->config->debug)) die();
if(PHP_SAPI == 'cli') die($errorLog);
if(empty($this->config->debug)) helper::end();
$htmlError = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /></head>";
$htmlError .= "<body>" . nl2br($errorLog) . "</body></html>";
die($htmlError);
if(PHP_SAPI == 'cli')
{
echo $errorLog;
}
else
{
$htmlError = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8' /></head>";
$htmlError .= "<body>" . nl2br($errorLog) . "</body></html>";
echo $htmlError;
helper::end();
}
}
}