1
|
|
|
<?php |
|
|
|
|
2
|
|
|
/** |
3
|
|
|
* @title Front Controller Class |
4
|
|
|
* |
5
|
|
|
* This class is used to instantiate the Controller and the action with the MVC pattern, in short it is the heart of pH7CMS's software. |
6
|
|
|
* It can also retrieve the URL roads, initialize the languages, themes, database, etc. |
7
|
|
|
* |
8
|
|
|
* @author Pierre-Henry Soria <[email protected]> |
9
|
|
|
* @copyright (c) 2011-2017, Pierre-Henry Soria. All Rights Reserved. |
10
|
|
|
* @license GNU General Public License; See PH7.LICENSE.txt and PH7.COPYRIGHT.txt in the root directory. |
11
|
|
|
* @package PH7 / Framework / Mvc / Router |
12
|
|
|
* @version 1.0 |
13
|
|
|
*/ |
14
|
|
|
|
15
|
|
|
namespace PH7\Framework\Mvc\Router; |
16
|
|
|
|
17
|
|
|
defined('PH7') or exit('Restricted access'); |
18
|
|
|
|
19
|
|
|
use PH7\Framework\Translate\Lang; |
20
|
|
|
use PH7\Framework\Layout\LoadTemplate; |
21
|
|
|
use PH7\Framework\Mvc\Model\Engine\Db; |
22
|
|
|
use PH7\Framework\Registry\Registry; |
23
|
|
|
use PH7\Framework\Config\Config; |
24
|
|
|
use PH7\Framework\File\Import as FileImporter; |
25
|
|
|
use PH7\Framework\Mvc\Model\DbConfig; |
26
|
|
|
use PH7\Framework\Layout\Gzip\Gzip; |
27
|
|
|
use PH7\Framework\Url\Header; |
28
|
|
|
use PH7\Framework\Mvc\Request\Http; |
29
|
|
|
use PH7\Framework\Url\Uri; |
|
|
|
|
30
|
|
|
use PH7\Framework\Mvc\Router\Uri as UriRoute; |
31
|
|
|
use PH7\Framework\Error\CException\PH7Exception; |
32
|
|
|
use PH7\Framework\Pattern\Singleton; |
33
|
|
|
|
34
|
|
|
/** |
35
|
|
|
* @class Singleton Class |
36
|
|
|
*/ |
37
|
|
|
final class FrontController |
38
|
|
|
{ |
39
|
|
|
const INDEX_FILE = 'index.php'; |
40
|
|
|
|
41
|
|
|
/** @var Config */ |
42
|
|
|
private $oConfig; |
43
|
|
|
|
44
|
|
|
/** @var Registry */ |
45
|
|
|
private $oRegistry; |
46
|
|
|
|
47
|
|
|
/** @var Http */ |
48
|
|
|
private $oHttpRequest; |
49
|
|
|
|
50
|
|
|
/** @var Uri */ |
51
|
|
|
private $oUri; |
52
|
|
|
|
53
|
|
|
/** @var array */ |
54
|
|
|
private $aRequestParameter; |
55
|
|
|
|
56
|
|
|
/** @var boolean */ |
57
|
|
|
private $bIsRouterRewritten = false; |
58
|
|
|
|
59
|
|
|
use Singleton; // Import the Singleton trait |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Routing controllers. |
63
|
|
|
*/ |
64
|
|
|
private function __construct() |
65
|
|
|
{ |
66
|
|
|
/** Objects are created for the functioning of the class. * */ |
67
|
|
|
$this->oConfig = Config::getInstance(); |
68
|
|
|
$this->oRegistry = Registry::getInstance(); |
69
|
|
|
$this->oHttpRequest = new Http; |
70
|
|
|
$this->oUri = Uri::getInstance(); |
71
|
|
|
|
72
|
|
|
$this->indexFileRouter(); |
73
|
|
|
|
74
|
|
|
if ($this->oUri->fragment(0) === 'asset' && $this->oUri->fragment(1) === 'gzip') |
75
|
|
|
{ |
76
|
|
|
// Loading and compress CSS and JavaScript files |
77
|
|
|
$this->gzipRouter(); |
78
|
|
|
exit; |
|
|
|
|
79
|
|
|
} |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* @internal We initialize the database after the compression of static files (self::gzipRouter() method), |
83
|
|
|
* so we can always display static files even if there are problems with the database. |
84
|
|
|
*/ |
85
|
|
|
$this->_databaseInitialize(); |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @internal "_languageInitialize()" method must be declared before the rest of the code, because it initializes the main language constants for the rest of the code. |
89
|
|
|
*/ |
90
|
|
|
$this->_languageInitialize(); |
91
|
|
|
|
92
|
|
|
$this->_assetsInitialize(); |
93
|
|
|
|
94
|
|
|
$this->launchRewritingRouter(); |
95
|
|
|
|
96
|
|
|
$this->launchNonRewritingRouters(); |
97
|
|
|
} |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* If the module action isn't rewriting, we launch the basic router. |
101
|
|
|
*/ |
102
|
|
|
private function launchNonRewritingRouters() |
103
|
|
|
{ |
104
|
|
|
if (!$this->bIsRouterRewritten) |
105
|
|
|
{ |
106
|
|
|
if ($this->oUri->fragment(0) === 'm') |
107
|
|
|
$this->simpleModuleRouter(); |
108
|
|
|
else |
109
|
|
|
$this->simpleRouter(); |
110
|
|
|
} |
111
|
|
|
} |
112
|
|
|
|
113
|
|
|
/** |
114
|
|
|
* Router for the modules that are rewriting through the custom XML route file. |
115
|
|
|
*/ |
116
|
|
|
private function launchRewritingRouter() |
117
|
|
|
{ |
118
|
|
|
$oUrl = UriRoute::loadFile(new \DomDocument); |
119
|
|
|
foreach ($oUrl->getElementsByTagName('route') as $oRoute) |
120
|
|
|
{ |
121
|
|
|
if (preg_match('`^' . $oRoute->getAttribute('url') . '/?(?:\?[^/]+\=[^/]+)?$`', $this->oHttpRequest->requestUri(), $aMatches)) |
122
|
|
|
{ |
123
|
|
|
$this->setRewritingRouter(); |
124
|
|
|
|
125
|
|
|
$sPathModule = $oRoute->getAttribute('path') . PH7_SH; |
126
|
|
|
|
127
|
|
|
// Get module |
128
|
|
|
$this->oRegistry->module = $oRoute->getAttribute('module'); |
|
|
|
|
129
|
|
|
|
130
|
|
|
// Check if file exist |
131
|
|
|
if (!$this->oConfig->load(PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) |
|
|
|
|
132
|
|
|
{ |
133
|
|
|
$this->notFound('The <b>' . $this->oRegistry->module . |
|
|
|
|
134
|
|
|
'</b> system module is not found.<br />File: <b>' . PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS . |
|
|
|
|
135
|
|
|
'</b><br /> or the <b>' . PH7_CONFIG_FILE . '</b> file is not found.<br />File: <b>' . PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE . '</b>'); |
|
|
|
|
136
|
|
|
// It reloads the config.ini file for the new module "error" |
137
|
|
|
$this->oConfig->load(PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
|
|
|
|
138
|
|
|
} |
139
|
|
|
|
140
|
|
|
/***** PATH THE MODULE *****/ |
141
|
|
|
$this->oRegistry->path_module = PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS; |
|
|
|
|
142
|
|
|
|
143
|
|
|
/***** URL THE MODULE *****/ |
144
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . $this->oRegistry->module . PH7_SH; |
|
|
|
|
145
|
|
|
|
146
|
|
|
/***** PATH THE TEMPLATE *****/ |
147
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_ROOT . PH7_LAYOUT . $sPathModule . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
148
|
|
|
|
149
|
|
|
/***** URL THE TEMPLATE *****/ |
150
|
|
|
$this->oRegistry->url_themes_module = PH7_RELATIVE . PH7_LAYOUT . $sPathModule . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
151
|
|
|
|
152
|
|
|
// Get the default controller |
153
|
|
|
$this->oRegistry->controller = ucfirst($oRoute->getAttribute('controller')) . 'Controller'; |
|
|
|
|
154
|
|
|
|
155
|
|
|
// Get the default action |
156
|
|
|
$this->oRegistry->action = $oRoute->getAttribute('action'); |
|
|
|
|
157
|
|
|
if ($oRoute->hasAttribute('vars')) |
158
|
|
|
{ |
159
|
|
|
$aVars = explode(',', $oRoute->getAttribute('vars')); |
160
|
|
|
$iOffset = count($aVars); |
161
|
|
|
|
162
|
|
|
foreach ($aMatches as $sKey => $sMatch) |
163
|
|
|
{ |
164
|
|
|
if ($sKey !== 0) |
165
|
|
|
{ |
166
|
|
|
$this->oHttpRequest->setGet($aVars[$sKey-1], $sMatch); |
167
|
|
|
|
168
|
|
|
/** Request Parameter for the Router Rewriting mode. * */ |
169
|
|
|
$this->aRequestParameter = $this->oUri->segments($this->oUri->totalFragment()-$iOffset); |
170
|
|
|
} |
171
|
|
|
} |
172
|
|
|
} |
173
|
|
|
break; |
174
|
|
|
} |
175
|
|
|
} |
176
|
|
|
unset($oUrl); |
177
|
|
|
} |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* Simple Router. |
181
|
|
|
|
182
|
|
|
* @return void |
183
|
|
|
*/ |
184
|
|
|
private function simpleRouter() |
185
|
|
|
{ |
186
|
|
|
if ($this->oUri->fragment(0) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(0))) |
187
|
|
|
{ |
188
|
|
|
// Set system module |
189
|
|
|
$this->oRegistry->module = $this->oUri->fragment(0); |
|
|
|
|
190
|
|
|
} |
191
|
|
|
else |
192
|
|
|
{ |
193
|
|
|
// Get system module |
194
|
|
|
$this->oRegistry->module = DbConfig::getSetting('defaultSysModule'); |
|
|
|
|
195
|
|
|
} |
196
|
|
|
|
197
|
|
|
// Check if file exist |
198
|
|
|
if (!$this->oConfig->load(PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) |
|
|
|
|
199
|
|
|
{ |
200
|
|
|
$this->notFound('The <b>' . $this->oRegistry->module . '</b> system module is not found.<br />File: <b>' . PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS . |
|
|
|
|
201
|
|
|
'</b><br /> or the <b>' . PH7_CONFIG_FILE . '</b> file is not found.<br />File: <b>' . PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE . '</b>'); |
|
|
|
|
202
|
|
|
|
203
|
|
|
// It reloads the config.ini file for the new module "error" |
204
|
|
|
$this->oConfig->load(PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
|
|
|
|
205
|
|
|
} |
206
|
|
|
|
207
|
|
|
/***** PATH THE MODULE *****/ |
208
|
|
|
$this->oRegistry->path_module = PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS; |
|
|
|
|
209
|
|
|
|
210
|
|
|
/***** URL THE MODULE *****/ |
211
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . $this->oRegistry->module . PH7_SH; |
|
|
|
|
212
|
|
|
|
213
|
|
|
/***** PATH THE TEMPLATE *****/ |
214
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_TPL_SYS_MOD . PH7_DS . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
215
|
|
|
|
216
|
|
|
/***** URL THE TEMPLATE *****/ |
217
|
|
|
$this->oRegistry->url_themes_module = PH7_URL_TPL_SYS_MOD . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
218
|
|
|
|
219
|
|
|
if ($this->oUri->fragment(1) === 'asset' && $this->oUri->fragment(2) === 'ajax') |
220
|
|
|
{ |
221
|
|
|
// Loading files Asynchronous Ajax |
222
|
|
|
$this->ajaxRouter($this->oRegistry->path_module); |
|
|
|
|
223
|
|
|
exit; |
|
|
|
|
224
|
|
|
|
225
|
|
|
} |
226
|
|
|
elseif ($this->oUri->fragment(1) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(1))) |
227
|
|
|
{ |
228
|
|
|
// Set the controller |
229
|
|
|
$this->oRegistry->controller = ucfirst($this->oUri->fragment(1)) . 'Controller'; |
|
|
|
|
230
|
|
|
} |
231
|
|
|
else |
232
|
|
|
{ |
233
|
|
|
// Get the default controller |
234
|
|
|
$this->oRegistry->controller = ucfirst($this->oConfig->values['module']['default_controller']) . 'Controller'; |
|
|
|
|
235
|
|
|
} |
236
|
|
|
|
237
|
|
|
if ($this->oUri->fragment(2) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(2))) |
238
|
|
|
{ |
239
|
|
|
// Set the action |
240
|
|
|
$this->oRegistry->action = $this->oUri->fragment(2); |
|
|
|
|
241
|
|
|
} |
242
|
|
|
else |
243
|
|
|
{ |
244
|
|
|
// Get the default action |
245
|
|
|
$this->oRegistry->action = $this->oConfig->values['module']['default_action']; |
|
|
|
|
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** Request Parameter for the Simple Router mode. **/ |
249
|
|
|
$this->aRequestParameter = $this->oUri->segments(3); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
/** |
253
|
|
|
* Simple Module Router. |
254
|
|
|
* |
255
|
|
|
* @return void |
256
|
|
|
*/ |
257
|
|
|
private function simpleModuleRouter() |
258
|
|
|
{ |
259
|
|
|
if ($this->oUri->fragment(1) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(1))) |
260
|
|
|
{ |
261
|
|
|
// Set module |
262
|
|
|
$this->oRegistry->module = $this->oUri->fragment(1); |
|
|
|
|
263
|
|
|
} |
264
|
|
|
|
265
|
|
|
// Check if file exist |
266
|
|
|
if (!$this->oConfig->load(PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) |
|
|
|
|
267
|
|
|
{ |
268
|
|
|
$this->notFound('The <b>' . $this->oRegistry->module . '</b> module is not found.<br />File: <b>' . PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . |
|
|
|
|
269
|
|
|
'</b><br /> or the <b>' . PH7_CONFIG_FILE . '</b> file is not found.<br />File: <b>' . PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE . '</b>'); |
|
|
|
|
270
|
|
|
// It reloads the config.ini file for the new module "error" |
271
|
|
|
$this->oConfig->load(PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
|
|
|
|
272
|
|
|
} |
273
|
|
|
|
274
|
|
|
/***** PATH THE MODULE *****/ |
275
|
|
|
$this->oRegistry->path_module = PH7_PATH_MOD . $this->oRegistry->module . PH7_DS; |
|
|
|
|
276
|
|
|
/***** URL THE MODULE *****/ |
277
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . 'm/' . $this->oRegistry->module . PH7_SH; |
|
|
|
|
278
|
|
|
/***** PATH THE TEMPLATE *****/ |
279
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_TPL_MOD . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
280
|
|
|
/***** URL THE TEMPLATE *****/ |
281
|
|
|
$this->oRegistry->url_themes_module = PH7_URL_TPL_MOD . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
282
|
|
|
|
283
|
|
|
if ($this->oUri->fragment(2) === 'asset' && $this->oUri->fragment(3) === 'ajax') |
284
|
|
|
{ |
285
|
|
|
// Loading files Asynchronous Ajax |
286
|
|
|
$this->ajaxRouter($this->oRegistry->path_module); |
|
|
|
|
287
|
|
|
exit; |
|
|
|
|
288
|
|
|
} |
289
|
|
|
elseif ($this->oUri->fragment(2) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(2))) |
290
|
|
|
{ |
291
|
|
|
// Set the controller |
292
|
|
|
$this->oRegistry->controller = ucfirst($this->oUri->fragment(2)) . 'Controller'; |
|
|
|
|
293
|
|
|
} |
294
|
|
|
else |
295
|
|
|
{ |
296
|
|
|
// Get the default controller |
297
|
|
|
$this->oRegistry->controller = ucfirst($this->oConfig->values['module']['default_controller']) . 'Controller'; |
|
|
|
|
298
|
|
|
} |
299
|
|
|
|
300
|
|
|
if ($this->oUri->fragment(3) && preg_match('#^[a-z0-9\.\-_]+$#i', $this->oUri->fragment(3))) |
301
|
|
|
{ |
302
|
|
|
// Set the action |
303
|
|
|
$this->oRegistry->action = $this->oUri->fragment(3); |
|
|
|
|
304
|
|
|
} |
305
|
|
|
else |
306
|
|
|
{ |
307
|
|
|
// Get the default action |
308
|
|
|
$this->oRegistry->action = $this->oConfig->values['module']['default_action']; |
|
|
|
|
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
/** Request Parameter for the Simple Module Router mode. **/ |
312
|
|
|
$this->aRequestParameter = $this->oUri->segments(4); |
313
|
|
|
} |
314
|
|
|
|
315
|
|
|
/** |
316
|
|
|
* If the action is rewriting by the XML route file, set the correct router to be used. |
317
|
|
|
* |
318
|
|
|
* @return void |
319
|
|
|
*/ |
320
|
|
|
private function setRewritingRouter() |
321
|
|
|
{ |
322
|
|
|
$this->bIsRouterRewritten = true; |
323
|
|
|
} |
324
|
|
|
|
325
|
|
|
/** |
326
|
|
|
* @return void |
327
|
|
|
*/ |
328
|
|
|
public function _databaseInitialize() |
329
|
|
|
{ |
330
|
|
|
$aDriverOptions[\PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $this->oConfig->values['database']['charset']; |
|
|
|
|
331
|
|
|
|
332
|
|
|
Db::getInstance( |
333
|
|
|
/* DSN */ |
334
|
|
|
$this->oConfig->values['database']['type'] . ':host=' . $this->oConfig->values['database']['hostname'] . ';port=' . $this->oConfig->values['database']['port'] . ';dbname=' . $this->oConfig->values['database']['name'], |
335
|
|
|
/* Username */ |
336
|
|
|
$this->oConfig->values['database']['username'], |
337
|
|
|
/* Password */ |
338
|
|
|
$this->oConfig->values['database']['password'], |
339
|
|
|
/* Driver */ |
340
|
|
|
$aDriverOptions, |
341
|
|
|
/* Prefix */ |
342
|
|
|
$this->oConfig->values['database']['prefix'] |
343
|
|
|
); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
/** |
347
|
|
|
* Removing the sensitive database information in the config object. |
348
|
|
|
* |
349
|
|
|
* @return void |
350
|
|
|
*/ |
351
|
|
|
public function _removeDatabaseInfo() |
352
|
|
|
{ |
353
|
|
|
unset($this->oConfig->values['database']); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* Internationalization with Gettext. |
358
|
|
|
* |
359
|
|
|
* @return void |
360
|
|
|
*/ |
361
|
|
|
public function _languageInitialize() |
362
|
|
|
{ |
363
|
|
|
if (!defined('PH7_PREF_LANG')) |
364
|
|
|
define('PH7_PREF_LANG', DbConfig::getSetting('defaultLanguage')); |
365
|
|
|
|
366
|
|
|
if (!defined('PH7_LANG_NAME')) { |
367
|
|
|
// Set the default language of the site and load the default language path |
368
|
|
|
define('PH7_LANG_NAME', (new Lang)->setDefaultLang(PH7_PREF_LANG)->init()->load('global', PH7_PATH_APP_LANG)->getLang()); |
369
|
|
|
} |
370
|
|
|
|
371
|
|
|
/*** Get the ISO language code (the two first letters) ***/ |
372
|
|
|
define('PH7_DEFAULT_LANG_CODE', substr(PH7_DEFAULT_LANG, 0, 2)); |
373
|
|
|
define('PH7_LANG_CODE', substr(PH7_LANG_NAME, 0, 2)); |
374
|
|
|
|
375
|
|
|
/*** Set locale environment variables for gettext ***/ |
376
|
|
|
putenv('LC_ALL=' . PH7_LANG_NAME); |
377
|
|
|
setlocale(LC_ALL, PH7_LANG_NAME); |
378
|
|
|
} |
379
|
|
|
|
380
|
|
|
/** |
381
|
|
|
* @return void |
382
|
|
|
*/ |
383
|
|
|
public function _templateInitialize() |
384
|
|
|
{ |
385
|
|
|
/***** Start Loading Views and Templates *****/ |
386
|
|
|
|
387
|
|
|
$oLoadTpl = (new LoadTemplate)->setDefaultTpl(DbConfig::getSetting('defaultTemplate')); |
388
|
|
|
$oLoadTpl->tpl(); |
389
|
|
|
$oLoadTpl->modTpl(); |
390
|
|
|
$oLoadTpl->mailTpl(); |
391
|
|
|
define('PH7_TPL_NAME', $oLoadTpl->getTpl()); |
392
|
|
|
define('PH7_TPL_MOD_NAME', $oLoadTpl->getModTpl()); |
393
|
|
|
define('PH7_TPL_MAIL_NAME', $oLoadTpl->getMailTpl()); |
394
|
|
|
unset($oLoadTpl); |
395
|
|
|
} |
396
|
|
|
|
397
|
|
|
/** |
398
|
|
|
* @return void |
399
|
|
|
*/ |
400
|
|
|
public function _pathInitialize() |
401
|
|
|
{ |
402
|
|
|
$this->oRegistry->action = strtolower($this->oRegistry->action); |
|
|
|
|
403
|
|
|
|
404
|
|
|
/***** SHORTCUTS PATH FOR MODULES *****/ |
405
|
|
|
$this->oRegistry->path_module_controllers = $this->oRegistry->path_module . PH7_CTRL; |
|
|
|
|
406
|
|
|
$this->oRegistry->path_module_models = $this->oRegistry->path_module . PH7_MODELS; |
|
|
|
|
407
|
|
|
$this->oRegistry->path_module_views = $this->oRegistry->path_module . PH7_VIEWS; |
|
|
|
|
408
|
|
|
$this->oRegistry->path_module_forms = $this->oRegistry->path_module . PH7_FORMS; |
|
|
|
|
409
|
|
|
$this->oRegistry->path_module_inc = $this->oRegistry->path_module . PH7_INC; |
|
|
|
|
410
|
|
|
$this->oRegistry->path_module_config = $this->oRegistry->path_module . PH7_CONFIG; |
|
|
|
|
411
|
|
|
$this->oRegistry->path_module_lang = $this->oRegistry->path_module . PH7_LANG; |
|
|
|
|
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* Initialize the resources of the assets folders. |
416
|
|
|
* |
417
|
|
|
* @return void |
418
|
|
|
*/ |
419
|
|
|
public function _assetsInitialize() |
420
|
|
|
{ |
421
|
|
|
if ($this->oUri->fragment(0) === 'asset') |
422
|
|
|
{ |
423
|
|
|
switch ($this->oUri->fragment(1)) |
424
|
|
|
{ |
425
|
|
|
case 'ajax': |
426
|
|
|
// Loading Asynchronous Ajax files |
427
|
|
|
$this->ajaxRouter(); |
428
|
|
|
break; |
429
|
|
|
|
430
|
|
|
case 'file': |
431
|
|
|
// Loading files |
432
|
|
|
$this->fileRouter(); |
433
|
|
|
break; |
434
|
|
|
|
435
|
|
|
case 'cron': |
436
|
|
|
// Loading Cron Jobs files |
437
|
|
|
$this->cronRouter(); |
438
|
|
|
break; |
439
|
|
|
|
440
|
|
|
case 'css': |
441
|
|
|
// Loading Style sheet files |
442
|
|
|
$this->cssRouter(); |
443
|
|
|
break; |
444
|
|
|
|
445
|
|
|
case 'js': |
446
|
|
|
// Loading JavaScript files |
447
|
|
|
$this->jsRouter(); |
448
|
|
|
break; |
449
|
|
|
|
450
|
|
|
default: |
451
|
|
|
$this->notFound('Not found Asset file!', 1); |
452
|
|
|
} |
453
|
|
|
exit; |
|
|
|
|
454
|
|
|
} |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* @return void |
459
|
|
|
*/ |
460
|
|
|
private function gzipRouter() |
461
|
|
|
{ |
462
|
|
|
(new Gzip)->run(); |
463
|
|
|
} |
464
|
|
|
|
465
|
|
|
/** |
466
|
|
|
* @return void |
467
|
|
|
*/ |
468
|
|
|
private function ajaxRouter($sMod = null) |
469
|
|
|
{ |
470
|
|
|
FileImporter::pH7FwkClass('Ajax.Ajax'); |
471
|
|
|
|
472
|
|
|
// Option for Content Type |
473
|
|
|
if ($this->oHttpRequest->getExists('option')) |
474
|
|
|
{ |
475
|
|
|
if ($this->oHttpRequest->get('option') == 'plain') |
476
|
|
|
header('Content-Type: text/plain; charset=utf-8'); |
477
|
|
|
} |
478
|
|
|
|
479
|
|
|
if (!empty($sMod)) |
480
|
|
|
{ |
481
|
|
|
// For module only! |
482
|
|
|
|
483
|
|
|
$this->_pathInitialize(); |
484
|
|
|
|
485
|
|
|
$sFolder = ($this->oUri->fragment(4) && preg_match('#^[\w]+$#', $this->oUri->fragment(4))) ? PH7_DS . $this->oUri->fragment(4) : ''; |
486
|
|
|
if (is_file($sMod . 'assets/ajax/' . $this->oUri->fragment(3) . $sFolder . 'Ajax.php')) |
487
|
|
|
{ |
488
|
|
|
include_once $sMod . 'assets/ajax/' . $this->oUri->fragment(3) . $sFolder . 'Ajax.php'; |
489
|
|
|
} |
490
|
|
|
else |
491
|
|
|
{ |
492
|
|
|
$this->notFound('Error while loading the library of module ajax<br />File: ' . $sMod . 'assets' . PH7_DS . 'ajax' . PH7_DS . $this->oUri->fragment(3) . $sFolder . 'Ajax.php does not exist', 1); |
493
|
|
|
} |
494
|
|
|
} |
495
|
|
|
else |
496
|
|
|
{ |
497
|
|
|
// For all scripts of the pH7 DatingCms |
498
|
|
|
$sFolder = ($this->oUri->fragment(3) && preg_match('#^[\w]+$#', $this->oUri->fragment(3))) ? PH7_DS . $this->oUri->fragment(3) : ''; |
499
|
|
|
|
500
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/ajax/' . $this->oUri->fragment(2) . $sFolder . 'CoreAjax.php')) |
501
|
|
|
{ |
502
|
|
|
include_once PH7_PATH_SYS . 'core/assets/ajax/' . $this->oUri->fragment(2) . $sFolder . 'CoreAjax.php'; |
503
|
|
|
} |
504
|
|
|
else |
505
|
|
|
{ |
506
|
|
|
$this->notFound('Error while loading the library of ajax<br />File: ' . PH7_PATH_SYS . 'core' . PH7_DS . 'assets' . PH7_DS . 'ajax' . PH7_DS . $this->oUri->fragment(2) . $sFolder . 'CoreAjax.php does not exist', 1); |
507
|
|
|
} |
508
|
|
|
} |
509
|
|
|
} |
510
|
|
|
|
511
|
|
|
/** |
512
|
|
|
* @return void |
513
|
|
|
*/ |
514
|
|
|
private function fileRouter() |
515
|
|
|
{ |
516
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/file/' . $this->oUri->fragment(2) . 'CoreFile.php')) |
517
|
|
|
include_once PH7_PATH_SYS . 'core/assets/file/' . $this->oUri->fragment(2) . 'CoreFile.php'; |
518
|
|
|
else |
519
|
|
|
$this->notFound('Error while loading the file<br />File: ' . PH7_PATH_SYS . 'core' . PH7_DS . 'assets' . PH7_DS . 'file' . PH7_DS . $this->oUri->fragment(2) . 'CoreFile.php does not exist', 1); |
520
|
|
|
} |
521
|
|
|
|
522
|
|
|
/** |
523
|
|
|
* @return void |
524
|
|
|
*/ |
525
|
|
|
private function cronRouter() |
526
|
|
|
{ |
527
|
|
|
if (strcmp($this->oHttpRequest->get('secret_word'), DbConfig::getSetting('cronSecurityHash')) === 0) |
528
|
|
|
{ |
529
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/cron/' . $this->oUri->fragment(2) . PH7_DS . $this->oUri->fragment(3) . 'CoreCron.php')) |
530
|
|
|
require PH7_PATH_SYS . 'core/assets/cron/' . $this->oUri->fragment(2) . PH7_DS . $this->oUri->fragment(3) . 'CoreCron.php'; |
531
|
|
|
else |
532
|
|
|
$this->notFound('Error while loading the Cron Jobs file<br />File: ' . PH7_PATH_SYS . 'core' . PH7_DS . 'assets' . PH7_DS . 'cron' . PH7_DS . $this->oUri->fragment(2) . PH7_DS . $this->oUri->fragment(3) . 'CoreCron.php does not exist', 1); |
533
|
|
|
} |
534
|
|
|
else |
535
|
|
|
{ |
536
|
|
|
Http::setHeadersByCode(403); |
537
|
|
|
exit('Secret word is invalid for the cron hash!'); |
|
|
|
|
538
|
|
|
} |
539
|
|
|
} |
540
|
|
|
|
541
|
|
|
/** |
542
|
|
|
* @return void |
543
|
|
|
*/ |
544
|
|
|
private function cssRouter() |
545
|
|
|
{ |
546
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/css/' . $this->oUri->fragment(2) . 'CoreCss.php')) |
547
|
|
|
{ |
548
|
|
|
header('Content-Type: text/css'); |
549
|
|
|
include_once PH7_PATH_SYS . 'core/assets/css/' . $this->oUri->fragment(2) . 'CoreCss.php'; |
550
|
|
|
} |
551
|
|
|
else |
552
|
|
|
{ |
553
|
|
|
$this->notFound('Error while loading the Javascript file<br />File: ' . PH7_PATH_SYS . 'core' . PH7_DS . 'assets' . PH7_DS . 'css' . PH7_DS . $this->oUri->fragment(2) . 'CoreCss.php does not exist', 1); |
554
|
|
|
} |
555
|
|
|
} |
556
|
|
|
|
557
|
|
|
/** |
558
|
|
|
* @return void |
559
|
|
|
*/ |
560
|
|
|
private function jsRouter() |
561
|
|
|
{ |
562
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/js/' . $this->oUri->fragment(2) . 'CoreJs.php')) |
563
|
|
|
{ |
564
|
|
|
header('Content-Type: text/javascript'); |
565
|
|
|
include_once PH7_PATH_SYS . 'core/assets/js/' . $this->oUri->fragment(2) . 'CoreJs.php'; |
566
|
|
|
} |
567
|
|
|
else |
568
|
|
|
{ |
569
|
|
|
$this->notFound('Error while loading the Javascript file<br />File: ' . PH7_PATH_SYS . 'core' . PH7_DS . 'assets' . PH7_DS . 'js' . PH7_DS . $this->oUri->fragment(2) . 'CoreJs.php does not exist', 1); |
570
|
|
|
} |
571
|
|
|
} |
572
|
|
|
|
573
|
|
|
/** |
574
|
|
|
* Run Router! |
575
|
|
|
* |
576
|
|
|
* @return void |
577
|
|
|
*/ |
578
|
|
|
public function runRouter() |
579
|
|
|
{ |
580
|
|
|
$this->_pathInitialize(); |
581
|
|
|
|
582
|
|
|
/***** FOR FILE CONFIG .INI OF MODULE *****/ |
583
|
|
|
$this->oConfig->load($this->oRegistry->path_module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
|
|
|
|
584
|
|
|
|
585
|
|
|
// PH7_DEFAULT_TPL_MOD constant has to be defined before calling "_templateInitialize()" |
586
|
|
|
define('PH7_DEFAULT_TPL_MOD', $this->oConfig->values['module']['default_theme']); |
587
|
|
|
|
588
|
|
|
$this->_templateInitialize(); |
589
|
|
|
|
590
|
|
|
if (is_file($this->oRegistry->path_module_controllers . $this->oRegistry->controller . '.php')) |
|
|
|
|
591
|
|
|
{ |
592
|
|
|
// For additional options modules |
593
|
|
|
if (is_file($this->oRegistry->path_module . 'Bootstrap.php')) |
|
|
|
|
594
|
|
|
require_once $this->oRegistry->path_module . 'Bootstrap.php'; // Include Bootstrap Module if there exists |
595
|
|
|
|
596
|
|
|
$sController = 'PH7\\' . $this->oRegistry->controller; |
|
|
|
|
597
|
|
|
if (class_exists($sController) && (new \ReflectionClass($sController))->hasMethod($this->oRegistry->action)) |
|
|
|
|
598
|
|
|
{ |
599
|
|
|
$oMvc = new \ReflectionMethod($sController, $this->oRegistry->action); |
|
|
|
|
600
|
|
|
if ($oMvc->isPublic()) |
601
|
|
|
{ |
602
|
|
|
$oCtrl = new $sController; |
603
|
|
|
|
604
|
|
|
// And finally we perform the controller's action |
605
|
|
|
$oMvc->invokeArgs($oCtrl, $this->getRequestParameter()); |
606
|
|
|
|
607
|
|
|
// Destruct the object to minimize CPU resources |
608
|
|
|
unset($oCtrl); |
609
|
|
|
} |
610
|
|
|
else |
611
|
|
|
{ |
612
|
|
|
$this->notFound('The <b>' . $this->oRegistry->action . '</b> method is not public!', 1); |
|
|
|
|
613
|
|
|
} |
614
|
|
|
} |
615
|
|
|
else |
616
|
|
|
{ |
617
|
|
|
$this->notFound('The <b>' . $this->oRegistry->action . '</b> method of the <b>' . $this->oRegistry->controller . '</b> controller does not exist.', 1); |
|
|
|
|
618
|
|
|
} |
619
|
|
|
} |
620
|
|
|
else |
621
|
|
|
{ |
622
|
|
|
$this->notFound('The <b>' . $this->oRegistry->controller . '</b> controller of the <b>' . $this->oRegistry->module . |
|
|
|
|
623
|
|
|
'</b> module is not found.<br />File: <b>' . $this->oRegistry->path_module . '</b>', 1); |
|
|
|
|
624
|
|
|
} |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
/** |
628
|
|
|
* Get the Request Parameters. |
629
|
|
|
* |
630
|
|
|
* @return array The Request Parameters if it exists, otherwise an empty array. |
631
|
|
|
*/ |
632
|
|
|
private function getRequestParameter() |
633
|
|
|
{ |
634
|
|
|
$aRequest = array(); |
635
|
|
|
|
636
|
|
|
if (count($this->aRequestParameter) > 0) |
637
|
|
|
{ |
638
|
|
|
foreach ($this->aRequestParameter as $sVal) |
639
|
|
|
{ |
640
|
|
|
$sVal = trim($this->secureRequestParameter($sVal)); |
641
|
|
|
|
642
|
|
|
if ($sVal !== '') |
643
|
|
|
{ |
644
|
|
|
// Clean the slug URL |
645
|
|
|
$sVal = $this->cleanSlugUrl($sVal); |
646
|
|
|
|
647
|
|
|
$aRequest[] = $sVal; |
648
|
|
|
} |
649
|
|
|
} |
650
|
|
|
} |
651
|
|
|
$this->clearRequestParameter(); |
652
|
|
|
|
653
|
|
|
return $aRequest; |
654
|
|
|
} |
655
|
|
|
|
656
|
|
|
/** |
657
|
|
|
* Clean the Slug Url. |
658
|
|
|
* |
659
|
|
|
* @param string $sVal The request action name to clean. |
660
|
|
|
* |
661
|
|
|
* @return string |
662
|
|
|
*/ |
663
|
|
|
private function cleanSlugUrl($sVal) |
664
|
|
|
{ |
665
|
|
|
return preg_replace('#&[^/]+\=[^/]+$#', '', $sVal); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
/** |
669
|
|
|
* Secures the Request Parameter. |
670
|
|
|
* |
671
|
|
|
* @param string $sVar |
672
|
|
|
* |
673
|
|
|
* @return string |
674
|
|
|
*/ |
675
|
|
|
private function secureRequestParameter($sVar) |
676
|
|
|
{ |
677
|
|
|
$sVar = escape($sVar, true); |
678
|
|
|
|
679
|
|
|
// Convert programatic characters to entities and return |
680
|
|
|
return str_replace(array( |
681
|
|
|
'$', |
682
|
|
|
'(', |
683
|
|
|
')', |
684
|
|
|
'%28', |
685
|
|
|
'%29'), // Bad |
686
|
|
|
array( |
687
|
|
|
'$', |
688
|
|
|
'(', |
689
|
|
|
')', |
690
|
|
|
'(', |
691
|
|
|
')'), // Good |
692
|
|
|
$sVar); |
693
|
|
|
} |
694
|
|
|
|
695
|
|
|
/** |
696
|
|
|
* Remove the Request Parameter variable. |
697
|
|
|
* |
698
|
|
|
* @return void |
699
|
|
|
*/ |
700
|
|
|
private function clearRequestParameter() |
701
|
|
|
{ |
702
|
|
|
unset($this->aRequestParameter); |
703
|
|
|
} |
704
|
|
|
|
705
|
|
|
/** |
706
|
|
|
* We display an error page if it on the index file to indicate no file extension in order to avoid utilization of a security vulnerability in the language. |
707
|
|
|
* Otherwise, if the URL rewrite extension is not enabled, we redirect the page to index.php file (then [URL]/index.php/[REQUEST]/ ). |
708
|
|
|
* |
709
|
|
|
* @see self::notFound() |
710
|
|
|
* |
711
|
|
|
* @return void |
712
|
|
|
*/ |
713
|
|
|
private function indexFileRouter() |
714
|
|
|
{ |
715
|
|
|
// The following code will be useless when pH7CMS will be able to work without mod_rewrite \\ |
716
|
|
|
if ($this->oHttpRequest->currentUrl() === PH7_URL_ROOT . static::INDEX_FILE) |
717
|
|
|
$this->notFound('If we\'re in production mode, we display an error page if it on the index file to indicate no file extension in order to avoid utilization of a security vulnerability in the language.'); |
718
|
|
|
|
719
|
|
|
/* |
|
|
|
|
720
|
|
|
|
721
|
|
|
// The following code will be useful when pH7CMS will be able to work without mod_rewrite \\ |
722
|
|
|
if (!\PH7\Framework\Server\Server::isRewriteMod() && false === strpos($this->oHttpRequest->currentUrl(), static::INDEX_FILE)) |
723
|
|
|
{ |
724
|
|
|
Header::redirect(PH7_URL_ROOT . static::INDEX_FILE); |
725
|
|
|
} |
726
|
|
|
elseif (\PH7\Framework\Server\Server::isRewriteMod() && false !== strpos($this->oHttpRequest->currentUrl(), static::INDEX_FILE)) |
727
|
|
|
{ |
728
|
|
|
$this->notFound('If we are in production mode, we display an error page if it is on the index.php file to indicate no file extension in order to avoid utilization of a security vulnerability in the PHP programming language.'); |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
*/ |
732
|
|
|
} |
733
|
|
|
|
734
|
|
|
/** |
735
|
|
|
* This method has two different behavior compared to the mode site. |
736
|
|
|
* 1. In production mode: Displays the page not found using the system module "error". |
737
|
|
|
* 2. In development mode: It throws an Exception with displaying an explanatory message that indicates why this page was not found. |
738
|
|
|
* |
739
|
|
|
* @param string $sMsg |
740
|
|
|
* @param string $iRedirect 1 = redirect |
741
|
|
|
* |
742
|
|
|
* @return void |
743
|
|
|
* |
744
|
|
|
* @throws PH7Exception If the site is in development mode, displays an explanatory message that indicates why this page was not found. |
745
|
|
|
*/ |
746
|
|
|
private function notFound($sMsg = null, $iRedirect = null) |
747
|
|
|
{ |
748
|
|
|
if (isDebug() && !empty($sMsg)) { |
749
|
|
|
throw new PH7Exception($sMsg); |
750
|
|
|
} else { |
751
|
|
|
if (empty($iRedirect)) { |
752
|
|
|
$this->oRegistry->module = 'error'; |
|
|
|
|
753
|
|
|
} else { |
754
|
|
|
Header::redirect(UriRoute::get('error', 'http', 'index')); |
755
|
|
|
} |
756
|
|
|
} |
757
|
|
|
} |
758
|
|
|
} |
759
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.