1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* The page model |
4
|
|
|
*/ |
5
|
|
|
namespace Phile\Model; |
6
|
|
|
|
7
|
|
|
use Phile\Core\Container; |
8
|
|
|
use Phile\Core\Router; |
9
|
|
|
use Phile\Core\ServiceLocator; |
10
|
|
|
use Phile\Repository\Page as Repository; |
11
|
|
|
|
12
|
|
|
/** |
13
|
|
|
* the Model class for a page |
14
|
|
|
* |
15
|
|
|
* @author Frank Nägler |
16
|
|
|
* @link https://philecms.com |
17
|
|
|
* @license http://opensource.org/licenses/MIT |
18
|
|
|
* @package Phile\Model |
19
|
|
|
*/ |
20
|
|
|
class Page |
21
|
|
|
{ |
22
|
|
|
/** |
23
|
|
|
* @var \Phile\Model\Meta the meta model |
24
|
|
|
*/ |
25
|
|
|
protected $meta; |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @var string the content |
29
|
|
|
*/ |
30
|
|
|
protected $content; |
31
|
|
|
|
32
|
|
|
/** |
33
|
|
|
* @var string the path to the original file |
34
|
|
|
*/ |
35
|
|
|
protected $filePath; |
36
|
|
|
|
37
|
|
|
/** |
38
|
|
|
* @var string the raw file |
39
|
|
|
*/ |
40
|
|
|
protected $rawData; |
41
|
|
|
|
42
|
|
|
/** |
43
|
|
|
* @var \Phile\ServiceLocator\ParserInterface the parser |
44
|
|
|
*/ |
45
|
|
|
protected $parser; |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* @var string the pageId of the page |
49
|
|
|
*/ |
50
|
|
|
protected $pageId; |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @var string The content folder, as passed to the class constructor when initiating the object. |
54
|
|
|
*/ |
55
|
|
|
protected $contentFolder; |
56
|
|
|
|
57
|
|
|
/** |
58
|
|
|
* @var string content extension |
59
|
|
|
*/ |
60
|
|
|
protected $contentExtension; |
61
|
|
|
|
62
|
|
|
/** @var Repository */ |
63
|
|
|
protected $repository; |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* the constructor |
67
|
|
|
* |
68
|
|
|
* @param $filePath |
69
|
|
|
* @param string $folder |
70
|
|
|
*/ |
71
|
19 |
|
public function __construct($filePath, $folder = null) |
72
|
|
|
{ |
73
|
19 |
|
$settings = Container::getInstance()->get('Phile_Config')->toArray(); |
74
|
19 |
|
$this->contentFolder = $folder ?: $settings['content_dir']; |
75
|
19 |
|
$this->contentExtension = $settings['content_ext']; |
76
|
19 |
|
$this->setFilePath($filePath); |
77
|
|
|
|
78
|
|
|
/** |
79
|
|
|
* @triggerEvent before_load_content this event is triggered before the content is loaded |
80
|
|
|
* |
81
|
|
|
* @param string filePath the path to the file |
82
|
|
|
* @param \Phile\Model\Page page the page model |
83
|
|
|
*/ |
84
|
19 |
|
Container::getInstance()->get('Phile_EventBus')->trigger( |
85
|
19 |
|
'before_load_content', |
86
|
19 |
|
['filePath' => &$this->filePath, 'page' => &$this] |
87
|
|
|
); |
88
|
19 |
|
if (file_exists($this->filePath)) { |
89
|
19 |
|
$this->rawData = file_get_contents($this->filePath); |
90
|
19 |
|
$this->parseRawData(); |
91
|
|
|
} |
92
|
|
|
/** |
93
|
|
|
* @triggerEvent after_load_content this event is triggered after the content is loaded |
94
|
|
|
* |
95
|
|
|
* @param string filePath the path to the file |
96
|
|
|
* @param string rawData the raw data |
97
|
|
|
* @param \Phile\Model\Page page the page model |
98
|
|
|
*/ |
99
|
19 |
|
Container::getInstance()->get('Phile_EventBus')->trigger( |
100
|
19 |
|
'after_load_content', |
101
|
|
|
[ |
102
|
19 |
|
'filePath' => &$this->filePath, |
103
|
19 |
|
'rawData' => $this->rawData, |
104
|
19 |
|
'page' => &$this |
105
|
|
|
] |
106
|
|
|
); |
107
|
|
|
|
108
|
19 |
|
$this->parser = ServiceLocator::getService('Phile_Parser'); |
109
|
19 |
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* method to get content of page, this method returned the parsed content |
113
|
|
|
* |
114
|
|
|
* @return mixed |
115
|
|
|
*/ |
116
|
4 |
|
public function getContent() |
117
|
|
|
{ |
118
|
|
|
/** |
119
|
|
|
* @triggerEvent before_parse_content this event is triggered before the content is parsed |
120
|
|
|
* |
121
|
|
|
* @param string content the raw data |
122
|
|
|
* @param \Phile\Model\Page page the page model |
123
|
|
|
*/ |
124
|
4 |
|
Container::getInstance()->get('Phile_EventBus')->trigger( |
125
|
4 |
|
'before_parse_content', |
126
|
4 |
|
['content' => $this->content, 'page' => &$this] |
127
|
|
|
); |
128
|
4 |
|
$content = $this->parser->parse($this->content); |
129
|
|
|
/** |
130
|
|
|
* @triggerEvent after_parse_content this event is triggered after the content is parsed |
131
|
|
|
* |
132
|
|
|
* @param string content the parsed content |
133
|
|
|
* @param \Phile\Model\Page page the page model |
134
|
|
|
*/ |
135
|
4 |
|
Container::getInstance()->get('Phile_EventBus')->trigger( |
136
|
4 |
|
'after_parse_content', |
137
|
4 |
|
['content' => &$content, 'page' => &$this] |
138
|
|
|
); |
139
|
|
|
|
140
|
4 |
|
return $content; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* set content of page |
145
|
|
|
* |
146
|
|
|
* @param $content |
147
|
|
|
*/ |
148
|
3 |
|
public function setContent($content) |
149
|
|
|
{ |
150
|
3 |
|
$this->content = $content; |
151
|
3 |
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* get raw (un-parsed) page content |
155
|
|
|
* |
156
|
|
|
* @return string |
157
|
|
|
*/ |
158
|
2 |
|
public function getRawContent() |
159
|
|
|
{ |
160
|
2 |
|
return $this->content; |
161
|
|
|
} |
162
|
|
|
|
163
|
|
|
/** |
164
|
|
|
* get the meta model |
165
|
|
|
* |
166
|
|
|
* @return Meta |
167
|
|
|
*/ |
168
|
9 |
|
public function getMeta() |
169
|
|
|
{ |
170
|
9 |
|
return $this->meta; |
171
|
|
|
} |
172
|
|
|
|
173
|
|
|
/** |
174
|
|
|
* parse the raw content |
175
|
|
|
*/ |
176
|
19 |
|
protected function parseRawData() |
177
|
|
|
{ |
178
|
19 |
|
$this->meta = new Meta($this->rawData); |
179
|
|
|
// Remove only the optional, leading meta-block comment |
180
|
19 |
|
$rawData = trim($this->rawData); |
181
|
19 |
|
if (strncmp('<!--', $rawData, 4) === 0) { |
182
|
|
|
// leading meta-block comment uses the <!-- --> style |
183
|
18 |
|
$this->content = substr($rawData, max(4, strpos($rawData, '-->') + 3)); |
184
|
1 |
|
} elseif (strncmp('/*', $rawData, 2) === 0) { |
185
|
|
|
// leading meta-block comment uses the /* */ style |
186
|
|
|
$this->content = substr($rawData, strpos($rawData, '*/') + 2); |
187
|
|
|
} else { |
188
|
|
|
// no leading meta-block comment |
189
|
1 |
|
$this->content = $rawData; |
190
|
|
|
} |
191
|
19 |
|
} |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Sets repository this page was retrieved by/belongs to |
195
|
|
|
* |
196
|
|
|
* @param Repository $repository |
197
|
|
|
* @return $this |
198
|
|
|
*/ |
199
|
19 |
|
public function setRepository(Repository $repository) |
200
|
|
|
{ |
201
|
19 |
|
$this->repository = $repository; |
202
|
19 |
|
return $this; |
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
/** |
206
|
|
|
* Gets repository this page belongs to |
207
|
|
|
* |
208
|
|
|
* @return Repository |
209
|
|
|
*/ |
210
|
6 |
|
public function getRepository() |
211
|
|
|
{ |
212
|
6 |
|
if (!$this->repository) { |
213
|
1 |
|
$this->repository = new Repository(); |
214
|
|
|
} |
215
|
6 |
|
return $this->repository; |
216
|
|
|
} |
217
|
|
|
|
218
|
|
|
/** |
219
|
|
|
* get the title of page from meta information |
220
|
|
|
* |
221
|
|
|
* @return string|null |
222
|
|
|
*/ |
223
|
6 |
|
public function getTitle() |
224
|
|
|
{ |
225
|
6 |
|
return $this->getMeta()->get('title'); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
/** |
229
|
|
|
* get Phile $pageId |
230
|
|
|
* |
231
|
|
|
* @param string $filePath |
232
|
|
|
* @return string |
233
|
|
|
*/ |
234
|
19 |
|
protected function buildPageId($filePath) |
235
|
|
|
{ |
236
|
19 |
|
$pageId = str_replace($this->contentFolder, '', $filePath); |
237
|
19 |
|
$pageId = str_replace($this->contentExtension, '', $pageId); |
238
|
19 |
|
$pageId = str_replace(DIRECTORY_SEPARATOR, '/', $pageId); |
239
|
19 |
|
$pageId = ltrim($pageId, '/'); |
240
|
19 |
|
$pageId = preg_replace('/(?<=^|\/)index$/', '', $pageId); |
241
|
19 |
|
return $pageId; |
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** |
245
|
|
|
* get the url of page |
246
|
|
|
* |
247
|
|
|
* @return string |
248
|
|
|
*/ |
249
|
3 |
View Code Duplication |
public function getUrl() |
|
|
|
|
250
|
|
|
{ |
251
|
3 |
|
$container = Container::getInstance(); |
252
|
3 |
|
if ($container->has('Phile_Router')) { |
253
|
2 |
|
$router = $container->get('Phile_Router'); |
254
|
|
|
} else { |
255
|
|
|
// BC: some old 1.x plugins may use Pages before the core is initialized |
256
|
1 |
|
$router = new Router; |
257
|
|
|
} |
258
|
3 |
|
return $router->urlForPage($this->pageId, false); |
259
|
|
|
} |
260
|
|
|
|
261
|
|
|
/** |
262
|
|
|
* set the filepath of the page |
263
|
|
|
* |
264
|
|
|
* @param string $filePath |
265
|
|
|
*/ |
266
|
19 |
|
public function setFilePath($filePath) |
267
|
|
|
{ |
268
|
19 |
|
$this->filePath = $filePath; |
269
|
19 |
|
$this->pageId = $this->buildPageId($this->filePath); |
270
|
19 |
|
} |
271
|
|
|
|
272
|
|
|
/** |
273
|
|
|
* get the filepath of the page |
274
|
|
|
* |
275
|
|
|
* @return string |
276
|
|
|
*/ |
277
|
3 |
|
public function getFilePath() |
278
|
|
|
{ |
279
|
3 |
|
return $this->filePath; |
280
|
|
|
} |
281
|
|
|
|
282
|
|
|
/** |
283
|
|
|
* get the folder name |
284
|
|
|
* |
285
|
|
|
* @return string |
286
|
|
|
*/ |
287
|
|
|
public function getFolder() |
288
|
|
|
{ |
289
|
|
|
return basename(dirname($this->getFilePath())); |
290
|
|
|
} |
291
|
|
|
|
292
|
4 |
|
public function getPageId() |
293
|
|
|
{ |
294
|
4 |
|
return $this->pageId; |
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** |
298
|
|
|
* get the previous page if one exist |
299
|
|
|
* |
300
|
|
|
* @return null|\Phile\Model\Page |
301
|
|
|
*/ |
302
|
1 |
|
public function getPreviousPage() |
303
|
|
|
{ |
304
|
1 |
|
return $this->getRepository()->getPageOffset($this, -1); |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* get the next page if one exist |
309
|
|
|
* |
310
|
|
|
* @return null|\Phile\Model\Page |
311
|
|
|
*/ |
312
|
1 |
|
public function getNextPage() |
313
|
|
|
{ |
314
|
1 |
|
return $this->getRepository()->getPageOffset($this, 1); |
315
|
|
|
} |
316
|
|
|
} |
317
|
|
|
|
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.