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-2019, 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
|
|
|
*/ |
13
|
|
|
|
14
|
|
|
namespace PH7\Framework\Mvc\Router; |
15
|
|
|
|
16
|
|
|
defined('PH7') or exit('Restricted access'); |
17
|
|
|
|
18
|
|
|
use DomDocument; |
19
|
|
|
use DOMElement; |
20
|
|
|
use PDO; |
21
|
|
|
use PH7\Framework\Config\Config; |
22
|
|
|
use PH7\Framework\Error\CException\PH7Exception; |
23
|
|
|
use PH7\Framework\File\Import as FileImporter; |
24
|
|
|
use PH7\Framework\Layout\Gzip\Gzip; |
25
|
|
|
use PH7\Framework\Layout\LoadTemplate; |
26
|
|
|
use PH7\Framework\Mvc\Model\DbConfig; |
27
|
|
|
use PH7\Framework\Mvc\Model\Engine\Db; |
28
|
|
|
use PH7\Framework\Mvc\Request\Http; |
29
|
|
|
use PH7\Framework\Mvc\Router\Uri as UriRoute; |
30
|
|
|
use PH7\Framework\Pattern\Singleton; |
31
|
|
|
use PH7\Framework\Registry\Registry; |
32
|
|
|
use PH7\Framework\Translate\Lang; |
33
|
|
|
use PH7\Framework\Url\Header; |
34
|
|
|
use PH7\Framework\Url\Uri; |
|
|
|
|
35
|
|
|
use ReflectionException; |
36
|
|
|
use ReflectionMethod; |
37
|
|
|
use Teapot\StatusCode; |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @class Singleton Class |
41
|
|
|
*/ |
42
|
|
|
final class FrontController |
43
|
|
|
{ |
44
|
|
|
const PROJECT_NAMESPACE = 'PH7\\'; |
45
|
|
|
const CONTROLLER_SUFFIX = 'Controller'; |
46
|
|
|
const INDEX_FILE = 'index.php'; |
47
|
|
|
|
48
|
|
|
const REDIRECT_ERROR_MOD = 1; |
49
|
|
|
|
50
|
|
|
const MAIN_GETTEXT_FILENAME = 'global'; |
51
|
|
|
const SIMPLE_MOD_REQUEST_PARAM_NAME = 'm'; |
52
|
|
|
const ASSET_REQUEST_PARAM_NAME = 'asset'; |
53
|
|
|
const AJAX_REQUEST_PARAM_NAME = 'ajax'; |
54
|
|
|
const GZIP_REQUEST_PARAM_NAME = 'gzip'; |
55
|
|
|
|
56
|
|
|
const REGEX_MODULE_FORMAT = '#^[a-z0-9\.\-_]+$#i'; |
57
|
|
|
const REGEX_CONTROLLER_FORMAT = '#^[a-z0-9_]+$#i'; |
58
|
|
|
const REGEX_ACTION_FORMAT = '#^[a-z0-9_]+$#i'; |
59
|
|
|
const REGEX_FOLDER_FORMAT = '#^[\w]+$#'; |
60
|
|
|
const REGEX_URL_EXTRA_OPTIONS = '/?(?:\?[^/]+\=[^/]+)?'; |
61
|
|
|
const REGEX_URL_PARAMS = '#&[^/]+\=[^/]+$#'; |
62
|
|
|
|
63
|
|
|
/** @var Config */ |
64
|
|
|
private $oConfig; |
65
|
|
|
|
66
|
|
|
/** @var Registry */ |
67
|
|
|
private $oRegistry; |
68
|
|
|
|
69
|
|
|
/** @var Http */ |
70
|
|
|
private $oHttpRequest; |
71
|
|
|
|
72
|
|
|
/** @var Uri */ |
73
|
|
|
private $oUri; |
74
|
|
|
|
75
|
|
|
/** @var array */ |
76
|
|
|
private $aRequestParameter = []; |
77
|
|
|
|
78
|
|
|
/** @var bool */ |
79
|
|
|
private $bIsRouterRewritten = false; |
80
|
|
|
|
81
|
|
|
use Singleton; // Import the Singleton trait |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Routing controllers. |
85
|
|
|
*/ |
86
|
|
|
private function __construct() |
87
|
|
|
{ |
88
|
|
|
/** Objects are created for the functioning of the class **/ |
89
|
|
|
$this->oConfig = Config::getInstance(); |
90
|
|
|
$this->oRegistry = Registry::getInstance(); |
91
|
|
|
$this->oHttpRequest = new Http; |
92
|
|
|
$this->oUri = Uri::getInstance(); |
93
|
|
|
|
94
|
|
|
$this->indexFileRouter(); |
95
|
|
|
|
96
|
|
|
if ($this->isAssetRequest(0) && $this->isGzipRequest(1)) { |
97
|
|
|
// Loading and compress CSS and JavaScript files |
98
|
|
|
$this->gzipRouter(); |
99
|
|
|
exit; |
|
|
|
|
100
|
|
|
} |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* @internal We initialize the database after the compression of static files (self::gzipRouter() method), |
104
|
|
|
* so we can always display static files even if there are problems with the database. |
105
|
|
|
*/ |
106
|
|
|
$this->_initializeDatabase(); |
107
|
|
|
|
108
|
|
|
/** |
109
|
|
|
* @internal self::initializeLanguage() method must be declared before the others, because it initializes the main language constants for the rest of the code. |
110
|
|
|
*/ |
111
|
|
|
$this->initializeLanguage(); |
112
|
|
|
|
113
|
|
|
$this->checkUriCacheStatus(); |
114
|
|
|
|
115
|
|
|
$this->initializeAssets(); |
116
|
|
|
|
117
|
|
|
$this->launchRewritingRouter(); |
118
|
|
|
|
119
|
|
|
$this->launchNonRewritingRouters(); |
120
|
|
|
} |
121
|
|
|
|
122
|
|
|
/** |
123
|
|
|
* If the module action isn't rewriting, we launch the basic router. |
124
|
|
|
*/ |
125
|
|
|
private function launchNonRewritingRouters() |
126
|
|
|
{ |
127
|
|
|
if (!$this->isRouterRewritten()) { |
128
|
|
|
if ($this->isSimpleModuleRequest()) { |
129
|
|
|
$this->simpleModuleRouter(); |
130
|
|
|
} else { |
131
|
|
|
$this->simpleRouter(); |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
} |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Router for the modules that are rewriting through the custom XML route file. |
138
|
|
|
* |
139
|
|
|
* @throws PH7Exception |
140
|
|
|
* @throws \PH7\Framework\File\IOException If the XML route file is not found. |
141
|
|
|
*/ |
142
|
|
|
private function launchRewritingRouter() |
143
|
|
|
{ |
144
|
|
|
$oUrl = UriRoute::loadFile(new DomDocument); |
145
|
|
|
|
146
|
|
|
foreach ($oUrl->getElementsByTagName('route') as $oRoute) { |
147
|
|
|
if ($this->isRewrittenUrl($oRoute, $aMatches)) { |
148
|
|
|
$this->setRewritingRouter(); |
149
|
|
|
|
150
|
|
|
$sPathModule = $oRoute->getAttribute('path') . PH7_SH; |
151
|
|
|
|
152
|
|
|
// Get module |
153
|
|
|
$this->oRegistry->module = $oRoute->getAttribute('module'); |
|
|
|
|
154
|
|
|
|
155
|
|
|
// Check if file exist |
156
|
|
|
if (!$this->oConfig->load(PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) { |
|
|
|
|
157
|
|
|
$this->notFound('The <b>' . $this->oRegistry->module . |
|
|
|
|
158
|
|
|
'</b> system module is not found.<br />File: <b>' . PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS . |
|
|
|
|
159
|
|
|
'</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>'); |
|
|
|
|
160
|
|
|
} |
161
|
|
|
|
162
|
|
|
/***** PATH THE MODULE *****/ |
163
|
|
|
$this->oRegistry->path_module = PH7_PATH_APP . $sPathModule . $this->oRegistry->module . PH7_DS; |
|
|
|
|
164
|
|
|
|
165
|
|
|
/***** URL THE MODULE *****/ |
166
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . $this->oRegistry->module . PH7_SH; |
|
|
|
|
167
|
|
|
|
168
|
|
|
/***** PATH THE TEMPLATE *****/ |
169
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_ROOT . PH7_LAYOUT . $sPathModule . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
170
|
|
|
|
171
|
|
|
/***** URL THE TEMPLATE *****/ |
172
|
|
|
$this->oRegistry->url_themes_module = PH7_RELATIVE . PH7_LAYOUT . $sPathModule . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
173
|
|
|
|
174
|
|
|
// Get the default controller |
175
|
|
|
$this->oRegistry->controller = ucfirst($oRoute->getAttribute('controller')) . self::CONTROLLER_SUFFIX; |
|
|
|
|
176
|
|
|
|
177
|
|
|
// Get the default action |
178
|
|
|
$this->oRegistry->action = $oRoute->getAttribute('action'); |
|
|
|
|
179
|
|
|
if ($oRoute->hasAttribute('vars')) { |
180
|
|
|
$this->generateRequestParameters($oRoute, $aMatches); |
181
|
|
|
} |
182
|
|
|
break; |
183
|
|
|
} |
184
|
|
|
} |
185
|
|
|
unset($oUrl); |
186
|
|
|
} |
187
|
|
|
|
188
|
|
|
/** |
189
|
|
|
* Simple Router. |
190
|
|
|
* |
191
|
|
|
* @return void |
192
|
|
|
* |
193
|
|
|
* @throws PH7Exception |
194
|
|
|
*/ |
195
|
|
|
private function simpleRouter() |
196
|
|
|
{ |
197
|
|
|
if ($this->oUri->fragment(0) && preg_match(self::REGEX_MODULE_FORMAT, $this->oUri->fragment(0))) { |
198
|
|
|
// Set system module |
199
|
|
|
$this->oRegistry->module = $this->oUri->fragment(0); |
|
|
|
|
200
|
|
|
} else { |
201
|
|
|
// Get system module |
202
|
|
|
$this->oRegistry->module = DbConfig::getSetting('defaultSysModule'); |
|
|
|
|
203
|
|
|
} |
204
|
|
|
|
205
|
|
|
// Check if file exist |
206
|
|
|
if (!$this->oConfig->load(PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) { |
|
|
|
|
207
|
|
|
$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 . |
|
|
|
|
208
|
|
|
'</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>'); |
|
|
|
|
209
|
|
|
} |
210
|
|
|
|
211
|
|
|
/***** PATH THE MODULE *****/ |
212
|
|
|
$this->oRegistry->path_module = PH7_PATH_SYS . PH7_MOD . $this->oRegistry->module . PH7_DS; |
|
|
|
|
213
|
|
|
|
214
|
|
|
/***** URL THE MODULE *****/ |
215
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . $this->oRegistry->module . PH7_SH; |
|
|
|
|
216
|
|
|
|
217
|
|
|
/***** PATH THE TEMPLATE *****/ |
218
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_TPL_SYS_MOD . PH7_DS . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
219
|
|
|
|
220
|
|
|
/***** URL THE TEMPLATE *****/ |
221
|
|
|
$this->oRegistry->url_themes_module = PH7_URL_TPL_SYS_MOD . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
222
|
|
|
|
223
|
|
|
if ($this->isAssetRequest(1) && $this->isAjaxRequest(2)) { |
224
|
|
|
// Loading files Asynchronous Ajax |
225
|
|
|
$this->ajaxRouter($this->oRegistry->path_module); |
|
|
|
|
226
|
|
|
exit; |
|
|
|
|
227
|
|
|
|
228
|
|
|
} elseif ($this->oUri->fragment(1) && preg_match(self::REGEX_CONTROLLER_FORMAT, $this->oUri->fragment(1))) { |
229
|
|
|
// Set the controller |
230
|
|
|
$this->oRegistry->controller = ucfirst($this->oUri->fragment(1)) . self::CONTROLLER_SUFFIX; |
|
|
|
|
231
|
|
|
} else { |
232
|
|
|
// Get the default controller |
233
|
|
|
$this->oRegistry->controller = ucfirst($this->oConfig->values['module']['default_controller']) . self::CONTROLLER_SUFFIX; |
|
|
|
|
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
if ($this->oUri->fragment(2) && preg_match(self::REGEX_ACTION_FORMAT, $this->oUri->fragment(2))) { |
237
|
|
|
// Set the action |
238
|
|
|
$this->oRegistry->action = $this->oUri->fragment(2); |
|
|
|
|
239
|
|
|
} else { |
240
|
|
|
// Get the default action |
241
|
|
|
$this->oRegistry->action = $this->oConfig->values['module']['default_action']; |
|
|
|
|
242
|
|
|
} |
243
|
|
|
|
244
|
|
|
/** Request Parameter for the Simple Router mode. **/ |
245
|
|
|
$this->addRequestParameter($this->oUri->segments(3)); |
246
|
|
|
} |
247
|
|
|
|
248
|
|
|
/** |
249
|
|
|
* Simple Module Router. |
250
|
|
|
* |
251
|
|
|
* @return void |
252
|
|
|
* |
253
|
|
|
* @throws PH7Exception |
254
|
|
|
*/ |
255
|
|
|
private function simpleModuleRouter() |
256
|
|
|
{ |
257
|
|
|
if ($this->oUri->fragment(1) && preg_match(self::REGEX_MODULE_FORMAT, $this->oUri->fragment(1))) { |
258
|
|
|
// Set module |
259
|
|
|
$this->oRegistry->module = $this->oUri->fragment(1); |
|
|
|
|
260
|
|
|
} |
261
|
|
|
|
262
|
|
|
// Check if file exist |
263
|
|
|
if (!$this->oConfig->load(PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE)) { |
|
|
|
|
264
|
|
|
$this->notFound('The <b>' . $this->oRegistry->module . '</b> module is not found.<br />File: <b>' . PH7_PATH_MOD . $this->oRegistry->module . PH7_DS . |
|
|
|
|
265
|
|
|
'</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>'); |
|
|
|
|
266
|
|
|
} |
267
|
|
|
|
268
|
|
|
/***** PATH THE MODULE *****/ |
269
|
|
|
$this->oRegistry->path_module = PH7_PATH_MOD . $this->oRegistry->module . PH7_DS; |
|
|
|
|
270
|
|
|
/***** URL THE MODULE *****/ |
271
|
|
|
$this->oRegistry->url_module = PH7_URL_ROOT . 'm/' . $this->oRegistry->module . PH7_SH; |
|
|
|
|
272
|
|
|
/***** PATH THE TEMPLATE *****/ |
273
|
|
|
$this->oRegistry->path_themes_module = PH7_PATH_TPL_MOD . $this->oRegistry->module . PH7_DS . PH7_TPL; |
|
|
|
|
274
|
|
|
/***** URL THE TEMPLATE *****/ |
275
|
|
|
$this->oRegistry->url_themes_module = PH7_URL_TPL_MOD . $this->oRegistry->module . PH7_SH . PH7_TPL; |
|
|
|
|
276
|
|
|
|
277
|
|
|
if ($this->isAssetRequest(2) && $this->isAjaxRequest(3)) { |
278
|
|
|
// Loading files Asynchronous Ajax |
279
|
|
|
$this->ajaxRouter($this->oRegistry->path_module); |
|
|
|
|
280
|
|
|
exit; |
|
|
|
|
281
|
|
|
} elseif ($this->oUri->fragment(2) && preg_match(self::REGEX_CONTROLLER_FORMAT, $this->oUri->fragment(2))) { |
282
|
|
|
// Set the controller |
283
|
|
|
$this->oRegistry->controller = ucfirst($this->oUri->fragment(2)) . self::CONTROLLER_SUFFIX; |
|
|
|
|
284
|
|
|
} else { |
285
|
|
|
// Get the default controller |
286
|
|
|
$this->oRegistry->controller = ucfirst($this->oConfig->values['module']['default_controller']) . self::CONTROLLER_SUFFIX; |
|
|
|
|
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
if ($this->oUri->fragment(3) && preg_match(self::REGEX_ACTION_FORMAT, $this->oUri->fragment(3))) { |
290
|
|
|
// Set the action |
291
|
|
|
$this->oRegistry->action = $this->oUri->fragment(3); |
|
|
|
|
292
|
|
|
} else { |
293
|
|
|
// Get the default action |
294
|
|
|
$this->oRegistry->action = $this->oConfig->values['module']['default_action']; |
|
|
|
|
295
|
|
|
} |
296
|
|
|
|
297
|
|
|
/** Request Parameter for the Simple Module Router mode. **/ |
298
|
|
|
$this->addRequestParameter($this->oUri->segments(4)); |
299
|
|
|
} |
300
|
|
|
|
301
|
|
|
/** |
302
|
|
|
* @return void |
303
|
|
|
*/ |
304
|
|
|
public function _initializeDatabase() |
305
|
|
|
{ |
306
|
|
|
$aDriverOptions[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $this->oConfig->values['database']['charset']; |
|
|
|
|
307
|
|
|
|
308
|
|
|
/* DSN */ |
309
|
|
|
Db::getInstance( |
310
|
|
|
$this->oConfig->values['database']['type'] . ':host=' . $this->oConfig->values['database']['hostname'] . ';port=' . $this->oConfig->values['database']['port'] . ';dbname=' . $this->oConfig->values['database']['name'], |
311
|
|
|
/* Username */ |
312
|
|
|
$this->oConfig->values['database']['username'], |
313
|
|
|
/* Password */ |
314
|
|
|
$this->oConfig->values['database']['password'], |
315
|
|
|
/* Driver */ |
316
|
|
|
$aDriverOptions, |
317
|
|
|
/* Prefix */ |
318
|
|
|
$this->oConfig->values['database']['prefix'] |
319
|
|
|
); |
320
|
|
|
} |
321
|
|
|
|
322
|
|
|
/** |
323
|
|
|
* Removing the sensitive database information in the config object. |
324
|
|
|
* |
325
|
|
|
* @return void |
326
|
|
|
*/ |
327
|
|
|
public function _unsetDatabaseInfo() |
328
|
|
|
{ |
329
|
|
|
unset($this->oConfig->values['database']); |
330
|
|
|
} |
331
|
|
|
|
332
|
|
|
/** |
333
|
|
|
* Internationalization with Gettext. |
334
|
|
|
* |
335
|
|
|
* @return void |
336
|
|
|
* |
337
|
|
|
* @throws \PH7\Framework\Translate\Exception |
338
|
|
|
*/ |
339
|
|
|
private function initializeLanguage() |
340
|
|
|
{ |
341
|
|
|
if (!defined('PH7_PREF_LANG')) { |
342
|
|
|
define('PH7_PREF_LANG', DbConfig::getSetting('defaultLanguage')); |
343
|
|
|
} |
344
|
|
|
|
345
|
|
|
if (!defined('PH7_LANG_NAME')) { |
346
|
|
|
// Set the default language of the site and load the default language path |
347
|
|
|
$sLangName = (new Lang) |
348
|
|
|
->setDefaultLang(PH7_PREF_LANG) |
349
|
|
|
->init() |
350
|
|
|
->load(self::MAIN_GETTEXT_FILENAME, PH7_PATH_APP_LANG) |
351
|
|
|
->getLang(); |
352
|
|
|
|
353
|
|
|
define('PH7_LANG_NAME', $sLangName); |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/*** Get the ISO language code (the two first letters) ***/ |
357
|
|
|
define('PH7_DEFAULT_LANG_CODE', Lang::getIsoCode(PH7_DEFAULT_LANG)); |
358
|
|
|
define('PH7_LANG_CODE', Lang::getIsoCode(PH7_LANG_NAME)); |
359
|
|
|
|
360
|
|
|
/*** Set locale environment variables for gettext ***/ |
361
|
|
|
putenv('LC_ALL=' . PH7_LANG_NAME); |
362
|
|
|
setlocale(LC_ALL, PH7_LANG_NAME); |
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* @return void |
367
|
|
|
* |
368
|
|
|
* @throws \PH7\Framework\Layout\Exception |
369
|
|
|
*/ |
370
|
|
|
private function initializeTemplate() |
371
|
|
|
{ |
372
|
|
|
/***** Start Loading Views and Templates *****/ |
373
|
|
|
$oLoadTpl = (new LoadTemplate)->setDefaultTpl(DbConfig::getSetting('defaultTemplate')); |
374
|
|
|
$oLoadTpl->tpl(); |
375
|
|
|
$oLoadTpl->modTpl(); |
376
|
|
|
$oLoadTpl->mailTpl(); |
377
|
|
|
define('PH7_TPL_NAME', $oLoadTpl->getTpl()); |
378
|
|
|
define('PH7_TPL_MOD_NAME', $oLoadTpl->getModTpl()); |
379
|
|
|
define('PH7_TPL_MAIL_NAME', $oLoadTpl->getMailTpl()); |
380
|
|
|
unset($oLoadTpl); |
381
|
|
|
} |
382
|
|
|
|
383
|
|
|
/** |
384
|
|
|
* @return void |
385
|
|
|
*/ |
386
|
|
|
private function initializePaths() |
387
|
|
|
{ |
388
|
|
|
$this->oRegistry->action = strtolower($this->oRegistry->action); |
|
|
|
|
389
|
|
|
|
390
|
|
|
/***** SHORTCUTS PATH FOR MODULES *****/ |
391
|
|
|
$this->oRegistry->path_module_controllers = $this->oRegistry->path_module . PH7_CTRL; |
|
|
|
|
392
|
|
|
$this->oRegistry->path_module_models = $this->oRegistry->path_module . PH7_MODELS; |
|
|
|
|
393
|
|
|
$this->oRegistry->path_module_views = $this->oRegistry->path_module . PH7_VIEWS; |
|
|
|
|
394
|
|
|
$this->oRegistry->path_module_forms = $this->oRegistry->path_module . PH7_FORMS; |
|
|
|
|
395
|
|
|
$this->oRegistry->path_module_inc = $this->oRegistry->path_module . PH7_INC; |
|
|
|
|
396
|
|
|
$this->oRegistry->path_module_config = $this->oRegistry->path_module . PH7_CONFIG; |
|
|
|
|
397
|
|
|
$this->oRegistry->path_module_lang = $this->oRegistry->path_module . PH7_LANG; |
|
|
|
|
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Initialize the resources of the assets folders. |
402
|
|
|
* |
403
|
|
|
* @return void |
404
|
|
|
* |
405
|
|
|
* @throws PH7Exception |
406
|
|
|
* @throws \PH7\Framework\Http\Exception |
407
|
|
|
*/ |
408
|
|
|
private function initializeAssets() |
409
|
|
|
{ |
410
|
|
|
if ($this->isAssetRequest(0)) { |
411
|
|
|
switch ($this->oUri->fragment(1)) { |
412
|
|
|
case self::AJAX_REQUEST_PARAM_NAME: |
413
|
|
|
// Loading Asynchronous Ajax files |
414
|
|
|
$this->ajaxRouter(); |
415
|
|
|
break; |
416
|
|
|
|
417
|
|
|
case 'file': |
418
|
|
|
// Loading files |
419
|
|
|
$this->fileRouter(); |
420
|
|
|
break; |
421
|
|
|
|
422
|
|
|
case 'cron': |
423
|
|
|
// Loading Cron Jobs files |
424
|
|
|
$this->cronRouter(); |
425
|
|
|
break; |
426
|
|
|
|
427
|
|
|
case 'css': |
428
|
|
|
// Loading Style sheet files |
429
|
|
|
$this->cssRouter(); |
430
|
|
|
break; |
431
|
|
|
|
432
|
|
|
case 'js': |
433
|
|
|
// Loading JavaScript files |
434
|
|
|
$this->jsRouter(); |
435
|
|
|
break; |
436
|
|
|
|
437
|
|
|
default: |
438
|
|
|
$this->notFound( |
439
|
|
|
'Asset file not found!', |
440
|
|
|
self::REDIRECT_ERROR_MOD |
441
|
|
|
); |
442
|
|
|
} |
443
|
|
|
exit; |
|
|
|
|
444
|
|
|
} |
445
|
|
|
} |
446
|
|
|
|
447
|
|
|
/** |
448
|
|
|
* Check if the URI cache needs to be regenerated when outdated. |
449
|
|
|
* |
450
|
|
|
* @return void |
451
|
|
|
*/ |
452
|
|
|
private function checkUriCacheStatus() |
453
|
|
|
{ |
454
|
|
|
if (UriRoute::URI_CACHE_ENABLED && UriRoute::isCachedUrlOutdated()) { |
455
|
|
|
UriRoute::clearCache(); |
456
|
|
|
} |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
/** |
460
|
|
|
* @return void |
461
|
|
|
* |
462
|
|
|
* @throws \PH7\Framework\Layout\Gzip\Exception If the cache file couldn't be written. |
463
|
|
|
* @throws \PH7\Framework\Layout\Gzip\Exception If the file couldn't be read. |
464
|
|
|
*/ |
465
|
|
|
private function gzipRouter() |
466
|
|
|
{ |
467
|
|
|
(new Gzip)->run(); |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
/** |
471
|
|
|
* @param string|null $sMod |
472
|
|
|
* |
473
|
|
|
* @return void |
474
|
|
|
* |
475
|
|
|
* @throws PH7Exception |
476
|
|
|
*/ |
477
|
|
|
private function ajaxRouter($sMod = null) |
478
|
|
|
{ |
479
|
|
|
// Load Ajax class for jsonMsg() func |
480
|
|
|
FileImporter::pH7FwkClass('Ajax.Ajax'); |
481
|
|
|
|
482
|
|
|
// Option for Content Type |
483
|
|
|
if ($this->oHttpRequest->getExists('option')) { |
484
|
|
|
if ($this->oHttpRequest->get('option') === 'plain') { |
485
|
|
|
header('Content-Type: text/plain; charset=utf-8'); |
486
|
|
|
} |
487
|
|
|
} |
488
|
|
|
|
489
|
|
|
// For module only! |
490
|
|
|
if (!empty($sMod)) { |
491
|
|
|
$this->initializePaths(); |
492
|
|
|
|
493
|
|
|
$sFolder = ($this->oUri->fragment(4) && preg_match(self::REGEX_FOLDER_FORMAT, $this->oUri->fragment(4))) ? PH7_DS . $this->oUri->fragment(4) : ''; |
494
|
|
|
if (is_file($sMod . 'assets/ajax/' . $this->oUri->fragment(3) . $sFolder . 'Ajax.php')) { |
495
|
|
|
include_once $sMod . 'assets/ajax/' . $this->oUri->fragment(3) . $sFolder . 'Ajax.php'; |
496
|
|
|
} else { |
497
|
|
|
$this->notFound( |
498
|
|
|
'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', |
499
|
|
|
self::REDIRECT_ERROR_MOD |
500
|
|
|
); |
501
|
|
|
} |
502
|
|
|
} else { |
503
|
|
|
$sFolder = ($this->oUri->fragment(3) && preg_match(self::REGEX_FOLDER_FORMAT, $this->oUri->fragment(3))) ? PH7_DS . $this->oUri->fragment(3) : ''; |
504
|
|
|
|
505
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/ajax/' . $this->oUri->fragment(2) . $sFolder . 'CoreAjax.php')) { |
506
|
|
|
include_once PH7_PATH_SYS . 'core/assets/ajax/' . $this->oUri->fragment(2) . $sFolder . 'CoreAjax.php'; |
507
|
|
|
} else { |
508
|
|
|
$this->notFound( |
509
|
|
|
'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', |
510
|
|
|
self::REDIRECT_ERROR_MOD |
511
|
|
|
); |
512
|
|
|
} |
513
|
|
|
} |
514
|
|
|
} |
515
|
|
|
|
516
|
|
|
/** |
517
|
|
|
* @throws PH7Exception |
518
|
|
|
*/ |
519
|
|
|
private function fileRouter() |
520
|
|
|
{ |
521
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/file/' . $this->oUri->fragment(2) . 'CoreFile.php')) { |
522
|
|
|
include_once PH7_PATH_SYS . 'core/assets/file/' . $this->oUri->fragment(2) . 'CoreFile.php'; |
523
|
|
|
} else { |
524
|
|
|
$this->notFound( |
525
|
|
|
'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', |
526
|
|
|
self::REDIRECT_ERROR_MOD |
527
|
|
|
); |
528
|
|
|
} |
529
|
|
|
} |
530
|
|
|
|
531
|
|
|
/** |
532
|
|
|
* @throws PH7Exception |
533
|
|
|
* @throws \PH7\Framework\Http\Exception |
534
|
|
|
*/ |
535
|
|
|
private function cronRouter() |
536
|
|
|
{ |
537
|
|
|
if ($this->isCronHashValid()) { |
538
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/cron/' . $this->oUri->fragment(2) . PH7_DS . $this->oUri->fragment(3) . 'CoreCron.php')) { |
539
|
|
|
ignore_user_abort(true); |
540
|
|
|
require PH7_PATH_SYS . 'core/assets/cron/' . $this->oUri->fragment(2) . PH7_DS . $this->oUri->fragment(3) . 'CoreCron.php'; |
541
|
|
|
} else { |
542
|
|
|
$this->notFound( |
543
|
|
|
'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', |
544
|
|
|
self::REDIRECT_ERROR_MOD |
545
|
|
|
); |
546
|
|
|
} |
547
|
|
|
} else { |
548
|
|
|
Http::setHeadersByCode(StatusCode::FORBIDDEN); |
549
|
|
|
exit('Secret word is invalid for the cron hash!'); |
|
|
|
|
550
|
|
|
} |
551
|
|
|
} |
552
|
|
|
|
553
|
|
|
/** |
554
|
|
|
* Check if the cron's security string is valid or not. |
555
|
|
|
* |
556
|
|
|
* @return bool |
557
|
|
|
*/ |
558
|
|
|
private function isCronHashValid() |
559
|
|
|
{ |
560
|
|
|
return strcmp( |
561
|
|
|
$this->oHttpRequest->get('secret_word'), |
562
|
|
|
DbConfig::getSetting('cronSecurityHash') |
563
|
|
|
) === 0; |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
/** |
567
|
|
|
* @throws PH7Exception |
568
|
|
|
*/ |
569
|
|
|
private function cssRouter() |
570
|
|
|
{ |
571
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/css/' . $this->oUri->fragment(2) . 'CoreCss.php')) { |
572
|
|
|
header('Content-Type: text/css'); |
573
|
|
|
include_once PH7_PATH_SYS . 'core/assets/css/' . $this->oUri->fragment(2) . 'CoreCss.php'; |
574
|
|
|
} else { |
575
|
|
|
$this->notFound( |
576
|
|
|
'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', |
577
|
|
|
self::REDIRECT_ERROR_MOD |
578
|
|
|
); |
579
|
|
|
} |
580
|
|
|
} |
581
|
|
|
|
582
|
|
|
/** |
583
|
|
|
* @throws PH7Exception |
584
|
|
|
*/ |
585
|
|
|
private function jsRouter() |
586
|
|
|
{ |
587
|
|
|
if (is_file(PH7_PATH_SYS . 'core/assets/js/' . $this->oUri->fragment(2) . 'CoreJs.php')) { |
588
|
|
|
header('Content-Type: text/javascript'); |
589
|
|
|
include_once PH7_PATH_SYS . 'core/assets/js/' . $this->oUri->fragment(2) . 'CoreJs.php'; |
590
|
|
|
} else { |
591
|
|
|
$this->notFound( |
592
|
|
|
'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', |
593
|
|
|
self::REDIRECT_ERROR_MOD |
594
|
|
|
); |
595
|
|
|
} |
596
|
|
|
} |
597
|
|
|
|
598
|
|
|
/** |
599
|
|
|
* @throws PH7Exception |
600
|
|
|
*/ |
601
|
|
|
public function runRouter() |
602
|
|
|
{ |
603
|
|
|
$this->initializePaths(); |
604
|
|
|
|
605
|
|
|
/***** FOR FILE CONFIG .INI OF MODULE *****/ |
606
|
|
|
$this->oConfig->load($this->oRegistry->path_module . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
|
|
|
|
607
|
|
|
|
608
|
|
|
// PH7_DEFAULT_TPL_MOD constant has to be defined before calling "initializeTemplate()" |
609
|
|
|
define('PH7_DEFAULT_TPL_MOD', $this->oConfig->values['module']['default_theme']); |
610
|
|
|
|
611
|
|
|
$this->initializeTemplate(); |
612
|
|
|
|
613
|
|
|
if ($this->doesControllerModuleExist()) { |
614
|
|
|
if ($this->doesModuleHaveBootstrap()) { |
615
|
|
|
require_once $this->oRegistry->path_module . 'Bootstrap.php'; |
616
|
|
|
} |
617
|
|
|
|
618
|
|
|
$this->runController(); |
619
|
|
|
} else { |
620
|
|
|
$this->notFound('The <b>' . $this->oRegistry->controller . '</b> controller of the <b>' . $this->oRegistry->module . |
|
|
|
|
621
|
|
|
'</b> module is not found.<br />File: <b>' . $this->oRegistry->path_module . '</b>', |
|
|
|
|
622
|
|
|
self::REDIRECT_ERROR_MOD |
623
|
|
|
); |
624
|
|
|
} |
625
|
|
|
} |
626
|
|
|
|
627
|
|
|
/** |
628
|
|
|
* Check if the module's action is rewriting by the XML route file or not. |
629
|
|
|
* |
630
|
|
|
* @return bool |
631
|
|
|
*/ |
632
|
|
|
private function isRouterRewritten() |
633
|
|
|
{ |
634
|
|
|
return $this->bIsRouterRewritten; |
635
|
|
|
} |
636
|
|
|
|
637
|
|
|
/** |
638
|
|
|
* If the action is rewriting by the XML route file, set the correct router to be used. |
639
|
|
|
* |
640
|
|
|
* @return void |
641
|
|
|
*/ |
642
|
|
|
private function setRewritingRouter() |
643
|
|
|
{ |
644
|
|
|
$this->bIsRouterRewritten = true; |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
/** |
648
|
|
|
* Run the module's controller (or display an error message if the controller doesn't exist). |
649
|
|
|
* |
650
|
|
|
* @return void |
651
|
|
|
*/ |
652
|
|
|
private function runController() |
653
|
|
|
{ |
654
|
|
|
$sController = self::PROJECT_NAMESPACE . $this->oRegistry->controller; |
|
|
|
|
655
|
|
|
|
656
|
|
|
try { |
657
|
|
|
$oMvc = new ReflectionMethod($sController, $this->oRegistry->action); |
|
|
|
|
658
|
|
|
if ($oMvc->isPublic()) { |
659
|
|
|
// Perform the controller's action |
660
|
|
|
$oMvc->invokeArgs(new $sController, $this->getRequestParameter()); |
661
|
|
|
} else { |
662
|
|
|
$this->notFound( |
663
|
|
|
'The <b>' . $this->oRegistry->action . '</b> method is not public!', |
|
|
|
|
664
|
|
|
self::REDIRECT_ERROR_MOD |
665
|
|
|
); |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
// Destruct object to minimize CPU resources |
669
|
|
|
unset($oMvc); |
670
|
|
|
} catch (ReflectionException $oExcept) { |
671
|
|
|
// If the class or method doesn't exist |
672
|
|
|
$this->notFound( |
673
|
|
|
$oExcept->getMessage(), |
674
|
|
|
self::REDIRECT_ERROR_MOD |
675
|
|
|
); |
676
|
|
|
} |
677
|
|
|
} |
678
|
|
|
|
679
|
|
|
/** |
680
|
|
|
* @param DOMElement $oRoute |
681
|
|
|
* @param array $aMatches |
682
|
|
|
* |
683
|
|
|
* @return bool |
684
|
|
|
*/ |
685
|
|
|
private function isRewrittenUrl(DOMElement $oRoute, &$aMatches) |
686
|
|
|
{ |
687
|
|
|
return preg_match( |
688
|
|
|
'`^' . $oRoute->getAttribute('url') . self::REGEX_URL_EXTRA_OPTIONS . '$`', |
689
|
|
|
$this->oHttpRequest->requestUri(), |
690
|
|
|
$aMatches |
691
|
|
|
); |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
private function generateRequestParameters(DOMElement $oRoute, array $aMatches) |
695
|
|
|
{ |
696
|
|
|
$aVars = explode(UriRoute::VARS_PARAM_DELIMITER, $oRoute->getAttribute('vars')); |
697
|
|
|
$iOffset = count($aVars); |
698
|
|
|
|
699
|
|
|
foreach ($aMatches as $sKey => $sMatch) { |
700
|
|
|
if ($sKey !== 0) { |
701
|
|
|
$this->oHttpRequest->setGet($aVars[$sKey - 1], $sMatch); |
702
|
|
|
|
703
|
|
|
/** Request Parameter for the Router Rewriting mode **/ |
704
|
|
|
$this->addRequestParameter( |
705
|
|
|
$this->oUri->segments($this->oUri->totalFragment() - $iOffset) |
706
|
|
|
); |
707
|
|
|
} |
708
|
|
|
} |
709
|
|
|
} |
710
|
|
|
|
711
|
|
|
/** |
712
|
|
|
* Get the Request Parameters. |
713
|
|
|
* |
714
|
|
|
* @return array The Request Parameters if it exists, otherwise an empty array. |
715
|
|
|
*/ |
716
|
|
|
private function getRequestParameter() |
717
|
|
|
{ |
718
|
|
|
$aRequest = []; |
719
|
|
|
|
720
|
|
|
if ($this->doRequestParameterExist()) { |
721
|
|
|
foreach ($this->aRequestParameter as $sVal) { |
722
|
|
|
$sVal = trim($this->secureRequestParameter($sVal)); |
723
|
|
|
|
724
|
|
|
if ($sVal !== '') { |
725
|
|
|
// Clean the slug URL |
726
|
|
|
$sVal = $this->cleanSlugUrl($sVal); |
727
|
|
|
|
728
|
|
|
$aRequest[] = $sVal; |
729
|
|
|
} |
730
|
|
|
} |
731
|
|
|
} |
732
|
|
|
$this->clearRequestParameter(); |
733
|
|
|
|
734
|
|
|
return $aRequest; |
735
|
|
|
} |
736
|
|
|
|
737
|
|
|
/** |
738
|
|
|
* Clean the Slug Url. |
739
|
|
|
* |
740
|
|
|
* @param string $sVal The request action name to clean. |
741
|
|
|
* |
742
|
|
|
* @return string |
743
|
|
|
*/ |
744
|
|
|
private function cleanSlugUrl($sVal) |
745
|
|
|
{ |
746
|
|
|
return preg_replace(self::REGEX_URL_PARAMS, '', $sVal); |
747
|
|
|
} |
748
|
|
|
|
749
|
|
|
/** |
750
|
|
|
* Secures the Request Parameter. |
751
|
|
|
* |
752
|
|
|
* @param string $sVar |
753
|
|
|
* |
754
|
|
|
* @return string |
755
|
|
|
*/ |
756
|
|
|
private function secureRequestParameter($sVar) |
757
|
|
|
{ |
758
|
|
|
$sVar = escape($sVar, true); |
759
|
|
|
|
760
|
|
|
// Convert characters to entities and return them |
761
|
|
|
$aBadCharacters = [ |
762
|
|
|
'$', |
763
|
|
|
'(', |
764
|
|
|
')', |
765
|
|
|
'%28', |
766
|
|
|
'%29' |
767
|
|
|
]; |
768
|
|
|
$aGoodCharacters = [ |
769
|
|
|
'$', |
770
|
|
|
'(', |
771
|
|
|
')', |
772
|
|
|
'(', |
773
|
|
|
')' |
774
|
|
|
]; |
775
|
|
|
|
776
|
|
|
return str_replace( |
777
|
|
|
$aBadCharacters, |
778
|
|
|
$aGoodCharacters, |
779
|
|
|
$sVar |
780
|
|
|
); |
781
|
|
|
} |
782
|
|
|
|
783
|
|
|
/** |
784
|
|
|
* Remove the Request Parameter variable. |
785
|
|
|
* |
786
|
|
|
* @return void |
787
|
|
|
*/ |
788
|
|
|
private function clearRequestParameter() |
789
|
|
|
{ |
790
|
|
|
unset($this->aRequestParameter); |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
private function addRequestParameter(array $aRequestParameter) |
794
|
|
|
{ |
795
|
|
|
$this->aRequestParameter = $aRequestParameter; |
796
|
|
|
} |
797
|
|
|
|
798
|
|
|
/** |
799
|
|
|
* @return bool |
800
|
|
|
*/ |
801
|
|
|
private function doRequestParameterExist() |
802
|
|
|
{ |
803
|
|
|
return count($this->aRequestParameter) > 0; |
804
|
|
|
} |
805
|
|
|
|
806
|
|
|
/** |
807
|
|
|
* @return bool |
808
|
|
|
*/ |
809
|
|
|
private function isSimpleModuleRequest() |
810
|
|
|
{ |
811
|
|
|
return $this->oUri->fragment(0) === self::SIMPLE_MOD_REQUEST_PARAM_NAME; |
812
|
|
|
} |
813
|
|
|
|
814
|
|
|
/** |
815
|
|
|
* @param int $iKey |
816
|
|
|
* |
817
|
|
|
* @return bool |
818
|
|
|
*/ |
819
|
|
|
private function isAssetRequest($iKey) |
820
|
|
|
{ |
821
|
|
|
return $this->oUri->fragment($iKey) === self::ASSET_REQUEST_PARAM_NAME; |
822
|
|
|
} |
823
|
|
|
|
824
|
|
|
/** |
825
|
|
|
* @param int $iKey |
826
|
|
|
* |
827
|
|
|
* @return bool |
828
|
|
|
*/ |
829
|
|
|
private function isAjaxRequest($iKey) |
830
|
|
|
{ |
831
|
|
|
return $this->oUri->fragment($iKey) === self::AJAX_REQUEST_PARAM_NAME; |
832
|
|
|
} |
833
|
|
|
|
834
|
|
|
/** |
835
|
|
|
* @param int $iKey |
836
|
|
|
* |
837
|
|
|
* @return bool |
838
|
|
|
*/ |
839
|
|
|
private function isGzipRequest($iKey) |
840
|
|
|
{ |
841
|
|
|
return $this->oUri->fragment($iKey) === self::GZIP_REQUEST_PARAM_NAME; |
842
|
|
|
} |
843
|
|
|
|
844
|
|
|
/** |
845
|
|
|
* @return bool |
846
|
|
|
*/ |
847
|
|
|
private function doesControllerModuleExist() |
848
|
|
|
{ |
849
|
|
|
return is_file($this->oRegistry->path_module_controllers . $this->oRegistry->controller . '.php'); |
|
|
|
|
850
|
|
|
} |
851
|
|
|
|
852
|
|
|
/** |
853
|
|
|
* @return bool |
854
|
|
|
*/ |
855
|
|
|
private function doesModuleHaveBootstrap() |
856
|
|
|
{ |
857
|
|
|
return is_file($this->oRegistry->path_module . 'Bootstrap.php'); |
|
|
|
|
858
|
|
|
} |
859
|
|
|
|
860
|
|
|
/** |
861
|
|
|
* We display an error page if someone request "index.php" filename in order to avoid disclosing and explicitly request the PHP index filename (e.g. for security reasons...). |
862
|
|
|
* Otherwise, if the URL rewrite extension is not enabled, we redirect the page to index.php file (then [URL]/index.php/[REQUEST]/ ). |
863
|
|
|
* |
864
|
|
|
* @see self::notFound() |
865
|
|
|
* |
866
|
|
|
* @return void |
867
|
|
|
* |
868
|
|
|
* @throws PH7Exception |
869
|
|
|
*/ |
870
|
|
|
private function indexFileRouter() |
871
|
|
|
{ |
872
|
|
|
// The following code will be useless if pH7CMS will be able to work without mod_rewrite |
873
|
|
|
if ($this->oHttpRequest->currentUrl() === PH7_URL_ROOT . static::INDEX_FILE) { |
874
|
|
|
$this->notFound('In "production" mode, it simulates "404 page not found" if the index.php filename is called, to avoid disclosing the language index filename (e.g. for security reasons...).'); |
875
|
|
|
} |
876
|
|
|
} |
877
|
|
|
|
878
|
|
|
/** |
879
|
|
|
* This method has two different behaviors depending of the environment mode site. |
880
|
|
|
* 1. In production mode: Displays the page not found using the system module "error". |
881
|
|
|
* 2. In development mode: It throws an Exception with displaying an explanatory message that indicates why this page was not found. |
882
|
|
|
* |
883
|
|
|
* @param string $sMsg |
884
|
|
|
* @param string $iRedirect 1 = redirect |
885
|
|
|
* |
886
|
|
|
* @return void |
887
|
|
|
* |
888
|
|
|
* @throws PH7Exception If the site is in development mode, displays an explanatory message that indicates why this page was not found. |
889
|
|
|
*/ |
890
|
|
|
private function notFound($sMsg = null, $iRedirect = null) |
891
|
|
|
{ |
892
|
|
|
if ($sMsg !== null && isDebug()) { |
893
|
|
|
throw new PH7Exception($sMsg); |
894
|
|
|
} else { |
895
|
|
|
if ($iRedirect === null) { |
896
|
|
|
$this->oRegistry->module = 'error'; |
|
|
|
|
897
|
|
|
|
898
|
|
|
// Reload the config.ini file for the "error" module |
899
|
|
|
$this->oConfig->load(PH7_PATH_SYS . PH7_MOD . 'error' . PH7_DS . PH7_CONFIG . PH7_CONFIG_FILE); |
900
|
|
|
} else { |
901
|
|
|
Header::redirect( |
902
|
|
|
UriRoute::get( |
903
|
|
|
'error', |
904
|
|
|
'http', |
905
|
|
|
'index' |
906
|
|
|
) |
907
|
|
|
); |
908
|
|
|
} |
909
|
|
|
} |
910
|
|
|
} |
911
|
|
|
} |
912
|
|
|
|
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.