1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Created by Gorlum 03.09.2019 0:16 |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace Template; |
7
|
|
|
|
8
|
|
|
use SnTemplate; |
9
|
|
|
use template; |
10
|
|
|
|
11
|
|
|
/** |
12
|
|
|
* Meta template - should work as interface between game and any rendering engine |
13
|
|
|
* |
14
|
|
|
* @package Template |
15
|
|
|
*/ |
16
|
|
|
class TemplateMeta { |
17
|
|
|
const INI_FILE_NAME = '_template.ini'; |
18
|
|
|
const CONFIG_RENDER_WHOLE = '_renderWhole'; |
19
|
|
|
/** |
20
|
|
|
* Конфигурация скина - читается из INI-файла |
21
|
|
|
* |
22
|
|
|
* @var array $config |
23
|
|
|
*/ |
24
|
|
|
protected $config = []; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* @var string |
28
|
|
|
*/ |
29
|
|
|
protected $name = ''; |
30
|
|
|
/** |
31
|
|
|
* Full path to template root |
32
|
|
|
* |
33
|
|
|
* @var string $pathFull |
34
|
|
|
*/ |
35
|
|
|
protected $pathFull = ''; |
36
|
|
|
/** |
37
|
|
|
* Relative path from any template |
38
|
|
|
* |
39
|
|
|
* @var string $pathRelative |
40
|
|
|
*/ |
41
|
|
|
protected $pathRelative = ''; |
42
|
|
|
|
43
|
|
|
/** |
44
|
|
|
* @var self|null $parent |
45
|
|
|
*/ |
46
|
|
|
protected $parent = null; |
47
|
|
|
|
48
|
|
|
/** |
49
|
|
|
* @var SnTemplate|null $manager |
50
|
|
|
*/ |
51
|
|
|
protected $manager = null; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* TemplateMeta constructor. |
55
|
|
|
* |
56
|
|
|
* @param SnTemplate $manager |
57
|
|
|
* @param $templateName |
58
|
|
|
* @param string $templatePath Path to template. Can be absolute (starting with '/', should also include template name if any) or relative to game root. Empty means "autodetect" |
59
|
|
|
*/ |
60
|
|
|
public function __construct($manager, $templateName, $templatePath = '') { |
61
|
|
|
$this->name = $templateName; |
62
|
|
|
$this->manager = $manager; |
63
|
|
|
|
64
|
|
|
if (empty($templatePath) || !is_string($templatePath)) { |
65
|
|
|
$this->pathFull = SN_ROOT_PHYSICAL . SnTemplate::SN_TEMPLATES_PARTIAL_PATH . $templateName . '/'; |
66
|
|
|
} else { |
67
|
|
|
if (substr($templatePath, -1) !== '/') { |
68
|
|
|
$templatePath .= '/'; |
69
|
|
|
} |
70
|
|
|
if (substr($templatePath, 0, 1) === '/') { |
71
|
|
|
// Absolute path |
72
|
|
|
$this->pathFull = $templatePath; |
73
|
|
|
} else { |
74
|
|
|
// Game root relative path |
75
|
|
|
$this->pathFull = SN_ROOT_PHYSICAL . $templatePath . $templateName . '/'; |
76
|
|
|
} |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
$this->loadIniFile(); |
80
|
|
|
$this->setParentFromConfig(); |
81
|
|
|
|
82
|
|
|
} |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* Loads skin configuration |
86
|
|
|
*/ |
87
|
|
|
protected function loadIniFile() { |
88
|
|
|
// Проверка на корректность и существование пути |
89
|
|
|
if (!is_file($this->pathFull . static::INI_FILE_NAME)) { |
90
|
|
|
return; |
91
|
|
|
} |
92
|
|
|
|
93
|
|
|
// Пытаемся распарсить файл |
94
|
|
|
// По секциям? images и config? Что бы не копировать конфигурацию? Или просто unset(__inherit) а затем заново записать |
95
|
|
|
$aConfig = parse_ini_file($this->pathFull . static::INI_FILE_NAME); |
96
|
|
|
if (empty($aConfig)) { |
97
|
|
|
return; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
$this->config = $aConfig; |
101
|
|
|
} |
102
|
|
|
|
103
|
|
|
protected function setParentFromConfig() { |
104
|
|
|
// Проверка на _inherit |
105
|
|
|
if (empty($this->config['_inherit'])) { |
106
|
|
|
return; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
$parentName = $this->config['_inherit']; |
110
|
|
|
// Если скин наследует себя... |
111
|
|
|
if ($parentName === $this->name) { |
112
|
|
|
// TODO - определять более сложные случаи циклических ссылок в _inherit |
113
|
|
|
// TODO - throw exception |
114
|
|
|
die('">circular skin inheritance!'); |
|
|
|
|
115
|
|
|
} |
116
|
|
|
|
117
|
|
|
$this->parent = $this->manager->registerTemplate($parentName); |
|
|
|
|
118
|
|
|
} |
119
|
|
|
|
120
|
|
|
/** |
121
|
|
|
* @param template $template |
122
|
|
|
* @param string $template_path |
123
|
|
|
* @param string $fallBackPath |
124
|
|
|
* |
125
|
|
|
* @return template |
126
|
|
|
*/ |
127
|
|
|
public function getTemplate($template, $template_path, $fallBackPath = '') { |
128
|
|
|
if (!is_object($template)) { |
129
|
|
|
$template = new template(SN_ROOT_PHYSICAL); |
130
|
|
|
} |
131
|
|
|
|
132
|
|
|
if (!$template_path || !is_string($template_path)) { |
133
|
|
|
$template_path = SN_ROOT_PHYSICAL . SnTemplate::SN_TEMPLATES_PARTIAL_PATH; |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
// var_dump($fallBackPath); |
137
|
|
|
// var_dump($template); |
138
|
|
|
|
139
|
|
|
if(empty($fallBackPath)) { |
140
|
|
|
if (!$this->parent || empty($fallbackName = $this->parent->getName()) || !$this->isTemplateExists()) { |
141
|
|
|
// If no parent template - then using default template as fallback one |
142
|
|
|
$fallbackName = SnTemplate::SN_TEMPLATE_NAME_DEFAULT; |
143
|
|
|
} |
144
|
|
|
$fallBackPath = $template_path . $fallbackName . '/'; |
145
|
|
|
} |
146
|
|
|
|
147
|
|
|
// var_dump($fallBackPath); |
148
|
|
|
|
149
|
|
|
$template->set_custom_template("{$template_path}{$this->name}/", $this->name, $fallBackPath); |
150
|
|
|
|
151
|
|
|
return $template; |
152
|
|
|
} |
153
|
|
|
|
154
|
|
|
|
155
|
|
|
public function getName() { |
156
|
|
|
return $this->name; |
157
|
|
|
} |
158
|
|
|
|
159
|
|
|
public function getPathFull() { |
160
|
|
|
return $this->pathFull; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
public function cssAddFileName($cssFileName, array $standard_css) { |
164
|
|
|
if ($this->parent) { |
165
|
|
|
$standard_css = $this->parent->cssAddFileName($cssFileName, $standard_css); |
166
|
|
|
} elseif (!$this->isTemplateExists()) { |
167
|
|
|
// If template dir does not exists - falling back to default CSS file |
168
|
|
|
$standard_css = SnTemplate::cssAddFileName(SnTemplate::SN_TEMPLATES_PARTIAL_PATH . SnTemplate::SN_TEMPLATE_NAME_DEFAULT . '/' . $cssFileName, $standard_css); |
169
|
|
|
} |
170
|
|
|
|
171
|
|
|
$standard_css = SnTemplate::cssAddFileName(SnTemplate::SN_TEMPLATES_PARTIAL_PATH . $this->name . '/' . $cssFileName, $standard_css); |
172
|
|
|
|
173
|
|
|
return $standard_css; |
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Does template files physically exists on disk? |
178
|
|
|
* Only full path to template checked |
179
|
|
|
* |
180
|
|
|
* @return bool |
181
|
|
|
*/ |
182
|
|
|
public function isTemplateExists() { |
183
|
|
|
return file_exists($this->pathFull); |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Is template rendered at once - not header/footer separately? |
188
|
|
|
* |
189
|
|
|
* @return bool |
190
|
|
|
*/ |
191
|
|
|
public function isRenderWhole() { |
192
|
|
|
return !empty($this->config[self::CONFIG_RENDER_WHOLE]); |
193
|
|
|
} |
194
|
|
|
|
195
|
|
|
} |
196
|
|
|
|
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.