-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathViewHandler.php
121 lines (97 loc) · 2.6 KB
/
ViewHandler.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
<?php
namespace App;
class ViewHandler {
private const CMD_EXTENDS = '/@extends\([\'"](.*?)[\'"]\)/im';
private const CMD_INCLUDE = '/@include\([\'"](.*?)[\'"]\)/im';
private $name;
private $vars;
/**
* ViewHandler constructor.
*/
public function __construct($name, array $vars = []) {
$this->name = $name;
$request = RequestHandler::$currentRequest;
$this->vars = array_merge($request->all(), $vars);
}
public function render(): string {
require_once implode(DIRECTORY_SEPARATOR, [
BASE_DIR,
'resources',
'views',
self::fileByName('helpers')
]);
$content = $this->view($this->name);
$content = $this->layout($content);
return $this->include($content);
}
public function with(string $name, $value): ViewHandler {
$this->vars[$name] = $value;
return $this;
}
private static function fileByName(string $name) {
return implode(DIRECTORY_SEPARATOR, explode('.', $name)) . '.php';
}
private function view(string $name) {
ob_start();
// load vars
foreach ($this->vars as $var_name => $value) {
$$var_name = $value;
}
// get the file
include implode(DIRECTORY_SEPARATOR, [
BASE_DIR,
'resources',
'views',
self::fileByName($name)
]);
$additionalVars = get_defined_vars();
unset($additionalVars['name']);
$this->vars = array_merge($this->vars, $additionalVars);
return ob_get_clean();
}
private function layout(string $content) {
preg_match(self::CMD_EXTENDS, $content, $matches);
if (count($matches) > 0) {
$content = preg_replace(self::CMD_EXTENDS, '', $content);
$extends = $matches[1];
} else {
return $content;
}
ob_start();
// load vars
foreach ($this->vars as $name => $value) {
$$name = $value;
}
include implode(DIRECTORY_SEPARATOR, [
BASE_DIR,
'resources',
'views',
self::fileByName($extends)
]);
$additionalVars = get_defined_vars();
unset(
$additionalVars['content'],
$additionalVars['matches'],
$additionalVars['value'],
$additionalVars['name'],
$additionalVars['extends']
);
$this->vars = array_merge($this->vars, $additionalVars);
return ob_get_clean();
}
private function include(string $content) {
$offset = 0;
while (preg_match(self::CMD_INCLUDE, $content, $matches, 0, $offset)) {
if (count($matches) > 0) {
$parts = preg_split(self::CMD_INCLUDE, $content, 2);
$partial = new ViewHandler($matches[1], $this->vars);
$partialRendered = $partial->render();
$offset = strlen($parts[0]) + strlen($partialRendered) - 1;
$content = implode('', [$parts[0], $partialRendered, $parts[1]]);
} else {
break;
}
}
return $content;
}
}