+ add zin and zui3 files.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user