1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Theme |
4
|
|
|
* |
5
|
|
|
* @package erdiko/core |
6
|
|
|
* @copyright 2012-2017 Arroyo Labs, Inc. http://www.arroyolabs.com |
7
|
|
|
* @author John Arroyo <[email protected]> |
8
|
|
|
*/ |
9
|
|
|
namespace erdiko\core; |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* @note the data array in this class uses a sort of NOSQL style approach to the theming |
14
|
|
|
*/ |
15
|
|
|
class Theme extends Container |
16
|
|
|
{ |
17
|
|
|
/** Theme root folder */ |
18
|
|
|
protected $_themeRootFolder; |
19
|
|
|
/** Name */ |
20
|
|
|
protected $_name = null; |
21
|
|
|
/** Context */ |
22
|
|
|
protected $_context = null; |
23
|
|
|
/** Context Config (application config) */ |
24
|
|
|
protected $_contextConfig = null; |
25
|
|
|
/** Theme Config */ |
26
|
|
|
protected $_themeConfig = null; |
27
|
|
|
/** Content */ |
28
|
|
|
protected $_content = null; |
29
|
|
|
|
30
|
|
|
/** |
31
|
|
|
* Constructor |
32
|
|
|
* |
33
|
|
|
* @param string $themeName |
34
|
|
|
* @param mixed $data |
35
|
|
|
* @param string $template Theme Object (Contanier) |
36
|
|
|
* @param string $context context to theme against (defaults to current environment context) |
37
|
|
|
*/ |
38
|
|
|
public function __construct($themeName = 'default', $data = null, |
39
|
|
|
$template = 'default', $context = null) |
40
|
|
|
{ |
41
|
|
|
$this->initiate($template, $data); |
42
|
|
|
$this->setThemeRootFolder('themes'); |
43
|
|
|
$this->setName($themeName); |
44
|
|
|
$this->_data = array( |
45
|
|
|
'js' =>array(), |
46
|
|
|
'css' => array(), |
47
|
|
|
'meta' => array() |
48
|
|
|
); |
49
|
|
|
|
50
|
|
|
// Context can only be set at instantiation (for theme stability) |
51
|
|
|
$this->_context = ($context === null) ? getenv('ERDIKO_CONTEXT') : $context; |
52
|
|
|
} |
53
|
|
|
|
54
|
|
|
/** |
55
|
|
|
* Get context config |
56
|
|
|
* This is the application config for the given context (e.g. default site) |
57
|
|
|
* Context is determined by environment variable ERDIKO_CONTEXT, getenv('ERDIKO_CONTEXT') |
58
|
|
|
* |
59
|
|
|
* @return array $config application config |
60
|
|
|
*/ |
61
|
|
|
public function getContextConfig() |
62
|
|
|
{ |
63
|
|
|
if (empty($this->_contextConfig)) |
64
|
|
|
$this->_contextConfig = Helper::getConfig('application', $this->_context); |
65
|
|
|
|
66
|
|
|
return $this->_contextConfig; |
67
|
|
|
} |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* Get Theme configuration (default theme) |
71
|
|
|
* |
72
|
|
|
* @return array $config |
73
|
|
|
*/ |
74
|
|
|
public function getThemeConfig() |
75
|
|
|
{ |
76
|
|
|
if (empty($this->_themeConfig)) { |
77
|
|
|
$file = $this->getThemeFolder() . 'theme.json'; |
78
|
|
|
$this->_themeConfig = Helper::getConfigFile($file); |
79
|
|
|
} |
80
|
|
|
return $this->_themeConfig; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Get Meta |
85
|
|
|
* |
86
|
|
|
* @return string $meta |
87
|
|
|
*/ |
88
|
|
View Code Duplication |
public function getMeta() |
|
|
|
|
89
|
|
|
{ |
90
|
|
|
if (isset($this->_contextConfig['site']['meta'])) { |
91
|
|
|
return array_merge($this->_contextConfig['site']['meta'],$this->_data['meta']); |
|
|
|
|
92
|
|
|
} else { |
93
|
|
|
return $this->_data['meta']; |
94
|
|
|
} |
95
|
|
|
} |
96
|
|
|
|
97
|
|
|
/** |
98
|
|
|
* Add meta file to page |
99
|
|
|
* |
100
|
|
|
* @param string $name |
101
|
|
|
* @param string $content |
102
|
|
|
*/ |
103
|
|
|
public function addMeta($name, $content) |
104
|
|
|
{ |
105
|
|
|
$this->_data['meta'][$name] = $content; |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* Add meta tag data to page |
110
|
|
|
* |
111
|
|
|
* @param array $meta format: array("name" => "content", "author" => "content", ...) |
112
|
|
|
*/ |
113
|
|
|
public function setMeta($meta) |
114
|
|
|
{ |
115
|
|
|
$this->_data['meta'] = $meta; |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
/** |
119
|
|
|
* Get SEO meta data and render as html (meta tags) |
120
|
|
|
* @return string html meta tags |
121
|
|
|
*/ |
122
|
|
|
public function getMetaMarkup() |
123
|
|
|
{ |
124
|
|
|
$html = ""; |
125
|
|
|
|
126
|
|
|
foreach ($this->getMeta() as $name => $content) |
|
|
|
|
127
|
|
|
{ |
128
|
|
|
if(is_array($content)) { |
129
|
|
|
foreach($content as $cont) |
130
|
|
|
$html .= "<meta name=\"{$name}\" content=\"{$cont}\">\n"; |
131
|
|
|
} else { |
132
|
|
|
$html .= "<meta name=\"{$name}\" content=\"{$content}\">\n"; |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
return $html; |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* Get page title |
141
|
|
|
* |
142
|
|
|
* @return string page title |
143
|
|
|
*/ |
144
|
|
|
public function getPageTitle() |
145
|
|
|
{ |
146
|
|
|
if (isset($this->_data['page_title'])) { |
147
|
|
|
return $this->_data['page_title']; |
148
|
|
|
} else { |
149
|
|
|
return null; |
150
|
|
|
} |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* Set page title |
155
|
|
|
* |
156
|
|
|
* @param string $title |
157
|
|
|
*/ |
158
|
|
|
public function setPageTitle($title) |
159
|
|
|
{ |
160
|
|
|
$this->_data['page_title'] = $title; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* Get body title |
165
|
|
|
* |
166
|
|
|
* @return string body title |
167
|
|
|
*/ |
168
|
|
|
public function getBodyTitle() |
169
|
|
|
{ |
170
|
|
|
if (isset($this->_data['body_title'])) { |
171
|
|
|
return $this->_data['body_title']; |
172
|
|
|
} else { |
173
|
|
|
return null; |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* Set body title |
179
|
|
|
* |
180
|
|
|
* @param string $title |
181
|
|
|
*/ |
182
|
|
|
public function setBodyTitle($title) |
183
|
|
|
{ |
184
|
|
|
$this->_data['body_title'] = $title; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* Get array of css files to include in theme |
189
|
|
|
* |
190
|
|
|
* @return array css file paths |
191
|
|
|
* @todo sort by the 'order' value |
192
|
|
|
*/ |
193
|
|
View Code Duplication |
public function getCss() |
|
|
|
|
194
|
|
|
{ |
195
|
|
|
if (isset($this->_themeConfig['css'])) { |
196
|
|
|
return array_merge($this->_themeConfig['css'], $this->_data['css']); |
197
|
|
|
} else { |
198
|
|
|
return $this->_data['css']; |
199
|
|
|
} |
200
|
|
|
} |
201
|
|
|
|
202
|
|
|
/** |
203
|
|
|
* Add css file to page |
204
|
|
|
* @note there are collisions with using addCss and data['css'] |
205
|
|
|
* |
206
|
|
|
* @param string $name |
207
|
|
|
* @param string $cssFile URL of injected css file |
208
|
|
|
* @param int $order |
209
|
|
|
* @param boolean $active defaults to 1 |
210
|
|
|
* @todo need to resolve order of merging and/or eliminate/refactor this function |
211
|
|
|
*/ |
212
|
|
|
public function addCss($name, $cssFile, $order = 10, $active = 1) |
213
|
|
|
{ |
214
|
|
|
$this->_data['css'][$name] = array( |
215
|
|
|
'file' => $cssFile, |
216
|
|
|
'order' => $order, |
217
|
|
|
'active' => $active |
218
|
|
|
); |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
/** |
222
|
|
|
* Get array of js files to include |
223
|
|
|
* |
224
|
|
|
* @return array js file paths |
225
|
|
|
* @todo sort by the 'order' value |
226
|
|
|
*/ |
227
|
|
View Code Duplication |
public function getJs() |
|
|
|
|
228
|
|
|
{ |
229
|
|
|
if (isset($this->_themeConfig['js'])) { |
230
|
|
|
return array_merge($this->_themeConfig['js'], $this->_data['js']); |
231
|
|
|
} else { |
232
|
|
|
return $this->_data['js']; |
233
|
|
|
} |
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Add js file to page |
238
|
|
|
* |
239
|
|
|
* @param string $name |
240
|
|
|
* @param string $jsFile URL of js file |
241
|
|
|
* @param int $order |
242
|
|
|
* @param boolean $active defaults to 1 |
243
|
|
|
* @todo same issue as addCss |
244
|
|
|
*/ |
245
|
|
|
public function addJs($name, $jsFile, $order = 10, $active = 1) |
246
|
|
|
{ |
247
|
|
|
$this->_data['js'][$name] = array( |
248
|
|
|
'file' => $jsFile, |
249
|
|
|
'order' => $order, |
250
|
|
|
'active' => $active |
251
|
|
|
); |
252
|
|
|
} |
253
|
|
|
|
254
|
|
|
/** |
255
|
|
|
* Get Theme Root Folder |
256
|
|
|
* |
257
|
|
|
* @param string $folder |
|
|
|
|
258
|
|
|
*/ |
259
|
|
|
public function getThemeRootFolder() |
260
|
|
|
{ |
261
|
|
|
return $this->_themeRootFolder; |
262
|
|
|
} |
263
|
|
|
|
264
|
|
|
/** |
265
|
|
|
* Set Theme Root Folder |
266
|
|
|
* |
267
|
|
|
* @param string $folder |
268
|
|
|
*/ |
269
|
|
|
public function setThemeRootFolder($folder) |
270
|
|
|
{ |
271
|
|
|
$this->_themeRootFolder = $folder; |
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/** |
275
|
|
|
* Get the theme folder |
276
|
|
|
* |
277
|
|
|
* @return string $folder |
278
|
|
|
*/ |
279
|
|
|
public function getThemeFolder() |
280
|
|
|
{ |
281
|
|
|
return $this->getTemplateFolderPath().$this->getThemeRootFolder().'/'.$this->getName().'/'; |
282
|
|
|
} |
283
|
|
|
|
284
|
|
|
/** |
285
|
|
|
* Get template folder relative to the theme root |
286
|
|
|
* |
287
|
|
|
* @return string |
288
|
|
|
*/ |
289
|
|
|
public function getTemplateFolder() |
290
|
|
|
{ |
291
|
|
|
return $this->getThemeFolder().'templates/'; |
292
|
|
|
} |
293
|
|
|
|
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Set content |
297
|
|
|
* |
298
|
|
|
* @param string|Container $content any string or object that implements __toString() |
299
|
|
|
*/ |
300
|
|
|
public function setContent($content) |
301
|
|
|
{ |
302
|
|
|
$this->_content = $content; |
303
|
|
|
} |
304
|
|
|
|
305
|
|
|
/** |
306
|
|
|
* Get content |
307
|
|
|
* |
308
|
|
|
* @return string|Container content |
309
|
|
|
*/ |
310
|
|
|
public function getContent() |
311
|
|
|
{ |
312
|
|
|
return $this->_content; |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* Set the theme name, the name is also the id of the theme |
317
|
|
|
* |
318
|
|
|
* @param string Theme name |
319
|
|
|
*/ |
320
|
|
|
public function setName($name) |
321
|
|
|
{ |
322
|
|
|
$this->_name = $name; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* Get name. |
327
|
|
|
* Return Theme name |
328
|
|
|
* |
329
|
|
|
* @return string name |
330
|
|
|
*/ |
331
|
|
|
public function getName() |
332
|
|
|
{ |
333
|
|
|
return $this->_name; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* Get template file populated by the config |
338
|
|
|
* |
339
|
|
|
* @usage Partial render need to be declared in theme.json |
340
|
|
|
* e.g. get header/footer |
341
|
|
|
* @param string $partial |
342
|
|
|
* @return string html |
343
|
|
|
*/ |
344
|
|
|
public function getTemplateHtml($partial) |
345
|
|
|
{ |
346
|
|
|
$config = $this->getThemeConfig(); |
347
|
|
|
// @todo add check here to make sure partial exists, if missing log error |
348
|
|
|
$filename = $this->getTemplateFolder().$config['templates'][$partial]['file']; |
349
|
|
|
|
350
|
|
|
$html = $this->getTemplateFile($filename, $this->getContextConfig()); |
351
|
|
|
|
352
|
|
|
return $html; |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
/** |
356
|
|
|
* Output content to html |
357
|
|
|
* |
358
|
|
|
* @return string html |
359
|
|
|
*/ |
360
|
|
|
public function toHtml() |
361
|
|
|
{ |
362
|
|
|
// load the theme and context (site) configs |
363
|
|
|
$this->getContextConfig(); |
364
|
|
|
$this->getThemeConfig(); |
365
|
|
|
|
366
|
|
|
$filename = $this->getTemplateFolder().$this->getTemplate(); |
367
|
|
|
$html = $this->getTemplateFile($filename, $this); |
|
|
|
|
368
|
|
|
|
369
|
|
|
return $html; |
370
|
|
|
} |
371
|
|
|
} |
372
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.