tidying up

Removed the unused helper, moved to composer because of the dependency
on klein.php, cleaned up the readme, added a proper robots.txt (allow
all indexing) and removed some unused files (.gitattributes, .gitignore,
assets/css/style.css)
This commit is contained in:
Samuel Ryan 2013-03-19 23:18:10 +00:00
parent 50b87d74bf
commit dd76089270
11 changed files with 16 additions and 1224 deletions

22
.gitattributes vendored
View File

@ -1,22 +0,0 @@
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain

163
.gitignore vendored
View File

@ -1,163 +0,0 @@
#################
## Eclipse
#################
*.pydevproject
.project
.metadata
bin/
tmp/
*.tmp
*.bak
*.swp
*~.nib
local.properties
.classpath
.settings/
.loadpath
# External tool builders
.externalToolBuilders/
# Locally stored "Eclipse launch configurations"
*.launch
# CDT-specific
.cproject
# PDT-specific
.buildpath
#################
## Visual Studio
#################
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
# User-specific files
*.suo
*.user
*.sln.docstates
# Build results
[Dd]ebug/
[Rr]elease/
*_i.c
*_p.c
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.vspscc
.builds
*.dotCover
## TODO: If you have NuGet Package Restore enabled, uncomment this
#packages/
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opensdf
*.sdf
# Visual Studio profiler
*.psess
*.vsp
# ReSharper is a .NET coding add-in
_ReSharper*
# Installshield output folder
[Ee]xpress
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish
# Others
[Bb]in
[Oo]bj
sql
TestResults
*.Cache
ClientBin
stylecop.*
~$*
*.dbmdl
Generated_Code #added for RIA/Silverlight projects
# Backup & report files from converting an old project file to a newer
# Visual Studio version. Backup files are not needed, because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
############
## Windows
############
# Windows image file caches
Thumbs.db
# Folder config file
Desktop.ini
#############
## Python
#############
*.py[co]
# Packages
*.egg
*.egg-info
dist
build
eggs
parts
bin
var
sdist
develop-eggs
.installed.cfg
# Installer logs
pip-log.txt
# Unit test / coverage reports
.coverage
.tox
#Translations
*.mo
#Mr Developer
.mr.developer.cfg
# Mac crap
.DS_Store

View File

@ -4,20 +4,6 @@ site. An individual code can be accessed via httpstatus.es/{status_code}.
Each individual code is stored in a file specific to the class it is a part of.
For example 404 is stored in 4.json, along with all other 4xx codes.
I have yet to decide on the criteria that a status code must meet to be included.
I am unsure if including vendor specific status codes is sensible (eg: Twitter
and Facebook API have their own status codes) or if it's confusing. For now I
will accept any that have some form of notability, long term I would like to
have a toggle for whether to show "real" only, or to include "vendor specific".
If you have any feedback please supply it via the github issue system.
(note: I am not 100% happy with the current code store format ({class}.json)
however I've been unable to formulate a better idea that allows for the class
information (summary) to be stored with the codes. I am open to suggestions, but
it must remain a flat file solution to allow new codes and changes to the codes
via git)
## json format
```json
@ -56,8 +42,8 @@ via git)
JSON should be formatted as above using four space tab and \r\n for new lines in
descriptions. There is no validation on the output and the only processing is
turning new lines into linebreaks, if you wish to include HTML that's fine
(preferably only links though and code tags)
turning new lines into line breaks, if you wish to include HTML that's fine
(preferably only links though and code tags).
## to do
- clean up the HTML and CSS
@ -68,7 +54,6 @@ status cats (http://httpcats.herokuapp.com/) link to each code page
- Decide on whether or not to add a method to return a specific class of error
codes, eg: 4xx, 5xx. Not sure if httpstatus.es/{class} makes sense (eg:
httpstatus.es/5) or httpstatus.es/{class}xx (eg: httpstatus.es/5xx)
- Favicon (maybe someone else will donate one? :-))
- Some sort of templating, why have I got the (uniform) head in 3 separate views!
- Languages?

View File

@ -1,166 +0,0 @@
*{
padding:0;
margin:0;
}
body{
color:#556270;
font-family:Arial, Helvetica, sans-serif;
font-size:12px;
font-style:normal;
font-variant:normal;
font-weight:normal;
line-height:20px;
background-color:#FFF;
}
a{
font-weight:bold;
text-decoration:none;
color:#D6156C;
}
a:hover{
color:#F56991;
}
/*
general layout
*/
#wrapper{
margin:40px;
width:600px;
}
.header{
font-size:22px;
font-weight:bold;
margin-bottom:10px;
}
.header .status_title{
color:#BBB;
text-transform:uppercase;
line-height:24px;
}
.share_buttons{
width:auto;
float:right;
}
.share_buttons .share_button{
float:left;
display:block;
}
#return{
font-size:14px;
}
#intro{
font-family:Georgia;
font-size:14px;
line-height:24px;
}
#intro p{
margin-bottom:10px;
}
#intro a{
text-decoration:none;
color:#AAA;
}
#desc{
font-family:Georgia;
font-size:14px;
line-height:24px;
}
#desc p{
margin-bottom:10px;
}
#desc .reference{
font-size:13px;
}
#statuses{
margin-top:20px;
}
.status_list{
margin-bottom:20px;
}
.status_list .head{
border-bottom:2px solid #EEE;
margin-bottom:10px;
/* color:#D6156C; */
padding-bottom:2px;
}
.status_list .head .title{
font-weight:bold;
font-size:14px;
float:left;
text-transform:lowercase;
}
.status_list .head .description{
font-style:italic;
float:right;
}
.status_list .status{
}
.status_list .status{
width:180px;
padding-right:20px;
height:70px;
float:left;
overflow:hidden;
}
.status_list .status .st{
font-size:14px;
font-weight:bold;
}
.status_list .status .description{
font-size:11px;
height:46px;
overflow:hidden;
width:160px;
}
#code_references{
margin:20px 0;
}
.info_list{
font-size:14px;
}
.info_list .info_item .title{
width:200px;
float:left;
}
.info_list .info_item .value{
float:left;
}
#footer{
margin-top:10px;
font-size:11px;
}
.clear{
clear:both;
}

6
composer.json Normal file
View File

@ -0,0 +1,6 @@
{
"require": {
"klein/klein": "*"
},
"minimum-stability": "dev"
}

View File

@ -1,8 +0,0 @@
<?php
function preint_r($array)
{
echo '<pre>';
print_r($array);
echo '</pre>';
}

View File

@ -5,7 +5,7 @@
Location: Brighton, England
/* SITE */
Last update: 2012-08-12
Last update: 2013-03-19
Doctype: HTML5
Languages: PHP5
Frameworks: Klein.php

View File

@ -1,8 +1,7 @@
<?php
require 'klein.php';
require 'vendor/autoload.php';
require 'httpstatuses.php';
require 'helper.php';
respond('/', function($request, $response) {
$class_list = Httpstatuses::statuses();

839
klein.php
View File

@ -1,839 +0,0 @@
<?php
# (c) Chris O'Hara <cohara87@gmail.com> (MIT License)
# http://github.com/chriso/klein.php
$__routes = array();
$__namespace = null;
//Add a route callback
function respond($method, $route = '*', $callback = null) {
global $__routes, $__namespace;
$count_match = true;
if (is_callable($method)) {
$callback = $method;
$method = $route = null;
$count_match = false;
} elseif (is_callable($route)) {
$callback = $route;
$route = $method;
$method = null;
}
if( $__namespace && $route[0] === '@' || ( $route[0] === '!' && $route[1] === '@' ) ) {
if( $route[0] === '!' ) {
$negate = true;
$route = substr( $route, 2 );
} else {
$negate = false;
$route = substr( $route, 1 );
}
// regex anchored to front of string
if( $route[0] === '^' ) {
$route = substr( $route, 1 );
} else {
$route = '.*' . $route;
}
if( $negate ) {
$route = '@^' . $__namespace . '(?!' . $route . ')';
} else {
$route = '@^' . $__namespace . $route;
}
}
// empty route with namespace is a match-all
elseif( $__namespace && ( null == $route || '*' === $route ) ) {
$route = '@^' . $__namespace . '(/|$)';
} else {
$route = $__namespace . $route;
}
$__routes[] = array($method, $route, $callback, $count_match);
return $callback;
}
//Each route defined inside $routes will be in the $namespace
function with($namespace, $routes) {
global $__namespace;
$previous = $__namespace;
$__namespace .= $namespace;
if (is_callable($routes)) {
$routes();
} else {
require_once $routes;
}
$__namespace = $previous;
}
function startSession() {
if (session_id() === '') {
session_start();
}
}
//Dispatch the request to the approriate route(s)
function dispatch($uri = null, $req_method = null, array $params = null, $capture = false) {
global $__routes;
//Pass $request, $response, and a blank object for sharing scope through each callback
$request = new _Request;
$response = new _Response;
$app = new _App;
//Get/parse the request URI and method
if (null === $uri) {
$uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
}
if (false !== strpos($uri, '?')) {
$uri = strstr($uri, '?', true);
}
if (null === $req_method) {
$req_method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
//For legacy servers, override the HTTP method with the X-HTTP-Method-Override
//header or _method parameter
if (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$req_method = $_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'];
} else if (isset($_REQUEST['_method'])) {
$req_method = $_REQUEST['_method'];
}
}
//Force request_order to be GP
//http://www.mail-archive.com/internals@lists.php.net/msg33119.html
$_REQUEST = array_merge($_GET, $_POST);
if (null !== $params) {
$_REQUEST = array_merge($_REQUEST, $params);
}
$matched = 0;
$apc = function_exists('apc_fetch');
ob_start();
foreach ($__routes as $handler) {
list($method, $_route, $callback, $count_match) = $handler;
//Was a method specified? If so, check it against the current request method
if (is_array($method)) {
$method_match = false;
foreach ($method as $test) {
if (strcasecmp($req_method, $test) === 0) {
$method_match = true;
continue;
}
}
if (false === $method_match) {
continue;
}
} elseif (null !== $method && strcasecmp($req_method, $method) !== 0) {
continue;
}
//! is used to negate a match
if (isset($_route[0]) && $_route[0] === '!') {
$negate = true;
$i = 1;
} else {
$negate = false;
$i = 0;
}
//Check for a wildcard (match all)
if ($_route === '*' || null == $_route) {
$match = true;
//Easily handle 404's
} elseif ($_route === '404' && !$matched) {
$callback($request, $response, $app, $matched);
++$matched;
//@ is used to specify custom regex
} elseif (isset($_route[$i]) && $_route[$i] === '@') {
$match = preg_match('`' . substr($_route, $i + 1) . '`', $uri, $params);
//Compiling and matching regular expressions is relatively
//expensive, so try and match by a substring first
} else {
$route = null;
$regex = false;
$j = 0;
$n = isset($_route[$i]) ? $_route[$i] : null;
//Find the longest non-regex substring and match it against the URI
while (true) {
if (!isset($_route[$i])) {
break;
} elseif (false === $regex) {
$c = $n;
$regex = $c === '[' || $c === '(' || $c === '.';
if (false === $regex && false !== isset($_route[$i+1])) {
$n = $_route[$i + 1];
$regex = $n === '?' || $n === '+' || $n === '*' || $n === '{';
}
if (false === $regex && $c !== '/' && (!isset($uri[$j]) || $c !== $uri[$j])) {
continue 2;
}
$j++;
}
$route .= $_route[$i++];
}
//Check if there's a cached regex string
if (false !== $apc) {
$regex = apc_fetch("route:$route");
if (false === $regex) {
$regex = compile_route($route);
apc_store("route:$route", $regex);
}
} else {
$regex = compile_route($route);
}
$match = preg_match($regex, $uri, $params);
}
if (isset($match) && $match ^ $negate) {
if (null !== $params) {
$_REQUEST = array_merge($_REQUEST, $params);
}
try {
$callback($request, $response, $app, $matched);
} catch (Exception $e) {
$response->error($e);
}
if ($_route !== '*' && $_route !== null) {
$count_match && ++$matched;
}
}
}
if (!$matched) {
$response->code(404);
}
if ($capture) {
return ob_get_clean();
} elseif ($response->chunked) {
$response->chunk();
} else {
ob_end_flush();
}
}
//Compiles a route string to a regular expression
function compile_route($route) {
if (preg_match_all('`(/|\.|)\[([^:\]]*+)(?::([^:\]]*+))?\](\?|)`', $route, $matches, PREG_SET_ORDER)) {
$match_types = array(
'i' => '[0-9]++',
'a' => '[0-9A-Za-z]++',
'h' => '[0-9A-Fa-f]++',
'*' => '.+?',
'**' => '.++',
'' => '[^/]++'
);
foreach ($matches as $match) {
list($block, $pre, $type, $param, $optional) = $match;
if (isset($match_types[$type])) {
$type = $match_types[$type];
}
if ($pre === '.') {
$pre = '\.';
}
//Older versions of PCRE require the 'P' in (?P<named>)
$pattern = '(?:'
. ($pre !== '' ? $pre : null)
. '('
. ($param !== '' ? "?P<$param>" : null)
. $type
. '))'
. ($optional !== '' ? '?' : null);
$route = str_replace($block, $pattern, $route);
}
}
return "`^$route$`";
}
class _Request {
protected $_id = null;
//HTTP headers helper
static $_headers = null;
//Returns all parameters (GET, POST, named) that match the mask
public function params($mask = null) {
$params = $_REQUEST;
if (null !== $mask) {
if (!is_array($mask)) {
$mask = func_get_args();
}
$params = array_intersect_key($params, array_flip($mask));
//Make sure each key in $mask has at least a null value
foreach ($mask as $key) {
if (!isset($params[$key])) {
$params[$key] = null;
}
}
}
return $params;
}
//Return a request parameter, or $default if it doesn't exist
public function param($key, $default = null) {
return isset($_REQUEST[$key]) && $_REQUEST[$key] !== '' ? $_REQUEST[$key] : $default;
}
public function __isset($param) {
return isset($_REQUEST[$param]);
}
public function __get($param) {
return isset($_REQUEST[$param]) ? $_REQUEST[$param] : null;
}
public function __set($param, $value) {
$_REQUEST[$param] = $value;
}
public function __unset($param) {
unset($_REQUEST[$param]);
}
//Is the request secure? If $required then redirect to the secure version of the URL
public function isSecure($required = false) {
$secure = isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'];
if (!$secure && $required) {
$url = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
self::$_headers->header('Location: ' . $url);
}
return $secure;
}
//Gets a request header
public function header($key, $default = null) {
$key = 'HTTP_' . strtoupper(str_replace('-','_', $key));
return isset($_SERVER[$key]) ? $_SERVER[$key] : $default;
}
//Gets a request cookie
public function cookie($key, $default = null) {
return isset($_COOKIE[$key]) ? $_COOKIE[$key] : $default;
}
//Gets the request method, or checks it against $is - e.g. method('post') => true
public function method($is = null) {
$method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
if (null !== $is) {
return strcasecmp($method, $is) === 0;
}
return $method;
}
//Start a validator chain for the specified parameter
public function validate($param, $err = null) {
return new _Validator($this->param($param), $err);
}
//Gets a unique ID for the request
public function id() {
if (null === $this->_id) {
$this->_id = sha1(mt_rand() . microtime(true) . mt_rand());
}
return $this->_id;
}
//Gets a session variable associated with the request
public function session($key, $default = null) {
startSession();
return isset($_SESSION[$key]) ? $_SESSION[$key] : $default;
}
//Gets the request IP address
public function ip() {
return isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : null;
}
//Gets the request user agent
public function userAgent() {
return isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : null;
}
//Gets the request URI
public function uri() {
return isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
}
}
class _Response extends StdClass {
public $chunked = false;
protected $_errorCallbacks = array();
protected $_layout = null;
protected $_view = null;
protected $_code = 200;
static $_headers = null;
//Enable response chunking. See: http://bit.ly/hg3gHb
public function chunk($str = null) {
if (false === $this->chunked) {
$this->chunked = true;
self::$_headers->header('Transfer-encoding: chunked');
flush();
}
if (null !== $str) {
printf("%x\r\n", strlen($str));
echo "$str\r\n";
flush();
} elseif (($ob_length = ob_get_length()) > 0) {
printf("%x\r\n", $ob_length);
ob_flush();
echo "\r\n";
flush();
}
}
//Sets a response header
public function header($key, $value = null) {
self::$_headers->header($key, $value);
}
//Sets a response cookie
public function cookie($key, $value = '', $expiry = null, $path = '/',
$domain = null, $secure = false, $httponly = false) {
if (null === $expiry) {
$expiry = time() + (3600 * 24 * 30);
}
return setcookie($key, $value, $expiry, $path, $domain, $secure, $httponly);
}
//Stores a flash message of $type
public function flash($msg, $type = 'info', $params = null) {
startSession();
if (is_array($type)) {
$params = $type;
$type = 'info';
}
if (!isset($_SESSION['__flashes'])) {
$_SESSION['__flashes'] = array($type => array());
} elseif (!isset($_SESSION['__flashes'][$type])) {
$_SESSION['__flashes'][$type] = array();
}
$_SESSION['__flashes'][$type][] = $this->markdown($msg, $params);
}
//Support basic markdown syntax
public function markdown($str, $args = null) {
$args = func_get_args();
$md = array(
'/\[([^\]]++)\]\(([^\)]++)\)/' => '<a href="$2">$1</a>',
'/\*\*([^\*]++)\*\*/' => '<strong>$1</strong>',
'/\*([^\*]++)\*/' => '<em>$1</em>'
);
$str = array_shift($args);
if (is_array($args[0])) {
$args = $args[0];
}
foreach ($args as &$arg) {
$arg = htmlentities($arg, ENT_QUOTES);
}
return vsprintf(preg_replace(array_keys($md), $md, $str), $args);
}
//Tell the browser not to cache the response
public function noCache() {
$this->header("Pragma: no-cache");
$this->header('Cache-Control: no-store, no-cache');
}
//Sends a file
public function file($path, $filename = null, $mimetype = null) {
$this->discard();
$this->noCache();
set_time_limit(1200);
if (null === $filename) {
$filename = basename($path);
}
if (null === $mimetype) {
$mimetype = finfo_file(finfo_open(FILEINFO_MIME_TYPE), $path);
}
$this->header('Content-type: ' . $mimetype);
$this->header('Content-length: ' . filesize($path));
$this->header('Content-Disposition: attachment; filename="'.$filename.'"');
readfile($path);
}
//Sends an object as json or jsonp by providing the padding prefix
public function json($object, $jsonp_prefix = null) {
$this->discard();
$this->noCache();
set_time_limit(1200);
$json = json_encode($object);
if (null !== $jsonp_prefix) {
header('Content-Type: text/javascript'); // should ideally be application/json-p once adopted
echo "$jsonp_prefix($json);";
} else {
header('Content-Type: application/json');
echo $json;
}
}
//Sends a HTTP response code
public function code($code = null) {
if(null !== $code) {
$this->_code = $code;
$protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0';
$this->header("$protocol $code");
}
return $this->_code;
}
//Redirects the request to another URL
public function redirect($url, $code = 302) {
$this->code($code);
$this->header("Location: $url");
exit;
}
//Redirects the request to the current URL
public function refresh() {
$this->redirect(isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/');
}
//Redirects the request back to the referrer
public function back() {
if (isset($_SERVER['HTTP_REFERER'])) {
$this->redirect($_SERVER['HTTP_REFERER']);
}
$this->refresh();
}
//Sets response properties/helpers
public function set($key, $value = null) {
if (!is_array($key)) {
return $this->$key = $value;
}
foreach ($key as $k => $value) {
$this->$k = $value;
}
}
//Adds to or modifies the current query string
public function query($key, $value = null) {
$query = array();
if (isset($_SERVER['QUERY_STRING'])) {
parse_str($_SERVER['QUERY_STRING'], $query);
}
if (is_array($key)) {
$query = array_merge($query, $key);
} else {
$query[$key] = $value;
}
$request_uri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '/';
if (strpos($request_uri, '?') !== false) {
$request_uri = strstr($request_uri, '?', true);
}
return $request_uri . (!empty($query) ? '?' . http_build_query($query) : null);
}
//Set the view layout
public function layout($layout) {
$this->_layout = $layout;
}
//Renders the current view
public function yield() {
require $this->_view;
}
//Renders a view + optional layout
public function render($view, array $data = array()) {
$original_view = $this->_view;
if (!empty($data)) {
$this->set($data);
}
$this->_view = $view;
if (null === $this->_layout) {
$this->yield();
} else {
require $this->_layout;
}
if (false !== $this->chunked) {
$this->chunk();
}
// restore state for parent render()
$this->_view = $original_view;
}
// Renders a view without a layout
public function partial($view, array $data = array()) {
$layout = $this->_layout;
$this->_layout = null;
$this->render($view, $data);
$this->_layout = $layout;
}
//Sets a session variable
public function session($key, $value = null) {
startSession();
return $_SESSION[$key] = $value;
}
//Adds an error callback to the stack of error handlers
public function onError($callback) {
$this->_errorCallbacks[] = $callback;
}
//Routes an exception through the error callbacks
public function error(Exception $err) {
$type = get_class($err);
$msg = $err->getMessage();
if (count($this->_errorCallbacks) > 0) {
foreach (array_reverse($this->_errorCallbacks) as $callback) {
if (is_callable($callback)) {
if ($callback($this, $msg, $type)) {
return;
}
} else {
$this->flash($err);
$this->redirect($callback);
}
}
} else {
$this->code(500);
throw new ErrorException($err);
}
}
//Returns an escaped request paramater
public function param($param, $default = null) {
return isset($_REQUEST[$param]) ? htmlentities($_REQUEST[$param], ENT_QUOTES) : $default;
}
//Returns and clears all flashes of optional $type
public function flashes($type = null) {
startSession();
if (!isset($_SESSION['__flashes'])) {
return array();
}
if (null === $type) {
$flashes = $_SESSION['__flashes'];
unset($_SESSION['__flashes']);
} elseif (null !== $type) {
$flashes = array();
if (isset($_SESSION['__flashes'][$type])) {
$flashes = $_SESSION['__flashes'][$type];
unset($_SESSION['__flashes'][$type]);
}
}
return $flashes;
}
//Escapes a string
public function escape($str) {
return htmlentities($str, ENT_QUOTES);
}
//Discards the current output buffer
public function discard() {
return ob_end_clean();
}
//Flushes the current output buffer
public function flush() {
ob_end_flush();
}
//Return the current output buffer as a string
public function buffer() {
return ob_get_contents();
}
//Dump a variable
public function dump($obj) {
if (is_array($obj) || is_object($obj)) {
$obj = print_r($obj, true);
}
echo '<pre>' . htmlentities($obj, ENT_QUOTES) . "</pre><br />\n";
}
//Allow callbacks to be assigned as properties and called like normal methods
public function __call($method, $args) {
if (!isset($this->$method) || !is_callable($this->$method)) {
throw new ErrorException("Unknown method $method()");
}
$callback = $this->$method;
switch (count($args)) {
case 1: return $callback($args[0]);
case 2: return $callback($args[0], $args[1]);
case 3: return $callback($args[0], $args[1], $args[2]);
case 4: return $callback($args[0], $args[1], $args[2], $args[3]);
default: return call_user_func_array($callback, $args);
}
}
}
function addValidator($method, $callback) {
_Validator::$_methods[strtolower($method)] = $callback;
}
class ValidatorException extends Exception {}
class _Validator {
public static $_methods = array();
protected $_str = null;
protected $_err = null;
//Sets up the validator chain with the string and optional error message
public function __construct($str, $err = null) {
$this->_str = $str;
$this->_err = $err;
if (empty(static::$_defaultAdded)) {
static::addDefault();
}
}
//Adds default validators on first use. See README for usage details
public static function addDefault() {
static::$_methods['null'] = function($str) {
return $str === null || $str === '';
};
static::$_methods['len'] = function($str, $min, $max = null) {
$len = strlen($str);
return null === $max ? $len === $min : $len >= $min && $len <= $max;
};
static::$_methods['int'] = function($str) {
return (string)$str === ((string)(int)$str);
};
static::$_methods['float'] = function($str) {
return (string)$str === ((string)(float)$str);
};
static::$_methods['email'] = function($str) {
return filter_var($str, FILTER_VALIDATE_EMAIL) !== false;
};
static::$_methods['url'] = function($str) {
return filter_var($str, FILTER_VALIDATE_URL) !== false;
};
static::$_methods['ip'] = function($str) {
return filter_var($str, FILTER_VALIDATE_IP) !== false;
};
static::$_methods['alnum'] = function($str) {
return ctype_alnum($str);
};
static::$_methods['alpha'] = function($str) {
return ctype_alpha($str);
};
static::$_methods['contains'] = function($str, $needle) {
return strpos($str, $needle) !== false;
};
static::$_methods['regex'] = function($str, $pattern) {
return preg_match($pattern, $str);
};
static::$_methods['chars'] = function($str, $chars) {
return preg_match("`^[$chars]++$`i", $str);
};
}
public function __call($method, $args) {
$reverse = false;
$validator = $method;
$method_substr = substr($method, 0, 2);
if ($method_substr === 'is') { //is<$validator>()
$validator = substr($method, 2);
} elseif ($method_substr === 'no') { //not<$validator>()
$validator = substr($method, 3);
$reverse = true;
}
$validator = strtolower($validator);
if (!$validator || !isset(static::$_methods[$validator])) {
throw new ErrorException("Unknown method $method()");
}
$validator = static::$_methods[$validator];
array_unshift($args, $this->_str);
switch (count($args)) {
case 1: $result = $validator($args[0]); break;
case 2: $result = $validator($args[0], $args[1]); break;
case 3: $result = $validator($args[0], $args[1], $args[2]); break;
case 4: $result = $validator($args[0], $args[1], $args[2], $args[3]); break;
default: $result = call_user_func_array($validator, $args); break;
}
$result = (bool)($result ^ $reverse);
if (false === $this->_err) {
return $result;
} elseif (false === $result) {
throw new ValidatorException($this->_err);
}
return $this;
}
}
class _App {
protected $services = array();
//Check for a lazy service
public function __get($name) {
if (!isset($this->services[$name])) {
throw new InvalidArgumentException("Unknown service $name");
}
$service = $this->services[$name];
return $service();
}
//Call a class property like a method
public function __call($method, $args) {
if (!isset($this->$method) || !is_callable($this->$method)) {
throw new ErrorException("Unknown method $method()");
}
return call_user_func_array($this->$method, $args);
}
//Register a lazy service
public function register($name, $closure) {
if (isset($this->services[$name])) {
throw new Exception("A service is already registered under $name");
}
$this->services[$name] = function() use ($closure) {
static $instance;
if (null === $instance) {
$instance = $closure();
}
return $instance;
};
}
}
class _Headers {
public function header($key, $value = null) {
header($this->_header($key, $value));
}
/**
* Output an HTTP header. If $value is null, $key is
* assume to be the HTTP response code, and the ":"
* separator will be omitted.
*/
public function _header($key, $value = null) {
if (null === $value ) {
return $key;
}
$key = str_replace(' ', '-', ucwords(str_replace('-', ' ', $key)));
return "$key: $value";
}
}
_Request::$_headers = _Response::$_headers = new _Headers;

View File

@ -0,0 +1,2 @@
User-agent: *
Disallow:

View File

@ -27,12 +27,12 @@
httpstatus.es
<div class="share_buttons">
<!--
<div class="share_button" id="gittip">
<iframe style="border: 0; margin: 0 20px 0 0; padding: 0;" src="https://www.gittip.com/citricsquid/widget.html" width="48" height="20"></iframe>
<div class="share_button" id="github">
<iframe src="http://ghbtns.com/github-btn.html?user=citricsquid&repo=httpstatus.es&type=watch" allowtransparency="true" frameborder="0" scrolling="0" width="72" height="20"></iframe>
</div>
-->
<div class="share_button" id="twitter">
<a href="https://twitter.com/share" class="twitter-share-button" data-via="citricsquid">Tweet</a>
<a href="https://twitter.com/share" class="twitter-share-button" data-via="citricsquid" data-url="http://httpstatus.es">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
</div>
<div class="share_button" id="facebook">
@ -48,9 +48,7 @@
Maintained by
<a href="http://twitter.com/citricsquid">@citricsquid</a>.
New codes and improvements can be commited via the
<a href="https://github.com/citricsquid/httpstatus.es">
Github repository
</a>
<a href="https://github.com/citricsquid/httpstatus.es">Github repository</a>.
</p>
</div>
<div id="statuses">