Passed
Pull Request — 8.0 (#3044)
by wj
02:20
created

Php::parseTemplate()   C

Complexity

Conditions 15
Paths 182

Size

Total Lines 56
Code Lines 35

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 240

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 15
eloc 35
nc 182
nop 1
dl 0
loc 56
ccs 0
cts 31
cp 0
crap 240
rs 5.2333
c 5
b 0
f 0

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