1
|
|
|
<?php declare(strict_types=1);
|
2
|
|
|
|
3
|
|
|
use html_go\i18n\I18n;
|
4
|
|
|
use html_go\indexing\IndexManager;
|
5
|
|
|
use html_go\markdown\MarkdownParser;
|
6
|
|
|
use html_go\markdown\ParsedownParser;
|
7
|
|
|
use html_go\model\Config;
|
8
|
|
|
use html_go\model\ModelFactory;
|
9
|
|
|
use html_go\templating\TemplateEngine;
|
10
|
|
|
use html_go\templating\TwigTemplateEngine;
|
11
|
|
|
|
12
|
|
|
/**
|
13
|
|
|
* Returns an multi-dimensional array. The first level is the menu name, the
|
14
|
|
|
* second level is an array of stdClass objects each representing a menu node.
|
15
|
|
|
* @return array<mixed>
|
16
|
|
|
*/
|
17
|
|
|
function get_menu(): array {
|
18
|
|
|
return get_index_manager()->getMenusIndex();
|
19
|
|
|
}
|
20
|
|
|
|
21
|
|
|
/**
|
22
|
|
|
* Returns the page number from the query string (if there is one).
|
23
|
|
|
* @return int Default value is one (1)
|
24
|
|
|
*/
|
25
|
|
|
function get_pagination_pagenumber(): int {
|
26
|
|
|
$pageNum = 1;
|
27
|
|
|
if (($page = get_query_parameter('page')) !== null && \ctype_digit($page)) {
|
28
|
|
|
$pageNum = (int)$page;
|
29
|
|
|
}
|
30
|
|
|
return $pageNum;
|
31
|
|
|
}
|
32
|
|
|
|
33
|
|
|
/**
|
34
|
|
|
* Returns a pagination page of tags.
|
35
|
|
|
* @param int $pageNum The page number
|
36
|
|
|
* @param int $perPage Items per page. Default is 0 (zero) which means return all
|
37
|
|
|
* @return array<\stdClass>
|
38
|
|
|
*/
|
39
|
|
|
function get_tags(int $pageNum = 1, int $perPage = 0): array {
|
40
|
|
|
$tags = get_index_manager()->getTagIndex();
|
41
|
|
|
if ($perPage > 0) {
|
42
|
|
|
$tags = \array_slice($tags, ($pageNum - 1) * $perPage, $perPage);
|
43
|
|
|
}
|
44
|
|
|
return get_model_list($tags);
|
45
|
|
|
}
|
46
|
|
|
|
47
|
|
|
/**
|
48
|
|
|
* Returns a pagination page of categories.
|
49
|
|
|
* @param int $pageNum The page number
|
50
|
|
|
* @param int $perPage Items per page. Default is 0 (zero) which means return all
|
51
|
|
|
* @return array<\stdClass> The resulting list of posts
|
52
|
|
|
*/
|
53
|
|
|
function get_categories(int $pageNum = 1, int $perPage = 0): array {
|
54
|
|
|
$cats = get_index_manager()->getCategoriesIndex();
|
55
|
|
|
if ($perPage > 0) {
|
56
|
|
|
$cats = \array_slice($cats, ($pageNum - 1) * $perPage, $perPage);
|
57
|
|
|
}
|
58
|
|
|
return get_model_list($cats);
|
59
|
|
|
}
|
60
|
|
|
|
61
|
|
|
/**
|
62
|
|
|
* Takes an array of index <code>Element</code> object and converts them to an array of
|
63
|
|
|
* <code>stdClass</code> objects.
|
64
|
|
|
* @param array<string, html_go\indexing\Element> $indexList
|
65
|
|
|
* @return array<\stdClass>
|
66
|
|
|
*/
|
67
|
|
|
function get_model_list(array $indexList): array {
|
68
|
|
|
$list = [];
|
69
|
|
|
$factory = get_model_factory();
|
70
|
|
|
foreach ($indexList as $obj) {
|
71
|
|
|
$list[] = $factory->createContentObject($obj);
|
72
|
|
|
}
|
73
|
|
|
return $list;
|
74
|
|
|
}
|
75
|
|
|
|
76
|
|
|
/**
|
77
|
|
|
* Build and return the template context.
|
78
|
|
|
* @param \stdClass $content
|
79
|
|
|
* @return array<mixed>
|
80
|
|
|
*/
|
81
|
|
|
function get_template_context(\stdClass $content): array {
|
82
|
|
|
$template = DEFAULT_TEMPLATE;
|
83
|
|
|
if (isset($content->template)) {
|
84
|
|
|
$template = $content->template;
|
85
|
|
|
}
|
86
|
|
|
return [
|
87
|
|
|
'i18n' => get_i18n(),
|
88
|
|
|
'content' => $content,
|
89
|
|
|
TEMPLATE_TPLVAR_KEY => $template
|
90
|
|
|
];
|
91
|
|
|
}
|
92
|
|
|
|
93
|
|
|
/**
|
94
|
|
|
* Return the <code>i18n</code> instance.
|
95
|
|
|
* @return I18n
|
96
|
|
|
*/
|
97
|
|
|
function get_i18n(): I18n {
|
98
|
|
|
static $object = null;
|
99
|
|
|
if (empty($object)) {
|
100
|
|
|
$object = new I18n(LANG_ROOT.DS.get_config()->getString(Config::KEY_LANG).'.messages.php');
|
101
|
|
|
}
|
102
|
|
|
return $object;
|
103
|
|
|
}
|
104
|
|
|
|
105
|
|
|
/**
|
106
|
|
|
* Render the given template placing the given variables into the template context.
|
107
|
|
|
* Note: template defined in the front matter of the content file takes precendence.
|
108
|
|
|
* @param string $template Default is <code>null</code>
|
109
|
|
|
* @param array<mixed> $vars
|
110
|
|
|
* @return string
|
111
|
|
|
*/
|
112
|
|
|
function render(string $template = null, array $vars = []): string {
|
113
|
|
|
$tpl = DEFAULT_TEMPLATE;
|
114
|
|
|
if (!empty($template)) {
|
115
|
|
|
$tpl = $template;
|
116
|
|
|
}
|
117
|
|
|
// Front matter from content file takes precendence
|
118
|
|
|
if (isset($vars[TEMPLATE_TPLVAR_KEY])) {
|
119
|
|
|
$tpl = $vars[TEMPLATE_TPLVAR_KEY];
|
120
|
|
|
}
|
121
|
|
|
return get_template_engine()->render($tpl, $vars);
|
122
|
|
|
}
|
123
|
|
|
|
124
|
|
|
/**
|
125
|
|
|
* Helper function for 404 page.
|
126
|
|
|
* @return string
|
127
|
|
|
*/
|
128
|
|
|
function not_found(): string {
|
129
|
|
|
return render('404.html', ['i18n' => get_i18n()]);
|
130
|
|
|
}
|
131
|
|
|
|
132
|
|
|
/**
|
133
|
|
|
* Get the configured template engine.
|
134
|
|
|
* @return TemplateEngine
|
135
|
|
|
*/
|
136
|
|
|
function get_template_engine(): TemplateEngine {
|
137
|
|
|
static $engine = null;
|
138
|
|
|
if (empty($engine)) {
|
139
|
|
|
$themeName = get_config()->getString(Config::KEY_THEME_NAME);
|
140
|
|
|
$engineName = get_config()->getString(Config::KEY_TPL_ENGINE);
|
141
|
|
|
|
142
|
|
|
$caching = false;
|
143
|
|
|
$strict = true;
|
|
|
|
|
144
|
|
|
if (get_config()->getBool(Config::KEY_TPL_CACHING)) {
|
145
|
|
|
$caching = CACHE_ROOT.DS.'template_cache';
|
146
|
|
|
}
|
147
|
|
|
$strict = get_config()->getBool(Config::KEY_TPL_STRICT_VARS_TWIG);
|
148
|
|
|
$options = [
|
149
|
|
|
'cache' => $caching,
|
150
|
|
|
'strict_variables' => $strict
|
151
|
|
|
];
|
152
|
|
|
$templateDirs = [THEMES_ROOT.DS.$engineName.DS.$themeName];
|
153
|
|
|
$engine = new TwigTemplateEngine($templateDirs, $options);
|
154
|
|
|
}
|
155
|
|
|
return $engine;
|
156
|
|
|
}
|
157
|
|
|
|
158
|
|
|
/**
|
159
|
|
|
* Returns the instance of the <code>IndexManager</code>.
|
160
|
|
|
* @return IndexManager
|
161
|
|
|
*/
|
162
|
|
|
function get_index_manager(): IndexManager {
|
163
|
|
|
static $manager = null;
|
164
|
|
|
if ($manager === null) {
|
165
|
|
|
$manager = new IndexManager(APP_ROOT);
|
166
|
|
|
}
|
167
|
|
|
return $manager;
|
168
|
|
|
}
|
169
|
|
|
|
170
|
|
|
/**
|
171
|
|
|
* Return the instance of the <code>Config</code>.
|
172
|
|
|
* @return Config
|
173
|
|
|
*/
|
174
|
|
|
function get_config(): Config {
|
175
|
|
|
static $config = null;
|
176
|
|
|
if (empty($config)) {
|
177
|
|
|
$config = new Config(CONFIG_ROOT);
|
178
|
|
|
}
|
179
|
|
|
return $config;
|
180
|
|
|
}
|
181
|
|
|
|
182
|
|
|
/**
|
183
|
|
|
* Returns the instance of the <code>ModelFactory</code>.
|
184
|
|
|
* @return ModelFactory
|
185
|
|
|
*/
|
186
|
|
|
function get_model_factory(): ModelFactory {
|
187
|
|
|
static $factory = null;
|
188
|
|
|
if (empty($factory)) {
|
189
|
|
|
$factory = new ModelFactory(get_config(), get_markdown_parser());
|
190
|
|
|
}
|
191
|
|
|
return $factory;
|
192
|
|
|
}
|
193
|
|
|
|
194
|
|
|
/**
|
195
|
|
|
* Returns the instance of the <code>MarkdownParser</code>.
|
196
|
|
|
* @return MarkdownParser
|
197
|
|
|
*/
|
198
|
|
|
function get_markdown_parser(): MarkdownParser {
|
199
|
|
|
static $parser = null;
|
200
|
|
|
if (empty($parser)) {
|
201
|
|
|
$parser = new ParsedownParser();
|
202
|
|
|
}
|
203
|
|
|
return $parser;
|
204
|
|
|
}
|
205
|
|
|
|
206
|
|
|
/**
|
207
|
|
|
* Get a <code>Content</code> object (if any) associated with the given slug.
|
208
|
|
|
* @param string $slug
|
209
|
|
|
* @param array<\stdClass>$listing
|
210
|
|
|
* @return \stdClass|NULL if no content was found associated with the given slug <code>null</code> is returned.
|
211
|
|
|
*/
|
212
|
|
|
function get_content_object(string $slug, array $listing = []): ?\stdClass {
|
213
|
|
|
$manager = get_index_manager();
|
214
|
|
|
if ($manager->elementExists($slug) === false) {
|
215
|
|
|
return null;
|
216
|
|
|
}
|
217
|
|
|
$content = get_model_factory()->createContentObject($manager->getElementFromSlugIndex($slug));
|
218
|
|
|
if (!empty($listing)) {
|
219
|
|
|
$content->listing = $listing;
|
220
|
|
|
}
|
221
|
|
|
$content->menus = get_menu();
|
222
|
|
|
return $content;
|
223
|
|
|
}
|
224
|
|
|
|
225
|
|
|
/**
|
226
|
|
|
* Returns a pagination page of posts.
|
227
|
|
|
* @param int $pageNum The page number
|
228
|
|
|
* @param int $perPage Items per page
|
229
|
|
|
* @return array<\stdClass> The resulting list of posts
|
230
|
|
|
*/
|
231
|
|
|
function get_posts(int $pageNum = 1, int $perPage = 5): array {
|
232
|
|
|
$posts = get_index_manager()->getPostsIndex();
|
233
|
|
|
$posts = \array_slice($posts, ($pageNum - 1) * $perPage, $perPage);
|
234
|
|
|
$list = [];
|
235
|
|
|
$factory = get_model_factory();
|
236
|
|
|
foreach ($posts as $post) {
|
237
|
|
|
$list[] = $factory->createContentObject($post);
|
238
|
|
|
}
|
239
|
|
|
return $list;
|
240
|
|
|
}
|
241
|
|
|
|
242
|
|
|
/**
|
243
|
|
|
* Checks if the given slug exists in the index manager (alias for <code>IndexManager::elementExists()</code>).
|
244
|
|
|
* @param string $slug
|
245
|
|
|
* @return bool
|
246
|
|
|
*/
|
247
|
|
|
function slug_exists(string $slug): bool {
|
248
|
|
|
return get_index_manager()->elementExists($slug);
|
249
|
|
|
}
|
250
|
|
|
|