Source

Ray / Ray / Ray.php

Full commit
<?php

namespace Ray;

class Ray{

    public  $config,
            $router,
            $view,
            $request,
            $response,
            $dispatch;

    public function __construct($config=array(), $preDispatch=null, $postDispatch=null){
        spl_autoload_register(array('Ray\Ray', 'autoload'));

        if ( @date_default_timezone_set(date_default_timezone_get()) === false ) {
            date_default_timezone_set('UTC');
        }

        if(!defined('DS')){
            define('DS', DIRECTORY_SEPARATOR);
        }

        if(!defined('ROOT')){
            define('ROOT', realpath(dirname(__FILE__)  . DS . '..' . DS ));
        }

        $this->config = array_merge(array(
            'mode' => 'production',
            'templates' => ROOT . DS . 'template',
            'view' => 'Ray\View\Inline'
        ), $config);

        if($preDispatch && is_callable($preDispatch)){
            $this->dispatch['pre'] = $preDispatch;
        }

        if($postDispatch && is_callable($postDispatch)){
            $this->dispatch['post'] = $postDispatch;
        }

        $this->router = new Router();

        $this->response = new Response();

        $this->request = new Request();

        $this->response->responseCode(Response::OK);
    }

    public function __call($method, $args){

        $reflection = new \ReflectionObject($this->request);

        $via = 'METHOD_' . strtoupper($method);

        if($reflection->hasConstant($via)){
            return $this->mapRoute($reflection->getConstant($via), $args);
        }else{
            throw new Exception\Call('What the heck is that!? <i>__call('.$method.', '.var_export($args, true).')</i>');
        }
    }

    public function __destruct(){

        if($this->router){
            if(isset($this->dispatch['pre'])){
                call_user_func($this->dispatch['pre']);
            }

            $return = $this->router->proccess($this->request->getRequest());

            if($return){
                $viewClass = isset($return['view']) && $return['view'] ? $return['view'] : $this->config['view'];
                $view = new $viewClass($return['callback'], $this->config);
                $send = $view->render();
            }elseif($this->router->hasRoute(Request::METHOD_GET, '/error/404')){
                $response = Response::NOT_FOUND;
                
                $request = $this->request->getRequest();
                
                $request->method = Request::METHOD_GET;
                
                $request->uri = '/error/404';
                
                $error = $this->router->proccess($request);
                
                $viewClass = isset($error['view']) && $error['view'] ? $error['view'] : $this->config['view'];
                
                $view = new $viewClass($error['callback'], $this->config);
                
                $send =  $view->render();
                
            }else{
                $response = Response::NOT_FOUND;
                $send = Response::NOT_FOUND;
            }

            if(isset($response)){
                $this->response->responseCode($response);
            }

            if(isset($this->dispatch['post'])){
                call_user_func($this->dispatch['post']);
            }

            $this->response->send($send);
        }
    }

    private function mapRoute($method, $args){
        if(count($args) >= 2){
            $pattern = $args[0];
            $callable = $args[1];
            $view = isset($args[2]) ? $args[2] : $this->config['view'];

            return $this->router->map($method, $pattern, $callable, $view);
        }

        return false;
    }

    public function map(){
        $args = func_get_args();
        return $this->mapRoute($args);
    }

    public function error($code, $callable, $view=null){
        $this->get('/error/'.$code, $callable, $view);
    }

    /**
     * Autoload
     */
    public static function autoload( $class ) {

        $file = ROOT . DIRECTORY_SEPARATOR . str_replace('\\', DIRECTORY_SEPARATOR, $class) . '.php';

        if ( file_exists($file) ) {
            require $file;
        }
    }
}