/system/rocket.php
PHP | 463 lines | 248 code | 90 blank | 125 comment | 48 complexity | 7643a868c239603e78c76e90d2940c19 MD5 | raw file
- <?
- /**
- * Rocket Framework
- *
- * @package Rocket
- * @author Ryan Faerman
- **/
- class rocket {
-
- public $server, $mongo, $cache, $callback, $callback_arguments;
- public $post, $get, $files, $storage, $config, $paint, $session;
- protected $routes;
- private $loaded_classes, $events, $eventdb;
-
- /**
- * Rocket Constructor
- *
- * @param array $routes will override routes.php
- */
- function __construct($routes = array()) {
- if(file_exists('config/system.php')) {
- include 'config/system.php';
- }
- $this->config = (object) $config;
-
- if(!count($routes)) {
- if(file_exists('config/system.php')) {
- include 'config/routes.php';
- }
- }
- $this->routes = $routes;
-
- $this->loaded_classes = array();
- spl_autoload_register(array($this, 'loader'));
-
-
- $this->server = (object) array_change_key_case($_SERVER);
- $this->server->request_uri = ($this->server->request_uri) ? rtrim($this->server->request_uri, '/') : '/';
- $this->server->request_uri = str_replace(
- array($this->server->query_string, '?', $this->config->paths->base),
- '',
- $this->server->request_uri
- );
-
- $this->callback = false;
- $this->callback_arguments = array();
-
-
- $this->mongo = false;
- if($this->config->database->enabled) {
- $this->mongo = new Mongo();
-
- $db = $this->config->database->name;
- $this->storage = $this->mongo->$db;
- }
-
- $this->session = false;
- if($this->config->database->enabled && $this->config->sessions->enabled) {
- $this->session = new tracer($this);
- }
-
- $this->events = array();
- if($this->config->events->enabled && $this->config->events->global) {
- $collection = $this->config->events->collection;
- $this->eventdb = $this->storage->$collection;
- }
-
- $this->post = (object) array_change_key_case($_POST);
- $this->get = (object) array_change_key_case($_GET);
- unset($_GET);
- unset($_POST);
- }
-
-
- /**
- * Autoloader implementation
- *
- * Any auto-loaded class is searched for in the following locations, in order:
- * - system
- * - controllers
- * - exceptions
- * the actual paths are determined by their respective configuration values.
- *
- * Once included, a class will not be included again.
- *
- * @param string $class
- */
- protected function loader($class) {
- $class = strtolower($class);
- if(in_array($class, $this->loaded_classes)) {
- return;
- }
-
-
- $file = $this->config->paths->system.$class.'.php';
- if(file_exists($file)) {
- include $file;
- $this->loaded_classes[] = $class;
- return;
- } else {
- $file = $this->config->paths->controllers.$class.'.php';
- if(file_exists($file)) {
- include $file;
- $this->loaded_classes[] = $class;
- return;
- }
- }
-
- if(strstr($class, 'exception_')) {
- $file = $this->config->paths->exceptions.$class.'.php';
- if(file_exists($file)) {
- include $file;
- } else {
- #throw new Exception('Exception Not Found');
- }
- }
-
- }
-
- /**
- * Accessor for routes
- *
- * route() -> returns routes array
- * route(someroute, false) -> remove route
- * route(someroute, callback) -> assigns callback to route
- * route(someroute, callback_class, callback_method)
- * route(someroute) -> returns callback
- */
- function route() {
- $args = func_get_args();
- switch(func_num_args()) {
- case 0:
- return $this->routes;
- case 1:
- return $this->routes[$args[0]];
- case 2:
- if($args[1] === false) {
- unset($this->routes[$args[0]]);
- } else {
- $this->routes[$args[0]] = $args[1];
- }
- return;
- case 3:
- $this->routes[$args[0]] = array($args[1], $args[2]);
- return;
- }
- }
- /**
- * An alias for $this->route()
- */
- function routes() {
- return $this->route();
- }
-
-
- /**
- * path() -> the current route path
- * path(callback)
- */
- function path() {
-
- }
-
-
- /**
- * Process the route and execute the callback
- *
- * Launching determines the best matching route and executes its callback.
- * The callback is loaded based on the request type and if it came via XHR.
- * The _most specific_ callback will be executed for the route.
- *
- * Some Examples:
- *
- * A regular POST request would first attempt to call the method 'method_post'
- * if that callback does not exist, the assigned callback would be called.
- *
- * Routes do not need to be created for each request type.
- *
- * For a POST via XHR, the following callbacks would be attempted, in order:
- * - method_xhr_post
- * - method_xhr
- * - method_post
- * - method
- */
- function launch() {
- $this->trigger('system.pre_launch');
-
- $output = '';
- foreach($this->routes as $pattern => $handler) {
-
- $pattern = trim($pattern, '/');
-
-
- if($pattern == $this->server->request_uri) {
- # direct route found
- $this->callback = $handler;
- break;
- } else {
- # indirect match?
- $pattern = str_replace('/', '\/', $pattern);
- if(preg_match('/^\/' . $pattern . '\/?$/', $this->server->request_uri, $matches)) {
- # indirect route found
- $this->callback = $handler;
- array_shift($matches);
- $this->callback_arguments = $matches;
-
-
- break;
- }
- }
- }
-
- if(!$this->callback) {
- #throw new Exception('Route Not Found for '.$this->server->request_uri, 404);
- }
-
- $xhr = $this->xhr();
- $this->trigger('system.route_found', array('callback'=> $this->callback, 'arguments' => $this->callback_arguments));
- if(is_array($this->callback)) {
- # callback is a class
-
- list($class, $method) = $this->callback;
- $discovered_method = $method;
- # This enables ROUTE(_xhr)?(_method)?
- if($xhr && method_exists($class, $method.'_xhr_'.$this->server->request_method)) {
- $discovered_method = $method.'_xhr_'.$this->server->request_method;
- } else if($xhr && method_exists($class, $method.'_xhr')) {
- $discovered_method = $method.'_xhr';
- } else if(method_exists($class, $method.'_'.$this->server->request_method)) {
- $discovered_method = $method.'_'.$this->server->request_method;
- } else if(!method_exists($class, $method)) {
- # invalid route
- throw new ErrorException('Invalid Route/Callback', 701);
- }
-
- # pass the callback the system instance then call the method
- $handler = new $class($this);
-
- $this->trigger('system.pre_handler');
- $output = call_user_func_array(array(&$handler, $discovered_method), $this->callback_arguments);
- $this->trigger('system.post_handler');
- } else {
- # callback is a function
- if(!function_exists($this->callback)) {
- # invalid route
- } else {
-
- # call the callback
- $this->trigger('system.pre_handler');
- $output = call_user_func_array($this->callback, $this->callback_arguments);
- $this->trigger('system.post_handler');
- }
- }
-
- $this->trigger('system.post_launch');
- return $output;
- }
-
- /**
- * A static helper for launching
- *
- * @param array $routes optional
- * @return void
- * @author Ryan Faerman
- */
- static function fly($routes = array()) {
- $systemName = __CLASS__;
- $system = new $systemName($routes);
- return $system->launch();
- }
-
- /**
- * Prepare to launch
- *
- * Executes all _preflight() methods, builds the events etc.
- *
- * @return void
- * @author Ryan Faerman
- */
- function prepare() {
- # reset the events database
- $this->eventdb->drop();
-
- $data = array();
- $i = 0;
- $grade = array();
-
- foreach(scandir($this->config->paths->controllers) as $file) {
- if(preg_match('/\.php$/', $file)) {
- $class = str_replace('.php', '', $file);
-
- $handler = new $class($this);
- if(method_exists($handler, '_preflight')) {
-
-
- $preflight = (object) $handler->_preflight();
-
- $data['controllers'][$i] = array();
- $data['controllers'][$i]['name'] = $class;
-
- # events registration
- $event_passed = array();
- foreach($preflight->events as $event => $callback) {
- $_id = $this->eventdb->insert(array(
- 'event' => $event,
- 'callback' => $callback
- ));
-
- $event_passed[] = ($_id) ? true : false ;
- }
-
-
- if(!in_array(false, $event_passed)) {
- $data['controllers'][$i]['events'] = 'passed';
- }
- $grade[] = !in_array(false, $event_passed);
-
-
-
- # setup each controller
- $setup_passed = array();
- foreach($preflight->setup as $class => $method) {
- # coming soon.
- }
-
- if(!in_array(false, $setup_passed)) {
- $data['controllers'][$i]['setup'] = 'passed';
- }
- $grade[] = !in_array(false, $setup_passed);
-
- $i++;
- }
- }
- }
-
- $data['grade'] = in_array(false, $grade) ? 'Failed' : 'Passed';
-
- $this->render('system/preflight', $data);
- }
-
- /**
- * A static helper for preparing
- *
- * @return void
- * @author Ryan Faerman
- */
- static function preflight() {
- $systemName = __CLASS__;
- $system = new $systemName();
- return $system->prepare();
- }
-
- /**
- * Determines if the current request is via XHR
- *
- * @return boolean
- * @author Ryan Faerman
- */
- function xhr() {
- $this->trigger('system.xhr_request');
- return isset($this->server->http_x_requested_with) && $this->server->http_x_requested_with == 'XMLHttpRequest';
- }
-
- /**
- * Register a callback for an event
- *
- * Registration of this type is only valid for the current request
- */
- function register($event, $callback) {
- $this->events[$event][] = $callback;
- }
-
- /**
- * Trigger an event and pass it arguments
- *
- * This will trigger both current request and global events
- *
- * @param string $event
- * @param array $params
- * @return void
- * @author Ryan Faerman
- */
- function trigger($event, $params = array()) {
- if(!$this->config->events->enabled) {
- return;
- }
-
- $return = array();
-
- if(array_key_exists($event, $this->events)) {
- foreach($this->events[$event] as $callback) {
- $return[] = call_user_func($callback, $params);
- }
- }
-
- if($this->config->events->global) {
- foreach($this->eventdb->find(array('event' => $event)) as $global_event) {
- #if method exist
-
- $global_event = (object) $global_event;
-
- list($class, $method) = $global_event->callback;
-
-
- $handler = new $class($this);
- $return[] = call_user_func(array(&$handler, $method), $params);
-
-
- }
-
- }
-
- return $return;
- }
-
- /**
- * A wrapper for the paint class, scope helps protect the system from the template
- */
- function render($template, $variables = array(), $partials = array()) {
- if(!$this->paint) {
- $this->paint = new paint($this);
- }
-
- $base_url = $this->config->paths->base;
- $variables['base_url'] = ($base_url != '') ? '/'.$base_url.'/' : '/';
-
- $event_vars = $this->trigger('system.variables');
- foreach($event_vars as $ev) {
- $variables = array_merge($variables, (array) $ev);
- }
-
- return $this->paint->render($template, $variables, $partials);
- }
-
- function partial($template, $variables = array(), $partials = array()) {
- if(!$this->paint) {
- $this->paint = new paint($this);
- }
- $base_url = $this->config->paths->base;
- $variables['base_url'] = ($base_url != '') ? '/'.$base_url.'/' : '/';
-
-
-
- return $this->paint->render($template, $variables, $partials, true);
- }
-
- /**
- * Simple HTTP redirection
- */
- function redirect($path) {
- header(sprintf('Location: //%s/%s', $this->server->server_name, $path));
- }
-
-
- }
- ?>