mirror of
https://gitee.com/fastadminnet/framework.git
synced 2026-07-01 12:42:48 +08:00
Merge branch 'master' of https://github.com/top-think/think
This commit is contained in:
@@ -121,7 +121,9 @@ return [
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'log' => [
|
||||
'type' => 'File', // 支持 file socket trace sae
|
||||
// 日志记录方式,支持 file socket trace sae
|
||||
'type' => 'File',
|
||||
// 日志保存目录
|
||||
'path' => LOG_PATH,
|
||||
],
|
||||
|
||||
@@ -130,9 +132,13 @@ return [
|
||||
// +----------------------------------------------------------------------
|
||||
|
||||
'cache' => [
|
||||
// 驱动方式
|
||||
'type' => 'File',
|
||||
// 缓存保存目录
|
||||
'path' => CACHE_PATH,
|
||||
// 缓存前缀
|
||||
'prefix' => '',
|
||||
// 缓存有效期 0表示永久缓存
|
||||
'expire' => 0,
|
||||
],
|
||||
|
||||
@@ -142,9 +148,13 @@ return [
|
||||
|
||||
'session' => [
|
||||
'id' => '',
|
||||
'var_session_id' => '', // SESSION_ID的提交变量,解决flash上传跨域
|
||||
// SESSION_ID的提交变量,解决flash上传跨域
|
||||
'var_session_id' => '',
|
||||
// SESSION 前缀
|
||||
'prefix' => 'think',
|
||||
// 驱动方式 支持redis memcache memcached
|
||||
'type' => '',
|
||||
// 是否自动开启 SESSION
|
||||
'auto_start' => true,
|
||||
],
|
||||
|
||||
|
||||
@@ -101,13 +101,13 @@ class Build
|
||||
$namespace = APP_NAMESPACE . '\\' . ($module ? $module . '\\' : '') . $path;
|
||||
$class = $val . (CLASS_APPEND_SUFFIX ? ucfirst($path) : '');
|
||||
switch ($path) {
|
||||
case CONTROLLER_LAYER: // 控制器
|
||||
case CONTROLLER_LAYER: // 控制器
|
||||
$content = "<?php\nnamespace {$namespace};\n\nclass {$class}\n{\n\n}";
|
||||
break;
|
||||
case MODEL_LAYER: // 模型
|
||||
case MODEL_LAYER: // 模型
|
||||
$content = "<?php\nnamespace {$namespace};\n\nuse think\Model;\n\nclass {$class} extends Model\n{\n\n}";
|
||||
break;
|
||||
case VIEW_LAYER: // 视图
|
||||
case VIEW_LAYER: // 视图
|
||||
$filename = $modulePath . $path . DS . $val . '.html';
|
||||
if (!is_dir(dirname($filename))) {
|
||||
// 创建目录
|
||||
@@ -131,7 +131,7 @@ class Build
|
||||
// 创建欢迎页面
|
||||
protected static function buildHello($module)
|
||||
{
|
||||
$filename = APP_PATH . ($module ? $module . DS : '') . CONTROLLER_LAYER . DS . Config::get('default_controller') . (CLASS_APPEND_SUFFIX ? ucfirst(CONTROLLER_LAYER) : '') . EXT;
|
||||
$filename = APP_PATH . ($module ? $module . DS : '') . CONTROLLER_LAYER . DS . 'Index' . (CLASS_APPEND_SUFFIX ? ucfirst(CONTROLLER_LAYER) : '') . EXT;
|
||||
if (!is_file($filename)) {
|
||||
$content = file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl');
|
||||
$content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [APP_NAMESPACE, $module ? $module . '\\' : '', CONTROLLER_LAYER, CLASS_APPEND_SUFFIX ? ucfirst(CONTROLLER_LAYER) : ''], $content);
|
||||
|
||||
@@ -221,15 +221,18 @@ class Template
|
||||
*/
|
||||
public function layout($name)
|
||||
{
|
||||
if (false !== $name) {
|
||||
$this->config['layout_on'] = true;
|
||||
if (is_string($name)) {
|
||||
$this->config['layout_name'] = $name;
|
||||
}
|
||||
} else {
|
||||
if (false === $name) {
|
||||
// 关闭布局
|
||||
$this->config['layout_on'] = false;
|
||||
return $this;
|
||||
}
|
||||
// 开启布局
|
||||
$this->config['layout_on'] = true;
|
||||
// 名称必须为字符串
|
||||
if (is_string($name)) {
|
||||
$this->config['layout_name'] = $name;
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -241,25 +244,36 @@ class Template
|
||||
*/
|
||||
private function checkCache($cacheFile)
|
||||
{
|
||||
if ($this->config['tpl_cache'] && is_file($cacheFile) && $handle = @fopen($cacheFile, "r")) {
|
||||
// 读取第一行
|
||||
preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches);
|
||||
if (isset($matches[1])) {
|
||||
$includeFile = unserialize($matches[1]);
|
||||
if (is_array($includeFile)) {
|
||||
// 检查模板文件是否有更新
|
||||
foreach ($includeFile as $path => $time) {
|
||||
if (is_file($path) && filemtime($path) > $time) {
|
||||
// 模板文件如果有更新则缓存需要更新
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// 检查编译存储是否有效
|
||||
return $this->storage->check($cacheFile, $this->config['cache_time']);
|
||||
// 未开启缓存功能
|
||||
if (!$this->config['tpl_cache']) {
|
||||
return false;
|
||||
}
|
||||
// 缓存文件不存在
|
||||
if (!is_file($cacheFile)) {
|
||||
return false;
|
||||
}
|
||||
// 读取缓存文件失败
|
||||
if (!$handle = @fopen($cacheFile, "r")) {
|
||||
return false;
|
||||
}
|
||||
// 读取第一行
|
||||
preg_match('/\/\*(.+?)\*\//', fgets($handle), $matches);
|
||||
if (!isset($matches[1])) {
|
||||
return false;
|
||||
}
|
||||
$includeFile = unserialize($matches[1]);
|
||||
if (!is_array($includeFile)) {
|
||||
return false;
|
||||
}
|
||||
// 检查模板文件是否有更新
|
||||
foreach ($includeFile as $path => $time) {
|
||||
if (is_file($path) && filemtime($path) > $time) {
|
||||
// 模板文件如果有更新则缓存需要更新
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
// 检查编译存储是否有效
|
||||
return $this->storage->check($cacheFile, $this->config['cache_time']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1016,12 +1030,20 @@ class Template
|
||||
private function parseTemplateFile($template)
|
||||
{
|
||||
if (false === strpos($template, '.')) {
|
||||
$template = str_replace(['/', ':'], $this->config['view_depr'], $template);
|
||||
// 跨模块支持
|
||||
if (strpos($template, '@')) {
|
||||
// 跨模块调用模板
|
||||
$template = str_replace(['/', ':'], $this->config['view_depr'], $template);
|
||||
$template = APP_PATH . str_replace('@', '/' . basename($this->config['view_path']) . '/', $template) . $this->config['view_suffix'];
|
||||
} else {
|
||||
$template = $this->config['view_path'] . $template . $this->config['view_suffix'];
|
||||
if (strpos($template, ':')) {
|
||||
// 指定主题
|
||||
list($theme, $template) = explode(':', $template, 2);
|
||||
$path = dirname($this->config['view_path']) . DS . $theme . DS;
|
||||
} else {
|
||||
$path = $this->config['view_path'];
|
||||
}
|
||||
$template = str_replace(['/', ':'], $this->config['view_depr'], $template);
|
||||
$template = $path . $template . $this->config['view_suffix'];
|
||||
}
|
||||
}
|
||||
if (is_file($template)) {
|
||||
|
||||
@@ -24,27 +24,23 @@ class View
|
||||
// 视图参数
|
||||
protected $config = [
|
||||
// 模板主题
|
||||
'theme_on' => false,
|
||||
// 是否自动侦测主题
|
||||
'auto_detect_theme' => false,
|
||||
// 自动侦测主题的URL变量
|
||||
'var_theme' => 't',
|
||||
'theme_on' => false,
|
||||
// 默认主题 开启模板主题有效
|
||||
'default_theme' => 'default',
|
||||
'default_theme' => 'default',
|
||||
// 视图文件路径
|
||||
'view_path' => '',
|
||||
'view_path' => '',
|
||||
// 视图文件后缀
|
||||
'view_suffix' => '.html',
|
||||
'view_suffix' => '.html',
|
||||
// 视图文件分隔符
|
||||
'view_depr' => DS,
|
||||
'view_depr' => DS,
|
||||
// 视图层目录名
|
||||
'view_layer' => VIEW_LAYER,
|
||||
'view_layer' => VIEW_LAYER,
|
||||
// 视图输出字符串替换
|
||||
'parse_str' => [],
|
||||
'parse_str' => [],
|
||||
// 视图驱动命名空间
|
||||
'namespace' => '\\think\\view\\driver\\',
|
||||
'namespace' => '\\think\\view\\driver\\',
|
||||
// 模板引擎配置参数
|
||||
'view_engine' => [
|
||||
'template' => [
|
||||
'type' => 'think',
|
||||
],
|
||||
];
|
||||
@@ -122,7 +118,10 @@ class View
|
||||
if ('php' == $engine) {
|
||||
$this->engine = 'php';
|
||||
} else {
|
||||
$class = $this->config['namespace'] . ucwords($engine);
|
||||
$class = $this->config['namespace'] . ucfirst($engine);
|
||||
if (empty($this->config['view_path']) && defined('VIEW_PATH')) {
|
||||
$this->config['view_path'] = VIEW_PATH;
|
||||
}
|
||||
$config = array_merge($config, [
|
||||
'view_path' => $this->config['view_path'],
|
||||
'view_suffix' => $this->config['view_suffix'],
|
||||
@@ -142,14 +141,13 @@ class View
|
||||
public function theme($theme)
|
||||
{
|
||||
if (true === $theme) {
|
||||
// 自动侦测
|
||||
$this->config['theme_on'] = true;
|
||||
$this->config['auto_detect_theme'] = true;
|
||||
// 启用主题
|
||||
$this->config['theme_on'] = true;
|
||||
} elseif (false === $theme) {
|
||||
// 关闭主题
|
||||
$this->config['theme_on'] = false;
|
||||
} else {
|
||||
// 指定模板主题
|
||||
// 指定主题
|
||||
$this->config['theme_on'] = true;
|
||||
$this->theme = $theme;
|
||||
}
|
||||
@@ -170,16 +168,8 @@ class View
|
||||
*/
|
||||
public function fetch($template = '', $vars = [], $config = [], $renderContent = false)
|
||||
{
|
||||
if (is_null($this->engine)) {
|
||||
// 初始化模板引擎
|
||||
if (empty($this->config['view_path']) && defined('VIEW_PATH')) {
|
||||
$this->config['view_path'] = VIEW_PATH;
|
||||
}
|
||||
$this->engine($this->config['view_engine']['type'], $this->config['view_engine']);
|
||||
}
|
||||
|
||||
// 模板变量
|
||||
$vars = $vars ? $vars : $this->data;
|
||||
$vars = array_merge($this->data, $vars);
|
||||
if (!$renderContent) {
|
||||
// 获取模板文件名
|
||||
$template = $this->parseTemplate($template);
|
||||
@@ -191,6 +181,10 @@ class View
|
||||
// 记录视图信息
|
||||
APP_DEBUG && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export($vars, true) . ' ]', 'info');
|
||||
}
|
||||
if (is_null($this->engine)) {
|
||||
// 初始化模板引擎
|
||||
$this->engine($this->config['template']['type'], $this->config['template']);
|
||||
}
|
||||
// 页面缓存
|
||||
ob_start();
|
||||
ob_implicit_flush(0);
|
||||
@@ -241,14 +235,20 @@ class View
|
||||
if (is_file($template)) {
|
||||
return realpath($template);
|
||||
}
|
||||
if (empty($this->config['view_path']) && defined('VIEW_PATH')) {
|
||||
$this->config['view_path'] = VIEW_PATH;
|
||||
}
|
||||
// 获取当前主题
|
||||
$theme = $this->getTemplateTheme();
|
||||
$this->config['view_path'] .= $theme;
|
||||
|
||||
$depr = $this->config['view_depr'];
|
||||
$template = str_replace(['/', ':'], $depr, $template);
|
||||
$theme = $this->getTemplateTheme();
|
||||
$path = $this->config['view_path'];
|
||||
if (strpos($template, '@')) {
|
||||
list($module, $template) = explode('@', $template);
|
||||
$path = APP_PATH . (APP_MULTI_MODULE ? $module . DS : '') . $this->config['view_layer'] . DS;
|
||||
} else {
|
||||
$path = $this->config['view_path'];
|
||||
}
|
||||
|
||||
// 分析模板文件规则
|
||||
@@ -260,7 +260,7 @@ class View
|
||||
$template = str_replace('.', DS, CONTROLLER_NAME) . $depr . $template;
|
||||
}
|
||||
}
|
||||
return realpath($path) . DS . $theme . $template . $this->config['view_suffix'];
|
||||
return realpath($path) . DS . $template . $this->config['view_suffix'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -274,24 +274,11 @@ class View
|
||||
if ($this->theme) {
|
||||
// 指定模板主题
|
||||
$theme = $this->theme;
|
||||
} elseif ($this->config['auto_detect_theme']) {
|
||||
// 自动侦测模板主题
|
||||
$t = $this->config['var_theme'];
|
||||
if (isset($_GET[$t])) {
|
||||
$theme = $_GET[$t];
|
||||
} elseif (Cookie::get('think_theme')) {
|
||||
$theme = Cookie::get('think_theme');
|
||||
}
|
||||
if (!isset($theme) || !is_dir($this->config['view_path'] . DS . $theme)) {
|
||||
$theme = $this->config['default_theme'];
|
||||
}
|
||||
Cookie::set('think_theme', $theme, 864000);
|
||||
} else {
|
||||
$theme = $this->config['default_theme'];
|
||||
}
|
||||
return $theme . DS;
|
||||
}
|
||||
return '';
|
||||
return isset($theme) ? $theme . DS : '';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
- conf 测试环境配置文件。
|
||||
- script 测试环境配置脚本。
|
||||
- thinkphp 测试用例和相关文件,与项目文件夹机构一致。
|
||||
- thinkphp 测试用例和相关文件,与项目文件夹结构一致。
|
||||
- mock.php 测试入口文件。
|
||||
|
||||
## 主要测试流程
|
||||
|
||||
14
tests/thinkphp/library/think/view/theme/index/template.html
Normal file
14
tests/thinkphp/library/think/view/theme/index/template.html
Normal file
@@ -0,0 +1,14 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="Generator" content="EditPlus®">
|
||||
<meta name="Author" content="">
|
||||
<meta name="Keywords" content="">
|
||||
<meta name="Description" content="">
|
||||
<title>Document</title>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -100,7 +100,6 @@ class viewTest extends \PHPUnit_Framework_TestCase
|
||||
$config_value = $property->getValue($view_instance);
|
||||
|
||||
$this->assertTrue($config_value['theme_on']);
|
||||
$this->assertTrue($config_value['auto_detect_theme']);
|
||||
|
||||
//关闭主题测试
|
||||
$data = $view_instance->theme(false);
|
||||
@@ -122,14 +121,16 @@ class viewTest extends \PHPUnit_Framework_TestCase
|
||||
public function testParseTemplate()
|
||||
{
|
||||
$view_instance = \think\View::instance();
|
||||
$method = new \ReflectionMethod('\think\View', 'ParseTemplate');
|
||||
$view_instance->theme('theme');
|
||||
$view_instance->config(['view_path' => __DIR__ . DS . 'view' . DS]);
|
||||
$method = new \ReflectionMethod('\think\View', 'ParseTemplate');
|
||||
$method->setAccessible(true);
|
||||
if (defined('CONTROLLER_NAME')) {
|
||||
$expect_data = DS . 'theme_name' . DS . CONTROLLER_NAME . DS . 'template_name.html';
|
||||
$expect_data = __DIR__ . DS . 'view' . DS . 'theme' . DS . CONTROLLER_NAME . DS . 'template.html';
|
||||
} else {
|
||||
$expect_data = DS . 'theme_name' . DS . 'template_name.html';
|
||||
$expect_data = __DIR__ . DS . 'view' . DS . 'theme' . DS . 'template.html';
|
||||
}
|
||||
$this->assertEquals($expect_data, $method->invoke($view_instance, 'template_name'));
|
||||
$this->assertEquals($expect_data, $method->invoke($view_instance, 'template'));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
padding: 20px;
|
||||
}
|
||||
h1{
|
||||
margin: 0;
|
||||
margin: 10px 0 0;
|
||||
font-size: 28px;
|
||||
font-weight: 500;
|
||||
line-height: 32px;
|
||||
@@ -22,7 +22,7 @@
|
||||
color: #4288ce;
|
||||
font-weight: 400;
|
||||
padding: 6px 0;
|
||||
margin: 10px 6px 0 0;
|
||||
margin: 6px 0 0;
|
||||
font-size: 18px;
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user