1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
48: class FrontController {
49: 50: 51: 52: 53: 54:
55: private $queryString;
56:
57: 58: 59: 60: 61: 62:
63: private $pageController;
64:
65: 66: 67: 68: 69: 70:
71: private $encryptedQuery = false;
72:
73: 74: 75: 76: 77: 78:
79: private $controllerAlias = array();
80:
81: 82: 83: 84: 85: 86: 87:
88: private $filters = array();
89:
90: 91: 92: 93: 94: 95:
96: private $currentAlias;
97:
98: 99: 100: 101: 102: 103:
104: private static $logger = null;
105:
106: 107: 108: 109: 110: 111:
112: public function __construct() {
113: self::$logger = new Logger('FrontController');
114:
115: self::$logger->debug('>>__construct()');
116:
117: global $config;
118:
119: self::$logger->debug('Requested URL is ['.$_SERVER['REQUEST_URI'].']');
120:
121:
122: if (isset($_GET['act'])) {
123: self::$logger->debug('Processing direct request to the front controller');
124: $this->pageController = $_GET['act'];
125:
126: }elseif($config->get('app.use.mod.rewrite') && !isset($_GET['tk'])) {
127: self::$logger->debug('Processing a mod_rewrite request');
128: $this->handleModRewriteRequests();
129:
130: }else{
131: if (!isset($_GET['tk'])) {
132: self::$logger->warn('No controller action set for the front controller, URL is ['.$_SERVER['REQUEST_URI'].']');
133: throw new ResourceNotFoundException('The file that you have requested cannot be found!');
134: }else{
135: self::$logger->debug('Processing a direct request to the front controller with an encrypted token param');
136: $this->setEncrypt(true);
137: try {
138: $this->decodeQuery();
139: $this->populateGetVars();
140: if(isset($_GET['act']))
141: $this->pageController = $_GET['act'];
142: else
143: throw new SecurityException('No act param provided in the secure token!');
144: }catch (SecurityException $e) {
145: self::$logger->error('Error while attempting to decode a secure token in the FrontController: '.$e->getMessage());
146: throw new ResourceNotFoundException('The file that you have requested cannot be found!');
147: }
148: }
149: }
150:
151: self::$logger->debug('<<__construct');
152: }
153:
154: 155: 156: 157: 158: 159:
160: public function setEncrypt($encryptedQuery) {
161: $this->encryptedQuery = $encryptedQuery;
162: }
163:
164: 165: 166: 167: 168: 169:
170: private function populateGetVars() {
171:
172: $pairs = explode('&', $this->queryString);
173:
174: foreach($pairs as $pair) {
175: $keyValue = explode('=', $pair);
176: if(count($keyValue) == 2) {
177: $_GET[$keyValue[0]] = $keyValue[1];
178: $_REQUEST[$keyValue[0]] = $keyValue[1];
179: }
180: }
181: }
182:
183: 184: 185: 186: 187: 188: 189:
190: public static function generateSecureURL($params) {
191: global $config;
192:
193: if($config->get('app.use.mod.rewrite'))
194: return $config->get('app.url').'tk/'.FrontController::encodeQuery($params);
195: else
196: return $config->get('app.url').'?tk='.FrontController::encodeQuery($params);
197: }
198:
199: 200: 201: 202: 203: 204: 205:
206: public static function encodeQuery($queryString) {
207: global $config;
208:
209: $return = base64_encode(AlphaSecurityUtils::encrypt($queryString));
210:
211: $return = strtr($return, '+/', '-_');
212:
213: return $return;
214: }
215:
216: 217: 218: 219: 220: 221:
222: private function decodeQuery() {
223: global $config;
224:
225: if (!isset($_GET['tk'])) {
226: throw new SecurityException('No token provided for the front controller!');
227: }else{
228:
229: $token = strtr($_GET['tk'], '-_', '+/');
230: $token = base64_decode($token);
231: $this->queryString = trim(AlphaSecurityUtils::decrypt($token));
232: }
233: }
234:
235: 236: 237: 238: 239: 240:
241: public static function decodeQueryParams($tk) {
242: global $config;
243:
244:
245: $token = strtr($tk, '-_', '+/');
246: $token = base64_decode($token);
247: $params = trim(AlphaSecurityUtils::decrypt($token));
248:
249: return $params;
250: }
251:
252: 253: 254: 255: 256: 257:
258: public static function getDecodeQueryParams($tk) {
259: global $config;
260:
261:
262: $token = strtr($tk, '-_', '+/');
263: $token = base64_decode($token);
264: $params = trim(AlphaSecurityUtils::decrypt($token));
265:
266: $pairs = explode('&', $params);
267:
268: $parameters = array();
269:
270: foreach($pairs as $pair) {
271: $split = explode('=', $pair);
272: $parameters[$split[0]] = $split[1];
273: }
274:
275: return $parameters;
276: }
277:
278: 279: 280: 281: 282: 283: 284:
285: public function loadController($allowRedirects = true) {
286: global $config;
287:
288: if($allowRedirects && $config->get('app.check.installed') && $this->pageController != 'Install' && $this->pageController != 'Login') {
289: if(!AlphaDAO::isInstalled()) {
290: self::$logger->info('Invoking the Install controller as the system DB is not installed...');
291: $url = FrontController::generateSecureURL('act=Install');
292: self::$logger->info('Redirecting to ['.$url.']');
293: header('Location: '.$url);
294: exit;
295: }
296: }
297:
298:
299: foreach ($this->filters as $filter)
300: $filter->process();
301:
302: if($allowRedirects) {
303:
304: if($config->get('app.force.front.controller') && $this->hasAlias($this->pageController)) {
305:
306: if(empty($this->currentAlias)) {
307:
308: header('HTTP/1.1 301 Moved Permanently');
309:
310:
311: if (count($_GET) > 1) {
312: $keys = array_keys($_GET);
313: $param = $_GET[$keys[1]];
314:
315: if($keys[1] == 'title')
316: $param = str_replace(' ','_',$param);
317:
318: $URL = $config->get('app.url').'/'.$this->getControllerAlias($this->pageController).'/'.
319: $this->getControllerParam($this->pageController).$param;
320: }else{
321: $URL = $config->get('app.url').'/'.$this->getControllerAlias($this->pageController);
322: }
323:
324: header('Location: '.$URL);
325: exit;
326: }
327: }
328: }
329:
330: try {
331: AlphaController::loadControllerDef($this->pageController);
332: $pageController = new $this->pageController();
333:
334: if(!empty($_POST)) {
335: $pageController->doPOST($_REQUEST);
336: }else{
337: $pageController->doGET($_GET);
338: }
339: }catch (LibraryNotInstalledException $e) {
340: self::$logger->warn($e->getMessage()."\nStacktrace:\n".$e->getTraceAsString()."\nRequest params:\n".var_export($_REQUEST, true)."\nRequested resource:\n".$_SERVER['REQUEST_URI']);
341: throw new LibraryNotInstalledException($e->getMessage());
342: }catch (ResourceNotAllowedException $e) {
343: self::$logger->warn($e->getMessage()."\nStacktrace:\n".$e->getTraceAsString()."\nRequest params:\n".var_export($_REQUEST, true)."\nRequested resource:\n".$_SERVER['REQUEST_URI']);
344: throw new ResourceNotAllowedException($e->getMessage());
345: }catch (ResourceNotFoundException $e) {
346: self::$logger->warn($e->getMessage()."\nStacktrace:\n".$e->getTraceAsString()."\nRequest params:\n".var_export($_REQUEST, true)."\nRequested resource:\n".$_SERVER['REQUEST_URI']);
347: throw new ResourceNotFoundException($e->getMessage());
348: }catch (IllegalArguementException $e) {
349: self::$logger->warn($e->getMessage()."\nStacktrace:\n".$e->getTraceAsString()."\nRequest params:\n".var_export($_REQUEST, true)."\nRequested resource:\n".$_SERVER['REQUEST_URI']);
350:
351: if($config->get('security.client.temp.blacklist.filter.enabled')) {
352: if(isset($_SERVER['HTTP_USER_AGENT']) && isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['REQUEST_URI'])) {
353: $request = new BadRequestObject();
354: $request->set('client', $_SERVER['HTTP_USER_AGENT']);
355: $request->set('IP', $_SERVER['REMOTE_ADDR']);
356: $request->set('requestedResource', $_SERVER['REQUEST_URI']);
357: $request->save();
358: }
359: }
360:
361: throw new ResourceNotFoundException('The file that you have requested cannot be found!');
362: }catch (AlphaException $e) {
363: self::$logger->warn($e->getMessage()."\nStacktrace:\n".$e->getTraceAsString()."\nRequest params:\n".var_export($_REQUEST, true)."\nRequested resource:\n".$_SERVER['REQUEST_URI']);
364:
365: if($config->get('security.client.temp.blacklist.filter.enabled')) {
366: if(isset($_SERVER['HTTP_USER_AGENT']) && isset($_SERVER['REMOTE_ADDR']) && isset($_SERVER['REQUEST_URI'])) {
367: $request = new BadRequestObject();
368: $request->set('client', $_SERVER['HTTP_USER_AGENT']);
369: $request->set('IP', $_SERVER['REMOTE_ADDR']);
370: $request->set('requestedResource', $_SERVER['REQUEST_URI']);
371: $request->save();
372: }
373: }
374:
375: throw new ResourceNotFoundException('The file that you have requested cannot be found!');
376: }
377: }
378:
379: 380: 381: 382: 383: 384: 385: 386: 387:
388: public function registerAlias($controller, $alias, $param=null) {
389: $this->controllerAlias[$alias] = $controller;
390: if(isset($param))
391: $this->controllerAlias[$alias.'_param'] = $param;
392:
393:
394: $this->handleModRewriteRequests();
395: }
396:
397: 398: 399: 400: 401: 402: 403:
404: public function checkAlias($alias) {
405: if(array_key_exists($alias, $this->controllerAlias))
406: return true;
407: else
408: return false;
409: }
410:
411: 412: 413: 414: 415: 416: 417:
418: public function hasAlias($controller) {
419: if(in_array($controller, $this->controllerAlias))
420: return true;
421: else
422: return false;
423: }
424:
425: 426: 427: 428: 429: 430: 431:
432: public function getAliasController($alias) {
433: if(array_key_exists($alias, $this->controllerAlias))
434: return $this->controllerAlias[$alias];
435: }
436:
437: 438: 439: 440: 441: 442: 443:
444: public function getControllerAlias($controller) {
445: if(in_array($controller, $this->controllerAlias)) {
446: $keys = array_keys($this->controllerAlias, $controller);
447:
448: return $keys[0];
449: }
450: }
451:
452: 453: 454: 455: 456: 457: 458:
459: public function getAliasParam($alias) {
460: if(array_key_exists($alias.'_param', $this->controllerAlias))
461: return $this->controllerAlias[$alias.'_param'];
462: else
463: return '';
464: }
465:
466: 467: 468: 469: 470: 471: 472:
473: public function getControllerParam($controller) {
474: $alias = $this->getControllerAlias($controller);
475: if(array_key_exists($alias.'_param', $this->controllerAlias))
476: return $this->controllerAlias[$alias.'_param'];
477: else
478: return '';
479: }
480:
481: 482: 483: 484: 485: 486: 487: 488: 489:
490: private static function multipleExplode($string, $delimiters = array()){
491:
492: $mainDelim=$delimiters[count($delimiters)-1];
493:
494: array_pop($delimiters);
495:
496: foreach($delimiters as $delimiter) {
497: $string = str_replace($delimiter, $mainDelim, $string);
498: }
499:
500: $result = explode($mainDelim, $string);
501:
502: return $result;
503: }
504:
505: 506: 507: 508: 509:
510: private function handleModRewriteRequests() {
511: self::$logger->debug('>>handleModRewriteRequests');
512: global $config;
513:
514:
515: $request = str_replace($config->get('app.url'), '', 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
516: self::$logger->debug('$request is ['.$request.']');
517: $params = self::multipleExplode($request, array('/','?','&'));
518: self::$logger->debug('$params are ['.var_export($params, true).']');
519:
520: try {
521:
522: if(empty($this->currentAlias) && !empty($params[0]))
523: $this->currentAlias = $params[0];
524:
525:
526: AlphaController::loadControllerDef($params[0]);
527: self::$logger->debug('Page controller name set on the request URL is ['.$params[0].']');
528: $this->pageController = $params[0];
529: }catch (IllegalArguementException $iae) {
530:
531: self::$logger->debug('The supplied controller alias is ['.$this->currentAlias.']');
532:
533:
534: if($this->checkAlias($this->currentAlias)) {
535: $this->pageController = $this->getAliasController($this->currentAlias);
536: self::$logger->debug('Page controller name obtained from the URL alias is ['.$this->pageController.']');
537:
538: if(isset($params[1])) {
539: if(!empty($_POST))
540: $_REQUEST[$this->getAliasParam($this->currentAlias)] = $params[1];
541: else
542: $_GET[$this->getAliasParam($this->currentAlias)] = $params[1];
543: }
544: }
545: }
546:
547: self::$logger->debug('$params are ['.var_export($params, true).']');
548: self::$logger->debug('currentAlias is ['.$this->currentAlias.']');
549:
550:
551: if($this->currentAlias == 'tk') {
552: self::$logger->debug('Setting the GET vars for a mod_rewrite request with a tk param');
553: $this->setEncrypt(true);
554: $this->queryString = FrontController::decodeQueryParams($params[1]);
555: $_GET['tk'] = $params[1];
556: $this->populateGetVars();
557: $this->pageController = $_GET['act'];
558: }else{
559: $count = count($params);
560:
561: for($i = 1; $i < $count; $i+=2) {
562: if(isset($params[$i+1])) {
563: if(!empty($_POST))
564: $_REQUEST[$params[$i]] = $params[$i+1];
565: else
566: $_GET[$params[$i]] = $params[$i+1];
567: }
568: }
569: }
570:
571: self::$logger->debug('$_GET is ['.var_export($_GET, true).']');
572: self::$logger->debug('<<handleModRewriteRequests');
573: }
574:
575: 576: 577: 578: 579: 580:
581: public function getPageController() {
582: return $this->pageController;
583: }
584:
585: 586: 587: 588: 589: 590: 591:
592: public function registerFilter($filterObject) {
593: if($filterObject instanceof AlphaFilterInterface)
594: array_push($this->filters, $filterObject);
595: else
596: throw new IllegalArguementException('Supplied filter object is not a valid AlphaFilterInterface instance!');
597: }
598:
599: 600: 601: 602: 603: 604:
605: public function getFilters() {
606: return $this->filters;
607: }
608: }
609:
610: ?>