Passed
Push — dev ( 5026e0...59bedf )
by 世昌
02:20
created

RawTemplate::assign()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace suda\application\template;
4
5
use Exception;
6
use function extract;
7
use function ob_get_clean;
8
use ReflectionException;
9
use suda\application\Resource;
10
use suda\framework\arrayobject\ArrayDotAccess;
11
use suda\application\exception\NoTemplateFoundException;
12
use suda\framework\runnable\Runnable;
13
14
/**
15
 * 应用程序
16
 */
17
class RawTemplate
18
{
19
    /**
20
     * 路径
21
     *
22
     * @var string
23
     */
24
    protected $path;
25
26
    /**
27
     * 模板值
28
     *
29
     * @var array
30
     */
31
    protected $value;
32
33
    /**
34
     * 父模版
35
     *
36
     * @var CompilableTemplate|null
37
     */
38
    protected $parent = null;
39
40
41
    /**
42
     * 模板钩子
43
     *
44
     * @var array
45
     */
46
    protected $hooks = [];
47
48
    /**
49
     * 继承的模板
50
     *
51
     * @var string|null
52
     */
53
    protected $extend = null;
54
55
    /**
56
     * RawTemplate constructor.
57
     * @param string $path
58
     * @param array $value
59
     */
60
    public function __construct(string $path, array $value = [])
61
    {
62
        $this->path = $path;
63
        $this->value = $value;
64
    }
65
66
    /**
67
     * 单个设置值
68
     *
69
     * @param string $name
70
     * @param mixed $value
71
     * @return $this
72
     */
73
    public function set(string $name, $value)
74
    {
75
        $this->value = ArrayDotAccess::set($this->value, $name, $value);
76
        return $this;
77
    }
78
79
    /**
80
     * 直接压入值
81
     *
82
     * @param array $values
83
     * @return $this
84
     */
85
    public function assign(array $values)
86
    {
87
        $this->value = array_merge($this->value, $values);
88
        return $this;
89
    }
90
91
92
    /**
93
     * 创建模板获取值
94
     *
95
     * @param string $name
96
     * @param mixed $default
97
     * @return mixed
98
     */
99
    public function get(string $name = null, $default = null)
100
    {
101
        if (null === $name) {
102
            return $this->value;
103
        }
104
        return ArrayDotAccess::get($this->value, $name, $default ?? $name);
105
    }
106
107
    /**
108
     * 检测值
109
     *
110
     * @param string $name
111
     * @return boolean
112
     */
113
    public function has(string $name)
114
    {
115
        return ArrayDotAccess::exist($this->value, $name);
116
    }
117
118
    protected function getPath()
119
    {
120
        return $this->path;
121
    }
122
123
    /**
124
     * @param string $name
125
     * @param mixed ...$args
126
     * @return mixed
127
     * @throws ReflectionException
128
     */
129
    public function data(string $name, ...$args)
130
    {
131
        if (func_num_args() > 1) {
132
            return (new Runnable($name))->run($this, ...$args);
133
        }
134
        return (new Runnable($name))->apply([$this]);
135
    }
136
137
138
    public function insert(string $name, $callback)
139
    {
140
        // 存在父模板
141
        if ($this->parent) {
142
            $this->parent->insert($name, $callback);
143
        } else {
144
            // 添加回调钩子
145
            $this->hooks[$name][] = new Runnable($callback);
146
        }
147
    }
148
149
    public function exec(string $name)
150
    {
151
        try {
152
            // 存在父模板
153
            if ($this->parent) {
154
                $this->parent->exec($name);
155
            } elseif (isset($this->hooks[$name])) {
156
                foreach ($this->hooks[$name] as $hook) {
157
                    $hook->run();
158
                }
159
            }
160
        } catch (Exception $e) {
161
            echo '<div style="color:red">' . $e->getMessage() . '</div>';
162
            return;
163
        }
164
    }
165
166
    /**
167
     * @return string
168
     * @throws Exception
169
     */
170
    public function getRenderedString()
171
    {
172
        if (file_exists($this->getPath())) {
173
            ob_start();
174
            extract($this->value);
175
            include $this->getPath();
176
            if ($this->extend) {
177
                $this->include($this->extend);
178
            }
179
            return ob_get_clean() ?: '';
180
        }
181
        throw new NoTemplateFoundException(
182
            'missing dest at ' . $this->getPath(),
183
            E_USER_ERROR,
184
            $this->getPath(),
185
            1
186
        );
187
    }
188
189
    /**
190
     * 获取渲染后的字符串
191
     * @ignore-dump
192
     * @throws Exception
193
     * @return string
194
     */
195
    public function render()
196
    {
197
        $content = $this->getRenderedString();
198
        $content = trim($content);
199
        return $content;
200
    }
201
202
    /**
203
     * 创建模板
204
     * @param $template
205
     * @return $this
206
     */
207
    public function parent($template)
208
    {
209
        $this->parent = $template;
210
        return $this;
211
    }
212
213
214
    /**
215
     * @param string $name
216
     * @return $this
217
     */
218
    public function extend(string $name)
219
    {
220
        $this->extend = $name;
221
        return $this;
222
    }
223
224
    /**
225
     * @param string $path
226
     * @throws Exception
227
     */
228
    public function include(string $path)
229
    {
230
        $included = new self($path, $this->value);
231
        $included->parent = $this;
0 ignored issues
show
Documentation Bug introduced by
$this is of type suda\application\template\RawTemplate, but the property $parent was declared to be of type null|suda\application\template\CompilableTemplate. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
232
        echo $included->getRenderedString();
233
    }
234
}
235