Php::parseTemplate()   F
last analyzed

Complexity

Conditions 16
Paths 338

Size

Total Lines 56
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 272

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 16
eloc 35
c 5
b 0
f 0
nc 338
nop 1
dl 0
loc 56
ccs 0
cts 31
cp 0
crap 272
rs 3.0083

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
// +----------------------------------------------------------------------
3
// | ThinkPHP [ WE CAN DO IT JUST THINK ]
4
// +----------------------------------------------------------------------
5
// | Copyright (c) 2006~2021 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 = [])
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
        extract($data, EXTR_OVERWRITE);
87
88
        include $this->template;
89
    }
90
91
    /**
92
     * 渲染模板内容
93
     * @access public
94
     * @param string $content 模板内容
95
     * @param array  $data    模板变量
96
     * @return void
97
     */
98
    public function display(string $content, array $data = []): void
99
    {
100
        $this->content = $content;
101
102
        extract($data, EXTR_OVERWRITE);
103
        eval('?>' . $this->content);
0 ignored issues
show
introduced by
The use of eval() is discouraged.
Loading history...
104
    }
105
106
    /**
107
     * 自动定位模板文件
108
     * @access private
109
     * @param string $template 模板文件规则
110
     * @return string
111
     */
112
    private function parseTemplate(string $template): string
113
    {
114
        $request = $this->app->request;
115
116
        // 获取视图根目录
117
        if (strpos($template, '@')) {
118
            // 跨应用调用
119
            [$app, $template] = explode('@', $template);
120
        }
121
122
        if ($this->config['view_path'] && !isset($app)) {
123
            $path = $this->config['view_path'];
124
        } else {
125
            $appName = isset($app) ? $app : $this->app->http->getName();
126
            $view    = $this->config['view_dir_name'];
127
128
            if (is_dir($this->app->getAppPath() . $view)) {
129
                $path = isset($app) ? $this->app->getBasePath() . ($appName ? $appName . DIRECTORY_SEPARATOR : '') . $view . DIRECTORY_SEPARATOR : $this->app->getAppPath() . $view . DIRECTORY_SEPARATOR;
130
            } else {
131
                $path = $this->app->getRootPath() . $view . DIRECTORY_SEPARATOR . ($appName ? $appName . DIRECTORY_SEPARATOR : '');
132
            }
133
        }
134
135
        $depr = $this->config['view_depr'];
136
137
        if (0 !== strpos($template, '/')) {
138
            $template   = str_replace(['/', ':'], $depr, $template);
139
            $controller = $request->controller();
140
            if (strpos($controller, '.')) {
141
                $pos        = strrpos($controller, '.');
142
                $controller = substr($controller, 0, $pos) . '.' . Str::snake(substr($controller, $pos + 1));
143
            } else {
144
                $controller = Str::snake($controller);
145
            }
146
147
            if ($controller) {
148
                if ('' == $template) {
149
                    // 如果模板文件名为空 按照默认规则定位
150
                    if (2 == $this->config['auto_rule']) {
151
                        $template = $request->action(true);
152
                    } elseif (3 == $this->config['auto_rule']) {
153
                        $template = $request->action();
154
                    } else {
155
                        $template = Str::snake($request->action());
156
                    }
157
158
                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
159
                } elseif (false === strpos($template, $depr)) {
160
                    $template = str_replace('.', DIRECTORY_SEPARATOR, $controller) . $depr . $template;
161
                }
162
            }
163
        } else {
164
            $template = str_replace(['/', ':'], $depr, substr($template, 1));
165
        }
166
167
        return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');
168
    }
169
170
    /**
171
     * 配置模板引擎
172
     * @access private
173
     * @param array $config 参数
174
     * @return void
175
     */
176
    public function config(array $config): void
177
    {
178
        $this->config = array_merge($this->config, $config);
179
    }
180
181
    /**
182
     * 获取模板引擎配置
183
     * @access public
184
     * @param string $name 参数名
185
     * @return mixed
186
     */
187
    public function getConfig(string $name)
188
    {
189
        return $this->config[$name] ?? null;
190
    }
191
}
192