Passed
Push — 6.0 ( a5b60d...b72c2e )
by liu
06:04
created

Php::config()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 2
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2019 http://thinkphp.cn All rights reserved.
6
// +----------------------------------------------------------------------
7
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
8
// +----------------------------------------------------------------------
9
// | Author: liu21st <[email protected]>
10
// +----------------------------------------------------------------------
11
declare (strict_types = 1);
12
13
namespace think\view\driver;
14
15
use RuntimeException;
16
use think\App;
17
use think\contract\TemplateHandlerInterface;
18
use think\helper\Str;
19
20
/**
21
 * PHP原生模板驱动
22
 */
23
class Php implements TemplateHandlerInterface
24
{
25
    protected $template;
26
    protected $content;
27
    protected $app;
28
29
    // 模板引擎参数
30
    protected $config = [
31
        // 默认模板渲染规则 1 解析为小写+下划线 2 全部转换小写 3 保持操作方法
32
        'auto_rule'     => 1,
33
        // 视图目录名
34
        'view_dir_name' => 'view',
35
        // 应用模板路径
36
        'view_path'     => '',
37
        // 模板文件后缀
38
        'view_suffix'   => 'php',
39
        // 模板文件名分隔符
40
        'view_depr'     => DIRECTORY_SEPARATOR,
41
    ];
42
43
    public function __construct(App $app, array $config = [])
0 ignored issues
show
Coding Style introduced by
Missing doc comment for function __construct()
Loading history...
44
    {
45
        $this->app    = $app;
46
        $this->config = array_merge($this->config, (array) $config);
47
    }
48
49
    /**
50
     * 检测是否存在模板文件
51
     * @access public
52
     * @param string $template 模板文件或者模板规则
53
     * @return bool
54
     */
55
    public function exists(string $template): bool
56
    {
57
        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
58
            // 获取模板文件名
59
            $template = $this->parseTemplate($template);
60
        }
61
62
        return is_file($template);
63
    }
64
65
    /**
66
     * 渲染模板文件
67
     * @access public
68
     * @param string $template 模板文件
69
     * @param array  $data     模板变量
70
     * @return void
71
     */
72
    public function fetch(string $template, array $data = []): void
73
    {
74
        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
75
            // 获取模板文件名
76
            $template = $this->parseTemplate($template);
77
        }
78
79
        // 模板不存在 抛出异常
80
        if (!is_file($template)) {
81
            throw new RuntimeException('template not exists:' . $template);
82
        }
83
84
        $this->template = $template;
85
86
        // 记录视图信息
87
        $this->app->log
88
            ->record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]');
89
90
        extract($data, EXTR_OVERWRITE);
91
92
        include $this->template;
93
    }
94
95
    /**
96
     * 渲染模板内容
97
     * @access public
98
     * @param string $content 模板内容
99
     * @param array  $data    模板变量
100
     * @return void
101
     */
102
    public function display(string $content, array $data = []): void
103
    {
104
        $this->content = $content;
105
106
        extract($data, EXTR_OVERWRITE);
107
        eval('?>' . $this->content);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
108
    }
109
110
    /**
111
     * 自动定位模板文件
112
     * @access private
113
     * @param string $template 模板文件规则
114
     * @return string
115
     */
116
    private function parseTemplate(string $template): string
0 ignored issues
show
Coding Style introduced by
Private method name "Php::parseTemplate" must be prefixed with an underscore
Loading history...
117
    {
118
        $request = $this->app->request;
119
120
        // 获取视图根目录
121
        if (strpos($template, '@')) {
122
            // 跨模块调用
123
            list($app, $template) = explode('@', $template);
124
        }
125
126
        if ($this->config['view_path'] && !isset($app)) {
127
            $path = $this->config['view_path'];
128
        } else {
129
            $appName = isset($app) ? $app : $request->app();
130
            $view    = $this->config['view_dir_name'];
131
132
            if (is_dir($this->app->getAppPath() . $view)) {
133
                $path = isset($app) ? $this->app->getBasePath() . ($appName ? $appName . DIRECTORY_SEPARATOR : '') . $view . DIRECTORY_SEPARATOR : $this->app->getAppPath() . $view . DIRECTORY_SEPARATOR;
134
            } else {
135
                $path = $this->app->getRootPath() . $view . DIRECTORY_SEPARATOR . ($appName ? $appName . DIRECTORY_SEPARATOR : '');
136
            }
137
        }
138
139
        $depr = $this->config['view_depr'];
140
141
        if (0 !== strpos($template, '/')) {
142
            $template   = str_replace(['/', ':'], $depr, $template);
143
            $controller = $request->controller();
144
            if (strpos($controller, '.')) {
145
                $pos        = strrpos($controller, '.');
146
                $controller = substr($controller, 0, $pos) . '.' . Str::snake(substr($controller, $pos + 1));
147
            } else {
148
                $controller = Str::snake($controller);
149
            }
150
151
            if ($controller) {
152
                if ('' == $template) {
153
                    // 如果模板文件名为空 按照默认规则定位
154
                    if (2 == $this->config['auto_rule']) {
155
                        $template = $request->action(true);
156
                    } elseif (3 == $this->config['auto_rule']) {
157
                        $template = $request->action();
158
                    } else {
159
                        $template = Str::snake($request->action());
160
                    }
161
162
                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
163
                } elseif (false === strpos($template, $depr)) {
164
                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
165
                }
166
            }
167
        } else {
168
            $template = str_replace(['/', ':'], $depr, substr($template, 1));
169
        }
170
171
        return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
172
    }
173
174
    /**
175
     * 配置模板引擎
176
     * @access private
177
     * @param array $config 参数
178
     * @return void
179
     */
180
    public function config(array $config): void
181
    {
182
        $this->config = array_merge($this->config, $config);
183
    }
184
185
    /**
186
     * 获取模板引擎配置
187
     * @access public
188
     * @param string $name 参数名
189
     * @return mixed
190
     */
191
    public function getConfig(string $name)
192
    {
193
        return $this->config[$name] ?? null;
194
    }
195
}
196