Switched to Slim PHP microframework.
This commit is contained in:
parent
ba4073f407
commit
c189e0948b
11
src/html/api/.htaccess
Normal file
11
src/html/api/.htaccess
Normal file
@ -0,0 +1,11 @@
|
||||
RewriteEngine On
|
||||
|
||||
# Some hosts may require you to use the `RewriteBase` directive.
|
||||
# If you need to use the `RewriteBase` directive, it should be the
|
||||
# absolute physical path to the directory that contains this htaccess file.
|
||||
#
|
||||
# RewriteBase /
|
||||
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
|
@ -1,114 +1,169 @@
|
||||
<?php
|
||||
require_once('rest.inc.php');
|
||||
require_once('slim/Slim.php');
|
||||
\Slim\Slim::registerAutoloader();
|
||||
|
||||
class EntryAPI extends RestAPI {
|
||||
public function __contruct() {
|
||||
parent::__construct();
|
||||
}
|
||||
$app=new \Slim\Slim();
|
||||
|
||||
protected function get_entries() {
|
||||
$connection=$this->get_db_connection();
|
||||
$app->get('/entries/:account_id/:year/:month', 'get_entries');
|
||||
$app->get('/accounts', 'get_accounts');
|
||||
$app->get('/accounts/:account_id/months', 'get_months');
|
||||
$app->delete('/entries/:id', 'remove_entry');
|
||||
$app->post('/entries/add', 'add_entry');
|
||||
$app->put('/entries/save/:id', 'save_entry');
|
||||
|
||||
if(array_key_exists("month", $this->_request) && array_key_exists("year", $this->_request)) {
|
||||
$day=$this->_request['year']."-".$this->_request['month']."-01";
|
||||
} else {
|
||||
$day=date("Y-m-01");
|
||||
}
|
||||
$app->run();
|
||||
|
||||
$account=$this->_request['account'];
|
||||
function get_connection() {
|
||||
$db=new PDO("pgsql:host=localhost;dbname=accountant", "accountant", "accountant");
|
||||
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$statement=$connection->prepare("select id, value_date, operation_date, label, value, account_id, sold, pointedsold, category from (select *, sum(value) over(order by value_date, operation_date, label desc, value desc) as sold, sum(value) over(partition by operation_date is not null order by value_date, operation_date, label desc, value desc) as pointedSold from entry where account_id=:account order by value_date desc, operation_date desc, label, value) as e where date_trunc('month', e.value_date) = :day ");
|
||||
$statement->bindParam("day", $day);
|
||||
$statement->bindParam("account", $account);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
if($return) {
|
||||
$this->response($statement->fetchAll(PDO::FETCH_ASSOC));
|
||||
} else {
|
||||
$this->response($statement->errorInfo()[2], 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function save_entry() {
|
||||
$entry=$this->_request['entry'];
|
||||
|
||||
$connection=$this->get_db_connection();
|
||||
|
||||
if($entry['id'] != null) {
|
||||
$statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account_id, category=:category where id=:id");
|
||||
} else {
|
||||
$statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id, category) values (:value_date, :operation_date, :label, :value, :account_id, :category)");
|
||||
}
|
||||
|
||||
$statement->bindParam("value_date", $entry['value_date']);
|
||||
$statement->bindParam("operation_date", $entry['operation_date'] == '' ? null : $entry['operation_date']);
|
||||
$statement->bindParam("label", $entry['label']);
|
||||
$statement->bindParam("value", $entry['value']);
|
||||
$statement->bindParam("account_id", $entry['account_id']);
|
||||
$statement->bindParam("id", $entry['id']);
|
||||
$statement->bindParam("category", $entry['category']);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
if($return) {
|
||||
$this->response(array("status"=>1, "message" => $entry['id'] . " saved."));
|
||||
} else {
|
||||
$this->response($statement->errorInfo()[2], 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function remove_entry() {
|
||||
$entry=$this->_request['entry'];
|
||||
|
||||
$connection=$this->get_db_connection();
|
||||
|
||||
$statement=$connection->prepare("delete from entry where id=:id");
|
||||
$statement->bindParam("id", $entry['id']);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
if($return) {
|
||||
$this->response(array("status"=>1, "message"=>"Entry #" . $entry['id'] . " removed."));
|
||||
} else {
|
||||
$this->response($statement->errorInfo()[2], 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_accounts() {
|
||||
$connection=$this->get_db_connection();
|
||||
|
||||
$statement=$connection->prepare("select account.id, account.name, sum(entry.value) as future, sum(case when entry.operation_date is not null then entry.value else cast(0 as numeric) end) as pointed, sum(case when entry.value_date <= now() then entry.value else cast(0 as numeric) end) as current from account join entry on (account.id = entry.account_id) group by account.id order by account.name");
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
if($return) {
|
||||
$result=$statement->fetchAll(PDO::FETCH_ASSOC);
|
||||
$this->response($result);
|
||||
} else {
|
||||
$this->response($statement->errorInfo()[2], 500);
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_months() {
|
||||
$account=$this->_request['account'];
|
||||
|
||||
$connection=$this->get_db_connection();
|
||||
|
||||
$statement=$connection->prepare("select distinct extract(year from value_date) as year, extract(month from value_date) as month from entry where account_id = :account order by year, month");
|
||||
$statement->bindParam("account", $account);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
if($return) {
|
||||
$this->response($statement->fetchAll(PDO::FETCH_ASSOC));
|
||||
} else {
|
||||
$this->response($statement->errorInfo()[2], 500);
|
||||
}
|
||||
}
|
||||
return $db;
|
||||
}
|
||||
|
||||
$entryApi = new EntryAPI();
|
||||
$entryApi->process_api();
|
||||
// Return the entries
|
||||
function get_entries($account_id, $year, $month) {
|
||||
|
||||
$day=$year."-".$month."-01";
|
||||
|
||||
$connection=get_connection();
|
||||
|
||||
$sql = <<<EOF
|
||||
select
|
||||
id,
|
||||
value_date,
|
||||
operation_date,
|
||||
label,
|
||||
value,
|
||||
account_id,
|
||||
sold,
|
||||
pointedsold,
|
||||
category
|
||||
from (
|
||||
select
|
||||
*,
|
||||
sum(value) over(order by value_date, operation_date, label desc, value desc) as sold,
|
||||
sum(value) over(partition by operation_date is not null order by value_date, operation_date, label desc, value desc) as pointedSold
|
||||
from entry
|
||||
where account_id=:account_id
|
||||
order by value_date desc, operation_date desc, label, value) as e
|
||||
where
|
||||
date_trunc('month', e.value_date) = :day
|
||||
EOF;
|
||||
|
||||
$statement=$connection->prepare($sql);
|
||||
$statement->bindParam("day", $day);
|
||||
$statement->bindParam("account_id", $account_id);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo(json_encode($statement->fetchAll(PDO::FETCH_ASSOC)));
|
||||
}
|
||||
|
||||
// Add an entry
|
||||
function add_entry() {
|
||||
$request = \Slim\Slim::getInstance()->request();
|
||||
$entry = json_decode($request->getBody(), true);
|
||||
|
||||
$connection=get_connection();
|
||||
|
||||
$statement=$connection->prepare("insert into entry (value_date, operation_date, label, value, account_id, category) values (:value_date, :operation_date, :label, :value, :account_id, :category)");
|
||||
|
||||
$statement->bindParam("value_date", $entry['value_date']);
|
||||
$statement->bindParam("operation_date", array_key_exists("operation_date", $entry) ? $entry['operation_date'] : null);
|
||||
$statement->bindParam("label", $entry['label']);
|
||||
$statement->bindParam("value", $entry['value']);
|
||||
$statement->bindParam("account_id", $entry['account_id']);
|
||||
$statement->bindParam("category", array_key_exists("category", $entry) ? $entry["category"] : null);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo("Entry saved.");
|
||||
}
|
||||
|
||||
// Saves an entry
|
||||
function save_entry($id) {
|
||||
$request = \Slim\Slim::getInstance()->request();
|
||||
$entry = json_decode($request->getBody(), true);
|
||||
|
||||
$connection=get_connection();
|
||||
|
||||
$statement=$connection->prepare("update entry set value_date=:value_date, operation_date=:operation_date, label=:label, value=:value, account_id=:account_id, category=:category where id=:id");
|
||||
|
||||
$statement->bindParam("value_date", $entry['value_date']);
|
||||
$statement->bindParam("operation_date", array_key_exists("operation_date", $entry) ? $entry['operation_date'] : null);
|
||||
$statement->bindParam("label", $entry['label']);
|
||||
$statement->bindParam("value", $entry['value']);
|
||||
$statement->bindParam("account_id", $entry['account_id']);
|
||||
$statement->bindParam("id", $entry['id']);
|
||||
$statement->bindParam("category", array_key_exists("category", $entry) ? $entry["category"] : null);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo($entry['id'] . " saved.");
|
||||
}
|
||||
|
||||
// Remove an entry
|
||||
function remove_entry($id) {
|
||||
$connection=get_connection();
|
||||
|
||||
$statement=$connection->prepare("delete from entry where id=:id");
|
||||
$statement->bindParam("id", $id);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo("Entry #" . $id . " removed.");
|
||||
}
|
||||
|
||||
// Return the accounts with their solds.
|
||||
function get_accounts() {
|
||||
$connection=get_connection();
|
||||
|
||||
$sql = <<<EOF
|
||||
select
|
||||
account.id,
|
||||
account.name,
|
||||
sum(entry.value) as future,
|
||||
sum(case when entry.operation_date is not null then entry.value else cast(0 as numeric) end) as pointed,
|
||||
sum(case when entry.value_date <= now() then entry.value else cast(0 as numeric) end) as current
|
||||
from
|
||||
account
|
||||
join entry on (account.id = entry.account_id)
|
||||
group by
|
||||
account.id
|
||||
order by
|
||||
account.name
|
||||
EOF;
|
||||
|
||||
$statement=$connection->prepare($sql);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo(json_encode($statement->fetchAll(PDO::FETCH_ASSOC)));
|
||||
}
|
||||
|
||||
// Returns the months for an account.
|
||||
function get_months($account_id) {
|
||||
$connection=get_connection();
|
||||
|
||||
$sql = <<<EOF
|
||||
select
|
||||
distinct extract(year from value_date) as year,
|
||||
extract(month from value_date) as month
|
||||
from
|
||||
entry
|
||||
where
|
||||
account_id = :account_id
|
||||
order by
|
||||
year,
|
||||
month
|
||||
EOF;
|
||||
|
||||
$statement=$connection->prepare($sql);
|
||||
$statement->bindParam("account_id", $account_id);
|
||||
|
||||
$return=$statement->execute();
|
||||
|
||||
echo(json_encode($statement->fetchAll(PDO::FETCH_ASSOC)));
|
||||
}
|
||||
?>
|
||||
|
||||
|
@ -1,86 +0,0 @@
|
||||
<?php
|
||||
class RestAPI {
|
||||
private $_content_type="application/json";
|
||||
protected $_request = array();
|
||||
|
||||
private $_code = 200;
|
||||
|
||||
public function __construct() {
|
||||
$this->init_request();
|
||||
}
|
||||
|
||||
private function init_request() {
|
||||
switch($_SERVER['REQUEST_METHOD']) {
|
||||
case "POST":
|
||||
$this->_request = $this->cleanup_request($_POST);
|
||||
break;
|
||||
case "GET":
|
||||
case "DELETE":
|
||||
$this->_request = $this->cleanup_request($_GET);
|
||||
break;
|
||||
case "PUT":
|
||||
parse_str(file_get_contents("php://input"),$this->_request);
|
||||
$this->_request = $this->cleanup_request($this->_request);
|
||||
break;
|
||||
default:
|
||||
$this->response('',406);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private function cleanup_request($data){
|
||||
$clean_input = array();
|
||||
|
||||
if(is_array($data)) {
|
||||
foreach($data as $k => $v) {
|
||||
$clean_input[$k] = $this->cleanup_request($v);
|
||||
}
|
||||
} else {
|
||||
if(get_magic_quotes_gpc()) {
|
||||
$data = trim(stripslashes($data));
|
||||
}
|
||||
|
||||
$data = strip_tags($data);
|
||||
$clean_input = trim($data);
|
||||
}
|
||||
return $clean_input == 'null' ? null : $clean_input;
|
||||
}
|
||||
|
||||
protected function response($data, $http_status=200) {
|
||||
$this->send_headers($http_status);
|
||||
|
||||
if(http_response_code() == 200) {
|
||||
if(is_array($data)) {
|
||||
echo json_encode($data);
|
||||
} else {
|
||||
echo $data;
|
||||
}
|
||||
}
|
||||
|
||||
exit;
|
||||
}
|
||||
|
||||
private function send_headers($http_status) {
|
||||
http_response_code($http_status);
|
||||
|
||||
if($http_status == 200) {
|
||||
header("Content-Type:" . "application/json");
|
||||
}
|
||||
}
|
||||
|
||||
public function process_api() {
|
||||
$func = strtolower(trim(str_replace("/","",$_REQUEST['action'])));
|
||||
|
||||
if((int)method_exists($this,$func) > 0) {
|
||||
$this->$func();
|
||||
} else {
|
||||
$this->response('',404);
|
||||
}
|
||||
}
|
||||
|
||||
protected function get_db_connection() {
|
||||
return new PDO("pgsql:host=localhost;dbname=accountant", "accountant", "accountant");
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
237
src/html/api/slim/Environment.php
Normal file
237
src/html/api/slim/Environment.php
Normal file
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Environment
|
||||
*
|
||||
* This class creates and returns a key/value array of common
|
||||
* environment variables for the current HTTP request.
|
||||
*
|
||||
* This is a singleton class; derived environment variables will
|
||||
* be common across multiple Slim applications.
|
||||
*
|
||||
* This class matches the Rack (Ruby) specification as closely
|
||||
* as possible. More information available below.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Environment implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties;
|
||||
|
||||
/**
|
||||
* @var \Slim\Environment
|
||||
*/
|
||||
protected static $environment;
|
||||
|
||||
/**
|
||||
* Get environment instance (singleton)
|
||||
*
|
||||
* This creates and/or returns an environment instance (singleton)
|
||||
* derived from $_SERVER variables. You may override the global server
|
||||
* variables by using `\Slim\Environment::mock()` instead.
|
||||
*
|
||||
* @param bool $refresh Refresh properties using global server variables?
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function getInstance($refresh = false)
|
||||
{
|
||||
if (is_null(self::$environment) || $refresh) {
|
||||
self::$environment = new self();
|
||||
}
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mock environment instance
|
||||
*
|
||||
* @param array $userSettings
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function mock($userSettings = array())
|
||||
{
|
||||
self::$environment = new self(array_merge(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '',
|
||||
'PATH_INFO' => '',
|
||||
'QUERY_STRING' => '',
|
||||
'SERVER_NAME' => 'localhost',
|
||||
'SERVER_PORT' => 80,
|
||||
'ACCEPT' => 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
||||
'ACCEPT_LANGUAGE' => 'en-US,en;q=0.8',
|
||||
'ACCEPT_CHARSET' => 'ISO-8859-1,utf-8;q=0.7,*;q=0.3',
|
||||
'USER_AGENT' => 'Slim Framework',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => @fopen('php://stderr', 'w')
|
||||
), $userSettings));
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor (private access)
|
||||
*
|
||||
* @param array|null $settings If present, these are used instead of global server variables
|
||||
*/
|
||||
private function __construct($settings = null)
|
||||
{
|
||||
if ($settings) {
|
||||
$this->properties = $settings;
|
||||
} else {
|
||||
$env = array();
|
||||
|
||||
//The HTTP request method
|
||||
$env['REQUEST_METHOD'] = $_SERVER['REQUEST_METHOD'];
|
||||
|
||||
//The IP
|
||||
$env['REMOTE_ADDR'] = $_SERVER['REMOTE_ADDR'];
|
||||
|
||||
/**
|
||||
* Application paths
|
||||
*
|
||||
* This derives two paths: SCRIPT_NAME and PATH_INFO. The SCRIPT_NAME
|
||||
* is the real, physical path to the application, be it in the root
|
||||
* directory or a subdirectory of the public document root. The PATH_INFO is the
|
||||
* virtual path to the requested resource within the application context.
|
||||
*
|
||||
* With htaccess, the SCRIPT_NAME will be an absolute path (without file name);
|
||||
* if not using htaccess, it will also include the file name. If it is "/",
|
||||
* it is set to an empty string (since it cannot have a trailing slash).
|
||||
*
|
||||
* The PATH_INFO will be an absolute path with a leading slash; this will be
|
||||
* used for application routing.
|
||||
*/
|
||||
if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) {
|
||||
$env['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME']; //Without URL rewrite
|
||||
} else {
|
||||
$env['SCRIPT_NAME'] = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']) ); //With URL rewrite
|
||||
}
|
||||
$env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME']));
|
||||
if (strpos($env['PATH_INFO'], '?') !== false) {
|
||||
$env['PATH_INFO'] = substr_replace($env['PATH_INFO'], '', strpos($env['PATH_INFO'], '?')); //query string is not removed automatically
|
||||
}
|
||||
$env['SCRIPT_NAME'] = rtrim($env['SCRIPT_NAME'], '/');
|
||||
$env['PATH_INFO'] = '/' . ltrim($env['PATH_INFO'], '/');
|
||||
|
||||
//The portion of the request URI following the '?'
|
||||
$env['QUERY_STRING'] = isset($_SERVER['QUERY_STRING']) ? $_SERVER['QUERY_STRING'] : '';
|
||||
|
||||
//Name of server host that is running the script
|
||||
$env['SERVER_NAME'] = $_SERVER['SERVER_NAME'];
|
||||
|
||||
//Number of server port that is running the script
|
||||
$env['SERVER_PORT'] = $_SERVER['SERVER_PORT'];
|
||||
|
||||
//HTTP request headers
|
||||
$specialHeaders = array('CONTENT_TYPE', 'CONTENT_LENGTH', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'PHP_AUTH_DIGEST', 'AUTH_TYPE');
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
$value = is_string($value) ? trim($value) : $value;
|
||||
if (strpos($key, 'HTTP_') === 0) {
|
||||
$env[substr($key, 5)] = $value;
|
||||
} elseif (strpos($key, 'X_') === 0 || in_array($key, $specialHeaders)) {
|
||||
$env[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
//Is the application running under HTTPS or HTTP protocol?
|
||||
$env['slim.url_scheme'] = empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ? 'http' : 'https';
|
||||
|
||||
//Input stream (readable one time only; not available for mutipart/form-data requests)
|
||||
$rawInput = @file_get_contents('php://input');
|
||||
if (!$rawInput) {
|
||||
$rawInput = '';
|
||||
}
|
||||
$env['slim.input'] = $rawInput;
|
||||
|
||||
//Error stream
|
||||
$env['slim.errors'] = fopen('php://stderr', 'w');
|
||||
|
||||
$this->properties = $env;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (isset($this->properties[$offset])) {
|
||||
return $this->properties[$offset];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->properties[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* IteratorAggregate
|
||||
*
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->properties);
|
||||
}
|
||||
}
|
50
src/html/api/slim/Exception/Pass.php
Normal file
50
src/html/api/slim/Exception/Pass.php
Normal file
@ -0,0 +1,50 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Exception;
|
||||
|
||||
/**
|
||||
* Pass Exception
|
||||
*
|
||||
* This Exception will cause the Router::dispatch method
|
||||
* to skip the current matching route and continue to the next
|
||||
* matching route. If no subsequent routes are found, a
|
||||
* HTTP 404 Not Found response will be sent to the client.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Pass extends \Exception
|
||||
{
|
||||
|
||||
}
|
48
src/html/api/slim/Exception/Stop.php
Normal file
48
src/html/api/slim/Exception/Stop.php
Normal file
@ -0,0 +1,48 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Exception;
|
||||
|
||||
/**
|
||||
* Stop Exception
|
||||
*
|
||||
* This Exception is thrown when the Slim application needs to abort
|
||||
* processing and return control flow to the outer PHP script.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Stop extends \Exception
|
||||
{
|
||||
|
||||
}
|
181
src/html/api/slim/Http/Headers.php
Normal file
181
src/html/api/slim/Http/Headers.php
Normal file
@ -0,0 +1,181 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* HTTP Headers
|
||||
*
|
||||
* This class is an abstraction of the HTTP response headers and
|
||||
* provides array access to the header list while automatically
|
||||
* stores and retrieves headers with lowercase canonical keys regardless
|
||||
* of the input format.
|
||||
*
|
||||
* This class also implements the `Iterator` and `Countable`
|
||||
* interfaces for even more convenient usage.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Headers implements \ArrayAccess, \Iterator, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array HTTP headers
|
||||
*/
|
||||
protected $headers;
|
||||
|
||||
/**
|
||||
* @var array Map canonical header name to original header name
|
||||
*/
|
||||
protected $map;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $headers
|
||||
*/
|
||||
public function __construct($headers = array())
|
||||
{
|
||||
$this->merge($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge Headers
|
||||
* @param array $headers
|
||||
*/
|
||||
public function merge($headers)
|
||||
{
|
||||
foreach ($headers as $name => $value) {
|
||||
$this[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform header name into canonical form
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function canonical($name)
|
||||
{
|
||||
return strtolower(trim($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->headers[$this->canonical($offset)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
if (isset($this->headers[$canonical])) {
|
||||
return $this->headers[$canonical];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
$this->headers[$canonical] = $value;
|
||||
$this->map[$canonical] = $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
unset($this->headers[$canonical], $this->map[$canonical]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable: Count
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Rewind
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Current
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Key
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
$key = key($this->headers);
|
||||
|
||||
return $this->map[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Next
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
return next($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Valid
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return current($this->headers) !== false;
|
||||
}
|
||||
}
|
585
src/html/api/slim/Http/Request.php
Normal file
585
src/html/api/slim/Http/Request.php
Normal file
@ -0,0 +1,585 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* Slim HTTP Request
|
||||
*
|
||||
* This class provides a human-friendly interface to the Slim environment variables;
|
||||
* environment variables are passed by reference and will be modified directly.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
const METHOD_HEAD = 'HEAD';
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
const METHOD_PUT = 'PUT';
|
||||
const METHOD_DELETE = 'DELETE';
|
||||
const METHOD_OPTIONS = 'OPTIONS';
|
||||
const METHOD_OVERRIDE = '_METHOD';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $formDataMediaTypes = array('application/x-www-form-urlencoded');
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $env;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $env
|
||||
* @see \Slim\Environment
|
||||
*/
|
||||
public function __construct($env)
|
||||
{
|
||||
$this->env = $env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP method
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->env['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a GET request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isGet()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_GET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a POST request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPost()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a PUT request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPut()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_PUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a DELETE request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelete()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_DELETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a HEAD request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isHead()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_HEAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a OPTIONS request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isOptions()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_OPTIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an AJAX request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isAjax()
|
||||
{
|
||||
if ($this->params('isajax')) {
|
||||
return true;
|
||||
} elseif (isset($this->env['X_REQUESTED_WITH']) && $this->env['X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an XHR request? (alias of Slim_Http_Request::isAjax)
|
||||
* @return bool
|
||||
*/
|
||||
public function isXhr()
|
||||
{
|
||||
return $this->isAjax();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch GET and POST data
|
||||
*
|
||||
* This method returns a union of GET and POST data as a key-value array, or the value
|
||||
* of the array key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function params($key = null)
|
||||
{
|
||||
$union = array_merge($this->get(), $this->post());
|
||||
if ($key) {
|
||||
if (isset($union[$key])) {
|
||||
return $union[$key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $union;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch GET data
|
||||
*
|
||||
* This method returns a key-value array of data sent in the HTTP request query string, or
|
||||
* the value of the array key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function get($key = null)
|
||||
{
|
||||
if (!isset($this->env['slim.request.query_hash'])) {
|
||||
$output = array();
|
||||
if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
|
||||
mb_parse_str($this->env['QUERY_STRING'], $output);
|
||||
} else {
|
||||
parse_str($this->env['QUERY_STRING'], $output);
|
||||
}
|
||||
$this->env['slim.request.query_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
}
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.query_hash'][$key])) {
|
||||
return $this->env['slim.request.query_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $this->env['slim.request.query_hash'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch POST data
|
||||
*
|
||||
* This method returns a key-value array of data sent in the HTTP request body, or
|
||||
* the value of a hash key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* @throws \RuntimeException If environment input is not available
|
||||
*/
|
||||
public function post($key = null)
|
||||
{
|
||||
if (!isset($this->env['slim.input'])) {
|
||||
throw new \RuntimeException('Missing slim.input in environment variables');
|
||||
}
|
||||
if (!isset($this->env['slim.request.form_hash'])) {
|
||||
$this->env['slim.request.form_hash'] = array();
|
||||
if ($this->isFormData() && is_string($this->env['slim.input'])) {
|
||||
$output = array();
|
||||
if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
|
||||
mb_parse_str($this->env['slim.input'], $output);
|
||||
} else {
|
||||
parse_str($this->env['slim.input'], $output);
|
||||
}
|
||||
$this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
} else {
|
||||
$this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($_POST);
|
||||
}
|
||||
}
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.form_hash'][$key])) {
|
||||
return $this->env['slim.request.form_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $this->env['slim.request.form_hash'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch PUT data (alias for \Slim\Http\Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function put($key = null)
|
||||
{
|
||||
return $this->post($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch DELETE data (alias for \Slim\Http\Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function delete($key = null)
|
||||
{
|
||||
return $this->post($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch COOKIE data
|
||||
*
|
||||
* This method returns a key-value array of Cookie data sent in the HTTP request, or
|
||||
* the value of a array key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|string|null
|
||||
*/
|
||||
public function cookies($key = null)
|
||||
{
|
||||
if (!isset($this->env['slim.request.cookie_hash'])) {
|
||||
$cookieHeader = isset($this->env['COOKIE']) ? $this->env['COOKIE'] : '';
|
||||
$this->env['slim.request.cookie_hash'] = Util::parseCookieHeader($cookieHeader);
|
||||
}
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.cookie_hash'][$key])) {
|
||||
return $this->env['slim.request.cookie_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $this->env['slim.request.cookie_hash'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does the Request body contain parseable form data?
|
||||
* @return bool
|
||||
*/
|
||||
public function isFormData()
|
||||
{
|
||||
$method = isset($this->env['slim.method_override.original_method']) ? $this->env['slim.method_override.original_method'] : $this->getMethod();
|
||||
|
||||
return ($method === self::METHOD_POST && is_null($this->getContentType())) || in_array($this->getMediaType(), self::$formDataMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Headers
|
||||
*
|
||||
* This method returns a key-value array of headers sent in the HTTP request, or
|
||||
* the value of a hash key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @param mixed $default The default value returned if the requested header is not available
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($key = null, $default = null)
|
||||
{
|
||||
if ($key) {
|
||||
$key = strtoupper($key);
|
||||
$key = str_replace('-', '_', $key);
|
||||
$key = preg_replace('@^HTTP_@', '', $key);
|
||||
if (isset($this->env[$key])) {
|
||||
return $this->env[$key];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
} else {
|
||||
$headers = array();
|
||||
foreach ($this->env as $key => $value) {
|
||||
if (strpos($key, 'slim.') !== 0) {
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Body
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->env['slim.input'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Content Type
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
if (isset($this->env['CONTENT_TYPE'])) {
|
||||
return $this->env['CONTENT_TYPE'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Media Type (type/subtype within Content Type header)
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMediaType()
|
||||
{
|
||||
$contentType = $this->getContentType();
|
||||
if ($contentType) {
|
||||
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
|
||||
|
||||
return strtolower($contentTypeParts[0]);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Media Type Params
|
||||
* @return array
|
||||
*/
|
||||
public function getMediaTypeParams()
|
||||
{
|
||||
$contentType = $this->getContentType();
|
||||
$contentTypeParams = array();
|
||||
if ($contentType) {
|
||||
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
|
||||
$contentTypePartsLength = count($contentTypeParts);
|
||||
for ($i = 1; $i < $contentTypePartsLength; $i++) {
|
||||
$paramParts = explode('=', $contentTypeParts[$i]);
|
||||
$contentTypeParams[strtolower($paramParts[0])] = $paramParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $contentTypeParams;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Content Charset
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentCharset()
|
||||
{
|
||||
$mediaTypeParams = $this->getMediaTypeParams();
|
||||
if (isset($mediaTypeParams['charset'])) {
|
||||
return $mediaTypeParams['charset'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Content-Length
|
||||
* @return int
|
||||
*/
|
||||
public function getContentLength()
|
||||
{
|
||||
if (isset($this->env['CONTENT_LENGTH'])) {
|
||||
return (int) $this->env['CONTENT_LENGTH'];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Host
|
||||
* @return string
|
||||
*/
|
||||
public function getHost()
|
||||
{
|
||||
if (isset($this->env['HOST'])) {
|
||||
if (strpos($this->env['HOST'], ':') !== false) {
|
||||
$hostParts = explode(':', $this->env['HOST']);
|
||||
|
||||
return $hostParts[0];
|
||||
}
|
||||
|
||||
return $this->env['HOST'];
|
||||
} else {
|
||||
return $this->env['SERVER_NAME'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Host with Port
|
||||
* @return string
|
||||
*/
|
||||
public function getHostWithPort()
|
||||
{
|
||||
return sprintf('%s:%s', $this->getHost(), $this->getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Port
|
||||
* @return int
|
||||
*/
|
||||
public function getPort()
|
||||
{
|
||||
return (int) $this->env['SERVER_PORT'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Scheme (https or http)
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->env['slim.url_scheme'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Script Name (physical path)
|
||||
* @return string
|
||||
*/
|
||||
public function getScriptName()
|
||||
{
|
||||
return $this->env['SCRIPT_NAME'];
|
||||
}
|
||||
|
||||
/**
|
||||
* LEGACY: Get Root URI (alias for Slim_Http_Request::getScriptName)
|
||||
* @return string
|
||||
*/
|
||||
public function getRootUri()
|
||||
{
|
||||
return $this->getScriptName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Path (physical path + virtual path)
|
||||
* @return string
|
||||
*/
|
||||
public function getPath()
|
||||
{
|
||||
return $this->getScriptName() . $this->getPathInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Path Info (virtual path)
|
||||
* @return string
|
||||
*/
|
||||
public function getPathInfo()
|
||||
{
|
||||
return $this->env['PATH_INFO'];
|
||||
}
|
||||
|
||||
/**
|
||||
* LEGACY: Get Resource URI (alias for Slim_Http_Request::getPathInfo)
|
||||
* @return string
|
||||
*/
|
||||
public function getResourceUri()
|
||||
{
|
||||
return $this->getPathInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL (scheme + host [ + port if non-standard ])
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
$url = $this->getScheme() . '://' . $this->getHost();
|
||||
if (($this->getScheme() === 'https' && $this->getPort() !== 443) || ($this->getScheme() === 'http' && $this->getPort() !== 80)) {
|
||||
$url .= sprintf(':%s', $this->getPort());
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get IP
|
||||
* @return string
|
||||
*/
|
||||
public function getIp()
|
||||
{
|
||||
if (isset($this->env['X_FORWARDED_FOR'])) {
|
||||
return $this->env['X_FORWARDED_FOR'];
|
||||
} elseif (isset($this->env['CLIENT_IP'])) {
|
||||
return $this->env['CLIENT_IP'];
|
||||
}
|
||||
|
||||
return $this->env['REMOTE_ADDR'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referrer
|
||||
* @return string|null
|
||||
*/
|
||||
public function getReferrer()
|
||||
{
|
||||
if (isset($this->env['REFERER'])) {
|
||||
return $this->env['REFERER'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Referer (for those who can't spell)
|
||||
* @return string|null
|
||||
*/
|
||||
public function getReferer()
|
||||
{
|
||||
return $this->getReferrer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get User Agent
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserAgent()
|
||||
{
|
||||
if (isset($this->env['USER_AGENT'])) {
|
||||
return $this->env['USER_AGENT'];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
459
src/html/api/slim/Http/Response.php
Normal file
459
src/html/api/slim/Http/Response.php
Normal file
@ -0,0 +1,459 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* Response
|
||||
*
|
||||
* This is a simple abstraction over top an HTTP response. This
|
||||
* provides methods to set the HTTP status, the HTTP headers,
|
||||
* and the HTTP body.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Response implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var int HTTP status code
|
||||
*/
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* @var \Slim\Http\Headers List of HTTP response headers
|
||||
*/
|
||||
protected $header;
|
||||
|
||||
/**
|
||||
* @var string HTTP response body
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* @var int Length of HTTP response body
|
||||
*/
|
||||
protected $length;
|
||||
|
||||
/**
|
||||
* @var array HTTP response codes and messages
|
||||
*/
|
||||
protected static $messages = array(
|
||||
//Informational 1xx
|
||||
100 => '100 Continue',
|
||||
101 => '101 Switching Protocols',
|
||||
//Successful 2xx
|
||||
200 => '200 OK',
|
||||
201 => '201 Created',
|
||||
202 => '202 Accepted',
|
||||
203 => '203 Non-Authoritative Information',
|
||||
204 => '204 No Content',
|
||||
205 => '205 Reset Content',
|
||||
206 => '206 Partial Content',
|
||||
//Redirection 3xx
|
||||
300 => '300 Multiple Choices',
|
||||
301 => '301 Moved Permanently',
|
||||
302 => '302 Found',
|
||||
303 => '303 See Other',
|
||||
304 => '304 Not Modified',
|
||||
305 => '305 Use Proxy',
|
||||
306 => '306 (Unused)',
|
||||
307 => '307 Temporary Redirect',
|
||||
//Client Error 4xx
|
||||
400 => '400 Bad Request',
|
||||
401 => '401 Unauthorized',
|
||||
402 => '402 Payment Required',
|
||||
403 => '403 Forbidden',
|
||||
404 => '404 Not Found',
|
||||
405 => '405 Method Not Allowed',
|
||||
406 => '406 Not Acceptable',
|
||||
407 => '407 Proxy Authentication Required',
|
||||
408 => '408 Request Timeout',
|
||||
409 => '409 Conflict',
|
||||
410 => '410 Gone',
|
||||
411 => '411 Length Required',
|
||||
412 => '412 Precondition Failed',
|
||||
413 => '413 Request Entity Too Large',
|
||||
414 => '414 Request-URI Too Long',
|
||||
415 => '415 Unsupported Media Type',
|
||||
416 => '416 Requested Range Not Satisfiable',
|
||||
417 => '417 Expectation Failed',
|
||||
422 => '422 Unprocessable Entity',
|
||||
423 => '423 Locked',
|
||||
//Server Error 5xx
|
||||
500 => '500 Internal Server Error',
|
||||
501 => '501 Not Implemented',
|
||||
502 => '502 Bad Gateway',
|
||||
503 => '503 Service Unavailable',
|
||||
504 => '504 Gateway Timeout',
|
||||
505 => '505 HTTP Version Not Supported'
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $body The HTTP response body
|
||||
* @param int $status The HTTP response status
|
||||
* @param \Slim\Http\Headers|array $header The HTTP response headers
|
||||
*/
|
||||
public function __construct($body = '', $status = 200, $header = array())
|
||||
{
|
||||
$this->status = (int) $status;
|
||||
$headers = array();
|
||||
foreach ($header as $key => $value) {
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
$this->header = new Headers(array_merge(array('Content-Type' => 'text/html'), $headers));
|
||||
$this->body = '';
|
||||
$this->write($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set status
|
||||
* @param int|null $status
|
||||
* @return int
|
||||
*/
|
||||
public function status($status = null)
|
||||
{
|
||||
if (!is_null($status)) {
|
||||
$this->status = (int) $status;
|
||||
}
|
||||
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set header
|
||||
* @param string $name Header name
|
||||
* @param string|null $value Header value
|
||||
* @return string Header value
|
||||
*/
|
||||
public function header($name, $value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$this[$name] = $value;
|
||||
}
|
||||
|
||||
return $this[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get headers
|
||||
* @return \Slim\Http\Headers
|
||||
*/
|
||||
public function headers()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set body
|
||||
* @param string|null $body Content of HTTP response body
|
||||
* @return string
|
||||
*/
|
||||
public function body($body = null)
|
||||
{
|
||||
if (!is_null($body)) {
|
||||
$this->write($body, true);
|
||||
}
|
||||
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set length
|
||||
* @param int|null $length
|
||||
* @return int
|
||||
*/
|
||||
public function length($length = null)
|
||||
{
|
||||
if (!is_null($length)) {
|
||||
$this->length = (int) $length;
|
||||
}
|
||||
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append HTTP response body
|
||||
* @param string $body Content to append to the current HTTP response body
|
||||
* @param bool $replace Overwrite existing response body?
|
||||
* @return string The updated HTTP response body
|
||||
*/
|
||||
public function write($body, $replace = false)
|
||||
{
|
||||
if ($replace) {
|
||||
$this->body = $body;
|
||||
} else {
|
||||
$this->body .= (string) $body;
|
||||
}
|
||||
$this->length = strlen($this->body);
|
||||
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize
|
||||
*
|
||||
* This prepares this response and returns an array
|
||||
* of [status, headers, body]. This array is passed to outer middleware
|
||||
* if available or directly to the Slim run method.
|
||||
*
|
||||
* @return array[int status, array headers, string body]
|
||||
*/
|
||||
public function finalize()
|
||||
{
|
||||
if (in_array($this->status, array(204, 304))) {
|
||||
unset($this['Content-Type'], $this['Content-Length']);
|
||||
|
||||
return array($this->status, $this->header, '');
|
||||
} else {
|
||||
return array($this->status, $this->header, $this->body);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie
|
||||
*
|
||||
* Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie`
|
||||
* header on its own and delegates this responsibility to the `Slim_Http_Util` class. This
|
||||
* response's header is passed by reference to the utility class and is directly modified. By not
|
||||
* relying on PHP's native implementation, Slim allows middleware the opportunity to massage or
|
||||
* analyze the raw header before the response is ultimately delivered to the HTTP client.
|
||||
*
|
||||
* @param string $name The name of the cookie
|
||||
* @param string|array $value If string, the value of cookie; if array, properties for
|
||||
* cookie including: value, expire, path, domain, secure, httponly
|
||||
*/
|
||||
public function setCookie($name, $value)
|
||||
{
|
||||
Util::setCookieHeader($this->header, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete cookie
|
||||
*
|
||||
* Instead of using PHP's `setcookie()` function, Slim manually constructs the HTTP `Set-Cookie`
|
||||
* header on its own and delegates this responsibility to the `Slim_Http_Util` class. This
|
||||
* response's header is passed by reference to the utility class and is directly modified. By not
|
||||
* relying on PHP's native implementation, Slim allows middleware the opportunity to massage or
|
||||
* analyze the raw header before the response is ultimately delivered to the HTTP client.
|
||||
*
|
||||
* This method will set a cookie with the given name that has an expiration time in the past; this will
|
||||
* prompt the HTTP client to invalidate and remove the client-side cookie. Optionally, you may
|
||||
* also pass a key/value array as the second argument. If the "domain" key is present in this
|
||||
* array, only the Cookie with the given name AND domain will be removed. The invalidating cookie
|
||||
* sent with this response will adopt all properties of the second argument.
|
||||
*
|
||||
* @param string $name The name of the cookie
|
||||
* @param array $value Properties for cookie including: value, expire, path, domain, secure, httponly
|
||||
*/
|
||||
public function deleteCookie($name, $value = array())
|
||||
{
|
||||
Util::deleteCookieHeader($this->header, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect
|
||||
*
|
||||
* This method prepares this response to return an HTTP Redirect response
|
||||
* to the HTTP client.
|
||||
*
|
||||
* @param string $url The redirect destination
|
||||
* @param int $status The redirect HTTP status code
|
||||
*/
|
||||
public function redirect ($url, $status = 302)
|
||||
{
|
||||
$this->status = $status;
|
||||
$this['Location'] = $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Empty?
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty()
|
||||
{
|
||||
return in_array($this->status, array(201, 204, 304));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Informational?
|
||||
* @return bool
|
||||
*/
|
||||
public function isInformational()
|
||||
{
|
||||
return $this->status >= 100 && $this->status < 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: OK?
|
||||
* @return bool
|
||||
*/
|
||||
public function isOk()
|
||||
{
|
||||
return $this->status === 200;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Successful?
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessful()
|
||||
{
|
||||
return $this->status >= 200 && $this->status < 300;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Redirect?
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->status, array(301, 302, 303, 307));
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Redirection?
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirection()
|
||||
{
|
||||
return $this->status >= 300 && $this->status < 400;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Forbidden?
|
||||
* @return bool
|
||||
*/
|
||||
public function isForbidden()
|
||||
{
|
||||
return $this->status === 403;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Not Found?
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotFound()
|
||||
{
|
||||
return $this->status === 404;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Client error?
|
||||
* @return bool
|
||||
*/
|
||||
public function isClientError()
|
||||
{
|
||||
return $this->status >= 400 && $this->status < 500;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helpers: Server Error?
|
||||
* @return bool
|
||||
*/
|
||||
public function isServerError()
|
||||
{
|
||||
return $this->status >= 500 && $this->status < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists( $offset )
|
||||
{
|
||||
return isset($this->header[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet( $offset )
|
||||
{
|
||||
if (isset($this->header[$offset])) {
|
||||
return $this->header[$offset];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->header[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->header[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable: Count
|
||||
*/
|
||||
public function count()
|
||||
{
|
||||
return count($this->header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator
|
||||
*
|
||||
* This returns the contained `\Slim\Http\Headers` instance which
|
||||
* is itself iterable.
|
||||
*
|
||||
* @return \Slim\Http\Headers
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get message for HTTP status code
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getMessageForCode($status)
|
||||
{
|
||||
if (isset(self::$messages[$status])) {
|
||||
return self::$messages[$status];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
389
src/html/api/slim/Http/Util.php
Normal file
389
src/html/api/slim/Http/Util.php
Normal file
@ -0,0 +1,389 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* Slim HTTP Utilities
|
||||
*
|
||||
* This class provides useful methods for handling HTTP requests.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
*
|
||||
* This method strips slashes from its input. By default, this method will only
|
||||
* strip slashes from its input if magic quotes are enabled. Otherwise, you may
|
||||
* override the magic quotes setting with either TRUE or FALSE as the send argument
|
||||
* to force this method to strip or not strip slashes from its input.
|
||||
*
|
||||
* @var array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null)
|
||||
{
|
||||
$strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes;
|
||||
if ($strip) {
|
||||
return self::_stripSlashes($rawData);
|
||||
} else {
|
||||
return $rawData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
* @param array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
protected static function _stripSlashes($rawData)
|
||||
{
|
||||
return is_array($rawData) ? array_map(array('self', '_stripSlashes'), $rawData) : stripslashes($rawData);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt data
|
||||
*
|
||||
* This method will encrypt data using a given key, vector, and cipher.
|
||||
* By default, this will encrypt data using the RIJNDAEL/AES 256 bit cipher. You
|
||||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The unencrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function encrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Merge settings with defaults
|
||||
$settings = array_merge(array(
|
||||
'algorithm' => MCRYPT_RIJNDAEL_256,
|
||||
'mode' => MCRYPT_MODE_CBC
|
||||
), $settings);
|
||||
|
||||
//Get module
|
||||
$module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
|
||||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
//Encrypt value
|
||||
mcrypt_generic_init($module, $key, $iv);
|
||||
$res = @mcrypt_generic($module, $data);
|
||||
mcrypt_generic_deinit($module);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt data
|
||||
*
|
||||
* This method will decrypt data using a given key, vector, and cipher.
|
||||
* By default, this will decrypt data using the RIJNDAEL/AES 256 bit cipher. You
|
||||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The encrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function decrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
//Merge settings with defaults
|
||||
$settings = array_merge(array(
|
||||
'algorithm' => MCRYPT_RIJNDAEL_256,
|
||||
'mode' => MCRYPT_MODE_CBC
|
||||
), $settings);
|
||||
|
||||
//Get module
|
||||
$module = mcrypt_module_open($settings['algorithm'], '', $settings['mode'], '');
|
||||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
//Decrypt value
|
||||
mcrypt_generic_init($module, $key, $iv);
|
||||
$decryptedData = @mdecrypt_generic($module, $data);
|
||||
$res = str_replace("\x0", '', $decryptedData);
|
||||
mcrypt_generic_deinit($module);
|
||||
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode secure cookie value
|
||||
*
|
||||
* This method will create the secure value of an HTTP cookie. The
|
||||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The unsecure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
*/
|
||||
public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode)
|
||||
{
|
||||
$key = hash_hmac('sha1', $expires, $secret);
|
||||
$iv = self::get_iv($expires, $secret);
|
||||
$secureString = base64_encode(self::encrypt($value, $key, $iv, array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
)));
|
||||
$verificationString = hash_hmac('sha1', $expires . $value, $key);
|
||||
|
||||
return implode('|', array($expires, $secureString, $verificationString));
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode secure cookie value
|
||||
*
|
||||
* This method will decode the secure value of an HTTP cookie. The
|
||||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The secure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
*/
|
||||
public static function decodeSecureCookie($value, $secret, $algorithm, $mode)
|
||||
{
|
||||
if ($value) {
|
||||
$value = explode('|', $value);
|
||||
if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) {
|
||||
$key = hash_hmac('sha1', $value[0], $secret);
|
||||
$iv = self::get_iv($value[0], $secret);
|
||||
$data = self::decrypt(base64_decode($value[1]), $key, $iv, array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
));
|
||||
$verificationString = hash_hmac('sha1', $value[0] . $data, $key);
|
||||
if ($verificationString === $value[2]) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set HTTP cookie header
|
||||
*
|
||||
* This method will construct and set the HTTP `Set-Cookie` header. Slim
|
||||
* uses this method instead of PHP's native `setcookie` method. This allows
|
||||
* more control of the HTTP header irrespective of the native implementation's
|
||||
* dependency on PHP versions.
|
||||
*
|
||||
* This method accepts the Slim_Http_Headers object by reference as its
|
||||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public static function setCookieHeader(&$header, $name, $value)
|
||||
{
|
||||
//Build cookie header
|
||||
if (is_array($value)) {
|
||||
$domain = '';
|
||||
$path = '';
|
||||
$expires = '';
|
||||
$secure = '';
|
||||
$httponly = '';
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$domain = '; domain=' . $value['domain'];
|
||||
}
|
||||
if (isset($value['path']) && $value['path']) {
|
||||
$path = '; path=' . $value['path'];
|
||||
}
|
||||
if (isset($value['expires'])) {
|
||||
if (is_string($value['expires'])) {
|
||||
$timestamp = strtotime($value['expires']);
|
||||
} else {
|
||||
$timestamp = (int) $value['expires'];
|
||||
}
|
||||
if ($timestamp !== 0) {
|
||||
$expires = '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp);
|
||||
}
|
||||
}
|
||||
if (isset($value['secure']) && $value['secure']) {
|
||||
$secure = '; secure';
|
||||
}
|
||||
if (isset($value['httponly']) && $value['httponly']) {
|
||||
$httponly = '; HttpOnly';
|
||||
}
|
||||
$cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string) $value['value']), $domain . $path . $expires . $secure . $httponly);
|
||||
} else {
|
||||
$cookie = sprintf('%s=%s', urlencode($name), urlencode((string) $value));
|
||||
}
|
||||
|
||||
//Set cookie header
|
||||
if (!isset($header['Set-Cookie']) || $header['Set-Cookie'] === '') {
|
||||
$header['Set-Cookie'] = $cookie;
|
||||
} else {
|
||||
$header['Set-Cookie'] = implode("\n", array($header['Set-Cookie'], $cookie));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete HTTP cookie header
|
||||
*
|
||||
* This method will construct and set the HTTP `Set-Cookie` header to invalidate
|
||||
* a client-side HTTP cookie. If a cookie with the same name (and, optionally, domain)
|
||||
* is already set in the HTTP response, it will also be removed. Slim uses this method
|
||||
* instead of PHP's native `setcookie` method. This allows more control of the HTTP header
|
||||
* irrespective of PHP's native implementation's dependency on PHP versions.
|
||||
*
|
||||
* This method accepts the Slim_Http_Headers object by reference as its
|
||||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public static function deleteCookieHeader(&$header, $name, $value = array())
|
||||
{
|
||||
//Remove affected cookies from current response header
|
||||
$cookiesOld = array();
|
||||
$cookiesNew = array();
|
||||
if (isset($header['Set-Cookie'])) {
|
||||
$cookiesOld = explode("\n", $header['Set-Cookie']);
|
||||
}
|
||||
foreach ($cookiesOld as $c) {
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$regex = sprintf('@%s=.*domain=%s@', urlencode($name), preg_quote($value['domain']));
|
||||
} else {
|
||||
$regex = sprintf('@%s=@', urlencode($name));
|
||||
}
|
||||
if (preg_match($regex, $c) === 0) {
|
||||
$cookiesNew[] = $c;
|
||||
}
|
||||
}
|
||||
if ($cookiesNew) {
|
||||
$header['Set-Cookie'] = implode("\n", $cookiesNew);
|
||||
} else {
|
||||
unset($header['Set-Cookie']);
|
||||
}
|
||||
|
||||
//Set invalidating cookie to clear client-side cookie
|
||||
self::setCookieHeader($header, $name, array_merge(array('value' => '', 'path' => null, 'domain' => null, 'expires' => time() - 100), $value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse cookie header
|
||||
*
|
||||
* This method will parse the HTTP requst's `Cookie` header
|
||||
* and extract cookies into an associative array.
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function parseCookieHeader($header)
|
||||
{
|
||||
$cookies = array();
|
||||
$header = rtrim($header, "\r\n");
|
||||
$headerPieces = preg_split('@\s*[;,]\s*@', $header);
|
||||
foreach ($headerPieces as $c) {
|
||||
$cParts = explode('=', $c);
|
||||
if (count($cParts) === 2) {
|
||||
$key = urldecode($cParts[0]);
|
||||
$value = urldecode($cParts[1]);
|
||||
if (!isset($cookies[$key])) {
|
||||
$cookies[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random IV
|
||||
*
|
||||
* This method will generate a non-predictable IV for use with
|
||||
* the cookie encryption
|
||||
*
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @return binary string with length 40
|
||||
*/
|
||||
private static function get_iv($expires, $secret)
|
||||
{
|
||||
$data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret);
|
||||
$data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret);
|
||||
|
||||
return pack("h*", $data1.$data2);
|
||||
}
|
||||
|
||||
}
|
237
src/html/api/slim/Log.php
Normal file
237
src/html/api/slim/Log.php
Normal file
@ -0,0 +1,237 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Log
|
||||
*
|
||||
* This is the primary logger for a Slim application. You may provide
|
||||
* a Log Writer in conjunction with this Log to write to various output
|
||||
* destinations (e.g. a file). This class provides this interface:
|
||||
*
|
||||
* debug( mixed $object )
|
||||
* info( mixed $object )
|
||||
* warn( mixed $object )
|
||||
* error( mixed $object )
|
||||
* fatal( mixed $object )
|
||||
*
|
||||
* This class assumes only that your Log Writer has a public `write()` method
|
||||
* that accepts any object as its one and only argument. The Log Writer
|
||||
* class may write or send its argument anywhere: a file, STDERR,
|
||||
* a remote web API, etc. The possibilities are endless.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Log
|
||||
{
|
||||
const FATAL = 0;
|
||||
const ERROR = 1;
|
||||
const WARN = 2;
|
||||
const INFO = 3;
|
||||
const DEBUG = 4;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected static $levels = array(
|
||||
self::FATAL => 'FATAL',
|
||||
self::ERROR => 'ERROR',
|
||||
self::WARN => 'WARN',
|
||||
self::INFO => 'INFO',
|
||||
self::DEBUG => 'DEBUG'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function __construct($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
$this->enabled = true;
|
||||
$this->level = self::DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function getEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable logging
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
if ($enabled) {
|
||||
$this->enabled = true;
|
||||
} else {
|
||||
$this->enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set level
|
||||
* @param int $level
|
||||
* @throws \InvalidArgumentException If invalid log level specified
|
||||
*/
|
||||
public function setLevel($level)
|
||||
{
|
||||
if (!isset(self::$levels[$level])) {
|
||||
throw new \InvalidArgumentException('Invalid log level');
|
||||
}
|
||||
$this->level = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get level
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set writer
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function setWriter($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get writer
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWriter()
|
||||
{
|
||||
return $this->writer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log debug message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function debug($object)
|
||||
{
|
||||
return $this->write($object, self::DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log info message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function info($object)
|
||||
{
|
||||
return $this->write($object, self::INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log warn message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function warn($object)
|
||||
{
|
||||
return $this->write($object, self::WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function error($object)
|
||||
{
|
||||
return $this->write($object, self::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log fatal message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
*/
|
||||
public function fatal($object)
|
||||
{
|
||||
return $this->write($object, self::FATAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log message
|
||||
* @param mixed The object to log
|
||||
* @param int The message level
|
||||
* @return int|false
|
||||
*/
|
||||
protected function write($object, $level)
|
||||
{
|
||||
if ($this->enabled && $this->writer && $level <= $this->level) {
|
||||
return $this->writer->write($object, $level);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
75
src/html/api/slim/LogWriter.php
Normal file
75
src/html/api/slim/LogWriter.php
Normal file
@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Log Writer
|
||||
*
|
||||
* This class is used by Slim_Log to write log messages to a valid, writable
|
||||
* resource handle (e.g. a file or STDERR).
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class LogWriter
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param resource $resource
|
||||
* @throws \InvalidArgumentException If invalid resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new \InvalidArgumentException('Cannot create LogWriter. Invalid resource handle.');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write message
|
||||
* @param mixed $message
|
||||
* @param int $level
|
||||
* @return int|false
|
||||
*/
|
||||
public function write($message, $level = null)
|
||||
{
|
||||
return fwrite($this->resource, (string) $message . PHP_EOL);
|
||||
}
|
||||
}
|
114
src/html/api/slim/Middleware.php
Normal file
114
src/html/api/slim/Middleware.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
abstract class Middleware
|
||||
{
|
||||
/**
|
||||
* @var \Slim Reference to the primary application instance
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* @var mixed Reference to the next downstream middleware
|
||||
*/
|
||||
protected $next;
|
||||
|
||||
/**
|
||||
* Set application
|
||||
*
|
||||
* This method injects the primary Slim application instance into
|
||||
* this middleware.
|
||||
*
|
||||
* @param \Slim $application
|
||||
*/
|
||||
final public function setApplication($application)
|
||||
{
|
||||
$this->app = $application;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get application
|
||||
*
|
||||
* This method retrieves the application previously injected
|
||||
* into this middleware.
|
||||
*
|
||||
* @return \Slim
|
||||
*/
|
||||
final public function getApplication()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set next middleware
|
||||
*
|
||||
* This method injects the next downstream middleware into
|
||||
* this middleware so that it may optionally be called
|
||||
* when appropriate.
|
||||
*
|
||||
* @param \Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function setNextMiddleware($nextMiddleware)
|
||||
{
|
||||
$this->next = $nextMiddleware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get next middleware
|
||||
*
|
||||
* This method retrieves the next downstream middleware
|
||||
* previously injected into this middleware.
|
||||
*
|
||||
* @return \Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function getNextMiddleware()
|
||||
{
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*
|
||||
* Perform actions specific to this middleware and optionally
|
||||
* call the next downstream middleware.
|
||||
*/
|
||||
abstract public function call();
|
||||
}
|
170
src/html/api/slim/Middleware/ContentTypes.php
Normal file
170
src/html/api/slim/Middleware/ContentTypes.php
Normal file
@ -0,0 +1,170 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Content Types
|
||||
*
|
||||
* This is middleware for a Slim application that intercepts
|
||||
* the HTTP request body and parses it into the appropriate
|
||||
* PHP data structure if possible; else it returns the HTTP
|
||||
* request body unchanged. This is particularly useful
|
||||
* for preparing the HTTP request body for an XML or JSON API.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class ContentTypes extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $contentTypes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->contentTypes = array_merge(array(
|
||||
'application/json' => array($this, 'parseJson'),
|
||||
'application/xml' => array($this, 'parseXml'),
|
||||
'text/xml' => array($this, 'parseXml'),
|
||||
'text/csv' => array($this, 'parseCsv')
|
||||
), $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$mediaType = $this->app->request()->getMediaType();
|
||||
if ($mediaType) {
|
||||
$env = $this->app->environment();
|
||||
$env['slim.input_original'] = $env['slim.input'];
|
||||
$env['slim.input'] = $this->parse($env['slim.input'], $mediaType);
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse input
|
||||
*
|
||||
* This method will attempt to parse the request body
|
||||
* based on its content type if available.
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $contentType
|
||||
* @return mixed
|
||||
*/
|
||||
protected function parse ($input, $contentType)
|
||||
{
|
||||
if (isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType])) {
|
||||
$result = call_user_func($this->contentTypes[$contentType], $input);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse JSON
|
||||
*
|
||||
* This method converts the raw JSON input
|
||||
* into an associative array.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array|string
|
||||
*/
|
||||
protected function parseJson($input)
|
||||
{
|
||||
if (function_exists('json_decode')) {
|
||||
$result = json_decode($input, true);
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse XML
|
||||
*
|
||||
* This method creates a SimpleXMLElement
|
||||
* based upon the XML input. If the SimpleXML
|
||||
* extension is not available, the raw input
|
||||
* will be returned unchanged.
|
||||
*
|
||||
* @param string $input
|
||||
* @return \SimpleXMLElement|string
|
||||
*/
|
||||
protected function parseXml($input)
|
||||
{
|
||||
if (class_exists('SimpleXMLElement')) {
|
||||
try {
|
||||
return new \SimpleXMLElement($input);
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse CSV
|
||||
*
|
||||
* This method parses CSV content into a numeric array
|
||||
* containing an array of data for each CSV line.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array
|
||||
*/
|
||||
protected function parseCsv($input)
|
||||
{
|
||||
$temp = fopen('php://memory', 'rw');
|
||||
fwrite($temp, $input);
|
||||
fseek($temp, 0);
|
||||
$res = array();
|
||||
while (($data = fgetcsv($temp)) !== false) {
|
||||
$res[] = $data;
|
||||
}
|
||||
fclose($temp);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
202
src/html/api/slim/Middleware/Flash.php
Normal file
202
src/html/api/slim/Middleware/Flash.php
Normal file
@ -0,0 +1,202 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Flash
|
||||
*
|
||||
* This is middleware for a Slim application that enables
|
||||
* Flash messaging between HTTP requests. This allows you
|
||||
* set Flash messages for the current request, for the next request,
|
||||
* or to retain messages from the previous request through to
|
||||
* the next request.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $messages;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param \Slim $app
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => 'slim.flash'), $settings);
|
||||
$this->messages = array(
|
||||
'prev' => array(), //flash messages from prev request (loaded when middleware called)
|
||||
'next' => array(), //flash messages for next request
|
||||
'now' => array() //flash messages for current request
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
//Read flash messaging from previous request if available
|
||||
$this->loadMessages();
|
||||
|
||||
//Prepare flash messaging for current request
|
||||
$env = $this->app->environment();
|
||||
$env['slim.flash'] = $this;
|
||||
$this->next->call();
|
||||
$this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Now
|
||||
*
|
||||
* Specify a flash message for a given key to be shown for the current request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function now($key, $value)
|
||||
{
|
||||
$this->messages['now'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set
|
||||
*
|
||||
* Specify a flash message for a given key to be shown for the next request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->messages['next'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep
|
||||
*
|
||||
* Retain flash messages from the previous request for the next request
|
||||
*/
|
||||
public function keep()
|
||||
{
|
||||
foreach ($this->messages['prev'] as $key => $val) {
|
||||
$this->messages['next'][$key] = $val;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$_SESSION[$this->settings['key']] = $this->messages['next'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load messages from previous request if available
|
||||
*/
|
||||
public function loadMessages()
|
||||
{
|
||||
if (isset($_SESSION[$this->settings['key']])) {
|
||||
$this->messages['prev'] = $_SESSION[$this->settings['key']];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of flash messages to be shown for the current request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages()
|
||||
{
|
||||
return array_merge($this->messages['prev'], $this->messages['now']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]) ? $messages[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->now($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->messages['prev'][$offset], $this->messages['now'][$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Aggregate: Get Iterator
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return new \ArrayIterator($messages);
|
||||
}
|
||||
}
|
96
src/html/api/slim/Middleware/MethodOverride.php
Normal file
96
src/html/api/slim/Middleware/MethodOverride.php
Normal file
@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* HTTP Method Override
|
||||
*
|
||||
* This is middleware for a Slim application that allows traditional
|
||||
* desktop browsers to submit psuedo PUT and DELETE requests by relying
|
||||
* on a pre-determined request parameter. Without this middleware,
|
||||
* desktop browsers are only able to submit GET and POST requests.
|
||||
*
|
||||
* This middleware is included automatically!
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class MethodOverride extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param \Slim $app
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => '_METHOD'), $settings);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*
|
||||
* Implements Slim middleware interface. This method is invoked and passed
|
||||
* an array of environment variables. This middleware inspects the environment
|
||||
* variables for the HTTP method override parameter; if found, this middleware
|
||||
* modifies the environment settings so downstream middleware and/or the Slim
|
||||
* application will treat the request with the desired HTTP method.
|
||||
*
|
||||
* @param array $env
|
||||
* @return array[status, header, body]
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$env = $this->app->environment();
|
||||
if (isset($env['X_HTTP_METHOD_OVERRIDE'])) {
|
||||
// Header commonly used by Backbone.js and others
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($env['X_HTTP_METHOD_OVERRIDE']);
|
||||
} elseif (isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST') {
|
||||
// HTML Form Override
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$method = $req->post($this->settings['key']);
|
||||
if ($method) {
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($method);
|
||||
}
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
}
|
114
src/html/api/slim/Middleware/PrettyExceptions.php
Normal file
114
src/html/api/slim/Middleware/PrettyExceptions.php
Normal file
@ -0,0 +1,114 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Pretty Exceptions
|
||||
*
|
||||
* This middleware catches any Exception thrown by the surrounded
|
||||
* application and displays a developer-friendly diagnostic screen.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class PrettyExceptions extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
try {
|
||||
$this->next->call();
|
||||
} catch (\Exception $e) {
|
||||
$env = $this->app->environment();
|
||||
$env['slim.log']->error($e);
|
||||
$this->app->contentType('text/html');
|
||||
$this->app->response()->status(500);
|
||||
$this->app->response()->body($this->renderBody($env, $e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render response body
|
||||
* @param array $env
|
||||
* @param \Exception $exception
|
||||
* @return string
|
||||
*/
|
||||
protected function renderBody(&$env, $exception)
|
||||
{
|
||||
$title = 'Slim Application Error';
|
||||
$code = $exception->getCode();
|
||||
$message = $exception->getMessage();
|
||||
$file = $exception->getFile();
|
||||
$line = $exception->getLine();
|
||||
$trace = $exception->getTraceAsString();
|
||||
$html = sprintf('<h1>%s</h1>', $title);
|
||||
$html .= '<p>The application could not run because of the following error:</p>';
|
||||
$html .= '<h2>Details</h2>';
|
||||
$html .= sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));
|
||||
if ($code) {
|
||||
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
|
||||
}
|
||||
if ($message) {
|
||||
$html .= sprintf('<div><strong>Message:</strong> %s</div>', $message);
|
||||
}
|
||||
if ($file) {
|
||||
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
|
||||
}
|
||||
if ($line) {
|
||||
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
|
||||
}
|
||||
if ($trace) {
|
||||
$html .= '<h2>Trace</h2>';
|
||||
$html .= sprintf('<pre>%s</pre>', $trace);
|
||||
}
|
||||
|
||||
return sprintf("<html><head><title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:65px;}</style></head><body>%s</body></html>", $title, $html);
|
||||
}
|
||||
}
|
203
src/html/api/slim/Middleware/SessionCookie.php
Normal file
203
src/html/api/slim/Middleware/SessionCookie.php
Normal file
@ -0,0 +1,203 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Session Cookie
|
||||
*
|
||||
* This class provides an HTTP cookie storage mechanism
|
||||
* for session data. This class avoids using a PHP session
|
||||
* and instead serializes/unserializes the $_SESSION global
|
||||
* variable to/from an HTTP cookie.
|
||||
*
|
||||
* If a secret key is provided with this middleware, the HTTP
|
||||
* cookie will be checked for integrity to ensure the client-side
|
||||
* cookie is not changed.
|
||||
*
|
||||
* You should NEVER store sensitive data in a client-side cookie
|
||||
* in any format, encrypted or not. If you need to store sensitive
|
||||
* user information in a session, you should rely on PHP's native
|
||||
* session implementation, or use other middleware to store
|
||||
* session data in a database or alternative server-side cache.
|
||||
*
|
||||
* Because this class stores serialized session data in an HTTP cookie,
|
||||
* you are inherently limtied to 4 Kb. If you attempt to store
|
||||
* more than this amount, serialization will fail.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class SessionCookie extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $settings;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array(
|
||||
'expires' => '20 minutes',
|
||||
'path' => '/',
|
||||
'domain' => null,
|
||||
'secure' => false,
|
||||
'httponly' => false,
|
||||
'name' => 'slim_session',
|
||||
'secret' => 'CHANGE_ME',
|
||||
'cipher' => MCRYPT_RIJNDAEL_256,
|
||||
'cipher_mode' => MCRYPT_MODE_CBC
|
||||
), $settings);
|
||||
if (is_string($this->settings['expires'])) {
|
||||
$this->settings['expires'] = strtotime($this->settings['expires']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Session
|
||||
*
|
||||
* We must start a native PHP session to initialize the $_SESSION superglobal.
|
||||
* However, we won't be using the native session store for persistence, so we
|
||||
* disable the session cookie and cache limiter. We also set the session
|
||||
* handler to this class instance to avoid PHP's native session file locking.
|
||||
*/
|
||||
ini_set('session.use_cookies', 0);
|
||||
session_cache_limiter(false);
|
||||
session_set_save_handler(
|
||||
array($this, 'open'),
|
||||
array($this, 'close'),
|
||||
array($this, 'read'),
|
||||
array($this, 'write'),
|
||||
array($this, 'destroy'),
|
||||
array($this, 'gc')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
*/
|
||||
public function call()
|
||||
{
|
||||
$this->loadSession();
|
||||
$this->next->call();
|
||||
$this->saveSession();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load session
|
||||
* @param array $env
|
||||
*/
|
||||
protected function loadSession()
|
||||
{
|
||||
if (session_id() === '') {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$value = \Slim\Http\Util::decodeSecureCookie(
|
||||
$this->app->request()->cookies($this->settings['name']),
|
||||
$this->settings['secret'],
|
||||
$this->settings['cipher'],
|
||||
$this->settings['cipher_mode']
|
||||
);
|
||||
if ($value) {
|
||||
$_SESSION = unserialize($value);
|
||||
} else {
|
||||
$_SESSION = array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Save session
|
||||
*/
|
||||
protected function saveSession()
|
||||
{
|
||||
$value = \Slim\Http\Util::encodeSecureCookie(
|
||||
serialize($_SESSION),
|
||||
$this->settings['expires'],
|
||||
$this->settings['secret'],
|
||||
$this->settings['cipher'],
|
||||
$this->settings['cipher_mode']
|
||||
);
|
||||
if (strlen($value) > 4096) {
|
||||
$this->app->getLog()->error('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.');
|
||||
} else {
|
||||
$this->app->response()->setCookie($this->settings['name'], array(
|
||||
'value' => $value,
|
||||
'domain' => $this->settings['domain'],
|
||||
'path' => $this->settings['path'],
|
||||
'expires' => $this->settings['expires'],
|
||||
'secure' => $this->settings['secure'],
|
||||
'httponly' => $this->settings['httponly']
|
||||
));
|
||||
}
|
||||
session_destroy();
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Session Handler
|
||||
*******************************************************************************/
|
||||
|
||||
public function open($savePath, $sessionName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function read($id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function write($id, $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function gc($maxlifetime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
416
src/html/api/slim/Route.php
Normal file
416
src/html/api/slim/Route.php
Normal file
@ -0,0 +1,416 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Route
|
||||
* @package Slim
|
||||
* @author Josh Lockhart, Thomas Bley
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
/**
|
||||
* @var string The route pattern (e.g. "/books/:id")
|
||||
*/
|
||||
protected $pattern;
|
||||
|
||||
/**
|
||||
* @var mixed The route callable
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
/**
|
||||
* @var array Conditions for this route's URL parameters
|
||||
*/
|
||||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* @var array Default conditions applied to all route instances
|
||||
*/
|
||||
protected static $defaultConditions = array();
|
||||
|
||||
/**
|
||||
* @var string The name of this route (optional)
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var array Key-value array of URL parameters
|
||||
*/
|
||||
protected $params = array();
|
||||
|
||||
/**
|
||||
* @var array value array of URL parameter names
|
||||
*/
|
||||
protected $paramNames = array();
|
||||
|
||||
/**
|
||||
* @var array key array of URL parameter names with + at the end
|
||||
*/
|
||||
protected $paramNamesPath = array();
|
||||
|
||||
/**
|
||||
* @var array HTTP methods supported by this Route
|
||||
*/
|
||||
protected $methods = array();
|
||||
|
||||
/**
|
||||
* @var array[Callable] Middleware to be run before only this route instance
|
||||
*/
|
||||
protected $middleware = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $pattern The URL pattern (e.g. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
*/
|
||||
public function __construct($pattern, $callable)
|
||||
{
|
||||
$this->setPattern($pattern);
|
||||
$this->setCallable($callable);
|
||||
$this->setConditions(self::getDefaultConditions());
|
||||
}
|
||||
|
||||
/**
|
||||
* Set default route conditions for all instances
|
||||
* @param array $defaultConditions
|
||||
*/
|
||||
public static function setDefaultConditions(array $defaultConditions)
|
||||
{
|
||||
self::$defaultConditions = $defaultConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get default route conditions for all instances
|
||||
* @return array
|
||||
*/
|
||||
public static function getDefaultConditions()
|
||||
{
|
||||
return self::$defaultConditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route pattern
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route pattern
|
||||
* @param string $pattern
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route callable
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallable()
|
||||
{
|
||||
return $this->callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route callable
|
||||
* @param mixed $callable
|
||||
* @throws \InvalidArgumentException If argument is not callable
|
||||
*/
|
||||
public function setCallable($callable)
|
||||
{
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException('Route callable must be callable');
|
||||
}
|
||||
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route conditions
|
||||
* @return array
|
||||
*/
|
||||
public function getConditions()
|
||||
{
|
||||
return $this->conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route conditions
|
||||
* @param array $conditions
|
||||
*/
|
||||
public function setConditions(array $conditions)
|
||||
{
|
||||
$this->conditions = $conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route name
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = (string) $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route parameters
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route parameters
|
||||
* @param array $params
|
||||
*/
|
||||
public function setParams($params)
|
||||
{
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route parameter value
|
||||
* @param string $index Name of URL parameter
|
||||
* @return string
|
||||
* @throws \InvalidArgumentException If route parameter does not exist at index
|
||||
*/
|
||||
public function getParam($index)
|
||||
{
|
||||
if (!isset($this->params[$index])) {
|
||||
throw new \InvalidArgumentException('Route parameter does not exist at specified index');
|
||||
}
|
||||
|
||||
return $this->params[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route parameter value
|
||||
* @param string $index Name of URL parameter
|
||||
* @param mixed $value The new parameter value
|
||||
* @throws \InvalidArgumentException If route parameter does not exist at index
|
||||
*/
|
||||
public function setParam($index, $value)
|
||||
{
|
||||
if (!isset($this->params[$index])) {
|
||||
throw new \InvalidArgumentException('Route parameter does not exist at specified index');
|
||||
}
|
||||
$this->params[$index] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add supported HTTP method(s)
|
||||
*/
|
||||
public function setHttpMethods()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->methods = $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get supported HTTP methods
|
||||
* @return array
|
||||
*/
|
||||
public function getHttpMethods()
|
||||
{
|
||||
return $this->methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append supported HTTP methods
|
||||
*/
|
||||
public function appendHttpMethods()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->methods = array_merge($this->methods, $args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Append supported HTTP methods (alias for Route::appendHttpMethods)
|
||||
* @return \Slim\Route
|
||||
*/
|
||||
public function via()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->methods = array_merge($this->methods, $args);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detect support for an HTTP method
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsHttpMethod($method)
|
||||
{
|
||||
return in_array($method, $this->methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get middleware
|
||||
* @return array[Callable]
|
||||
*/
|
||||
public function getMiddleware()
|
||||
{
|
||||
return $this->middleware;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set middleware
|
||||
*
|
||||
* This method allows middleware to be assigned to a specific Route.
|
||||
* If the method argument `is_callable` (including callable arrays!),
|
||||
* we directly append the argument to `$this->middleware`. Else, we
|
||||
* assume the argument is an array of callables and merge the array
|
||||
* with `$this->middleware`. Each middleware is checked for is_callable()
|
||||
* and an InvalidArgumentException is thrown immediately if it isn't.
|
||||
*
|
||||
* @param Callable|array[Callable]
|
||||
* @return \Slim\Route
|
||||
* @throws \InvalidArgumentException If argument is not callable or not an array of callables.
|
||||
*/
|
||||
public function setMiddleware($middleware)
|
||||
{
|
||||
if (is_callable($middleware)) {
|
||||
$this->middleware[] = $middleware;
|
||||
} elseif (is_array($middleware)) {
|
||||
foreach($middleware as $callable) {
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException('All Route middleware must be callable');
|
||||
}
|
||||
}
|
||||
$this->middleware = array_merge($this->middleware, $middleware);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Route middleware must be callable or an array of callables');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches URI?
|
||||
*
|
||||
* Parse this route's pattern, and then compare it to an HTTP resource URI
|
||||
* This method was modeled after the techniques demonstrated by Dan Sosedoff at:
|
||||
*
|
||||
* http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/
|
||||
*
|
||||
* @param string $resourceUri A Request URI
|
||||
* @return bool
|
||||
*/
|
||||
public function matches($resourceUri)
|
||||
{
|
||||
//Convert URL params into regex patterns, construct a regex for this route, init params
|
||||
$patternAsRegex = preg_replace_callback('#:([\w]+)\+?#', array($this, 'matchesCallback'),
|
||||
str_replace(')', ')?', (string) $this->pattern));
|
||||
if (substr($this->pattern, -1) === '/') {
|
||||
$patternAsRegex .= '?';
|
||||
}
|
||||
|
||||
//Cache URL params' names and values if this route matches the current HTTP request
|
||||
if (!preg_match('#^' . $patternAsRegex . '$#', $resourceUri, $paramValues)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->paramNames as $name) {
|
||||
if (isset($paramValues[$name])) {
|
||||
if (isset($this->paramNamesPath[ $name ])) {
|
||||
$this->params[$name] = explode('/', urldecode($paramValues[$name]));
|
||||
} else {
|
||||
$this->params[$name] = urldecode($paramValues[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a URL parameter (e.g. ":id", ":id+") into a regular expression
|
||||
* @param array URL parameters
|
||||
* @return string Regular expression for URL parameter
|
||||
*/
|
||||
protected function matchesCallback($m)
|
||||
{
|
||||
$this->paramNames[] = $m[1];
|
||||
if (isset($this->conditions[ $m[1] ])) {
|
||||
return '(?P<' . $m[1] . '>' . $this->conditions[ $m[1] ] . ')';
|
||||
}
|
||||
if (substr($m[0], -1) === '+') {
|
||||
$this->paramNamesPath[ $m[1] ] = 1;
|
||||
|
||||
return '(?P<' . $m[1] . '>.+)';
|
||||
}
|
||||
|
||||
return '(?P<' . $m[1] . '>[^/]+)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
* @param string $name The name of the route
|
||||
* @return \Slim\Route
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
$this->setName($name);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge route conditions
|
||||
* @param array $conditions Key-value array of URL parameter conditions
|
||||
* @return \Slim\Route
|
||||
*/
|
||||
public function conditions(array $conditions)
|
||||
{
|
||||
$this->conditions = array_merge($this->conditions, $conditions);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
235
src/html/api/slim/Router.php
Normal file
235
src/html/api/slim/Router.php
Normal file
@ -0,0 +1,235 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Router
|
||||
*
|
||||
* This class organizes, iterates, and dispatches \Slim\Route objects.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Router
|
||||
{
|
||||
/**
|
||||
* @var Route The current route (most recently dispatched)
|
||||
*/
|
||||
protected $currentRoute;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of all route objects
|
||||
*/
|
||||
protected $routes;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of named route objects, keyed by route name (lazy-loaded)
|
||||
*/
|
||||
protected $namedRoutes;
|
||||
|
||||
/**
|
||||
* @var array Array of route objects that match the request URI (lazy-loaded)
|
||||
*/
|
||||
protected $matchedRoutes;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->routes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Route object or the first matched one if matching has been performed
|
||||
* @return \Slim\Route|null
|
||||
*/
|
||||
public function getCurrentRoute()
|
||||
{
|
||||
if ($this->currentRoute !== null) {
|
||||
return $this->currentRoute;
|
||||
}
|
||||
|
||||
if (is_array($this->matchedRoutes) && count($this->matchedRoutes) > 0) {
|
||||
return $this->matchedRoutes[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return route objects that match the given HTTP method and URI
|
||||
* @param string $httpMethod The HTTP method to match against
|
||||
* @param string $resourceUri The resource URI to match against
|
||||
* @param bool $reload Should matching routes be re-parsed?
|
||||
* @return array[\Slim\Route]
|
||||
*/
|
||||
public function getMatchedRoutes($httpMethod, $resourceUri, $reload = false)
|
||||
{
|
||||
if ($reload || is_null($this->matchedRoutes)) {
|
||||
$this->matchedRoutes = array();
|
||||
foreach ($this->routes as $route) {
|
||||
if (!$route->supportsHttpMethod($httpMethod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($route->matches($resourceUri)) {
|
||||
$this->matchedRoutes[] = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->matchedRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a route object to a callback function
|
||||
* @param string $pattern The URL pattern (ie. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return \Slim\Route
|
||||
*/
|
||||
public function map($pattern, $callable)
|
||||
{
|
||||
$route = new \Slim\Route($pattern, $callable);
|
||||
$this->routes[] = $route;
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL for named route
|
||||
* @param string $name The name of the route
|
||||
* @param array Associative array of URL parameter names and replacement values
|
||||
* @throws RuntimeException If named route not found
|
||||
* @return string The URL for the given route populated with provided replacement values
|
||||
*/
|
||||
public function urlFor($name, $params = array())
|
||||
{
|
||||
if (!$this->hasNamedRoute($name)) {
|
||||
throw new \RuntimeException('Named route not found for name: ' . $name);
|
||||
}
|
||||
$search = array();
|
||||
foreach (array_keys($params) as $key) {
|
||||
$search[] = '#:' . $key . '\+?(?!\w)#';
|
||||
}
|
||||
$pattern = preg_replace($search, $params, $this->getNamedRoute($name)->getPattern());
|
||||
|
||||
//Remove remnants of unpopulated, trailing optional pattern segments
|
||||
return preg_replace('#\(/?:.+\)|\(|\)#', '', $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch route
|
||||
*
|
||||
* This method invokes the route object's callable. If middleware is
|
||||
* registered for the route, each callable middleware is invoked in
|
||||
* the order specified.
|
||||
*
|
||||
* @param \Slim\Route $route The route object
|
||||
* @return bool Was route callable invoked successfully?
|
||||
*/
|
||||
public function dispatch(\Slim\Route $route)
|
||||
{
|
||||
$this->currentRoute = $route;
|
||||
|
||||
//Invoke middleware
|
||||
foreach ($route->getMiddleware() as $mw) {
|
||||
call_user_func_array($mw, array($route));
|
||||
}
|
||||
|
||||
//Invoke callable
|
||||
call_user_func_array($route->getCallable(), array_values($route->getParams()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add named route
|
||||
* @param string $name The route name
|
||||
* @param \Slim\Route $route The route object
|
||||
* @throws \RuntimeException If a named route already exists with the same name
|
||||
*/
|
||||
public function addNamedRoute($name, \Slim\Route $route)
|
||||
{
|
||||
if ($this->hasNamedRoute($name)) {
|
||||
throw new \RuntimeException('Named route already exists with name: ' . $name);
|
||||
}
|
||||
$this->namedRoutes[(string) $name] = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has named route
|
||||
* @param string $name The route name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNamedRoute($name)
|
||||
{
|
||||
$this->getNamedRoutes();
|
||||
|
||||
return isset($this->namedRoutes[(string) $name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get named route
|
||||
* @param string $name
|
||||
* @return \Slim\Route|null
|
||||
*/
|
||||
public function getNamedRoute($name)
|
||||
{
|
||||
$this->getNamedRoutes();
|
||||
if ($this->hasNamedRoute($name)) {
|
||||
return $this->namedRoutes[(string) $name];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get named routes
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getNamedRoutes()
|
||||
{
|
||||
if (is_null($this->namedRoutes)) {
|
||||
$this->namedRoutes = array();
|
||||
foreach ($this->routes as $route) {
|
||||
if ($route->getName() !== null) {
|
||||
$this->addNamedRoute($route->getName(), $route);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new \ArrayIterator($this->namedRoutes);
|
||||
}
|
||||
}
|
1309
src/html/api/slim/Slim.php
Normal file
1309
src/html/api/slim/Slim.php
Normal file
File diff suppressed because it is too large
Load Diff
216
src/html/api/slim/View.php
Normal file
216
src/html/api/slim/View.php
Normal file
@ -0,0 +1,216 @@
|
||||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* View
|
||||
*
|
||||
* The view is responsible for rendering a template. The view
|
||||
* should subclass \Slim\View and implement this interface:
|
||||
*
|
||||
* public render(string $template);
|
||||
*
|
||||
* This method should render the specified template and return
|
||||
* the resultant string.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* @var string Absolute or relative filesystem path to a specific template
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* This variable will be removed in the near future
|
||||
*/
|
||||
protected $templatePath = '';
|
||||
|
||||
/**
|
||||
* @var array Associative array of template variables
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @var string Absolute or relative path to the application's templates directory
|
||||
*/
|
||||
protected $templatesDirectory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This is empty but may be implemented in a subclass
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data
|
||||
* @param string|null $key
|
||||
* @return mixed If key is null, array of template data;
|
||||
* If key exists, value of datum with key;
|
||||
* If key does not exist, null;
|
||||
*/
|
||||
public function getData($key = null)
|
||||
{
|
||||
if (!is_null($key)) {
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
} else {
|
||||
return $this->data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set data
|
||||
*
|
||||
* If two arguments:
|
||||
* A single datum with key is assigned value;
|
||||
*
|
||||
* $view->setData('color', 'red');
|
||||
*
|
||||
* If one argument:
|
||||
* Replace all data with provided array keys and values;
|
||||
*
|
||||
* $view->setData(array('color' => 'red', 'number' => 1));
|
||||
*
|
||||
* @param mixed
|
||||
* @param mixed
|
||||
* @throws InvalidArgumentException If incorrect method signature
|
||||
*/
|
||||
public function setData()
|
||||
{
|
||||
$args = func_get_args();
|
||||
if (count($args) === 1 && is_array($args[0])) {
|
||||
$this->data = $args[0];
|
||||
} elseif (count($args) === 2) {
|
||||
$this->data[(string) $args[0]] = $args[1];
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append new data to existing template data
|
||||
* @param array
|
||||
* @throws InvalidArgumentException If not given an array argument
|
||||
*/
|
||||
public function appendData($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
|
||||
}
|
||||
$this->data = array_merge($this->data, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates directory
|
||||
* @return string|null Path to templates directory without trailing slash;
|
||||
* Returns null if templates directory not set;
|
||||
*/
|
||||
public function getTemplatesDirectory()
|
||||
{
|
||||
return $this->templatesDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set templates directory
|
||||
* @param string $dir
|
||||
*/
|
||||
public function setTemplatesDirectory($dir)
|
||||
{
|
||||
$this->templatesDirectory = rtrim($dir, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set template
|
||||
* @param string $template
|
||||
* @throws RuntimeException If template file does not exist
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* This method will be removed in the near future.
|
||||
*/
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
|
||||
if (!file_exists($this->templatePath)) {
|
||||
throw new \RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display template
|
||||
*
|
||||
* This method echoes the rendered template to the current output buffer
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directoy
|
||||
*/
|
||||
public function display($template)
|
||||
{
|
||||
echo $this->fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch rendered template
|
||||
*
|
||||
* This method returns the rendered template
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directory
|
||||
* @return string
|
||||
*/
|
||||
public function fetch($template)
|
||||
{
|
||||
return $this->render($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directory
|
||||
* @return string
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* Use `\Slim\View::fetch` to return a rendered template instead of `\Slim\View::render`.
|
||||
*/
|
||||
public function render($template)
|
||||
{
|
||||
$this->setTemplate($template);
|
||||
extract($this->data);
|
||||
ob_start();
|
||||
require $this->templatePath;
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
}
|
@ -29,7 +29,7 @@ function month() {
|
||||
// Util function to show a message in message placeholder.
|
||||
function message(alertType, title, message) {
|
||||
$(".alert").alert('close');
|
||||
$("#message-placeholder").append('<div class="alert alert-' + alertType + '"><button type="button" class="close" data-dismiss="alert">×</button><h4>' + title + '</h4><strong>' + message + '</strong></div>');
|
||||
$("#message-placeholder").append('<div class="alert alert-' + alertType + '"><button type="button" class="close" data-dismiss="alert">×</button><h4>' + title + '</h4>' + message + '</div>');
|
||||
}
|
||||
|
||||
// The ListViewModel used to instanciate viewmodel.
|
||||
@ -140,20 +140,20 @@ var ListViewModel = function() {
|
||||
|
||||
// Function to load entries from server for a specific account and month.
|
||||
self.loadEntries = function(account, month) {
|
||||
$.post("api/entry.php", {action: "get_entries", account: account.id(), year: month.year(), month: month.month()}, function(data) {
|
||||
$.get("api/entries/" + account.id() + "/" + month.year() + "/" + month.month()).success(function(data) {
|
||||
// Clean up selected entry.
|
||||
self.selectedItem(null);
|
||||
|
||||
// Update entries
|
||||
self.entries(ko.utils.arrayMap(data, ko.mapping.fromJS));
|
||||
self.entries(ko.utils.arrayMap($.parseJSON(data), ko.mapping.fromJS));
|
||||
});
|
||||
};
|
||||
|
||||
// Function to load accounts
|
||||
self.loadAccounts = function() {
|
||||
$.post("api/entry.php", {action: "get_accounts"}).success(function (data) {
|
||||
$.get("api/accounts").success(function (data) {
|
||||
// Update accounts
|
||||
self.accounts(ko.utils.arrayMap(data, ko.mapping.fromJS));
|
||||
self.accounts(ko.utils.arrayMap($.parseJSON(data), ko.mapping.fromJS));
|
||||
|
||||
// Reset selected account to the new instance corresponding to the old one.
|
||||
if(self.account()) {
|
||||
@ -182,9 +182,9 @@ var ListViewModel = function() {
|
||||
|
||||
// Function to load months
|
||||
self.loadMonths = function(account){
|
||||
$.post("api/entry.php", {action: "get_months", account: account.id()}).success(function (data) {
|
||||
$.get("api/accounts/" + account.id() + "/months").success(function (data) {
|
||||
// Update months
|
||||
self.months(ko.utils.arrayMap(data, ko.mapping.fromJS));
|
||||
self.months(ko.utils.arrayMap($.parseJSON(data), ko.mapping.fromJS));
|
||||
|
||||
// Reset selected month to the new instance corresponding to the old one
|
||||
if(self.month()) {
|
||||
@ -280,12 +280,22 @@ var ListViewModel = function() {
|
||||
|
||||
// Function to save the current selected entry.
|
||||
self.save = function() {
|
||||
// Transform selected entry to a javascript object.
|
||||
var item = ko.toJS(self.selectedItem());
|
||||
var item = self.selectedItem();
|
||||
|
||||
// Ajax call to save the entry.
|
||||
$.post("api/entry.php", {action: "save_entry", entry:item}).success(function(data) {
|
||||
message("success", "Save", data.message);
|
||||
var type;
|
||||
var url = "api/entries/";
|
||||
|
||||
if(item.id()) {
|
||||
type = "PUT";
|
||||
url += "save/" + item.id();
|
||||
} else {
|
||||
type = "POST";
|
||||
url += "add";
|
||||
}
|
||||
|
||||
$.ajax({url: url, type: type, data:ko.toJSON(item)}).success(function(data) {
|
||||
message("success", "Save", data);
|
||||
|
||||
self.selectedItem(null);
|
||||
self.savedItem = null;
|
||||
@ -314,7 +324,7 @@ var ListViewModel = function() {
|
||||
self.confirmRemove = function() {
|
||||
var item = self.removedItem;
|
||||
|
||||
$.post("api/entry.php", {action: "remove_entry", entry:item}).success(function (result) {
|
||||
$.ajax("api/entries/" + ko.utils.unwrapObservable(item.id), {type: "DELETE"}).success(function (result) {
|
||||
// Reload accounts to update solds.
|
||||
self.loadAccounts();
|
||||
}).complete(function (result) {
|
||||
@ -500,7 +510,7 @@ ko.bindingHandlers.pieChart = {
|
||||
|
||||
// Default AJAX error handler.
|
||||
$(document).ajaxError(function(event, xhr, settings) {
|
||||
message("error", "Error.", xhr.statusText);
|
||||
message("error", xhr.statusText, xhr.responseText);
|
||||
});
|
||||
|
||||
// Resize callback.
|
||||
|
Loading…
Reference in New Issue
Block a user