Overview

Packages

  • Onion::Controllers
  • Onion::Core
  • Onion::UI
  • Onion::Utils

Classes

  • Authenticator
  • Controller
  • Database
  • DatabaseResult
  • Log
  • Model
  • Onion
  • Request
  • Response
  • User
  • Overview
  • Package
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * Onion Framework - Jadro frameworku
  5:  *
  6:  * Copyright (c) 2011 Jano Gašpar (http://webstranky.net)
  7:  *
  8:  * @author    Jano Gašpar
  9:  * @copyright Copyright (c) 2011 Jano Gašpar
 10:  * @package   Onion::Core
 11:  **/
 12: class Onion {
 13:     /**
 14:      * @var array úložisko správ
 15:      */
 16:     private $flash = array(
 17:         'prev' => array(),
 18:         'next' => array(),
 19:         'current' => array()
 20:         );
 21: 
 22: 
 23:     /**
 24:      * @var array úložisko rout
 25:      */
 26:     private $routes = array();
 27: 
 28: 
 29:     /**
 30:      * @var array aktuálna routa
 31:      */
 32:     private $route;
 33: 
 34: 
 35:     /**
 36:      * @var object Request objekt s informáciami o aktuálnej požiadavke
 37:      */
 38:     private $request;
 39: 
 40: 
 41:     /**
 42:      * @var object Response objekt s odpoveďou na aktuálnu požiadavku
 43:      */
 44:     private $response;
 45: 
 46: 
 47:     /**
 48:      * @var string názov kontroleru
 49:      */
 50:     public $controller_name;
 51: 
 52: 
 53:     /**
 54:      * @var string meno metódy "action"
 55:      */
 56:     public $action_name;
 57: 
 58: 
 59:     /**
 60:      * @var object objekt kontroleru
 61:      */
 62:     private $controller;
 63: 
 64: 
 65:     /**
 66:      * @var array asociatívne pole s nastaveniami aplikácie
 67:      */
 68:     private $settings = array();
 69: 
 70: 
 71:     /**
 72:      * @var array argumenty aktuálnej požiadavky, nie $_GET
 73:      */
 74:     private $arguments = array();
 75: 
 76: 
 77:     /**
 78:      * @var object Authentificator aktuálny užívateľ
 79:      */
 80:     private $user;
 81: 
 82: 
 83:     /**
 84:      * @var bool ochrana proti zacykleniu pri nastavení Not Found handleru ktorý neexistuje
 85:      */
 86:     private $not_found = FALSE;
 87: 
 88: 
 89:     /**
 90:      * Konštruktor
 91:      *
 92:      * @param  array asociatívne pole s nastaveniami
 93:      * @return void
 94:      */
 95:     public function __construct($settings = array())
 96:     {
 97:         ob_start();
 98: 
 99:         spl_autoload_register(array($this, 'loader'));
100: 
101:         $this->request  = new Request;
102: 
103:         $this->settings($settings);
104: 
105:         if (defined('DEBUG') === FALSE) {
106:             define('DEBUG', FALSE);
107:         }
108: 
109:         Log::enable();
110:         Log::$templates_dir = ONION_DIR . '/Templates';
111:         Log::$logs_dir = TEMP_DIR . '/logs';
112:         if (empty($this->settings['system']['dev_mail']) === FALSE) {
113:             Log::$email = $this->settings['system']['dev_mail'];
114:         }
115: 
116:         date_default_timezone_set($this->settings['system']['timezone']);
117: 
118: 
119:         $this->response = new Response($this);
120:         $this->response->cache_lifetime = $this->settings['system']['cache']['http']['lifetime'];
121:         $this->response->public_cache   = $this->settings['system']['cache']['http']['public'];
122: 
123:         if (empty($this->settings['db']) === FALSE) {
124:             if (is_array(reset($this->settings['db'])) === TRUE) {
125:                 foreach ($this->settings['db'] as $connection_name => $connection_settings) {
126:                     Database::connection($connection_settings, $connection_name);
127:                 }
128: 
129:             } else {
130:                 Database::connection($this->settings['db']);
131:             }
132:         }
133: 
134:         $this->user = new Authenticator($this->settings['system']['auth']);
135: 
136:         Filesystem::init($this->settings['ftp']);
137: 
138:         $this->start_session();
139: 
140:         if (isset($_SESSION['flash']) === TRUE) {
141:             $this->flash['prev'] = $_SESSION['flash'];
142:         }
143:     }
144: 
145: 
146:     /**
147:      * Spustenie aplikácie
148:      */
149:     public function run()
150:     {
151:         $this->add_route(array(
152:             'uri' => '/assets/(js|css)/(.+)',
153:             'name' => 'assets',
154:             'controller' => 'Assets',
155:             'action' => 'send',
156:             'uri_template' => '/#/type/name'
157:             ));
158: 
159:         if ($this->route === NULL) {
160:             $this->add_route(array(
161:                 'uri' => '.*',
162:                 'name' => '.*',
163:                 ));
164:         }
165: 
166:         $this->hooks($this->settings['system']['hooks']['controller']['create']['before']);
167: 
168:         $template = APP_DIR . '/Templates/' . $this->controller_name . '.html';
169:         $this->controller_name .= 'Controller';
170: 
171:         if (method_exists($this->controller_name, $this->action_name) === FALSE) {
172:             $this->not_found(NULL, 'action');
173:         }
174: 
175:         $this->hooks(Arrays::get_value($this->settings, array('system', 'hooks', 'controller', 'run', 'before')));
176: 
177:         $this->controller = new $this->controller_name($this);
178:         $this->controller->view = new Template($template);
179: 
180:         if (method_exists($this->controller, '_before') === TRUE) {
181:             call_user_func_array(array($this->controller, '_before'), $this->arguments);
182:         }
183: 
184:         call_user_func_array(array($this->controller, $this->action_name), $this->arguments);
185: 
186:         if (method_exists($this->controller, '_after') === TRUE) {
187:             call_user_func_array(array($this->controller, '_after'), $this->arguments);
188:         }
189: 
190:         $this->controller->view->set_data('app', $this);
191: 
192:         $flash = array_merge($this->flash['prev'], $this->flash['current']);
193:         $this->controller->view->set_data('flash', $flash);
194:         $this->controller->view->set_data('host', $this->request->host);
195:         $this->controller->view->set_data('base_uri', $this->request->base_uri);
196:         $this->controller->view->set_data('base_domain', $this->request->base_domain);
197:         $this->controller->view->set_data('base_domain_uri', $this->request->base_domain_uri);
198:         $this->controller->view->set_data('subdomain', $this->request->subdomain);
199:         $this->controller->view->set_data('uri', $this->request->uri);
200:         $this->controller->view->set_data('resource', $this->request->resource);
201: 
202:         $this->hooks(Arrays::get_value($this->settings, array('system', 'hooks', 'view', 'before', 'render')));
203: 
204:         $body = $this->controller->view->render();
205:         $this->response->set_body($body);
206: 
207:         $this->hooks(Arrays::get_value($this->settings, array('system', 'hooks', 'view', 'after', 'render')));
208: 
209:         $_SESSION['flash'] = $this->flash['next'];
210:         $this->response->set_body($body);
211:         $this->response->send();
212:     }
213: 
214: 
215:     /**
216:      * Uloženie nastavení aplikácie
217:      *
218:      * @param array asociatívne pole s nastaveniami aplikácie
219:      * @return void
220:      */
221:     private function settings($app_settings)
222:     {
223:         $cookie_domain = $this->request->host;
224:         if (empty($app_settings['system']['multi_domain']) === FALSE) {
225:             $$cookie_domain = $this->request->base_domain;
226:         }
227: 
228:         $settings = array(
229:             'system' => array(
230:                 'timezone' => 'Europe/Bratislava',
231: 
232:                 'cache' => array(
233:                     'http' => array(
234:                         'lifetime' => 3600,
235:                         'public' => TRUE,
236:                         )
237:                     ),
238: 
239:                 'session' => array(
240:                     'lifetime' => 14400,
241:                     'name' => 'onion',
242:                     ),
243: 
244:                 'auth' => array(
245:                     'cookie' => 'onion_autologin',
246:                     'lifetime' => 31536000, // 365 dní
247:                     'login' => array('Login', 'form'),
248:                     'cookie_domain' => $this->request->host,
249:                     'cookie_path' => $this->request->root,
250:                     ),
251:                 ),
252:             );
253: 
254:         $this->settings = Arrays::merge($settings, $app_settings);
255:     }
256: 
257: 
258:     /**
259:      * Pridanie routy
260:      *
261:      * @param  array routa
262:      * @return void
263:      */
264:     public function add_route($route)
265:     {
266:         if (isset($route['method']) === FALSE) {
267:             $route['method'] = array('GET', 'POST');
268:         }
269: 
270:         $route['method'] = (array) $route['method'];
271: 
272:         $name = $route['uri'];
273:         if (isset($route['name']) === TRUE) {
274:             $name = $route['name'];
275:         }
276:         $route['name'] = $name;
277: 
278:         $this->routes[$name] = $route;
279: 
280:         if ($this->route !== NULL) {
281:             return;
282:         }
283: 
284:         $method = $this->request->method;
285:         $resource = $this->request->resource;
286: 
287:         if (empty($resource) === TRUE) {
288:             $resource = '/';
289:         }
290: 
291:         if (preg_match('@^' . $route['uri'] . '$@i', $resource, $matches) === 0) {
292:             return;
293:         }
294: 
295:         if (Arrays::in_array($method, $route['method']) === FALSE) {
296:             return;
297:         }
298: 
299:         if (empty($route['subdomains']) === FALSE
300:             AND Arrays::in_array($this->request->subdomain, $route['subdomains']) === FALSE) {
301: 
302:             return;
303:         }
304: 
305:         $this->route = $route;
306: 
307:         $arguments = $segments = explode('/', trim($matches[0], '/'));
308: 
309:         if (isset($route['controller']) === TRUE) {
310:             if (is_numeric($route['controller']) === TRUE) {
311:                 $controller_name = $segments[$route['controller']];
312: 
313:             } else {
314:                 $controller_name = $route['controller'];
315:             }
316: 
317:         } elseif (isset($segments[0]) === TRUE) {
318:             $controller_name = array_shift($arguments);
319: 
320:         } else {
321:             $controller_name = 'default';
322:         }
323: 
324:         if (empty($controller_name) === TRUE) {
325:             $controller_name = 'default';
326:         }
327: 
328:         if (isset($route['action']) === TRUE) {
329:             if (is_numeric($route['action']) === TRUE) {
330:                 $action_name = $segments[$route['action']];
331:                 array_splice($arguments, $route['action'], 1);
332: 
333:             } else {
334:                 $action_name = $route['action'];
335:             }
336: 
337:         } elseif (isset($segments[1]) === TRUE) {
338:             $action_name = array_shift($arguments);
339: 
340:         } else {
341:             $action_name = '_default';
342:         }
343: 
344:         if (empty($action_name) === TRUE) {
345:             $action_name = '_default';
346:         }
347: 
348:         if (isset($route['controller']) === TRUE
349:             AND is_numeric($route['controller']) === TRUE) {
350: 
351:             array_splice($arguments, $route['controller'], 1);
352:         }
353: 
354:         if (isset($route['uri_template']) === TRUE) {
355:             $arguments_template = explode('/', trim($route['uri_template'], '/'));
356: 
357:             $arguments = array();
358:             $i = -1;
359:             foreach ($arguments_template as $key => $argument) {
360:                 $i++;
361: 
362:                 if ($argument === '#') {
363:                     continue;
364:                 }
365: 
366:                 if (isset($route['action']) === TRUE
367:                     AND is_numeric($route['action']) === TRUE
368:                     AND $i == $route['action']) {
369: 
370:                     continue;
371:                 }
372: 
373:                 if (isset($segments[$key]) === TRUE) {
374:                     $arguments[$argument] = $segments[$key];
375:                 }
376:             }
377:         }
378: 
379:         if (isset($route['name']) === TRUE
380:             AND isset($route['defaults']) === TRUE) {
381: 
382:             foreach ($route['defaults'] as $argument => $value) {
383:                 if ($value === '#') {
384:                     $route['defaults'][$argument] = $arguments[$argument];
385:                 }
386:             }
387: 
388:             $current_args = array_keys($arguments);
389:             $default_args = array_keys($route['defaults']);
390: 
391:             sort($current_args);
392:             sort($default_args);
393: 
394:             $uri_data = $this->request->get;
395:             $new_uri = $this->create_uri($route['name'], $route['defaults'], $uri_data);
396: 
397:             if ($current_args !== $default_args) {
398:                 $this->response->redirect($new_uri, 301);
399:             }
400: 
401:             foreach ($arguments as $argument => $value) {
402:                 if (strlen($value) === 0) {
403:                     $this->response->redirect($new_uri, 301);
404:                 }
405:             }
406:         }
407: 
408:         if (empty($this->route['roles']) === FALSE
409:             AND $this->user->has_roles($this->route['roles']) === FALSE) {
410: 
411:             $controller_name = $this->settings['system']['auth']['login'][0];
412:             $action_name = $this->settings['system']['auth']['login'][1];
413: 
414:         } elseif (empty($this->route['permissions']) === FALSE
415:             AND $this->user->has_permissions($this->route['permissions']) === FALSE) {
416: 
417:             $controller_name = $this->settings['system']['auth']['login'][0];
418:             $action_name = $this->settings['system']['auth']['login'][1];
419:         }
420: 
421:         $controller_name = ucfirst($controller_name);
422: 
423:         foreach ($arguments as $key => &$value) {
424:             $value = urldecode($value);
425:         }
426: 
427:         $action_name = strtr($action_name, array('.' => '_', '-' => '_'));
428: 
429:         $this->controller_name = $controller_name;
430:         $this->action_name = $action_name;
431:         $this->arguments = $arguments;
432:     }
433: 
434: 
435:     /**
436:      * Autoloader
437:      *
438:      * @param  string názov triedy
439:      * @return void
440:      */
441:     public function loader($class)
442:     {
443:         static $paths = array(
444:             'Authenticator' => '/Core/Authenticator.php',
445:             'Controller' => '/Core/Controller.php',
446:             'Database' => '/Core/Database.php',
447:             'DatabaseResult' => '/Core/Database.php',
448:             'Log' => '/Core/Log.php',
449:             'Model' => '/Core/Model.php',
450:             'Request' => '/Core/Request.php',
451:             'Response' => '/Core/Response.php',
452:             'User' => '/Core/User.php',
453: 
454:             'Form' => '/UI/Form.php',
455:             'Grid' => '/UI/Grid.php',
456:             'Html' => '/UI/Html.php',
457:             'IconsGrid' => '/UI/IconsGrid.php',
458:             'Paginator' => '/UI/Paginator.php',
459:             'Template' => '/UI/Template.php',
460:             'Widget' => '/UI/Widget.php',
461: 
462:             'Arrays' => '/Utils/Arrays.php',
463:             'Assets' => '/Utils/Assets.php',
464:             'AssetsController' => '/Utils/Assets.php',
465:             'Filesystem' => '/Utils/Filesystem.php',
466:             'Image' => '/Utils/Image.php',
467:             'Languages' => '/Utils/Languages.php',
468:             'Mail' => '/Utils/Mail.php',
469:             'Secure' => '/Utils/Secure.php',
470:             'Strings' => '/Utils/Strings.php',
471:             'SWF' => '/Utils/SWF.php',
472:             'Utils' => '/Utils/Utils.php',
473:             'Validate' => '/Utils/Validate.php',
474:             'Visitor' => '/Utils/Visitor.php',
475: 
476:             'JSMin' => '/Ext/JSMin/jsmin.php',
477:             'Texy' => '/Ext/Texy/texy.min.php',
478:             'PHPMailer' => '/Ext/PHPMailer/class.phpmailer.php',
479:             );
480: 
481:         if (isset($paths[$class]) === TRUE) {
482:             $class_file = ONION_DIR . $paths[$class];
483: 
484:         } else {
485:             $id = substr($class, -5);
486: 
487:             switch ($id) {
488:                 case 'oller':
489:                     $class_file = APP_DIR . '/Controllers/' . $class . '.php';
490:                     if (file_exists($class_file) === FALSE) {
491:                         if ($this->not_found === TRUE) {
492:                             return;
493:                         }
494: 
495:                         $this->not_found(NULL, 'controller');
496:                     }
497:                     break;
498: 
499:                 case 'idget':
500:                     $class_file = APP_DIR . '/Widgets/' . $class . '.php';
501:                     break;
502: 
503:                 case 'Model':
504:                     $class_file = APP_DIR . '/Models/' . $class . '.php';
505:                     break;
506: 
507:                 default:
508:                     $class_file = LIBS_DIR . '/' . $class . '.php';
509:             }
510:         }
511: 
512:         include($class_file);
513:     }
514: 
515: 
516:     /**
517:      * Naštartovanie session
518:      *
519:      * @return void
520:      */
521:     private function start_session()
522:     {
523:         session_cache_limiter(FALSE);
524: 
525:         $lifetime = $this->settings['system']['session']['lifetime'];
526: 
527:         $host = $this->request->host;
528:         if (empty($this->settings['system']['multi_domain']) === FALSE) {
529:             $host = $this->request->base_domain;
530:         }
531: 
532:         $root = $this->request->root;
533: 
534:         if (empty($root) === TRUE) {
535:             $root = '/';
536:         }
537: 
538:         $session_name = $this->settings['system']['session']['name'];
539: 
540:         session_save_path(TEMP_DIR . '/sessions');
541: 
542:         session_set_cookie_params($lifetime, $root, $host);
543:         session_name($session_name);
544:         session_start();
545: 
546:         if (isset($_COOKIE[$session_name]) === TRUE) {
547:             setcookie(
548:                 $session_name,
549:                 $_COOKIE[$session_name],
550:                 time() + $lifetime,
551:                 $root,
552:                 $host
553:                 );
554:         }
555: 
556:         session_regenerate_id();
557:         $sid = session_id();
558:         session_write_close();
559:         session_id($sid);
560:         session_start();
561: 
562:         session_set_cookie_params($lifetime, $root, $host);
563:         session_name($session_name);
564:     }
565: 
566: 
567:     /**
568:      * Pridanie správy
569:      *
570:      * @param  string text správy
571:      * @param  string typ správy - info, error
572:      * @param  string požiadavka - current, next
573:      * @return void
574:      */
575:     public function set_flash($message, $type = 'info', $request = 'next')
576:     {
577:         $this->flash[$request][] = array($type, $message);
578:     }
579: 
580: 
581:     /**
582:      * Získanie správ požiadavky
583:      *
584:      * @param  string požiadavka - prev, current, next
585:      * @return array  správy požiadavky
586:      */
587:     public function get_flash($request = 'prev')
588:     {
589:         return $this->flash[$request];
590:     }
591: 
592: 
593:     /**
594:      * Uloženie aktuálnych správ pre nasledujúcu požiadavku
595:      *
596:      * @return void
597:      */
598:     public function keep_flash()
599:     {
600:         $this->flash['next'] = array_merge($this->flash['next'], $this->flash['prev'], $this->flash['current']);
601:     }
602: 
603: 
604:     /**
605:      * Handler požiadaviek na neexistujúce objekty
606:      *
607:      * @param  string   text hláasenia
608:      * @param  string   typ objektu
609:      * @param  callback vlastný handler
610:      * @return void
611:      */
612:     public function not_found($message = NULL, $type, $handler = NULL)
613:     {
614:         if ($message === NULL) {
615:             $message  = 'Not Found :: Controller: ' . $this->controller_name;
616:             $message .= ' / Action: ' . $this->action_name;
617:             $message .= ' / Route: ' . $this->route['name'];
618:         }
619: 
620:         if ($handler === NULL) {
621:             $handler = Arrays::get_value($this->settings['system'], 'not_found_handler');
622:         }
623: 
624: 
625:         if ($handler !== NULL) {
626:             $this->controller_name = $handler[0];
627:             $this->action_name = $handler[1];
628:             $this->arguments = array('message' => $message, 'type' => $type);
629:         }
630: 
631:         $this->not_found = TRUE;
632:         if (method_exists($this->controller_name . 'Controller', $this->action_name) === TRUE) {
633:             $this->run();
634:         }
635: 
636:         $this->response->status_code = 404;
637:         $this->response->set_body($message);
638:         $this->response->send();
639:     }
640: 
641: 
642:     /**
643:      * Vytvorenie uri
644:      *
645:      * @param  string meno routy podľa ktorej sa má adresa vytvoriť
646:      * @param  array  parametre pre resources
647:      * @param  array  parametre pre $_GET
648:      * @param  string kotva
649:      * @return string uri
650:      */
651:     public function create_uri($route_name, $data = array(), $uri_data = NULL, $anchor = NULL)
652:     {
653:         if (isset($this->routes[$route_name]) === FALSE) {
654:             trigger_error('Named route <strong>"' . $route_name . '"</strong> not found!', E_USER_ERROR);
655:         }
656: 
657:         $route = $this->routes[$route_name];
658: 
659:         $uri = $this->request->base_uri;
660: 
661:         $route_uri = str_replace(array('(', ')'), array('', ''), $route['uri']);
662: 
663:         $resource_current = explode('/', trim($this->request->resource, '/'));
664:         $resource = explode('/', trim($route_uri, '/'));
665:         $template = explode('/', trim($route['uri_template'], '/'));
666: 
667:         if (empty($resource) === TRUE) {
668:             return $uri . '/' . implode('/', $data);
669:         }
670: 
671:         foreach ($template as $key => $segment) {
672:             $uri .= '/';
673: 
674:             if ($segment === '#') {
675:                 $uri .= $resource[$key];
676: 
677:             } else {
678:                 if (isset($data[$segment]) === FALSE) {
679:                     $uri .= $resource_current[$key];
680: 
681:                 } else {
682:                     $uri .= $data[$segment];
683:                 }
684:             }
685:         }
686: 
687:         if (empty($uri_data) === FALSE) {
688:             ksort($uri_data);
689: 
690:             $uri .= '/?' . http_build_query($uri_data);
691:         }
692: 
693:         if ($anchor !== NULL) {
694:             $uri .= '#' . $anchor;
695:         }
696: 
697:         return $uri;
698:     }
699: 
700: 
701:     /**
702:      * Spustenie háčikov
703:      *
704:      * @param  array zoznam háčikov
705:      * @return void
706:      */
707:     private function hooks($hooks)
708:     {
709:         if (empty($hooks) === TRUE) {
710:             return;
711:         }
712: 
713:         foreach ($hooks as $hook) {
714:             if (isset($hook[0]) === TRUE
715:                 AND is_object($hook[0]) === FALSE) {
716: 
717:                 $hook[0] = new $hook[0]($this);
718:             }
719: 
720:             if (is_string($hook) === TRUE) {
721:                 call_user_func_array($hook, $this->arguments);
722: 
723:             } else {
724:                 call_user_func_array(array($hook[0], $hook[1]), $this->arguments);
725:             }
726:         }
727:     }
728: 
729: 
730:     /**
731:      * Metóda na vrátenie hodnoty chránenej vlastnosti
732:      *
733:      * @param  string meno vlastnosti
734:      * @return mixed  hodnota vlastnosti
735:      */
736:     public function __get($property)
737:     {
738:         if (isset($this->$property) === TRUE) {
739:             return $this->$property;
740:         }
741: 
742:         return NULL;
743:     }
744: }
Onion API documentation generated by ApiGen.
Generated using the TokenReflection library.