Location: PHPKode > projects > Fitzgerald > jim-fitzgerald-5b1ac5f/lib/fitzgerald.php
<?php

    // This is the only file you really need! The directory structure of this repo is a suggestion,
    // not a requirement. It's your app.


    /*  Fitzgerald - a single file PHP framework
     *  (c) 2010 Jim Benton and contributors, released under the MIT license
     *  Version 0.3
     */

    class Template {
        private $fileName;
        private $root;
        public function __construct($root, $fileName) {
            $this->fileName = $fileName;
            $this->root = $root;
        }
        public function render($locals) {
            extract($locals);
            ob_start();
            include(realpath($this->root . 'views/' . $this->fileName . '.php'));
            return ob_get_clean();
        }
    }

    class Url {
        private $url;
        private $method;
        private $conditions;

        public $params = array();
        public $match = false;

        public function __construct($httpMethod, $url, $conditions=array(), $mountPoint) {

            $requestMethod = $_SERVER['REQUEST_METHOD'];
            $requestUri = str_replace($mountPoint, '', preg_replace('/\?.+/', '', $_SERVER['REQUEST_URI']));

            $this->url = $url;
            $this->method = $httpMethod;
            $this->conditions = $conditions;

            if (strtoupper($httpMethod) == $requestMethod) {

                $paramNames = array();
                $paramValues = array();

                preg_match_all('@:([a-zA-Z]+)@', $url, $paramNames, PREG_PATTERN_ORDER);                    // get param names
                $paramNames = $paramNames[1];                                                               // we want the set of matches
                $regexedUrl = preg_replace_callback('@:[a-zA-Z_\-]+@', array($this, 'regexValue'), $url);     // replace param with regex capture
                if (preg_match('@^' . $regexedUrl . '$@', $requestUri, $paramValues)){                      // determine match and get param values
                    array_shift($paramValues);                                                              // remove the complete text match
                    for ($i=0; $i < count($paramNames); $i++) {
                        $this->params[$paramNames[$i]] = $paramValues[$i];
                    }
                    $this->match = true;
                }
            }
        }

        private function regexValue($matches) {
            $key = str_replace(':', '', $matches[0]);
            if (array_key_exists($key, $this->conditions)) {
                return '(' . $this->conditions[$key] . ')';
            } else {
                return '([a-zA-Z0-9_\-]+)';
            }
        }

    }

    class ArrayWrapper {
        private $subject;
        public function __construct(&$subject) {
            $this->subject = $subject;
        }
        public function __get($key) {
            return isset($this->subject[$key]) ? $this->subject[$key] : null;
        }

        public function __set($key, $value) {
            $this->subject[$key] = $value;
            return $value;
        }
    }

    class SessionWrapper {
        public function __get($key) {
            global $_SESSION;
            return isset($_SESSION[$key]) ? $_SESSION[$key] : null;
        }

        public function __set($key, $value) {
            global $_SESSION;
            $_SESSION[$key] = $value;
            return $value;
        }
    }

    class RequestWrapper {
        public function __get($key) {
            global $_REQUEST;
            return isset($_REQUEST[$key]) ? $_REQUEST[$key] : null;
        }

        public function __set($key, $value) {
            global $_REQUEST;
            $_REQUEST[$key] = $value;
            return $value;
        }
    }

    class Fitzgerald {

        private $mappings = array(), $before_filters = Array(), $after_filters = Array();
        protected $options;
        protected $session;
        protected $request;

        public function __construct($options=array()) {
            $this->options = new ArrayWrapper($options);
            session_name('fitzgerald_session');
            session_start();
            $this->session = new SessionWrapper;
            $this->request = new RequestWrapper;
            set_error_handler(array($this, 'handleError'), 2);
        }

        public function handleError($number, $message, $file, $line) {
            header("HTTP/1.0 500 Server Error");
            echo $this->render('500', compact('number', 'message', 'file', 'line'));
            die();
        }

        public function show404() {
            header("HTTP/1.0 404 Not Found");
            echo $this->render('404');
            die();
        }

        public function get($url, $methodName, $conditions = array()) {
           $this->event('get', $url, $methodName, $conditions);
        }

        public function post($url, $methodName, $conditions = array()) {
           $this->event('post', $url, $methodName, $conditions);
        }

        public function put($url, $methodName, $conditions = array()) {
           $this->event('put', $url, $methodName, $conditions);
        }

        public function delete($url, $methodName, $conditions = array()) {
           $this->event('delete', $url, $methodName, $conditions);
        }

        public function before($methodName, $filterName) {
            $this->push_filter($this->before_filters, $methodName, $filterName);
        }

        public function after($methodName, $filterName) {
            $this->push_filter($this->after_filters, $methodName, $filterName);
        }

        private function push_filter(&$arr_filter, $methodName, $filterName) {
            if (!is_array($methodName)) {
                $methodName = explode('|', $methodName);
            }

            for ($i = 0; $i < count($methodName); $i++) {
                $method = $methodName[$i];
                if (!isset($arr_filter[$method])) {
                    $arr_filter[$method] = array();
                }
                array_push($arr_filter[$method], $filterName);
            }
        }

        private function run_filter($arr_filter, $methodName) {
            if(isset($arr_filter[$methodName])) {
                for ($i=0; $i < count($arr_filter[$methodName]); $i++) {
                    $return = call_user_func(array($this, $arr_filter[$methodName][$i]));

                    if(!is_null($return)) {
                        return $return;
                    }
                }
            }
        }

        public function run() {
            echo $this->processRequest();
        }

        protected function redirect($path) {
            $protocol = empty($_SERVER['HTTPS']) ? 'http' : 'https';
            $host = (preg_match('%^http://|https://%', $path) > 0) ? '' : "$protocol://" . $_SERVER['HTTP_HOST'];
            $uri = is_string($this->options->mountPoint) ? $this->options->mountPoint : '';
            if (!empty($this->error)) {
              $this->session->error = $this->error;
            }
            if (!empty($this->success)) {
              $this->session->success = $this->success;
            }
            header("Location: $host$uri$path");
            return false;
        }

        protected function render($fileName, $variableArray=array()) {
            $variableArray['options'] = $this->options;
            $variableArray['request'] = $this->request;
            $variableArray['session'] = $this->session;
            if(isset($this->error)) {
                $variableArray['error'] = $this->error;
            }
            if(isset($this->success)) {
                $variableArray['success'] = $this->success;
            }

            if (is_string($this->options->layout)) {
                $contentTemplate = new Template($this->root(), $fileName);              // create content template
                $variableArray['content'] = $contentTemplate->render($variableArray);   // render and store contet
                $layoutTemplate = new Template($this->root(), $this->options->layout);  // create layout template
                return $layoutTemplate->render($variableArray);                         // render layout template and return
            } else {
                $template = new Template($this->root(), $fileName);                     // create template
                return $template->render($variableArray);                               // render template and return
            }
        }

        protected function sendFile($filename, $contentType, $path) {
            header("Content-type: $contentType");
            header("Content-Disposition: attachment; filename=$filename");
            return readfile($path);
        }

        protected function sendDownload($filename, $path) {
            header("Content-Type: application/force-download");
            header("Content-Type: application/octet-stream");
            header("Content-Type: application/download");
            header("Content-Description: File Transfer");
            header("Content-Disposition: attachment; filename=$filename".";");
            header("Content-Transfer-Encoding: binary");
            return readfile($path);
        }

        private function execute($methodName, $params) {
            $this->run_filter($this->before_filters, $methodName);

            if ($this->session->error) {
                $this->error = $this->session->error;
                $this->session->error = null;
            }

            if ($this->session->success) {
                $this->success = $this->session->success;
                $this->session->success = null;
            }

            $reflection = new ReflectionMethod(get_class($this), $methodName);
            $args = array();

            foreach($reflection->getParameters() as $param) {
                if(isset($params[$param->name])) {
                    $args[$param->name] = $params[$param->name];
                }
                else if($param->isDefaultValueAvailable()) {
                    $args[$param->name] = $param->getDefaultValue();
                }
            }

            $response = $reflection->invokeArgs($this, $args);

            $this->run_filter($this->after_filters, $methodName);

            return $response;
        }

        private function event($httpMethod, $url, $methodName, $conditions=array()) {
            if (method_exists($this, $methodName)) {
                array_push($this->mappings, array($httpMethod, $url, $methodName, $conditions));
            }
        }

        protected function root() {
            if($root = $this->options->root)
              return $root;
            else
              return dirname(__FILE__) . '/../';
        }

        protected function path($path) {
            return $this->root() . $path;
        }

        private function processRequest() {
            $charset = (is_string($this->options->charset)) ? ";charset={$this->options->charset}" : "";
            header("Content-type: text/html" . $charset);

            for($i = 0; $i < count($this->mappings); $i++) {
                $mapping = $this->mappings[$i];
                $mountPoint = is_string($this->options->mountPoint) ? $this->options->mountPoint : '';
                $url = new Url($mapping[0], $mapping[1], $mapping[3], $mountPoint);

                if($url->match) {
                    return $this->execute($mapping[2], $url->params);
                }
            }

            return $this->show404();
        }
    }
Return current item: Fitzgerald