Location: PHPKode > scripts > Genghis > bobthecow-genghis-f5a39e0/src/php/Genghis/App.php
<?php

class Genghis_App
{
    protected $assets     = array();
    protected $assetEtags = array();
    protected $baseUrl;

    public function run()
    {
        try {
            $response = $this->route($this->getRequestMethod(), $this->getRequestPath());
            if ($response instanceof Genghis_Response) {
                $response->render();
            } else {
                throw new Genghis_HttpException(500);
            }
        } catch (Genghis_HttpException $e) {
            $errorResponse = $this->renderTemplate(
                'error.html.mustache',
                $e->getStatus(),
                array(
                    'message' => $e->getMessage(),
                    'status'  => $e->getStatus(),
                )
            );
            $errorResponse->render();
        }
    }

    public function route($method, $path)
    {
        if ($this->isJsonRequest()) {
            try {
                $api = new Genghis_Api;

                return $api->route($method, $path);
            } catch (Genghis_HttpException $e) {
                $msg = $e->getMessage() ? $e->getMessage() : Genghis_Response::getStatusText($e->getStatus());

                return new Genghis_JsonResponse(array('error' => $msg, 'status' => $e->getStatus()), $e->getStatus());
            }
        } else {
            if (strpos($path, '/assets/') === 0) {
                return $this->getAsset(substr($path, 8));
            } else {
                // not an api request, we'll return index.html and render the page in javascript.
                return $this->renderTemplate('index.html.mustache');
            }
            break;
        }
    }

    protected function isJsonRequest()
    {
        if (in_array($this->getRequestMethod(), array('POST', 'PUT'))) {
            if (array_key_exists('HTTP_CONTENT_TYPE', $_SERVER)) {
                $type = $_SERVER['HTTP_CONTENT_TYPE'];
            } elseif (array_key_exists('CONTENT_TYPE', $_SERVER)) {
                $type = $_SERVER['CONTENT_TYPE'];
            } else {
                $type = 'x-www-form-urlencoded';
            }
        } else {
            $type = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : 'text/html';
        }

        return strpos($type, 'application/json') !== false || strpos($type, 'application/javascript') !== false;
    }

    protected function getBaseUrl()
    {
        if (!isset($this->baseUrl)) {
            $this->baseUrl = $this->prepareBaseUrl();
        }

        return $this->baseUrl;
    }

    protected function prepareBaseUrl()
    {
        $filename = basename($_SERVER['SCRIPT_FILENAME']);

        foreach (array('SCRIPT_NAME', 'PHP_SELF', 'ORIG_SCRIPT_NAME') as $key) {
            if (isset($_SERVER[$key]) && basename($_SERVER[$key]) == $filename) {
                $baseUrl = $_SERVER[$key];
                break;
            }
        }

        if (!isset($baseUrl)) {
            $path    = isset($_SERVER['PHP_SELF']) ? $_SERVER['PHP_SELF'] : '';
            $file    = isset($_SERVER['SCRIPT_FILENAME']) ? $_SERVER['SCRIPT_FILENAME'] : '';
            $chunks  = array_reverse(explode('/', trim($file, '/')));
            $index   = 0;
            $last    = count($chunks);
            $baseUrl = '';
            do {
                $seg     = $chunks[$index];
                $baseUrl = '/'.$seg.$baseUrl;
                ++$index;
            } while (($last > $index) && (false !== ($pos = strpos($path, $baseUrl))) && (0 != $pos));
        }

        // Does the baseUrl have anything in common with the request_uri?
        $requestUri = $_SERVER['REQUEST_URI'];

        if ($baseUrl && 0 === strpos($requestUri, $baseUrl)) {
            // full $baseUrl matches
            return $baseUrl;
        }

        if ($baseUrl && 0 === strpos($requestUri, dirname($baseUrl))) {
            // directory portion of $baseUrl matches
            return rtrim(dirname($baseUrl), '/');
        }

        $truncatedRequestUri = $requestUri;
        if (($pos = strpos($requestUri, '?')) !== false) {
            $truncatedRequestUri = substr($requestUri, 0, $pos);
        }

        $basename = basename($baseUrl);
        if (empty($basename) || !strpos($truncatedRequestUri, $basename)) {
            // no match whatsoever; set it blank
            return '';
        }

        // If using mod_rewrite or ISAPI_Rewrite strip the script filename
        // out of baseUrl. $pos !== 0 makes sure it is not matching a value
        // from PATH_INFO or QUERY_STRING
        if ((strlen($requestUri) >= strlen($baseUrl)) && ((false !== ($pos = strpos($requestUri, $baseUrl))) && ($pos !== 0))) {
            $baseUrl = substr($requestUri, 0, $pos + strlen($baseUrl));
        }

        return rtrim($baseUrl, '/');
    }

    protected function getRequestMethod()
    {
        return $_SERVER['REQUEST_METHOD'];
    }

    protected function getRequestPath()
    {
        if (isset($_SERVER['PATH_INFO'])) {
            return $_SERVER['PATH_INFO'];
        } elseif (isset($_SERVER['REQUEST_URI'])) {
            return parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        } else {
            return '/';
        }
    }

    protected function getQueryParams()
    {
        global $_GET;

        return $_GET;
    }

    protected function getQueryParam($name, $default = null)
    {
        $params = $this->getQueryParams();
        if (isset($params[$name])) {
            return $params[$name];
        } else {
            return $default;
        }
    }

    protected function renderTemplate($name, $status = 200, array $vars = array())
    {
        $this->initAssets();
        $defaults = array(
            'base_url'        => $this->getBaseUrl(),
            'genghis_version' => GENGHIS_VERSION,
        );

        return new Genghis_Response(strtr($this->assets[$name], $this->prepareVars(array_merge($defaults, $vars))), $status);
    }

    protected function prepareVars($vars)
    {
        $ret = array();
        foreach ($vars as $name => $var) {
            $ret['{{ '.$name.' }}'] = $var;
        }

        return $ret;
    }

    protected function getAsset($name)
    {
        $this->initAssets();
        if (isset($this->assets[$name])) {
            return new Genghis_AssetResponse($name, $this->assets[$name], array(
                'Last-Modified' => gmdate("D, d M Y H:i:s", filemtime(__FILE__))." GMT",
                'Etag'          => sprintf('"%s"', $this->assetEtags[$name]),
            ));
        }
        throw new Genghis_HttpException(404);
    }

    protected function initAssets()
    {
        if (empty($this->assets)) {
            $data = file_get_contents(__FILE__, false, null, __COMPILER_HALT_OFFSET__);
            foreach (preg_split("/^@@(?=[\w\d\.]+( [\w\d\.]+)?$)/m", $data, -1) as $asset) {
                if (trim($asset)) {
                    list($line, $content)    = explode("\n", $asset, 2);
                    list($name, $etag)       = explode(" ",  $line,  2);
                    $this->assets[$name]     = trim($content);
                    $this->assetEtags[$name] = $etag;
                }
            }
        }
    }
}
Return current item: Genghis