Added function to generate the passcode
This commit is contained in:
parent
6f14b71386
commit
6f03be8cf6
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,7 +29,6 @@
|
|||
* 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
|
||||
|
@ -41,10 +39,7 @@ namespace Slim\Exception;
|
|||
* HTTP 404 Not Found response will be sent to the client.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Pass extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
class Slim_Exception_Pass extends Exception {}
|
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,7 +29,6 @@
|
|||
* 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;
|
||||
|
||||
/**
|
||||
* Request Slash Exception
|
||||
|
@ -42,10 +40,7 @@ namespace Slim\Exception;
|
|||
* to the same resource URI with a trailing slash.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class RequestSlash extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
class Slim_Exception_RequestSlash extends Exception {}
|
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,7 +29,6 @@
|
|||
* 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
|
||||
|
@ -39,10 +37,7 @@ namespace Slim\Exception;
|
|||
* processing and return control flow to the outer PHP script.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Stop extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
class Slim_Exception_Stop extends Exception {}
|
|
@ -0,0 +1,222 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.5.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cookie
|
||||
*
|
||||
* Object-oriented representation of a Cookie to be sent in an HTTP response
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Slim_Http_Cookie {
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $value;
|
||||
|
||||
/**
|
||||
* @var int UNIX timestamp
|
||||
*/
|
||||
protected $expires;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $path;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $domain;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $secure;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
protected $httponly;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $name The cookie name
|
||||
* @param string $value The cookie value
|
||||
* @param mixed $time The duration of the cookie;
|
||||
* If integer, should be a UNIX timestamp;
|
||||
* If string, converted to UNIX timestamp with `strtotime`;
|
||||
* @param string $path The path on the server in which the cookie will be available on
|
||||
* @param string $domain The domain that the cookie is available to
|
||||
* @param bool $secure Indicates that the cookie should only be transmitted over a secure
|
||||
* HTTPS connection from the client
|
||||
* @param bool $httponly When TRUE the cookie will be made accessible only through the HTTP protocol
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $name, $value = null, $expires = 0, $path = null, $domain = null, $secure = false, $httponly = false ) {
|
||||
$this->setName($name);
|
||||
$this->setValue($value);
|
||||
$this->setExpires($expires);
|
||||
$this->setPath($path);
|
||||
$this->setDomain($domain);
|
||||
$this->setSecure($secure);
|
||||
$this->setHttpOnly($httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie name
|
||||
* @return string
|
||||
*/
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie name
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function setName( $name ) {
|
||||
$this->name = (string)$name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie value
|
||||
* @return string
|
||||
*/
|
||||
public function getValue() {
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie value
|
||||
* @param string $value
|
||||
* @return void
|
||||
*/
|
||||
public function setValue( $value ) {
|
||||
$this->value = (string)$value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie expiration time
|
||||
* @return int UNIX timestamp
|
||||
*/
|
||||
public function getExpires() {
|
||||
return $this->expires;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie expiration time
|
||||
* @param string|int Cookie expiration time
|
||||
* @return void
|
||||
*/
|
||||
public function setExpires( $time ) {
|
||||
$this->expires = is_string($time) ? strtotime($time) : (int)$time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie path
|
||||
* @return string
|
||||
*/
|
||||
public function getPath() {
|
||||
return $this->path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie path
|
||||
* @param string $path
|
||||
* @return void
|
||||
*/
|
||||
public function setPath( $path ) {
|
||||
$this->path = (string)$path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie domain
|
||||
* @return string
|
||||
*/
|
||||
public function getDomain() {
|
||||
return $this->domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set cookie domain
|
||||
* @param string $domain
|
||||
* @return void
|
||||
*/
|
||||
public function setDomain( $domain ) {
|
||||
$this->domain = (string)$domain;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is cookie sent only if SSL/HTTPS is used?
|
||||
* @return bool
|
||||
*/
|
||||
public function getSecure() {
|
||||
return $this->secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether cookie is sent only if SSL/HTTPS is used
|
||||
* @param bool $secure
|
||||
* @return void
|
||||
*/
|
||||
public function setSecure( $secure ) {
|
||||
$this->secure = (bool)$secure;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is cookie sent with HTTP protocol only?
|
||||
* @return bool
|
||||
*/
|
||||
public function getHttpOnly() {
|
||||
return $this->httponly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether cookie is sent with HTTP protocol only
|
||||
* @param bool $httponly
|
||||
* @return void
|
||||
*/
|
||||
public function setHttpOnly( $httponly ) {
|
||||
$this->httponly = (bool)$httponly;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,401 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.5.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Cooke Jar
|
||||
*
|
||||
* Used to manage signed, encrypted Cookies. Provides:
|
||||
*
|
||||
* - Cookie integrity and authenticity with HMAC
|
||||
* - Confidentiality with symmetric encryption
|
||||
* - Protection from replay attack if using SSL or TLS
|
||||
* - Protection from interception if using SSL or TLS
|
||||
*
|
||||
* This code was originally called "BigOrNot_CookieManager" and written by
|
||||
* Matthieu Huguet released under "CopyLeft" license. I have cleaned up the
|
||||
* code formatting to conform with Slim Framework contributor guidelines and
|
||||
* added additional code where necessary to play nice with Slim Cookie objects.
|
||||
*
|
||||
* Requirements:
|
||||
*
|
||||
* - libmcrypt > 2.4.x
|
||||
*
|
||||
* @author Matthies Huguet <http://bigornot.blogspot.com/2008/06/security-cookies-and-rest.html>
|
||||
*/
|
||||
class Slim_Http_CookieJar {
|
||||
|
||||
/**
|
||||
* @var string Server secret key
|
||||
*/
|
||||
protected $_secret = '';
|
||||
|
||||
/**
|
||||
* @var int Cryptographic algorithm used to encrypt cookies data
|
||||
*/
|
||||
protected $_algorithm = MCRYPT_RIJNDAEL_256;
|
||||
|
||||
/**
|
||||
* @var int Cryptographic mode (CBC, CFB ...)
|
||||
*/
|
||||
protected $_mode = MCRYPT_MODE_CBC;
|
||||
|
||||
/**
|
||||
* @var resource mcrypt module resource
|
||||
*/
|
||||
protected $_cryptModule = null;
|
||||
|
||||
/**
|
||||
* @var bool Enable high confidentiality for cookie value (symmetric encryption)
|
||||
*/
|
||||
protected $_highConfidentiality = true;
|
||||
|
||||
/**
|
||||
* @var bool Enable SSL support
|
||||
*/
|
||||
protected $_ssl = false;
|
||||
|
||||
/**
|
||||
* @var array[Cookie] Cookie objects
|
||||
*/
|
||||
protected $_cookies = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Initialize cookie manager and mcrypt module.
|
||||
*
|
||||
* @param string $secret Server's secret key
|
||||
* @param array $config
|
||||
* @throws Exception If secret key is empty
|
||||
* @throws Exception If unable to open mcypt module
|
||||
*/
|
||||
public function __construct( $secret, $config = null ) {
|
||||
if ( empty($secret) ) {
|
||||
throw new Exception('You must provide a secret key');
|
||||
}
|
||||
$this->_secret = $secret;
|
||||
if ( $config !== null && !is_array($config) ) {
|
||||
throw new Exception('Config must be an array');
|
||||
}
|
||||
if ( is_array($config) ) {
|
||||
if ( isset($config['high_confidentiality']) ) {
|
||||
$this->_highConfidentiality = $config['high_confidentiality'];
|
||||
}
|
||||
if ( isset($config['mcrypt_algorithm']) ) {
|
||||
$this->_algorithm = $config['mcrypt_algorithm'];
|
||||
}
|
||||
if ( isset($config['mcrypt_mode']) ) {
|
||||
$this->_mode = $config['mcrypt_mode'];
|
||||
}
|
||||
if ( isset($config['enable_ssl']) ) {
|
||||
$this->_ssl = $config['enable_ssl'];
|
||||
}
|
||||
}
|
||||
if ( extension_loaded('mcrypt') ) {
|
||||
$this->_cryptModule = mcrypt_module_open($this->_algorithm, '', $this->_mode, '');
|
||||
if ( $this->_cryptModule === false ) {
|
||||
throw new Exception('Error while loading mcrypt module');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the high confidentiality mode
|
||||
*
|
||||
* @return bool TRUE if cookie data encryption is enabled, or FALSE if it isn't
|
||||
*/
|
||||
public function getHighConfidentiality() {
|
||||
return $this->_highConfidentiality;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable cookie data encryption
|
||||
*
|
||||
* @param bool $enable TRUE to enable, FALSE to disable
|
||||
* @return CookieJar
|
||||
*/
|
||||
public function setHighConfidentiality( $enable ) {
|
||||
$this->_highConfidentiality = (bool)$enable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the SSL status (enabled or disabled?)
|
||||
*
|
||||
* @return bool TRUE if SSL support is enabled, or FALSE if it isn't
|
||||
*/
|
||||
public function getSSL() {
|
||||
return $this->_ssl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable SSL support (not enabled by default)
|
||||
*
|
||||
* Pro: Protect against replay attack
|
||||
* Con: Cookie's lifetime is limited to SSL session's lifetime
|
||||
*
|
||||
* @param bool $enable TRUE to enable, FALSE to disable
|
||||
* @return CookieJar
|
||||
*/
|
||||
public function setSSL( $enable ) {
|
||||
$this->_ssl = (bool)$enable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cookies for Response
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @return array[Cookie]
|
||||
*/
|
||||
public function getResponseCookies() {
|
||||
return $this->_cookies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Cookie with name for Response
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @param string $cookiename The name of the Cookie
|
||||
* @return Cookie|null Cookie, or NULL if Cookie with name not found
|
||||
*/
|
||||
public function getResponseCookie( $cookiename ) {
|
||||
return isset($this->_cookies[$cookiename]) ? $this->_cookies[$cookiename] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a secure cookie
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param string $value Cookie value
|
||||
* @param string $username User identifier
|
||||
* @param integer $expire Expiration time
|
||||
* @param string $path Cookie path
|
||||
* @param string $domain Cookie domain
|
||||
* @param bool $secure When TRUE, send the cookie only on a secure connection
|
||||
* @param bool $httponly When TRUE the cookie will be made accessible only through the HTTP protocol
|
||||
*/
|
||||
public function setCookie( $cookiename, $value, $username, $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = null ) {
|
||||
$secureValue = extension_loaded('mcrypt') ? $this->_secureCookieValue($value, $username, $expire) : $value;
|
||||
$this->setClassicCookie($cookiename, $secureValue, $expire, $path, $domain, $secure, $httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cookie
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param string $path Cookie path
|
||||
* @param string $domain Cookie domain
|
||||
* @param bool $secure When TRUE, send the cookie only on a secure connection
|
||||
* @param bool $httponly When TRUE the cookie will be made accessible only through the HTTP protocol
|
||||
*/
|
||||
public function deleteCookie( $name, $path = '/', $domain = '', $secure = false, $httponly = null ) {
|
||||
$expire = 315554400; /* 1980-01-01 */
|
||||
$this->_cookies[$name] = new Slim_Http_Cookie($name, '', $expire, $path, $domain, $secure, $httponly);
|
||||
//setcookie($name, '', $expire, $path, $domain, $secure, $httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a secure cookie value
|
||||
*
|
||||
* Verify the integrity of cookie data and decrypt it. If the cookie
|
||||
* is invalid, it can be automatically destroyed (default behaviour)
|
||||
*
|
||||
* @param string $cookiename Cookie name
|
||||
* @param bool $delete Destroy the cookie if invalid?
|
||||
* @return string|false The Cookie value, or FALSE if Cookie invalid
|
||||
*/
|
||||
public function getCookieValue( $cookiename, $deleteIfInvalid = true ) {
|
||||
if ( $this->cookieExists($cookiename) ) {
|
||||
if ( extension_loaded('mcrypt') ) {
|
||||
$cookieValues = explode('|', $_COOKIE[$cookiename]);
|
||||
if ( (count($cookieValues) === 4) && ($cookieValues[1] == 0 || $cookieValues[1] >= time()) ) {
|
||||
$key = hash_hmac('sha1', $cookieValues[0] . $cookieValues[1], $this->_secret);
|
||||
$cookieData = base64_decode($cookieValues[2]);
|
||||
if ( $cookieData !== '' && $this->getHighConfidentiality() ) {
|
||||
$data = $this->_decrypt($cookieData, $key, md5($cookieValues[1]));
|
||||
} else {
|
||||
$data = $cookieData;
|
||||
}
|
||||
if ( $this->_ssl && isset($_SERVER['SSL_SESSION_ID']) ) {
|
||||
$verifKey = hash_hmac('sha1', $cookieValues[0] . $cookieValues[1] . $data . $_SERVER['SSL_SESSION_ID'], $key);
|
||||
} else {
|
||||
$verifKey = hash_hmac('sha1', $cookieValues[0] . $cookieValues[1] . $data, $key);
|
||||
}
|
||||
if ( $verifKey == $cookieValues[3] ) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return $_COOKIE[$cookiename];
|
||||
}
|
||||
}
|
||||
if ( $deleteIfInvalid ) {
|
||||
$this->deleteCookie($cookiename);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a classic (unsecure) cookie
|
||||
*
|
||||
* @param string $name Cookie name
|
||||
* @param string $value Cookie value
|
||||
* @param integer $expire Expiration time
|
||||
* @param string $path Cookie path
|
||||
* @param string $domain Cookie domain
|
||||
* @param bool $secure When TRUE, send the cookie only on a secure connection
|
||||
* @param bool $httponly When TRUE the cookie will be made accessible only through the HTTP protocol
|
||||
*/
|
||||
public function setClassicCookie( $cookiename, $value, $expire = 0, $path = '/', $domain = '', $secure = false, $httponly = null ) {
|
||||
/* httponly option is only available for PHP version >= 5.2 */
|
||||
if ( $httponly === null ) {
|
||||
$this->_cookies[$cookiename] = new Slim_Http_Cookie($cookiename, $value, $expire, $path, $domain, $secure);
|
||||
//setcookie($cookiename, $value, $expire, $path, $domain, $secure);
|
||||
} else {
|
||||
$this->_cookies[$cookiename] = new Slim_Http_Cookie($cookiename, $value, $expire, $path, $domain, $secure, $httponly);
|
||||
//setcookie($cookiename, $value, $expire, $path, $domain, $secure, $httponly);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify if a cookie exists
|
||||
*
|
||||
* @param string $cookiename
|
||||
* @return bool TRUE if cookie exist, or FALSE if not
|
||||
*/
|
||||
public function cookieExists($cookiename) {
|
||||
return isset($_COOKIE[$cookiename]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Secure a cookie value
|
||||
*
|
||||
* The initial value is transformed with this protocol:
|
||||
*
|
||||
* secureValue = username|expire|base64((value)k,expire)|HMAC(user|expire|value,k)
|
||||
* where k = HMAC(user|expire, sk)
|
||||
* and sk is server's secret key
|
||||
* (value)k,md5(expire) is the result an cryptographic function (ex: AES256) on "value" with key k and initialisation vector = md5(expire)
|
||||
*
|
||||
* @param string $value Unsecure value
|
||||
* @param string $username User identifier
|
||||
* @param integer $expire Expiration time
|
||||
* @return string Secured value
|
||||
*/
|
||||
protected function _secureCookieValue( $value, $username, $expire ) {
|
||||
if ( is_string($expire) ) {
|
||||
$expire = strtotime($expire);
|
||||
}
|
||||
$key = hash_hmac('sha1', $username . $expire, $this->_secret);
|
||||
if ( $value !== '' && $this->getHighConfidentiality() ) {
|
||||
$encryptedValue = base64_encode($this->_encrypt($value, $key, md5($expire)));
|
||||
} else {
|
||||
$encryptedValue = base64_encode($value);
|
||||
}
|
||||
if ( $this->_ssl && isset($_SERVER['SSL_SESSION_ID']) ) {
|
||||
$verifKey = hash_hmac('sha1', $username . $expire . $value . $_SERVER['SSL_SESSION_ID'], $key);
|
||||
} else {
|
||||
$verifKey = hash_hmac('sha1', $username . $expire . $value, $key);
|
||||
}
|
||||
$result = array($username, $expire, $encryptedValue, $verifKey);
|
||||
return implode('|', $result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypt a given data with a given key and a given initialisation vector
|
||||
*
|
||||
* @param string $data Data to crypt
|
||||
* @param string $key Secret key
|
||||
* @param string $iv Initialisation vector
|
||||
* @return string Encrypted data
|
||||
*/
|
||||
protected function _encrypt( $data, $key, $iv ) {
|
||||
$iv = $this->_validateIv($iv);
|
||||
$key = $this->_validateKey($key);
|
||||
mcrypt_generic_init($this->_cryptModule, $key, $iv);
|
||||
$res = @mcrypt_generic($this->_cryptModule, $data);
|
||||
mcrypt_generic_deinit($this->_cryptModule);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypt a given data with a given key and a given initialisation vector
|
||||
*
|
||||
* @param string $data Data to crypt
|
||||
* @param string $key Secret key
|
||||
* @param string $iv Initialisation vector
|
||||
* @return string Encrypted data
|
||||
*/
|
||||
protected function _decrypt( $data, $key, $iv ) {
|
||||
$iv = $this->_validateIv($iv);
|
||||
$key = $this->_validateKey($key);
|
||||
mcrypt_generic_init($this->_cryptModule, $key, $iv);
|
||||
$decryptedData = mdecrypt_generic($this->_cryptModule, $data);
|
||||
$res = str_replace("\x0", '', $decryptedData);
|
||||
mcrypt_generic_deinit($this->_cryptModule);
|
||||
return $res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Initialization vector
|
||||
*
|
||||
* If given IV is too long for the selected mcrypt algorithm, it will be truncated
|
||||
*
|
||||
* @param string $iv Initialization vector
|
||||
* @return string
|
||||
*/
|
||||
protected function _validateIv($iv) {
|
||||
$ivSize = mcrypt_enc_get_iv_size($this->_cryptModule);
|
||||
if ( strlen($iv) > $ivSize ) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
return $iv;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate key
|
||||
*
|
||||
* If given key is too long for the selected mcrypt algorithm, it will be truncated
|
||||
*
|
||||
* @param string $key key
|
||||
* @param string
|
||||
*/
|
||||
protected function _validateKey($key) {
|
||||
$keySize = mcrypt_enc_get_key_size($this->_cryptModule);
|
||||
if ( strlen($key) > $keySize ) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
return $key;
|
||||
}
|
||||
|
||||
}
|
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,20 +29,24 @@
|
|||
* 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
|
||||
* Request
|
||||
*
|
||||
* This class provides a human-friendly interface to the Slim environment variables;
|
||||
* environment variables are passed by reference and will be modified directly.
|
||||
* Object-oriented representation of an HTTP request. This class
|
||||
* is responsible for parsing the raw HTTP request into a format
|
||||
* usable by the Slim application.
|
||||
*
|
||||
* This class will automatically remove slashes from GET, POST, PUT,
|
||||
* and Cookie data if magic quotes are enabled.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @author Kris Jordan <http://www.github.com/KrisJordan>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Request
|
||||
{
|
||||
class Slim_Http_Request {
|
||||
|
||||
const METHOD_HEAD = 'HEAD';
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
|
@ -53,533 +56,350 @@ class Request
|
|||
const METHOD_OVERRIDE = '_METHOD';
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var string Request method (ie. "GET", "POST", "PUT", "DELETE", "HEAD")
|
||||
*/
|
||||
protected static $formDataMediaTypes = array('application/x-www-form-urlencoded');
|
||||
protected $method;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var array Key-value array of HTTP request headers
|
||||
*/
|
||||
protected $env;
|
||||
protected $headers;
|
||||
|
||||
/**
|
||||
* @var array Names of additional headers to parse from the current
|
||||
* HTTP request that are not prefixed with "HTTP_"
|
||||
*/
|
||||
protected $additionalHeaders = array('content-type', 'content-length', 'php-auth-user', 'php-auth-pw', 'auth-type', 'x-requested-with');
|
||||
|
||||
/**
|
||||
* @var array Key-value array of cookies sent with the
|
||||
* current HTTP request
|
||||
*/
|
||||
protected $cookies;
|
||||
|
||||
/**
|
||||
* @var array Key-value array of HTTP GET parameters
|
||||
*/
|
||||
protected $get;
|
||||
|
||||
/**
|
||||
* @var array Key-value array of HTTP POST parameters
|
||||
*/
|
||||
protected $post;
|
||||
|
||||
/**
|
||||
* @var array Key-value array of HTTP PUT parameters
|
||||
*/
|
||||
protected $put;
|
||||
|
||||
/**
|
||||
* @var string Raw body of HTTP request
|
||||
*/
|
||||
protected $body;
|
||||
|
||||
/**
|
||||
* @var string Content type of HTTP request
|
||||
*/
|
||||
protected $contentType;
|
||||
|
||||
/**
|
||||
* @var string Resource URI (ie. "/person/1")
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* @var string The root URI of the Slim application without trailing slash.
|
||||
* This will be "" if the app is installed at the web
|
||||
* document root. If the app is installed in a
|
||||
* sub-directory "/foo", this will be "/foo".
|
||||
*/
|
||||
protected $root;
|
||||
|
||||
/**
|
||||
* 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'];
|
||||
public function __construct() {
|
||||
$this->method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : false;
|
||||
$this->headers = $this->loadHttpHeaders();
|
||||
$this->body = @file_get_contents('php://input');
|
||||
$this->get = self::stripSlashesIfMagicQuotes($_GET);
|
||||
$this->post = self::stripSlashesIfMagicQuotes($_POST);
|
||||
$this->put = self::stripSlashesIfMagicQuotes($this->loadPutParameters());
|
||||
$this->cookies = self::stripSlashesIfMagicQuotes($_COOKIE);
|
||||
$this->root = Slim_Http_Uri::getBaseUri(true);
|
||||
$this->resource = Slim_Http_Uri::getUri(true);
|
||||
$this->checkForHttpMethodOverride();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a GET request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isGet()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_GET;
|
||||
public function isGet() {
|
||||
return $this->method === self::METHOD_GET;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a POST request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPost()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_POST;
|
||||
public function isPost() {
|
||||
return $this->method === self::METHOD_POST;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a PUT request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPut()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_PUT;
|
||||
public function isPut() {
|
||||
return $this->method === self::METHOD_PUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a DELETE request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelete()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_DELETE;
|
||||
public function isDelete() {
|
||||
return $this->method === self::METHOD_DELETE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a HEAD request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isHead()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_HEAD;
|
||||
public function isHead() {
|
||||
return $this->method === self::METHOD_HEAD;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this a OPTIONS request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isOptions()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_OPTIONS;
|
||||
public function isOptions() {
|
||||
return $this->method === self::METHOD_OPTIONS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an AJAX request?
|
||||
* Is this a XHR 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;
|
||||
}
|
||||
public function isAjax() {
|
||||
return ( $this->params('isajax') || $this->headers('X_REQUESTED_WITH') === 'XMLHttpRequest' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this an XHR request? (alias of Slim_Http_Request::isAjax)
|
||||
* @return bool
|
||||
* Fetch a PUT|POST|GET parameter value
|
||||
*
|
||||
* The preferred method to fetch the value of a
|
||||
* PUT, POST, or GET parameter (searched in that order).
|
||||
*
|
||||
* @param string $key The paramter name
|
||||
* @return string|null The value of parameter, or NULL if parameter not found
|
||||
*/
|
||||
public function isXhr()
|
||||
{
|
||||
return $this->isAjax();
|
||||
public function params( $key ) {
|
||||
foreach ( array('put', 'post', 'get') as $dataSource ) {
|
||||
$source = $this->$dataSource;
|
||||
if ( isset($source[(string)$key]) ) {
|
||||
return $source[(string)$key];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 parameter(s)
|
||||
* @param string $key Name of parameter
|
||||
* @return array|string|null All parameters, parameter value if $key
|
||||
* and parameter exists, or NULL if $key
|
||||
* and parameter does not exist.
|
||||
*/
|
||||
public function get( $key = null ) {
|
||||
return $this->arrayOrArrayValue($this->get, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*
|
||||
* Fetch POST parameter(s)
|
||||
* @param string $key Name of parameter
|
||||
* @return array|string|null All parameters, parameter value if $key
|
||||
* and parameter exists, or NULL if $key
|
||||
* and parameter does not exist.
|
||||
*/
|
||||
public function post( $key = null ) {
|
||||
return $this->arrayOrArrayValue($this->post, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch PUT parameter(s)
|
||||
* @param string $key Name of parameter
|
||||
* @return array|string|null All parameters, parameter value if $key
|
||||
* and parameter exists, or NULL if $key
|
||||
* and parameter does not exist.
|
||||
*/
|
||||
public function put( $key = null ) {
|
||||
return $this->arrayOrArrayValue($this->put, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch COOKIE value(s)
|
||||
* @param string $key The cookie name
|
||||
* @return array|string|null All parameters, parameter value if $key
|
||||
* and parameter exists, or NULL if $key
|
||||
* and parameter does not exist.
|
||||
*/
|
||||
public function cookies( $key = null ) {
|
||||
return $this->arrayOrArrayValue($this->cookies, $key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP request header
|
||||
* @param string $key The header name
|
||||
* @return array|string|null All parameters, parameter value if $key
|
||||
* and parameter exists, or NULL if $key
|
||||
* and parameter does not exist.
|
||||
*/
|
||||
public function headers( $key = null ) {
|
||||
return is_null($key) ? $this->headers : $this->arrayOrArrayValue($this->headers, $this->convertHttpHeaderName($key));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP request body
|
||||
* @return string|false String, or FALSE if body could not be read
|
||||
*/
|
||||
public function getBody() {
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP method
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod() {
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP request content type
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType() {
|
||||
if ( !isset($this->contentType) ) {
|
||||
$contentType = 'application/x-www-form-urlencoded';
|
||||
$header = $this->headers('CONTENT_TYPE');
|
||||
if ( !is_null($header) ) {
|
||||
$headerParts = preg_split('/\s*;\s*/', $header);
|
||||
$contentType = $headerParts[0];
|
||||
}
|
||||
$this->contentType = $contentType;
|
||||
}
|
||||
return $this->contentType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP request resource URI
|
||||
* @return string
|
||||
*/
|
||||
public function getResourceUri() {
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get HTTP request root URI
|
||||
* @return string
|
||||
*/
|
||||
public function getRootUri() {
|
||||
return $this->root;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch array or array value
|
||||
* @param array $array
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* @return array|mixed Array if key is null, else array value
|
||||
*/
|
||||
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);
|
||||
protected function arrayOrArrayValue( array &$array, $key = null ) {
|
||||
return is_null($key) ? $array : $this->arrayValueForKey($array, $key);
|
||||
}
|
||||
$this->env['slim.request.query_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
|
||||
/**
|
||||
* Fetch value from array
|
||||
* @return mixed|null
|
||||
*/
|
||||
protected function arrayValueForKey( array &$array, $key ) {
|
||||
return isset($array[(string)$key]) ? $array[(string)$key] : null;
|
||||
}
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.query_hash'][$key])) {
|
||||
return $this->env['slim.request.query_hash'][$key];
|
||||
|
||||
/**
|
||||
* Strip slashes from string or array of strings
|
||||
* @param array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
public static function stripSlashesIfMagicQuotes( $rawData ) {
|
||||
if ( get_magic_quotes_gpc() ) {
|
||||
return is_array($rawData) ? array_map(array('self', 'stripSlashesIfMagicQuotes'), $rawData) : stripslashes($rawData);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return $this->env['slim.request.query_hash'];
|
||||
return $rawData;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Get PUT parameters
|
||||
* @return array Key-value array of HTTP request PUT parameters
|
||||
*/
|
||||
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);
|
||||
protected function loadPutParameters() {
|
||||
if ( $this->getContentType() === 'application/x-www-form-urlencoded' ) {
|
||||
$input = is_string($this->body) ? $this->body : '';
|
||||
if ( function_exists('mb_parse_str') ) {
|
||||
mb_parse_str($input, $output);
|
||||
} else {
|
||||
parse_str($this->env['slim.input'], $output);
|
||||
parse_str($input, $output);
|
||||
}
|
||||
$this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
return $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'];
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch PUT data (alias for \Slim\Http\Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* Get HTTP request headers
|
||||
* @return array Key-value array of HTTP request headers
|
||||
*/
|
||||
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 {
|
||||
protected function loadHttpHeaders() {
|
||||
$headers = array();
|
||||
foreach ($this->env as $key => $value) {
|
||||
if (strpos($key, 'slim.') !== 0) {
|
||||
$headers[$key] = $value;
|
||||
foreach ( $_SERVER as $key => $value ) {
|
||||
$key = $this->convertHttpHeaderName($key);
|
||||
if ( strpos($key, 'http-') === 0 || in_array($key, $this->additionalHeaders) ) {
|
||||
$name = str_replace('http-', '', $key);
|
||||
$headers[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Body
|
||||
* Convert HTTP header name
|
||||
* @return string
|
||||
*/
|
||||
public function getBody()
|
||||
{
|
||||
return $this->env['slim.input'];
|
||||
protected function convertHttpHeaderName( $name ) {
|
||||
return str_replace('_', '-', strtolower($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Content Type
|
||||
* @return string
|
||||
* Check for HTTP request method override
|
||||
*
|
||||
* Because traditional web browsers do not support PUT and DELETE
|
||||
* HTTP methods, we use a hidden form input field to
|
||||
* mimic PUT and DELETE requests. We check for this override here.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function getContentType()
|
||||
{
|
||||
if (isset($this->env['CONTENT_TYPE'])) {
|
||||
return $this->env['CONTENT_TYPE'];
|
||||
} else {
|
||||
return null;
|
||||
protected function checkForHttpMethodOverride() {
|
||||
if ( isset($this->post[self::METHOD_OVERRIDE]) ) {
|
||||
$this->method = $this->post[self::METHOD_OVERRIDE];
|
||||
unset($this->post[self::METHOD_OVERRIDE]);
|
||||
if ( $this->isPut() ) {
|
||||
$this->put = $this->post;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,40 +29,54 @@
|
|||
* 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.
|
||||
* Object-oriented representation of an HTTP response that is
|
||||
* returned to the client. This class is responsible for:
|
||||
*
|
||||
* - HTTP response status
|
||||
* - HTTP response body
|
||||
* - HTTP response headers
|
||||
* - HTTP response cookies
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @author Kris Jordan <http://github.com/KrisJordan>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Response implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
class Slim_Http_Response {
|
||||
|
||||
/**
|
||||
* @var Slim_Http_Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected $httpVersion = '1.1';
|
||||
|
||||
/**
|
||||
* @var int HTTP status code
|
||||
*/
|
||||
protected $status;
|
||||
protected $status = 200;
|
||||
|
||||
/**
|
||||
* @var \Slim\Http\Headers List of HTTP response headers
|
||||
* @var array Key-value array of HTTP response headers
|
||||
*/
|
||||
protected $header;
|
||||
protected $headers = array();
|
||||
|
||||
/**
|
||||
* @var string HTTP response body
|
||||
*/
|
||||
protected $body;
|
||||
protected $body = '';
|
||||
|
||||
/**
|
||||
* @var int Length of HTTP response body
|
||||
*/
|
||||
protected $length;
|
||||
protected $length = 0;
|
||||
|
||||
/**
|
||||
* @var array HTTP response codes and messages
|
||||
|
@ -120,340 +133,189 @@ class Response implements \ArrayAccess, \Countable, \IteratorAggregate
|
|||
);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @var CookieJar Manages Cookies to be sent with this Response
|
||||
*/
|
||||
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);
|
||||
protected $cookieJar;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct( Slim_Http_Request $req ) {
|
||||
$this->request = $req;
|
||||
$this->header('Content-Type', 'text/html');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set status
|
||||
* @param int|null $status
|
||||
* @return int
|
||||
* Set and/or get the HTTP response version
|
||||
* @param string $version
|
||||
* @return void
|
||||
* @throws InvalidArgumentException If argument is not a valid HTTP version
|
||||
*/
|
||||
public function status($status = null)
|
||||
{
|
||||
if (!is_null($status)) {
|
||||
$this->status = (int) $status;
|
||||
public function httpVersion( $version = null ) {
|
||||
if ( $version ) {
|
||||
$version = (string)$version;
|
||||
if ( $version === '1.0' || $version === '1.1' ) {
|
||||
$this->httpVersion = $version;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid HTTP version in Response object');
|
||||
}
|
||||
}
|
||||
return $this->httpVersion;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set and/or get the HTTP response status code
|
||||
* @param int $status
|
||||
* @return int
|
||||
* @throws InvalidArgumentException If argument is not a valid HTTP status code
|
||||
*/
|
||||
public function status( $status = null ) {
|
||||
if ( !is_null($status) ) {
|
||||
if ( !in_array(intval($status), array_keys(self::$messages)) ) {
|
||||
throw new InvalidArgumentException('Cannot set Response status. Provided status code "' . $status . '" is not a valid HTTP response code.');
|
||||
}
|
||||
$this->status = intval($status);
|
||||
}
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set header
|
||||
* @param string $name Header name
|
||||
* @param string|null $value Header value
|
||||
* @return string Header value
|
||||
* Get HTTP response headers
|
||||
* @return array
|
||||
*/
|
||||
public function header($name, $value = null)
|
||||
{
|
||||
public function headers() {
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and/or set an HTTP response header
|
||||
* @param string $key The header name
|
||||
* @param string $value The header value
|
||||
* @return string|null The header value, or NULL if header not set
|
||||
*/
|
||||
public function header( $key, $value = null ) {
|
||||
if ( !is_null($value) ) {
|
||||
$this[$name] = $value;
|
||||
$this->headers[$key] = $value;
|
||||
}
|
||||
|
||||
return $this[$name];
|
||||
return isset($this->headers[$key]) ? $this->headers[$key] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get headers
|
||||
* @return \Slim\Http\Headers
|
||||
* Set the HTTP response body
|
||||
* @param string $body The new HTTP response body
|
||||
* @return string The new HTTP response body
|
||||
*/
|
||||
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)
|
||||
{
|
||||
public function body( $body = null ) {
|
||||
if ( !is_null($body) ) {
|
||||
$this->write($body, true);
|
||||
$this->body = '';
|
||||
$this->length = 0;
|
||||
$this->write($body);
|
||||
}
|
||||
|
||||
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
|
||||
* Append the 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;
|
||||
public function write( $body ) {
|
||||
$body = (string)$body;
|
||||
$this->length += strlen($body);
|
||||
$this->body .= $body;
|
||||
$this->header('Content-Length', $this->length);
|
||||
return $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]
|
||||
* Set cookie jar
|
||||
* @param Slim_Http_CookieJar $cookieJar
|
||||
* @return void
|
||||
*/
|
||||
public function finalize()
|
||||
{
|
||||
public function setCookieJar( Slim_Http_CookieJar $cookieJar ) {
|
||||
$this->cookieJar = $cookieJar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cookie jar
|
||||
* @return Slim_Http_CookieJar
|
||||
*/
|
||||
public function getCookieJar() {
|
||||
return $this->cookieJar;
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize response headers before response is sent
|
||||
* @return void
|
||||
*/
|
||||
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);
|
||||
$this->body('');
|
||||
unset($this->headers['Content-Type']);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
public static function getMessageForCode( $status ) {
|
||||
return isset(self::$messages[$status]) ? self::$messages[$status] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can this HTTP response have a body?
|
||||
* @return bool
|
||||
*/
|
||||
public function canHaveBody() {
|
||||
return ( $this->status < 100 || $this->status >= 200 ) && $this->status != 204 && $this->status != 304;
|
||||
}
|
||||
|
||||
/**
|
||||
* Send headers for HTTP response
|
||||
* @return void
|
||||
*/
|
||||
protected function sendHeaders() {
|
||||
//Finalize response
|
||||
$this->finalize();
|
||||
|
||||
if ( substr(PHP_SAPI, 0, 3) === 'cgi') {
|
||||
//Send Status header if running with fastcgi
|
||||
header('Status: ' . self::getMessageForCode($this->status()));
|
||||
} else {
|
||||
return null;
|
||||
//Else send HTTP message
|
||||
header(sprintf('HTTP/%s %s', $this->httpVersion, self::getMessageForCode($this->status())));
|
||||
}
|
||||
|
||||
//Send headers
|
||||
foreach ( $this->headers() as $name => $value ) {
|
||||
header("$name: $value");
|
||||
}
|
||||
|
||||
//Send cookies
|
||||
foreach ( $this->getCookieJar()->getResponseCookies() as $name => $cookie ) {
|
||||
setcookie($cookie->getName(), $cookie->getValue(), $cookie->getExpires(), $cookie->getPath(), $cookie->getDomain(), $cookie->getSecure(), $cookie->getHttpOnly());
|
||||
}
|
||||
|
||||
//Flush all output to client
|
||||
flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send HTTP response
|
||||
*
|
||||
* This method will set Response headers, set Response cookies,
|
||||
* and `echo` the Response body to the current output buffer.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function send() {
|
||||
if ( !headers_sent() ) {
|
||||
$this->sendHeaders();
|
||||
}
|
||||
if ( $this->canHaveBody() && $this->request->isHead() === false ) {
|
||||
echo $this->body;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,131 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.5.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Uri
|
||||
*
|
||||
* Parses base uri and application uri from Request.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Slim_Http_Uri {
|
||||
|
||||
/**
|
||||
* @var string "https" or "http"
|
||||
*/
|
||||
protected static $scheme;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $baseUri;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected static $uri;
|
||||
|
||||
/**
|
||||
* @var string The URI query string, excluding leading "?"
|
||||
*/
|
||||
protected static $queryString;
|
||||
|
||||
/**
|
||||
* Get Base URI without trailing slash
|
||||
* @param bool $reload Force reparse the base URI?
|
||||
* @return string
|
||||
*/
|
||||
public static function getBaseUri( $reload = false ) {
|
||||
if ( $reload || is_null(self::$baseUri) ) {
|
||||
$requestUri = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : $_SERVER['PHP_SELF']; //Full Request URI
|
||||
$scriptName = $_SERVER['SCRIPT_NAME']; //Script path from docroot
|
||||
$baseUri = strpos($requestUri, $scriptName) === 0 ? $scriptName : str_replace('\\', '/', dirname($scriptName));
|
||||
self::$baseUri = rtrim($baseUri, '/');
|
||||
}
|
||||
return self::$baseUri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI with leading slash
|
||||
* @param bool $reload Force reparse the URI?
|
||||
* @return string
|
||||
* @throws RuntimeException If unable if unable to determine URI
|
||||
*/
|
||||
public static function getUri( $reload = false ) {
|
||||
if ( $reload || is_null(self::$uri) ) {
|
||||
$uri = '';
|
||||
if ( !empty($_SERVER['PATH_INFO']) ) {
|
||||
$uri = $_SERVER['PATH_INFO'];
|
||||
} else {
|
||||
if ( isset($_SERVER['REQUEST_URI']) ) {
|
||||
$uri = parse_url(self::getScheme() . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
||||
} else if ( isset($_SERVER['PHP_SELF']) ) {
|
||||
$uri = $_SERVER['PHP_SELF'];
|
||||
} else {
|
||||
throw new RuntimeException('Unable to detect request URI');
|
||||
}
|
||||
}
|
||||
if ( self::getBaseUri() !== '' && strpos($uri, self::getBaseUri()) === 0 ) {
|
||||
$uri = substr($uri, strlen(self::getBaseUri()));
|
||||
}
|
||||
self::$uri = '/' . ltrim($uri, '/');
|
||||
}
|
||||
return self::$uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI Scheme
|
||||
* @param bool $reload For reparse the URL scheme?
|
||||
* @return string "https" or "http"
|
||||
*/
|
||||
public static function getScheme( $reload = false ) {
|
||||
if ( $reload || is_null(self::$scheme) ) {
|
||||
self::$scheme = ( empty($_SERVER['HTTPS']) || $_SERVER['HTTPS'] === 'off' ) ? 'http' : 'https';
|
||||
}
|
||||
return self::$scheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URI Query String
|
||||
* @param bool $reload For reparse the URL query string?
|
||||
* @return string
|
||||
*/
|
||||
public static function getQueryString( $reload = false ) {
|
||||
if ( $reload || is_null(self::$queryString) ) {
|
||||
self::$queryString = $_SERVER['QUERY_STRING'];
|
||||
}
|
||||
return self::$queryString;
|
||||
}
|
||||
|
||||
}
|
164
Slim/Log.php
164
Slim/Log.php
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,14 +29,12 @@
|
|||
* 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
|
||||
* Log Adapter
|
||||
*
|
||||
* 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:
|
||||
* This is an adapter for your own custom Logger. This adapter assumes
|
||||
* your custom Logger provides the following public instance methods:
|
||||
*
|
||||
* debug( mixed $object )
|
||||
* info( mixed $object )
|
||||
|
@ -45,75 +42,39 @@ namespace Slim;
|
|||
* 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.
|
||||
* This class assumes nothing else about your custom Logger, so you are free
|
||||
* to use Apache's Log4PHP logger or any other log class that, at the
|
||||
* very least, implements the five public instance methods shown above.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Log
|
||||
{
|
||||
const FATAL = 0;
|
||||
const ERROR = 1;
|
||||
const WARN = 2;
|
||||
const INFO = 3;
|
||||
const DEBUG = 4;
|
||||
class Slim_Log {
|
||||
|
||||
/**
|
||||
* @var array
|
||||
* @var mixed An object that implements expected Logger interface
|
||||
*/
|
||||
protected static $levels = array(
|
||||
self::FATAL => 'FATAL',
|
||||
self::ERROR => 'ERROR',
|
||||
self::WARN => 'WARN',
|
||||
self::INFO => 'INFO',
|
||||
self::DEBUG => 'DEBUG'
|
||||
);
|
||||
protected $logger;
|
||||
|
||||
/**
|
||||
* @var mixed
|
||||
*/
|
||||
protected $writer;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
* @var bool Enable logging?
|
||||
*/
|
||||
protected $enabled;
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected $level;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function __construct($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
public function __construct() {
|
||||
$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
|
||||
* @return void
|
||||
*/
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
public function setEnabled( $enabled ) {
|
||||
if ( $enabled ) {
|
||||
$this->enabled = true;
|
||||
} else {
|
||||
|
@ -121,52 +82,11 @@ class Log
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
public function isEnabled() {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
|
@ -175,9 +95,8 @@ class Log
|
|||
* @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->log($object, self::DEBUG);
|
||||
public function debug( $object ) {
|
||||
return isset($this->logger) && $this->isEnabled() ? $this->logger->debug($object) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,9 +104,8 @@ class Log
|
|||
* @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->log($object, self::INFO);
|
||||
public function info( $object ) {
|
||||
return isset($this->logger) && $this->isEnabled() ? $this->logger->info($object) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -195,9 +113,8 @@ class Log
|
|||
* @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->log($object, self::WARN);
|
||||
public function warn( $object ) {
|
||||
return isset($this->logger) && $this->isEnabled() ? $this->logger->warn($object) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -205,9 +122,8 @@ class Log
|
|||
* @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->log($object, self::ERROR);
|
||||
public function error( $object ) {
|
||||
return isset($this->logger) && $this->isEnabled() ? $this->logger->error($object) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -215,23 +131,25 @@ class Log
|
|||
* @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->log($object, self::FATAL);
|
||||
public function fatal( $object ) {
|
||||
return isset($this->logger) && $this->isEnabled() ? $this->logger->fatal($object) : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log message
|
||||
* @param mixed The object to log
|
||||
* @param int The message level
|
||||
* @return int|false
|
||||
* Set Logger
|
||||
* @param mixed $logger
|
||||
* @return void
|
||||
*/
|
||||
protected function log($object, $level)
|
||||
{
|
||||
if ($this->enabled && $this->writer && $level <= $this->level) {
|
||||
return $this->writer->write($object, $level);
|
||||
} else {
|
||||
return false;
|
||||
public function setLogger( $logger ) {
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Logger
|
||||
* @return mixed
|
||||
*/
|
||||
public function getLogger() {
|
||||
return $this->logger;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,200 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.5.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Logger
|
||||
*
|
||||
* A simple Logger that writes to a daily-unique log file in
|
||||
* a user-specified directory. By default, this class will write log
|
||||
* messages for all log levels; the log level may be changed to filter
|
||||
* unwanted log messages from the log file.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Slim_Logger {
|
||||
|
||||
/**
|
||||
* @var array Log levels
|
||||
*/
|
||||
protected $levels = array(
|
||||
0 => 'FATAL',
|
||||
1 => 'ERROR',
|
||||
2 => 'WARN',
|
||||
3 => 'INFO',
|
||||
4 => 'DEBUG'
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string Absolute path to log directory with trailing slash
|
||||
*/
|
||||
protected $directory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $directory Absolute or relative path to log directory
|
||||
* @param int $level The maximum log level reported by this Logger
|
||||
*/
|
||||
public function __construct( $directory, $level = 4 ) {
|
||||
$this->setDirectory($directory);
|
||||
$this->setLevel($level);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set log directory
|
||||
* @param string $directory Absolute or relative path to log directory
|
||||
* @return void
|
||||
*/
|
||||
public function setDirectory( $directory ) {
|
||||
$realPath = realpath($directory);
|
||||
if ( $realPath ) {
|
||||
$this->directory = rtrim($realPath, '/') . '/';
|
||||
} else {
|
||||
$this->directory = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log directory
|
||||
* @return string|false Absolute path to log directory with trailing slash
|
||||
*/
|
||||
public function getDirectory() {
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set log level
|
||||
* @param int The maximum log level reported by this Logger
|
||||
* @return void
|
||||
* @throws InvalidArgumentException If level specified is not 0, 1, 2, 3, 4
|
||||
*/
|
||||
public function setLevel( $level ) {
|
||||
$theLevel = (int)$level;
|
||||
if ( $theLevel >= 0 && $theLevel <= 4 ) {
|
||||
$this->level = $theLevel;
|
||||
} else {
|
||||
throw new InvalidArgumentException('Invalid Log Level. Must be one of: 0, 1, 2, 3, 4.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get log level
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel() {
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log debug data
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function debug( $data ) {
|
||||
$this->log($data, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log info data
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function info( $data ) {
|
||||
$this->log($data, 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log warn data
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function warn( $data ) {
|
||||
$this->log($data, 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error data
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function error( $data ) {
|
||||
$this->log($data, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log fatal data
|
||||
* @param mixed $data
|
||||
* @return void
|
||||
*/
|
||||
public function fatal( $data ) {
|
||||
$this->log($data, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get absolute path to current daily log file
|
||||
* @return string
|
||||
*/
|
||||
public function getFile() {
|
||||
return $this->getDirectory() . strftime('%Y-%m-%d') . '.log';
|
||||
}
|
||||
|
||||
/**
|
||||
* Log data to file
|
||||
* @param mixed $data
|
||||
* @param int $level
|
||||
* @return void
|
||||
* @throws RuntimeException If log directory not found or not writable
|
||||
*/
|
||||
protected function log( $data, $level ) {
|
||||
$dir = $this->getDirectory();
|
||||
if ( $dir == false || !is_dir($dir) ) {
|
||||
throw new RuntimeException("Log directory '$dir' invalid.");
|
||||
}
|
||||
if ( !is_writable($dir) ) {
|
||||
throw new RuntimeException("Log directory '$dir' not writable.");
|
||||
}
|
||||
if ( $level <= $this->getLevel() ) {
|
||||
$this->write(sprintf("[%s] %s - %s\r\n", $this->levels[$level], date('c'), (string)$data));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Persist data to log
|
||||
* @param string Log message
|
||||
* @return void
|
||||
*/
|
||||
protected function write( $data ) {
|
||||
@file_put_contents($this->getFile(), $data, FILE_APPEND | LOCK_EX);
|
||||
}
|
||||
|
||||
}
|
283
Slim/Route.php
283
Slim/Route.php
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,23 +29,23 @@
|
|||
* 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
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Route
|
||||
{
|
||||
class Slim_Route {
|
||||
|
||||
/**
|
||||
* @var string The route pattern (e.g. "/books/:id")
|
||||
* @var string The route pattern (ie. "/books/:id")
|
||||
*/
|
||||
protected $pattern;
|
||||
|
||||
/**
|
||||
* @var mixed The route callable
|
||||
* @var mixed The callable associated with this route
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
|
@ -56,7 +55,7 @@ class Route
|
|||
protected $conditions = array();
|
||||
|
||||
/**
|
||||
* @var array Default conditions applied to all route instances
|
||||
* @var array Default conditions applied to all Route instances
|
||||
*/
|
||||
protected static $defaultConditions = array();
|
||||
|
||||
|
@ -70,33 +69,27 @@ class Route
|
|||
*/
|
||||
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
|
||||
* @var Slim_Router The Router to which this Route belongs
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* @var array[Callable] Middleware
|
||||
*/
|
||||
protected $middleware = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $pattern The URL pattern (e.g. "/books/:id")
|
||||
* @param string $pattern The URL pattern (ie. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
*/
|
||||
public function __construct($pattern, $callable)
|
||||
{
|
||||
public function __construct( $pattern, $callable ) {
|
||||
$this->setPattern($pattern);
|
||||
$this->setCallable($callable);
|
||||
$this->setConditions(self::getDefaultConditions());
|
||||
|
@ -105,9 +98,9 @@ class Route
|
|||
/**
|
||||
* Set default route conditions for all instances
|
||||
* @param array $defaultConditions
|
||||
* @return void
|
||||
*/
|
||||
public static function setDefaultConditions(array $defaultConditions)
|
||||
{
|
||||
public static function setDefaultConditions( array $defaultConditions ) {
|
||||
self::$defaultConditions = $defaultConditions;
|
||||
}
|
||||
|
||||
|
@ -115,8 +108,7 @@ class Route
|
|||
* Get default route conditions for all instances
|
||||
* @return array
|
||||
*/
|
||||
public static function getDefaultConditions()
|
||||
{
|
||||
public static function getDefaultConditions() {
|
||||
return self::$defaultConditions;
|
||||
}
|
||||
|
||||
|
@ -124,35 +116,33 @@ class Route
|
|||
* Get route pattern
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern()
|
||||
{
|
||||
public function getPattern() {
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route pattern
|
||||
* @param string $pattern
|
||||
* @return void
|
||||
*/
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
public function setPattern( $pattern ) {
|
||||
$this->pattern = str_replace(')', ')?', (string)$pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route callable
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallable()
|
||||
{
|
||||
public function getCallable() {
|
||||
return $this->callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route callable
|
||||
* @param mixed $callable
|
||||
* @return void
|
||||
*/
|
||||
public function setCallable($callable)
|
||||
{
|
||||
public function setCallable($callable) {
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
|
@ -160,17 +150,16 @@ class Route
|
|||
* Get route conditions
|
||||
* @return array
|
||||
*/
|
||||
public function getConditions()
|
||||
{
|
||||
public function getConditions() {
|
||||
return $this->conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route conditions
|
||||
* @param array $conditions
|
||||
* @return void
|
||||
*/
|
||||
public function setConditions(array $conditions)
|
||||
{
|
||||
public function setConditions( array $conditions ) {
|
||||
$this->conditions = $conditions;
|
||||
}
|
||||
|
||||
|
@ -178,72 +167,33 @@ class Route
|
|||
* Get route name
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
public function getName() {
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
* @param string $name
|
||||
* @return void
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
public function setName( $name ) {
|
||||
$this->name = (string)$name;
|
||||
$this->router->cacheNamedRoute($this->name, $this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route parameters
|
||||
* @return array
|
||||
*/
|
||||
public function getParams()
|
||||
{
|
||||
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)
|
||||
* @return void
|
||||
*/
|
||||
public function setHttpMethods()
|
||||
{
|
||||
public function setHttpMethods() {
|
||||
$args = func_get_args();
|
||||
$this->methods = $args;
|
||||
}
|
||||
|
@ -252,29 +202,26 @@ class Route
|
|||
* Get supported HTTP methods
|
||||
* @return array
|
||||
*/
|
||||
public function getHttpMethods()
|
||||
{
|
||||
public function getHttpMethods() {
|
||||
return $this->methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append supported HTTP methods
|
||||
* @return void
|
||||
*/
|
||||
public function appendHttpMethods()
|
||||
{
|
||||
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
|
||||
* @return Slim_Route
|
||||
*/
|
||||
public function via()
|
||||
{
|
||||
public function via() {
|
||||
$args = func_get_args();
|
||||
$this->methods = array_merge($this->methods, $args);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -282,17 +229,32 @@ class Route
|
|||
* Detect support for an HTTP method
|
||||
* @return bool
|
||||
*/
|
||||
public function supportsHttpMethod($method)
|
||||
{
|
||||
public function supportsHttpMethod( $method ) {
|
||||
return in_array($method, $this->methods);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get router
|
||||
* @return Slim_Router
|
||||
*/
|
||||
public function getRouter() {
|
||||
return $this->router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set router
|
||||
* @param Slim_Router $router
|
||||
* @return void
|
||||
*/
|
||||
public function setRouter( Slim_Router $router ) {
|
||||
$this->router = $router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get middleware
|
||||
* @return array[Callable]
|
||||
*/
|
||||
public function getMiddleware()
|
||||
{
|
||||
public function getMiddleware() {
|
||||
return $this->middleware;
|
||||
}
|
||||
|
||||
|
@ -305,22 +267,20 @@ class Route
|
|||
* assume the argument is an array of callables and merge the array
|
||||
* with `$this->middleware`. Even if non-callables are included in the
|
||||
* argument array, we still merge them; we lazily check each item
|
||||
* against `is_callable` during Router::dispatch().
|
||||
* against `is_callable` during Route::dispatch().
|
||||
*
|
||||
* @param Callable|array[Callable]
|
||||
* @return \Slim\Route
|
||||
* @throws \InvalidArgumentException If argument is not callable or not an array
|
||||
* @return Slim_Route
|
||||
* @throws InvalidArgumentException If argument is not callable or not an array
|
||||
*/
|
||||
public function setMiddleware($middleware)
|
||||
{
|
||||
public function setMiddleware( $middleware ) {
|
||||
if ( is_callable($middleware) ) {
|
||||
$this->middleware[] = $middleware;
|
||||
} else if ( is_array($middleware) ) {
|
||||
$this->middleware = array_merge($this->middleware, $middleware);
|
||||
} else {
|
||||
throw new \InvalidArgumentException('Route middleware must be callable or an array of callables');
|
||||
throw new InvalidArgumentException('Route middleware must be callable or an array of callables');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -335,73 +295,104 @@ class Route
|
|||
* @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));
|
||||
public function matches( $resourceUri ) {
|
||||
//Extract URL params
|
||||
preg_match_all('@:([\w]+)@', $this->pattern, $paramNames, PREG_PATTERN_ORDER);
|
||||
$paramNames = $paramNames[0];
|
||||
|
||||
//Convert URL params into regex patterns, construct a regex for this route
|
||||
$patternAsRegex = preg_replace_callback('@:[\w]+@', array($this, 'convertPatternToRegex'), $this->pattern);
|
||||
if ( substr($this->pattern, -1) === '/' ) {
|
||||
$patternAsRegex .= '?';
|
||||
$patternAsRegex = $patternAsRegex . '?';
|
||||
}
|
||||
$patternAsRegex = '@^' . $patternAsRegex . '$@';
|
||||
|
||||
//Cache URL params' names and values if this route matches the current HTTP request
|
||||
if (!preg_match('#^' . $patternAsRegex . '$#', $resourceUri, $paramValues)) {
|
||||
if ( preg_match($patternAsRegex, $resourceUri, $paramValues) ) {
|
||||
array_shift($paramValues);
|
||||
foreach ( $paramNames as $index => $value ) {
|
||||
$val = substr($value, 1);
|
||||
if ( isset($paramValues[$val]) ) {
|
||||
$this->params[$val] = urldecode($paramValues[$val]);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
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
|
||||
* Convert a URL parameter (ie. ":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] ] . ')';
|
||||
protected function convertPatternToRegex( $matches ) {
|
||||
$key = str_replace(':', '', $matches[0]);
|
||||
if ( array_key_exists($key, $this->conditions) ) {
|
||||
return '(?P<' . $key . '>' . $this->conditions[$key] . ')';
|
||||
} else {
|
||||
return '(?P<' . $key . '>[a-zA-Z0-9_\-\.\!\~\*\\\'\(\)\:\@\&\=\$\+,%]+)';
|
||||
}
|
||||
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
|
||||
* @return Slim_Route
|
||||
*/
|
||||
public function name($name)
|
||||
{
|
||||
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
|
||||
* @return Slim_Route
|
||||
*/
|
||||
public function conditions(array $conditions)
|
||||
{
|
||||
public function conditions( array $conditions ) {
|
||||
$this->conditions = array_merge($this->conditions, $conditions);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch route
|
||||
*
|
||||
* This method invokes this route's callable. If middleware is
|
||||
* registered for this route, each callable middleware is invoked in
|
||||
* the order specified.
|
||||
*
|
||||
* This method is smart about trailing slashes on the route pattern.
|
||||
* If this route's pattern is defined with a trailing slash, and if the
|
||||
* current request URI does not have a trailing slash but otherwise
|
||||
* matches this route's pattern, a Slim_Exception_RequestSlash
|
||||
* will be thrown triggering an HTTP 301 Permanent Redirect to the same
|
||||
* URI _with_ a trailing slash. This Exception is caught in the
|
||||
* `Slim::run` loop. If this route's pattern is defined without a
|
||||
* trailing slash, and if the current request URI does have a trailing
|
||||
* slash, this route will not be matched and a 404 Not Found
|
||||
* response will be sent if no subsequent matching routes are found.
|
||||
*
|
||||
* @return bool Was route callable invoked successfully?
|
||||
* @throws Slim_Exception_RequestSlash
|
||||
*/
|
||||
public function dispatch() {
|
||||
if ( substr($this->pattern, -1) === '/' && substr($this->router->getRequest()->getResourceUri(), -1) !== '/' ) {
|
||||
throw new Slim_Exception_RequestSlash();
|
||||
}
|
||||
//Invoke middleware
|
||||
foreach ( $this->middleware as $mw ) {
|
||||
if ( is_callable($mw) ) {
|
||||
call_user_func($mw);
|
||||
}
|
||||
}
|
||||
//Invoke callable
|
||||
if ( is_callable($this->getCallable()) ) {
|
||||
call_user_func_array($this->callable, array_values($this->params));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
290
Slim/Router.php
290
Slim/Router.php
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,41 +29,43 @@
|
|||
* 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.
|
||||
* Responsible for registering route paths with associated callables.
|
||||
* When a Slim application is run, the Router finds a matching Route for
|
||||
* the current HTTP request, and if a matching route is found, executes
|
||||
* the Route's associated callable passing it parameters from the Request URI.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.0
|
||||
*/
|
||||
class Router implements \Iterator
|
||||
{
|
||||
/**
|
||||
* @var string Request URI
|
||||
*/
|
||||
protected $resourceUri;
|
||||
class Slim_Router implements IteratorAggregate {
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of all route objects
|
||||
* @var Slim_Http_Request
|
||||
*/
|
||||
protected $request;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of routes, keyed by Request method
|
||||
*/
|
||||
protected $routes;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of named route objects, keyed by route name (lazy-loaded)
|
||||
* @var array Lookup hash of named routes, keyed by route name
|
||||
*/
|
||||
protected $namedRoutes;
|
||||
|
||||
/**
|
||||
* @var array Array of route objects that match the request URI (lazy-loaded)
|
||||
* @var array Array of routes that match the Request method and URL
|
||||
*/
|
||||
protected $matchedRoutes;
|
||||
|
||||
/**
|
||||
* @var mixed Callable to be invoked if no matching route objects are found
|
||||
* @var mixed Callable to be invoked if no matching routes are found
|
||||
*/
|
||||
protected $notFound;
|
||||
|
||||
|
@ -75,193 +76,104 @@ class Router implements \Iterator
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Slim_Http_Request $request The HTTP request object
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
public function __construct( Slim_Http_Request $request ) {
|
||||
$this->request = $request;
|
||||
$this->routes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set Resource URI
|
||||
*
|
||||
* This method injects the current request's resource URI. This method should be invoked
|
||||
* only immediately before router iteration.
|
||||
*
|
||||
* @param string $uri The request URI
|
||||
* Get Iterator
|
||||
* @return ArrayIterator
|
||||
*/
|
||||
public function setResourceUri($uri)
|
||||
{
|
||||
$this->resourceUri = $uri;
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->getMatchedRoutes());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Current Route object
|
||||
* @return \Slim\Route|false
|
||||
* Get Request
|
||||
* @return Slim_Http_Request
|
||||
*/
|
||||
public function getCurrentRoute()
|
||||
{
|
||||
$this->getMatchedRoutes(); // <-- Parse if not already parsed
|
||||
|
||||
return $this->current();
|
||||
public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return route objects that match the current request URI
|
||||
* @param bool $reload Should matching routes be re-parsed?
|
||||
* @return array[\Slim\Route]
|
||||
* Set Request
|
||||
* @param Slim_Http_Request $req
|
||||
* @return void
|
||||
*/
|
||||
public function getMatchedRoutes($reload = false)
|
||||
{
|
||||
public function setRequest( Slim_Http_Request $req ) {
|
||||
$this->request = $req;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return routes that match the current request
|
||||
* @return array[Slim_Route]
|
||||
*/
|
||||
public function getMatchedRoutes( $reload = false ) {
|
||||
if ( $reload || is_null($this->matchedRoutes) ) {
|
||||
$this->matchedRoutes = array();
|
||||
foreach ( $this->routes as $route ) {
|
||||
if ($route->matches($this->resourceUri)) {
|
||||
if ( $route->matches($this->request->getResourceUri()) ) {
|
||||
$this->matchedRoutes[] = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->matchedRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Map a route object to a callback function
|
||||
* Map a route 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
|
||||
* @return Slim_Route
|
||||
*/
|
||||
public function map($pattern, $callable)
|
||||
{
|
||||
$route = new \Slim\Route($pattern, $callable);
|
||||
public function map( $pattern, $callable ) {
|
||||
$route = new Slim_Route($pattern, $callable);
|
||||
$route->setRouter($this);
|
||||
$this->routes[] = $route;
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cache 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
|
||||
* @return void
|
||||
*/
|
||||
public function cacheNamedRoute( $name, Slim_Route $route ) {
|
||||
if ( isset($this->namedRoutes[(string)$name]) ) {
|
||||
throw new RuntimeException('Named route already exists with name: ' . $name);
|
||||
}
|
||||
$this->namedRoutes[$name] = $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
|
||||
* @param array Associative array of URL parameter names and values
|
||||
* @throws RuntimeException If named route not found
|
||||
* @return string The URL for the given route populated with provided replacement values
|
||||
* @return string The URL for the given route populated with the given parameters
|
||||
*/
|
||||
public function urlFor($name, $params = array())
|
||||
{
|
||||
if (!$this->hasNamedRoute($name)) {
|
||||
throw new \RuntimeException('Named route not found for name: ' . $name);
|
||||
public function urlFor( $name, $params = array() ) {
|
||||
if ( !isset($this->namedRoutes[(string)$name]) ) {
|
||||
throw new RuntimeException('Named route not found for name: ' . $name);
|
||||
}
|
||||
$search = array();
|
||||
foreach (array_keys($params) as $key) {
|
||||
$search[] = '#:' . $key . '\+?(?!\w)#';
|
||||
$pattern = $this->namedRoutes[(string)$name]->getPattern();
|
||||
$search = $replace = array();
|
||||
foreach ( $params as $key => $value ) {
|
||||
$search[] = ':' . $key;
|
||||
$replace[] = $value;
|
||||
}
|
||||
$pattern = preg_replace($search, $params, $this->getNamedRoute($name)->getPattern());
|
||||
|
||||
$pattern = str_replace($search, $replace, $pattern);
|
||||
//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.
|
||||
*
|
||||
* This method is smart about trailing slashes on the route pattern.
|
||||
* If the route's pattern is defined with a trailing slash, and if the
|
||||
* current request URI does not have a trailing slash but otherwise
|
||||
* matches the route's pattern, a Slim_Exception_RequestSlash
|
||||
* will be thrown triggering an HTTP 301 Permanent Redirect to the same
|
||||
* URI _with_ a trailing slash. This Exception is caught in the
|
||||
* `Slim::call` loop. If the route's pattern is defined without a
|
||||
* trailing slash, and if the current request URI does have a trailing
|
||||
* slash, the route will not be matched and a 404 Not Found
|
||||
* response will be sent if no subsequent matching routes are found.
|
||||
*
|
||||
* @param \Slim\Route $route The route object
|
||||
* @return bool Was route callable invoked successfully?
|
||||
* @throws \Slim\Exception\RequestSlash
|
||||
*/
|
||||
public function dispatch(\Slim\Route $route)
|
||||
{
|
||||
if (substr($route->getPattern(), -1) === '/' && substr($this->resourceUri, -1) !== '/') {
|
||||
throw new Exception\RequestSlash();
|
||||
}
|
||||
|
||||
//Invoke middleware
|
||||
foreach ($route->getMiddleware() as $mw) {
|
||||
if (is_callable($mw)) {
|
||||
call_user_func_array($mw, array($route));
|
||||
}
|
||||
}
|
||||
|
||||
//Invoke callable
|
||||
if (is_callable($route->getCallable())) {
|
||||
call_user_func_array($route->getCallable(), array_values($route->getParams()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
return preg_replace(array(
|
||||
'@\(\/?:.+\/??\)\??@',
|
||||
'@\?|\(|\)@'
|
||||
), '', $this->request->getRootUri() . $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -269,12 +181,10 @@ class Router implements \Iterator
|
|||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return mixed
|
||||
*/
|
||||
public function notFound($callable = null)
|
||||
{
|
||||
public function notFound( $callable = null ) {
|
||||
if ( is_callable($callable) ) {
|
||||
$this->notFound = $callable;
|
||||
}
|
||||
|
||||
return $this->notFound;
|
||||
}
|
||||
|
||||
|
@ -283,55 +193,11 @@ class Router implements \Iterator
|
|||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return mixed
|
||||
*/
|
||||
public function error($callable = null)
|
||||
{
|
||||
public function error( $callable = null ) {
|
||||
if ( is_callable($callable) ) {
|
||||
$this->error = $callable;
|
||||
}
|
||||
|
||||
return $this->error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Interface: Rewind
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->matchedRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Interface: Current
|
||||
* @return \Slim\Route|false
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->matchedRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Interface: Key
|
||||
* @return int|null
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return key($this->matchedRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Interface: Next
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
next($this->matchedRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Interface: Valid
|
||||
* @return boolean
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
return $this->current();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,192 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.5.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Flash Messaging
|
||||
*
|
||||
* This class enables Flash messaging. Messages are persisted in $_SESSION
|
||||
* with a user-defined key.
|
||||
*
|
||||
* USAGE:
|
||||
*
|
||||
* 1. Set Flash message to be shown on the next request
|
||||
*
|
||||
* Slim::flash('error', 'The object could not be saved');
|
||||
*
|
||||
* 2. Set Flash message to be shown on the current request
|
||||
*
|
||||
* Slim::flashNow('error', 'The object could not be saved');
|
||||
*
|
||||
* 3. Keep old Flash messages for the next request
|
||||
*
|
||||
* Slim::flashKeep();
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since Version 1.3
|
||||
*/
|
||||
class Slim_Session_Flash implements ArrayAccess {
|
||||
|
||||
/**
|
||||
* @var string Key used to identify flash information in $_SESSION array
|
||||
*/
|
||||
protected $sessionKey = 'flash';
|
||||
|
||||
/**
|
||||
* @var array[array] Storage for flash messages
|
||||
*/
|
||||
protected $messages = array(
|
||||
'prev' => array(), //flash messages from prev request
|
||||
'next' => array(), //flash messages for next request
|
||||
'now' => array() //flash messages for current request
|
||||
);
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* Establishes Flash session key and loads existing
|
||||
* Flash messages from the $_SESSION.
|
||||
*
|
||||
* @param string $sessionKey
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $sessionKey = null ) {
|
||||
if ( !is_null($sessionKey) ) {
|
||||
$this->setSessionKey($sessionKey);
|
||||
}
|
||||
$this->load();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the $_SESSION key used to access Flash messages
|
||||
* @param string $key
|
||||
* @throws RuntimeException If session key is null
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function setSessionKey( $key ) {
|
||||
if ( is_null($key) ) {
|
||||
throw new RuntimeException('Session key cannot be null');
|
||||
}
|
||||
$this->sessionKey = (string)$key;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the $_SESSION key used to access Flash messages
|
||||
* @return string
|
||||
*/
|
||||
public function getSessionKey() {
|
||||
return $this->sessionKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Flash message for the current request
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function now( $key, $value ) {
|
||||
$this->messages['now'][(string)$key] = $value;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a Flash message for the next request
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function set( $key, $value ) {
|
||||
$this->messages['next'][(string)$key] = $value;
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Flash messages intended for the current request's View
|
||||
* @return array[String]
|
||||
*/
|
||||
public function getMessages() {
|
||||
return array_merge($this->messages['prev'], $this->messages['now']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Flash messages from $_SESSION
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function load() {
|
||||
$this->messages['prev'] = isset($_SESSION[$this->sessionKey]) ? $_SESSION[$this->sessionKey] : array();
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Transfer Flash messages from the previous request
|
||||
* so they are available to the next request.
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function keep() {
|
||||
foreach ( $this->messages['prev'] as $key => $val ) {
|
||||
$this->messages['next'][$key] = $val;
|
||||
}
|
||||
return $this->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Flash messages to $_SESSION
|
||||
* @return Slim_Session_Flash
|
||||
*/
|
||||
public function save() {
|
||||
$_SESSION[$this->sessionKey] = $this->messages['next'];
|
||||
return $this;
|
||||
}
|
||||
|
||||
/***** ARRAY ACCESS INTERFACE *****/
|
||||
|
||||
public function offsetExists( $offset ) {
|
||||
$messages = $this->getMessages();
|
||||
return isset($messages[$offset]);
|
||||
}
|
||||
|
||||
public function offsetGet( $offset ) {
|
||||
$messages = $this->getMessages();
|
||||
return isset($messages[$offset]) ? $messages[$offset] : null;
|
||||
}
|
||||
|
||||
public function offsetSet( $offset, $value ) {
|
||||
$this->now($offset, $value);
|
||||
}
|
||||
|
||||
public function offsetUnset( $offset ) {
|
||||
unset($this->messages['prev'][$offset]);
|
||||
unset($this->messages['now'][$offset]);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @copyright 2011 Josh Lockhart
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Abstract Session Handler
|
||||
*
|
||||
* This abstract class should be extended by each concrete
|
||||
* session handler. This class defines the contractual class interface
|
||||
* methods that must be implemented in concrete subclasses. This class
|
||||
* also provides the final `register` method used by Slim itself to
|
||||
* actually register the concrete session handler with PHP.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since Version 1.3
|
||||
*/
|
||||
abstract class Slim_Session_Handler {
|
||||
|
||||
/**
|
||||
* @var Slim
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
/**
|
||||
* Register session handler
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
final public function register( Slim $app ) {
|
||||
$this->app = $app;
|
||||
return session_set_save_handler(
|
||||
array($this, 'open'),
|
||||
array($this, 'close'),
|
||||
array($this, 'read'),
|
||||
array($this, 'write'),
|
||||
array($this, 'destroy'),
|
||||
array($this, 'gc')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Open session
|
||||
*
|
||||
* @param string $savePath
|
||||
* @param string $sessionName
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function open( $savePath, $sessionName );
|
||||
|
||||
/**
|
||||
* Close session
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function close();
|
||||
|
||||
/**
|
||||
* Read session data with ID
|
||||
*
|
||||
* @param string $id The session identifier
|
||||
* @return string
|
||||
*/
|
||||
abstract public function read( $id );
|
||||
|
||||
/**
|
||||
* Write session data with ID
|
||||
*
|
||||
* The "write" handler is not executed until after the output stream is
|
||||
* closed. Thus, output from debugging statements in the "write" handler
|
||||
* will never be seen in the browser. If debugging output is necessary, it
|
||||
* is suggested that the debug output be written to a file instead.
|
||||
*
|
||||
* @param string $id The session identifier
|
||||
* @param mixed $sessionData The session data
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function write( $id, $sessionData );
|
||||
|
||||
/**
|
||||
* Destroy session with ID
|
||||
*
|
||||
* @param string $id The session identifier
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function destroy( $id );
|
||||
|
||||
/**
|
||||
* Session garbage collection
|
||||
*
|
||||
* Executed when the PHP session garbage collector is invoked; should
|
||||
* remove all session data older than the `$maxLifetime`.
|
||||
*
|
||||
* @param int $maxLifetime
|
||||
* @return mixed
|
||||
*/
|
||||
abstract public function gc( $maxLifetime );
|
||||
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @copyright 2011 Josh Lockhart
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Session Cookie Handler
|
||||
*
|
||||
* This class is used as an adapter for PHP's $_SESSION handling.
|
||||
* Session data will be written to and read from signed, encrypted
|
||||
* cookies. If the current PHP installation does not have the `mcrypt`
|
||||
* extension, session data will be written to signed but unencrypted
|
||||
* cookies; however, the session cookies will still be secure and will
|
||||
* become invalid if manually edited after set by PHP.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since Version 1.3
|
||||
*/
|
||||
class Slim_Session_Handler_Cookies extends Slim_Session_Handler {
|
||||
|
||||
public function open( $savePath, $sessionName ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public function close() {
|
||||
return true; //Not used
|
||||
}
|
||||
|
||||
public function read( $id ) {
|
||||
return $this->app->getEncryptedCookie($id);
|
||||
}
|
||||
|
||||
public function write( $id, $sessionData ) {
|
||||
$this->app->setEncryptedCookie($id, $sessionData, 0);
|
||||
}
|
||||
|
||||
public function destroy( $id ) {
|
||||
$this->app->deleteCookie($id);
|
||||
}
|
||||
|
||||
public function gc( $maxLifetime ) {
|
||||
return true; //Not used
|
||||
}
|
||||
|
||||
}
|
1064
Slim/Slim.php
1064
Slim/Slim.php
File diff suppressed because it is too large
Load Diff
163
Slim/View.php
163
Slim/View.php
|
@ -2,12 +2,11 @@
|
|||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
* @version 1.5.0
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
|
@ -30,62 +29,47 @@
|
|||
* 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
|
||||
* 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.
|
||||
* The View is responsible for rendering and/or displaying a template.
|
||||
* It is recommended that you subclass View and re-implement the
|
||||
* `View::render` method to use a custom templating engine such as
|
||||
* Smarty, Twig, Mustache, etc. It is important that `View::render`
|
||||
* `return` the final template output. Do not `echo` the output.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
* @author Josh Lockhart <info@joshlockhart.com>
|
||||
* @since Version 1.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 = '';
|
||||
class Slim_View {
|
||||
|
||||
/**
|
||||
* @var array Associative array of template variables
|
||||
* @var array Key-value array of data available to the template
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @var string Absolute or relative path to the application's templates directory
|
||||
* @var string Absolute or relative path to the templates directory
|
||||
*/
|
||||
protected $templatesDirectory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This is empty but may be implemented in a subclass
|
||||
* This is empty but may be overridden in a subclass
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
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;
|
||||
* @param string $key
|
||||
* @return array|mixed|null All View data if no $key, value of datum
|
||||
* if $key, or NULL if $key but datum
|
||||
* does not exist.
|
||||
*/
|
||||
public function getData($key = null)
|
||||
{
|
||||
public function getData( $key = null ) {
|
||||
if ( !is_null($key) ) {
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
} else {
|
||||
|
@ -96,121 +80,88 @@ class View
|
|||
/**
|
||||
* Set data
|
||||
*
|
||||
* If two arguments:
|
||||
* A single datum with key is assigned value;
|
||||
* This method is overloaded to accept two different method signatures.
|
||||
* You may use this to set a specific key with a specfic value,
|
||||
* or you may use this to set all data to a specific array.
|
||||
*
|
||||
* $view->setData('color', 'red');
|
||||
* USAGE:
|
||||
*
|
||||
* If one argument:
|
||||
* Replace all data with provided array keys and values;
|
||||
* View::setData('color', 'red');
|
||||
* View::setData(array('color' => 'red', 'number' => 1));
|
||||
*
|
||||
* $view->setData(array('color' => 'red', 'number' => 1));
|
||||
*
|
||||
* @param mixed
|
||||
* @param mixed
|
||||
* @param string|array
|
||||
* @param mixed Optional. Only use if first argument is a string.
|
||||
* @return void
|
||||
* @throws InvalidArgumentException If incorrect method signature
|
||||
*/
|
||||
public function setData()
|
||||
{
|
||||
public function setData() {
|
||||
$args = func_get_args();
|
||||
if ( count($args) === 1 && is_array($args[0]) ) {
|
||||
$this->data = $args[0];
|
||||
} else if ( 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, ... ]);`');
|
||||
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
|
||||
* Append data to existing View data
|
||||
* @param array $data
|
||||
* @return void
|
||||
*/
|
||||
public function appendData($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
|
||||
}
|
||||
public function appendData( array $data ) {
|
||||
$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;
|
||||
* @return string|null Path to templates directory without trailing slash
|
||||
*/
|
||||
public function getTemplatesDirectory()
|
||||
{
|
||||
public function getTemplatesDirectory() {
|
||||
return $this->templatesDirectory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set templates directory
|
||||
* @param string $dir
|
||||
* @return void
|
||||
* @throws RuntimeException If directory is not a directory or does not exist
|
||||
*/
|
||||
public function setTemplatesDirectory($dir)
|
||||
{
|
||||
public function setTemplatesDirectory( $dir ) {
|
||||
if ( !is_dir($dir) ) {
|
||||
throw new RuntimeException('Cannot set View templates directory to: ' . $dir . '. Directory does not exist.');
|
||||
}
|
||||
$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
|
||||
* @param string $template Path to template file relative to templates directoy
|
||||
* @return void
|
||||
*/
|
||||
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);
|
||||
public function display( $template ) {
|
||||
echo $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`.
|
||||
* @param string $template Path to template file relative to templates directory
|
||||
* @return string Rendered template
|
||||
* @throws RuntimeException If template does not exist
|
||||
*/
|
||||
public function render($template)
|
||||
{
|
||||
$this->setTemplate($template);
|
||||
public function render( $template ) {
|
||||
extract($this->data);
|
||||
$templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
|
||||
if ( !file_exists($templatePath) ) {
|
||||
throw new RuntimeException('View cannot render template `' . $templatePath . '`. Template does not exist.');
|
||||
}
|
||||
ob_start();
|
||||
require $this->templatePath;
|
||||
|
||||
require $templatePath;
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
function aprspass ($callsign) {
|
||||
$stophere = strpos($callsign, '-');
|
||||
if ($stophere) $callsign = substr($callsign, 0, $stophere);
|
||||
$realcall = strtoupper(substr($callsign, 0, 10));
|
||||
|
||||
// initialize hash
|
||||
$hash = 0x73e2;
|
||||
$i = 0;
|
||||
$len = strlen($realcall);
|
||||
|
||||
// hash callsign two bytes at a time
|
||||
while ($i < $len) {
|
||||
$hash ^= ord(substr($realcall, $i, 1))<<8;
|
||||
$hash ^= ord(substr($realcall, $i + 1, 1));
|
||||
$i += 2;
|
||||
}
|
||||
|
||||
// mask off the high bit so number is always positive
|
||||
return $hash & 0x7fff;
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
// Load Slim
|
||||
require 'Slim/Slim.php';
|
||||
|
||||
$app = new Slim();
|
||||
|
||||
// Functions
|
||||
//GET route
|
||||
$app->get('/', function () {
|
||||
// Require HTML Template
|
||||
require('templates/main.php');
|
||||
});
|
||||
|
||||
$app->post('/passcode', function () {
|
||||
require('aprs_func.php');
|
||||
echo aprspass($_POST['callsign']);
|
||||
});
|
||||
|
||||
|
||||
// Run slim
|
||||
$app->run();
|
||||
|
||||
?>
|
|
@ -0,0 +1,41 @@
|
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||||
|
||||
<head>
|
||||
<title>APRS Passcode Generator</title>
|
||||
<style type="text/css" media="screen">
|
||||
body {
|
||||
font-family: Arial, "MS Trebuchet", sans-serif;
|
||||
font-size: 14px;
|
||||
background-color: whiteSmoke;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin: 0 auto;
|
||||
width: 400px;
|
||||
padding: 10px;
|
||||
border: 1px solid #E5E5E5;
|
||||
background-color: #ffffff;
|
||||
}
|
||||
label {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<div id="container">
|
||||
|
||||
<h1>APRS Passcode Generator</h1>
|
||||
|
||||
<form method="post" action="index.php/passcode">
|
||||
<label for="callsign">Callsign</label>
|
||||
<input type="text" name="callsign" value="" />
|
||||
<input type="submit" name="Submit" value="Get Passcode" />
|
||||
</form>
|
||||
|
||||
<p>Techical Example of Passcode Generation using PHP</p>
|
||||
<p>Source code available on <a href="https://github.com/magicbug/PHP-APRS-Passcode" title="Github" target="_blank">Github</a></p>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
Loading…
Reference in New Issue