bump library versions
This commit is contained in:
parent
3d03cff797
commit
16b22e3263
|
@ -12,6 +12,6 @@ RewriteEngine On
|
|||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
|
||||
<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
|
||||
Header set Cache-Control "max-age=604800, public"
|
||||
</FilesMatch>
|
||||
#<FilesMatch "\.(jpg|jpeg|png|gif|swf)$">
|
||||
#Header set Cache-Control "max-age=604800, public"
|
||||
#</FilesMatch>
|
||||
|
|
26
LICENSE
26
LICENSE
|
@ -1,13 +1,19 @@
|
|||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
Copyright (c) 2012 Josh Lockhart
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
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:
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
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.
|
||||
|
|
188
README.markdown
188
README.markdown
|
@ -1,64 +1,152 @@
|
|||
# Gophper: A Gopher Proxy for Modern Times #
|
||||
# Slim Framework
|
||||
|
||||
The [Gopher](http://en.wikipedia.org/wiki/Gopher_(protocol))
|
||||
protocol was published in 1991. It was popular for some
|
||||
time, but died off in the late 1990s, partially because of some
|
||||
poor decisions by the University of Minnesota (which owned
|
||||
the licensing rights), and also because HTTP and HTML was
|
||||
undoubtedly a better system for what became the World Wide Web.
|
||||
[![Build Status](https://secure.travis-ci.org/codeguy/Slim.png)](http://travis-ci.org/codeguy/Slim)
|
||||
|
||||
There are still gopher servers out there today, but most
|
||||
browsers can't visit them anymore, because support for the
|
||||
Gopher protocol has been removed. There are a couple of
|
||||
proxy servers out there, but they all suck, and none of them
|
||||
are open-source, so I wrote Gophper, a very simple proxy
|
||||
server with a small PHP backend, and a parser written in
|
||||
Javascript.
|
||||
Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs.
|
||||
Slim is easy to use for both beginners and professionals. Slim favors cleanliness over terseness and common cases
|
||||
over edge cases. Its interface is simple, intuitive, and extensively documented — both online and in the code itself.
|
||||
Thank you for choosing the Slim Framework for your next project. I think you're going to love it.
|
||||
|
||||
## About Gophper ##
|
||||
## Features
|
||||
|
||||
Gophper has a bunch of cool features:
|
||||
* Powerful router
|
||||
* Standard and custom HTTP methods
|
||||
* Route parameters with wildcards and conditions
|
||||
* Route redirect, halt, and pass
|
||||
* Route middleware
|
||||
* Template rendering with custom views
|
||||
* Flash messages
|
||||
* Secure cookies with AES-256 encryption
|
||||
* HTTP caching
|
||||
* Logging with custom log writers
|
||||
* Error handling and debugging
|
||||
* Middleware and hook architecture
|
||||
* Simple configuration
|
||||
|
||||
* The backend is written in PHP using the Slim framework. It is very
|
||||
simple and easy to modify.
|
||||
* The bulk of the work is done in Javascript, so you can very easily
|
||||
re-implement with a different backend if desired.
|
||||
* Uses the Twitter Bootstrap framework for output -- it's visually
|
||||
appealing, generates nice code, and should be easy to tweak if
|
||||
needed.
|
||||
* It caches gopher pages for fast performance.
|
||||
* Displays images in modal windows
|
||||
* Detects when a user has requested a binary file (Image, Document,
|
||||
etc) and returns that file to the browser, rather than returning junk
|
||||
and crashing your browser like most gopher proxies.
|
||||
* Report traffic to GA, and also track stats locally to present reports to users.
|
||||
* Restrict the proxy to a single host or port if desired. That way you
|
||||
can use it as the web frontend to your nifty gopher project.
|
||||
## Getting Started
|
||||
|
||||
## Using Gophper ##
|
||||
### Install
|
||||
|
||||
Using Gophper is easy:
|
||||
* drop the code wherever you want it
|
||||
* copy config.php.example to config.php, and update any values inside
|
||||
if needed
|
||||
* If you want to track traffic in the database, run stats.sql, and
|
||||
make sure that you've set the right login credentials in the config
|
||||
file.
|
||||
* Update templates/intro.html if you want, to point to your Gopher
|
||||
server, etc. Right now, it has a description of gophper-proxy and
|
||||
links to some popular gopher sites.
|
||||
You may install the Slim Framework with Composer (recommended) or manually.
|
||||
|
||||
## Bugs/Troubleshooting ##
|
||||
[Read how to install Slim](http://docs.slimframework.com/pages/getting-started-install)
|
||||
|
||||
If you have a problem, feel free to submit a support request on Github.
|
||||
### System Requirements
|
||||
|
||||
## TODO ##
|
||||
You need **PHP >= 5.3.0**. If you use encrypted cookies, you'll also need the `mcrypt` extension.
|
||||
|
||||
* Make it possible to run in a subdirectory
|
||||
### Hello World Tutorial
|
||||
|
||||
## Copyright/License ##
|
||||
Instantiate a Slim application:
|
||||
|
||||
Copyright (c) 2012 Colin Mitchell. Licensed under WTFPL
|
||||
licence. Please see LICENSE.txt for further details.
|
||||
$app = new \Slim\Slim();
|
||||
|
||||
http://muffinlabs.com
|
||||
Define a HTTP GET route:
|
||||
|
||||
$app->get('/hello/:name', function ($name) {
|
||||
echo "Hello, $name";
|
||||
});
|
||||
|
||||
Run the Slim application:
|
||||
|
||||
$app->run();
|
||||
|
||||
### Setup your web server
|
||||
|
||||
#### Apache
|
||||
|
||||
Ensure the `.htaccess` and `index.php` files are in the same public-accessible directory. The `.htaccess` file
|
||||
should contain this code:
|
||||
|
||||
RewriteEngine On
|
||||
RewriteCond %{REQUEST_FILENAME} !-f
|
||||
RewriteRule ^ index.php [QSA,L]
|
||||
|
||||
#### Nginx
|
||||
|
||||
Your nginx configuration file should contain this code (along with other settings you may need) in your `location` block:
|
||||
|
||||
try_files $uri $uri/ /index.php;
|
||||
|
||||
This assumes that Slim's `index.php` is in the root folder of your project (www root).
|
||||
|
||||
#### lighttpd ####
|
||||
|
||||
Your lighttpd configuration file should contain this code (along with other settings you may need). This code requires
|
||||
lighttpd >= 1.4.24.
|
||||
|
||||
url.rewrite-if-not-file = ("(.*)" => "/index.php/$0")
|
||||
|
||||
This assumes that Slim's `index.php` is in the root folder of your project (www root).
|
||||
|
||||
#### IIS
|
||||
|
||||
Ensure the `Web.config` and `index.php` files are in the same public-accessible directory. The `Web.config` file should contain this code:
|
||||
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<configuration>
|
||||
<system.webServer>
|
||||
<rewrite>
|
||||
<rules>
|
||||
<rule name="slim" patternSyntax="Wildcard">
|
||||
<match url="*" />
|
||||
<conditions>
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
|
||||
<add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
|
||||
</conditions>
|
||||
<action type="Rewrite" url="index.php" />
|
||||
</rule>
|
||||
</rules>
|
||||
</rewrite>
|
||||
</system.webServer>
|
||||
</configuration>
|
||||
|
||||
## Documentation
|
||||
|
||||
<http://docs.slimframework.com/>
|
||||
|
||||
## How to Contribute
|
||||
|
||||
### Pull Requests
|
||||
|
||||
1. Fork the Slim Framework repository
|
||||
2. Create a new branch for each feature or improvement
|
||||
3. Send a pull request from each feature branch to the **develop** branch
|
||||
|
||||
It is very important to separate new features or improvements into separate feature branches, and to send a pull
|
||||
request for each branch. This allows me to review and pull in new features or improvements individually.
|
||||
|
||||
### Style Guide
|
||||
|
||||
All pull requests must adhere to the [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md) standard.
|
||||
|
||||
### Unit Testing
|
||||
|
||||
All pull requests must be accompanied by passing unit tests and complete code coverage. The Slim Framework uses
|
||||
`phpunit` for testing.
|
||||
|
||||
[Learn about PHPUnit](https://github.com/sebastianbergmann/phpunit/)
|
||||
|
||||
## Community
|
||||
|
||||
### Forum and Knowledgebase
|
||||
|
||||
Visit Slim's official forum and knowledge base at <http://help.slimframework.com> where you can find announcements,
|
||||
chat with fellow Slim users, ask questions, help others, or show off your cool Slim Framework apps.
|
||||
|
||||
### Twitter
|
||||
|
||||
Follow [@slimphp](http://www.twitter.com/slimphp) on Twitter to receive news and updates about the framework.
|
||||
|
||||
## Author
|
||||
|
||||
The Slim Framework is created and maintained by [Josh Lockhart](https://www.joshlockhart.com). Josh is a senior
|
||||
web developer at [New Media Campaigns](http://www.newmediacampaigns.com/). Josh also created and maintains
|
||||
[PHP: The Right Way](http://www.phptherightway.com/), a popular movement in the PHP community to introduce new
|
||||
PHP programmers to best practices and good information.
|
||||
|
||||
## License
|
||||
|
||||
The Slim Framework is released under the MIT public license.
|
||||
|
||||
<http://www.slimframework.com/license>
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Environment
|
||||
|
@ -47,41 +48,45 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
||||
class Environment implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
protected $properties;
|
||||
|
||||
/**
|
||||
* @var Slim_Environment
|
||||
* @var \Slim\Environment
|
||||
*/
|
||||
protected static $environment;
|
||||
|
||||
/**
|
||||
* Get environment instance (singleton)
|
||||
*
|
||||
* This creates and/or returns an Environment instance (singleton)
|
||||
* derived from $_SERVER variables. You may override the global server
|
||||
* variables by using `Environment::mock()` instead.
|
||||
* This creates and/or returns an environment instance (singleton)
|
||||
* derived from $_SERVER variables. You may override the global server
|
||||
* variables by using `\Slim\Environment::mock()` instead.
|
||||
*
|
||||
* @param bool $refresh Refresh properties using global server variables?
|
||||
* @return Slim_Environment
|
||||
* @param bool $refresh Refresh properties using global server variables?
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function getInstance( $refresh = false ) {
|
||||
if ( is_null(self::$environment) || $refresh ) {
|
||||
public static function getInstance($refresh = false)
|
||||
{
|
||||
if (is_null(self::$environment) || $refresh) {
|
||||
self::$environment = new self();
|
||||
}
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mock environment instance
|
||||
*
|
||||
* @param array $userSettings
|
||||
* @return Environment
|
||||
* @param array $userSettings
|
||||
* @return \Slim\Environment
|
||||
*/
|
||||
public static function mock( $userSettings = array() ) {
|
||||
public static function mock($userSettings = array())
|
||||
{
|
||||
self::$environment = new self(array_merge(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '',
|
||||
|
@ -98,17 +103,18 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
'slim.input' => '',
|
||||
'slim.errors' => @fopen('php://stderr', 'w')
|
||||
), $userSettings));
|
||||
|
||||
return self::$environment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor (private access)
|
||||
*
|
||||
* @param array|null $settings If present, these are used instead of global server variables
|
||||
* @return void
|
||||
* @param array|null $settings If present, these are used instead of global server variables
|
||||
*/
|
||||
private function __construct( $settings = null ) {
|
||||
if ( $settings ) {
|
||||
private function __construct($settings = null)
|
||||
{
|
||||
if ($settings) {
|
||||
$this->properties = $settings;
|
||||
} else {
|
||||
$env = array();
|
||||
|
@ -134,13 +140,13 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
* The PATH_INFO will be an absolute path with a leading slash; this will be
|
||||
* used for application routing.
|
||||
*/
|
||||
if ( strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0 ) {
|
||||
if (strpos($_SERVER['REQUEST_URI'], $_SERVER['SCRIPT_NAME']) === 0) {
|
||||
$env['SCRIPT_NAME'] = $_SERVER['SCRIPT_NAME']; //Without URL rewrite
|
||||
} else {
|
||||
$env['SCRIPT_NAME'] = pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_DIRNAME); //With URL rewrite
|
||||
$env['SCRIPT_NAME'] = str_replace('\\', '/', dirname($_SERVER['SCRIPT_NAME']) ); //With URL rewrite
|
||||
}
|
||||
$env['PATH_INFO'] = substr_replace($_SERVER['REQUEST_URI'], '', 0, strlen($env['SCRIPT_NAME']));
|
||||
if ( strpos($env['PATH_INFO'], '?') !== false ) {
|
||||
if (strpos($env['PATH_INFO'], '?') !== false) {
|
||||
$env['PATH_INFO'] = substr_replace($env['PATH_INFO'], '', strpos($env['PATH_INFO'], '?')); //query string is not removed automatically
|
||||
}
|
||||
$env['SCRIPT_NAME'] = rtrim($env['SCRIPT_NAME'], '/');
|
||||
|
@ -157,10 +163,11 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
|
||||
//HTTP request headers
|
||||
$specialHeaders = array('CONTENT_TYPE', 'CONTENT_LENGTH', 'PHP_AUTH_USER', 'PHP_AUTH_PW', 'PHP_AUTH_DIGEST', 'AUTH_TYPE');
|
||||
foreach ( $_SERVER as $key => $value ) {
|
||||
if ( strpos($key, 'HTTP_') === 0 ) {
|
||||
foreach ($_SERVER as $key => $value) {
|
||||
$value = is_string($value) ? trim($value) : $value;
|
||||
if (strpos($key, 'HTTP_') === 0) {
|
||||
$env[substr($key, 5)] = $value;
|
||||
} else if ( strpos($key, 'X_') === 0 || in_array($key, $specialHeaders) ) {
|
||||
} elseif (strpos($key, 'X_') === 0 || in_array($key, $specialHeaders)) {
|
||||
$env[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
@ -170,7 +177,7 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
|
||||
//Input stream (readable one time only; not available for mutipart/form-data requests)
|
||||
$rawInput = @file_get_contents('php://input');
|
||||
if ( !$rawInput ) {
|
||||
if (!$rawInput) {
|
||||
$rawInput = '';
|
||||
}
|
||||
$env['slim.input'] = $rawInput;
|
||||
|
@ -185,15 +192,17 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
if ( isset($this->properties[$offset]) ) {
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
if (isset($this->properties[$offset])) {
|
||||
return $this->properties[$offset];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -203,23 +212,26 @@ class Slim_Environment implements ArrayAccess, IteratorAggregate {
|
|||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->properties[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset( $offset ) {
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->properties[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* IteratorAggregate
|
||||
*
|
||||
* @return ArrayIterator
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->properties);
|
||||
public function getIterator()
|
||||
{
|
||||
return new \ArrayIterator($this->properties);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* 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
|
||||
|
@ -43,4 +44,7 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Exception_Pass extends Exception {}
|
||||
class Pass extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* 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
|
||||
|
@ -41,4 +42,7 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Exception_Stop extends Exception {}
|
||||
class Stop extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* HTTP Headers
|
||||
|
@ -46,7 +47,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
|
||||
class Headers implements \ArrayAccess, \Iterator, \Countable
|
||||
{
|
||||
/**
|
||||
* @var array HTTP headers
|
||||
*/
|
||||
|
@ -59,46 +61,49 @@ class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $headers
|
||||
* @return void
|
||||
* @param array $headers
|
||||
*/
|
||||
public function __construct( $headers = array() ) {
|
||||
public function __construct($headers = array())
|
||||
{
|
||||
$this->merge($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge Headers
|
||||
* @param array $headers
|
||||
* @return void
|
||||
* @param array $headers
|
||||
*/
|
||||
public function merge( $headers ) {
|
||||
foreach ( $headers as $name => $value ) {
|
||||
public function merge($headers)
|
||||
{
|
||||
foreach ($headers as $name => $value) {
|
||||
$this[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform header name into canonical form
|
||||
* @param string $name
|
||||
* @return string
|
||||
* @param string $name
|
||||
* @return string
|
||||
*/
|
||||
protected function canonical( $name ) {
|
||||
protected function canonical($name)
|
||||
{
|
||||
return strtolower(trim($name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
return isset($this->headers[$this->canonical($offset)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
if ( isset($this->headers[$canonical]) ) {
|
||||
if (isset($this->headers[$canonical])) {
|
||||
return $this->headers[$canonical];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -108,7 +113,8 @@ class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
|
|||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
$this->headers[$canonical] = $value;
|
||||
$this->map[$canonical] = $offset;
|
||||
|
@ -117,7 +123,8 @@ class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
|
|||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset( $offset ) {
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
$canonical = $this->canonical($offset);
|
||||
unset($this->headers[$canonical], $this->map[$canonical]);
|
||||
}
|
||||
|
@ -125,43 +132,50 @@ class Slim_Http_Headers implements ArrayAccess, Iterator, Countable {
|
|||
/**
|
||||
* Countable: Count
|
||||
*/
|
||||
public function count() {
|
||||
public function count()
|
||||
{
|
||||
return count($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Rewind
|
||||
*/
|
||||
public function rewind() {
|
||||
public function rewind()
|
||||
{
|
||||
reset($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Current
|
||||
*/
|
||||
public function current() {
|
||||
public function current()
|
||||
{
|
||||
return current($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Key
|
||||
*/
|
||||
public function key() {
|
||||
public function key()
|
||||
{
|
||||
$key = key($this->headers);
|
||||
|
||||
return $this->map[$key];
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Next
|
||||
*/
|
||||
public function next() {
|
||||
public function next()
|
||||
{
|
||||
return next($this->headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator: Valid
|
||||
*/
|
||||
public function valid() {
|
||||
public function valid()
|
||||
{
|
||||
return current($this->headers) !== false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* 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
|
||||
|
@ -41,7 +42,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Http_Request {
|
||||
class Request
|
||||
{
|
||||
const METHOD_HEAD = 'HEAD';
|
||||
const METHOD_GET = 'GET';
|
||||
const METHOD_POST = 'POST';
|
||||
|
@ -62,10 +64,11 @@ class Slim_Http_Request {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param array $env
|
||||
* @see Slim_Environment
|
||||
* @param array $env
|
||||
* @see \Slim\Environment
|
||||
*/
|
||||
public function __construct( $env ) {
|
||||
public function __construct($env)
|
||||
{
|
||||
$this->env = $env;
|
||||
}
|
||||
|
||||
|
@ -73,7 +76,8 @@ class Slim_Http_Request {
|
|||
* Get HTTP method
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod() {
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->env['REQUEST_METHOD'];
|
||||
}
|
||||
|
||||
|
@ -81,7 +85,8 @@ class Slim_Http_Request {
|
|||
* Is this a GET request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isGet() {
|
||||
public function isGet()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_GET;
|
||||
}
|
||||
|
||||
|
@ -89,7 +94,8 @@ class Slim_Http_Request {
|
|||
* Is this a POST request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPost() {
|
||||
public function isPost()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_POST;
|
||||
}
|
||||
|
||||
|
@ -97,7 +103,8 @@ class Slim_Http_Request {
|
|||
* Is this a PUT request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isPut() {
|
||||
public function isPut()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_PUT;
|
||||
}
|
||||
|
||||
|
@ -105,7 +112,8 @@ class Slim_Http_Request {
|
|||
* Is this a DELETE request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isDelete() {
|
||||
public function isDelete()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_DELETE;
|
||||
}
|
||||
|
||||
|
@ -113,7 +121,8 @@ class Slim_Http_Request {
|
|||
* Is this a HEAD request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isHead() {
|
||||
public function isHead()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_HEAD;
|
||||
}
|
||||
|
||||
|
@ -121,7 +130,8 @@ class Slim_Http_Request {
|
|||
* Is this a OPTIONS request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isOptions() {
|
||||
public function isOptions()
|
||||
{
|
||||
return $this->getMethod() === self::METHOD_OPTIONS;
|
||||
}
|
||||
|
||||
|
@ -129,10 +139,11 @@ class Slim_Http_Request {
|
|||
* Is this an AJAX request?
|
||||
* @return bool
|
||||
*/
|
||||
public function isAjax() {
|
||||
if ( $this->params('isajax') ) {
|
||||
public function isAjax()
|
||||
{
|
||||
if ($this->params('isajax')) {
|
||||
return true;
|
||||
} else if ( isset($this->env['X_REQUESTED_WITH']) && $this->env['X_REQUESTED_WITH'] === 'XMLHttpRequest' ) {
|
||||
} elseif (isset($this->env['X_REQUESTED_WITH']) && $this->env['X_REQUESTED_WITH'] === 'XMLHttpRequest') {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
|
@ -143,7 +154,8 @@ class Slim_Http_Request {
|
|||
* Is this an XHR request? (alias of Slim_Http_Request::isAjax)
|
||||
* @return bool
|
||||
*/
|
||||
public function isXhr() {
|
||||
public function isXhr()
|
||||
{
|
||||
return $this->isAjax();
|
||||
}
|
||||
|
||||
|
@ -153,13 +165,14 @@ class Slim_Http_Request {
|
|||
* 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
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function params( $key = null ) {
|
||||
public function params($key = null)
|
||||
{
|
||||
$union = array_merge($this->get(), $this->post());
|
||||
if ( $key ) {
|
||||
if ( isset($union[$key]) ) {
|
||||
if ($key) {
|
||||
if (isset($union[$key])) {
|
||||
return $union[$key];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -175,21 +188,22 @@ class Slim_Http_Request {
|
|||
* This method returns a key-value array of data sent in the HTTP request query string, or
|
||||
* the value of the array key if requested; if the array key does not exist, NULL is returned.
|
||||
*
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function get( $key = null ) {
|
||||
if ( !isset($this->env['slim.request.query_hash']) ) {
|
||||
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']) ) {
|
||||
if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
|
||||
mb_parse_str($this->env['QUERY_STRING'], $output);
|
||||
} else {
|
||||
parse_str($this->env['QUERY_STRING'], $output);
|
||||
}
|
||||
$this->env['slim.request.query_hash'] = Slim_Http_Util::stripSlashesIfMagicQuotes($output);
|
||||
$this->env['slim.request.query_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
}
|
||||
if ( $key ) {
|
||||
if ( isset($this->env['slim.request.query_hash'][$key]) ) {
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.query_hash'][$key])) {
|
||||
return $this->env['slim.request.query_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -205,28 +219,31 @@ class Slim_Http_Request {
|
|||
* 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
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* @throws \RuntimeException If environment input is not available
|
||||
*/
|
||||
public function post( $key = null ) {
|
||||
if ( !isset($this->env['slim.input']) ) {
|
||||
throw new RuntimeException('Missing slim.input in environment variables');
|
||||
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']) ) {
|
||||
if (!isset($this->env['slim.request.form_hash'])) {
|
||||
$this->env['slim.request.form_hash'] = array();
|
||||
if ( $this->isFormData() ) {
|
||||
if ($this->isFormData() && is_string($this->env['slim.input'])) {
|
||||
$output = array();
|
||||
if ( function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte']) ) {
|
||||
if (function_exists('mb_parse_str') && !isset($this->env['slim.tests.ignore_multibyte'])) {
|
||||
mb_parse_str($this->env['slim.input'], $output);
|
||||
} else {
|
||||
parse_str($this->env['slim.input'], $output);
|
||||
}
|
||||
$this->env['slim.request.form_hash'] = Slim_Http_Util::stripSlashesIfMagicQuotes($output);
|
||||
$this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($output);
|
||||
} else {
|
||||
$this->env['slim.request.form_hash'] = Util::stripSlashesIfMagicQuotes($_POST);
|
||||
}
|
||||
}
|
||||
if ( $key ) {
|
||||
if ( isset($this->env['slim.request.form_hash'][$key]) ) {
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.form_hash'][$key])) {
|
||||
return $this->env['slim.request.form_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -237,11 +254,22 @@ class Slim_Http_Request {
|
|||
}
|
||||
|
||||
/**
|
||||
* Fetch PUT data (alias for Slim_Http_Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
* Fetch PUT data (alias for \Slim\Http\Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function put( $key = null ) {
|
||||
public function put($key = null)
|
||||
{
|
||||
return $this->post($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch DELETE data (alias for \Slim\Http\Request::post)
|
||||
* @param string $key
|
||||
* @return array|mixed|null
|
||||
*/
|
||||
public function delete($key = null)
|
||||
{
|
||||
return $this->post($key);
|
||||
}
|
||||
|
||||
|
@ -251,16 +279,17 @@ class Slim_Http_Request {
|
|||
* 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
|
||||
* @param string $key
|
||||
* @return array|string|null
|
||||
*/
|
||||
public function cookies( $key = null ) {
|
||||
if ( !isset($this->env['slim.request.cookie_hash']) ) {
|
||||
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'] = Slim_Http_Util::parseCookieHeader($cookieHeader);
|
||||
$this->env['slim.request.cookie_hash'] = Util::parseCookieHeader($cookieHeader);
|
||||
}
|
||||
if ( $key ) {
|
||||
if ( isset($this->env['slim.request.cookie_hash'][$key]) ) {
|
||||
if ($key) {
|
||||
if (isset($this->env['slim.request.cookie_hash'][$key])) {
|
||||
return $this->env['slim.request.cookie_hash'][$key];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -274,9 +303,11 @@ class Slim_Http_Request {
|
|||
* Does the Request body contain parseable form data?
|
||||
* @return bool
|
||||
*/
|
||||
public function isFormData() {
|
||||
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);
|
||||
|
||||
return ($method === self::METHOD_POST && is_null($this->getContentType())) || in_array($this->getMediaType(), self::$formDataMediaTypes);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -285,27 +316,29 @@ class Slim_Http_Request {
|
|||
* 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
|
||||
* @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 ) {
|
||||
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]) ) {
|
||||
if (isset($this->env[$key])) {
|
||||
return $this->env[$key];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
} else {
|
||||
$headers = array();
|
||||
foreach ( $this->env as $key => $value ) {
|
||||
if ( strpos($key, 'slim.') !== 0 ) {
|
||||
foreach ($this->env as $key => $value) {
|
||||
if (strpos($key, 'slim.') !== 0) {
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $headers;
|
||||
}
|
||||
}
|
||||
|
@ -314,7 +347,8 @@ class Slim_Http_Request {
|
|||
* Get Body
|
||||
* @return string
|
||||
*/
|
||||
public function getBody() {
|
||||
public function getBody()
|
||||
{
|
||||
return $this->env['slim.input'];
|
||||
}
|
||||
|
||||
|
@ -322,8 +356,9 @@ class Slim_Http_Request {
|
|||
* Get Content Type
|
||||
* @return string
|
||||
*/
|
||||
public function getContentType() {
|
||||
if ( isset($this->env['CONTENT_TYPE']) ) {
|
||||
public function getContentType()
|
||||
{
|
||||
if (isset($this->env['CONTENT_TYPE'])) {
|
||||
return $this->env['CONTENT_TYPE'];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -334,10 +369,12 @@ class Slim_Http_Request {
|
|||
* Get Media Type (type/subtype within Content Type header)
|
||||
* @return string|null
|
||||
*/
|
||||
public function getMediaType() {
|
||||
public function getMediaType()
|
||||
{
|
||||
$contentType = $this->getContentType();
|
||||
if ( $contentType ) {
|
||||
if ($contentType) {
|
||||
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
|
||||
|
||||
return strtolower($contentTypeParts[0]);
|
||||
} else {
|
||||
return null;
|
||||
|
@ -348,17 +385,19 @@ class Slim_Http_Request {
|
|||
* Get Media Type Params
|
||||
* @return array
|
||||
*/
|
||||
public function getMediaTypeParams() {
|
||||
public function getMediaTypeParams()
|
||||
{
|
||||
$contentType = $this->getContentType();
|
||||
$contentTypeParams = array();
|
||||
if ( $contentType ) {
|
||||
if ($contentType) {
|
||||
$contentTypeParts = preg_split('/\s*[;,]\s*/', $contentType);
|
||||
$contentTypePartsLength = count($contentTypeParts);
|
||||
for ( $i = 1; $i < $contentTypePartsLength; $i++ ) {
|
||||
for ($i = 1; $i < $contentTypePartsLength; $i++) {
|
||||
$paramParts = explode('=', $contentTypeParts[$i]);
|
||||
$contentTypeParams[strtolower($paramParts[0])] = $paramParts[1];
|
||||
}
|
||||
}
|
||||
|
||||
return $contentTypeParams;
|
||||
}
|
||||
|
||||
|
@ -366,9 +405,10 @@ class Slim_Http_Request {
|
|||
* Get Content Charset
|
||||
* @return string|null
|
||||
*/
|
||||
public function getContentCharset() {
|
||||
public function getContentCharset()
|
||||
{
|
||||
$mediaTypeParams = $this->getMediaTypeParams();
|
||||
if ( isset($mediaTypeParams['charset']) ) {
|
||||
if (isset($mediaTypeParams['charset'])) {
|
||||
return $mediaTypeParams['charset'];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -379,9 +419,10 @@ class Slim_Http_Request {
|
|||
* Get Content-Length
|
||||
* @return int
|
||||
*/
|
||||
public function getContentLength() {
|
||||
if ( isset($this->env['CONTENT_LENGTH']) ) {
|
||||
return (int)$this->env['CONTENT_LENGTH'];
|
||||
public function getContentLength()
|
||||
{
|
||||
if (isset($this->env['CONTENT_LENGTH'])) {
|
||||
return (int) $this->env['CONTENT_LENGTH'];
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
@ -391,8 +432,15 @@ class Slim_Http_Request {
|
|||
* Get Host
|
||||
* @return string
|
||||
*/
|
||||
public function getHost() {
|
||||
if ( isset($this->env['HOST']) ) {
|
||||
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'];
|
||||
|
@ -403,7 +451,8 @@ class Slim_Http_Request {
|
|||
* Get Host with Port
|
||||
* @return string
|
||||
*/
|
||||
public function getHostWithPort() {
|
||||
public function getHostWithPort()
|
||||
{
|
||||
return sprintf('%s:%s', $this->getHost(), $this->getPort());
|
||||
}
|
||||
|
||||
|
@ -411,15 +460,17 @@ class Slim_Http_Request {
|
|||
* Get Port
|
||||
* @return int
|
||||
*/
|
||||
public function getPort() {
|
||||
return (int)$this->env['SERVER_PORT'];
|
||||
public function getPort()
|
||||
{
|
||||
return (int) $this->env['SERVER_PORT'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Scheme (https or http)
|
||||
* @return string
|
||||
*/
|
||||
public function getScheme() {
|
||||
public function getScheme()
|
||||
{
|
||||
return $this->env['slim.url_scheme'];
|
||||
}
|
||||
|
||||
|
@ -427,7 +478,8 @@ class Slim_Http_Request {
|
|||
* Get Script Name (physical path)
|
||||
* @return string
|
||||
*/
|
||||
public function getScriptName() {
|
||||
public function getScriptName()
|
||||
{
|
||||
return $this->env['SCRIPT_NAME'];
|
||||
}
|
||||
|
||||
|
@ -435,7 +487,8 @@ class Slim_Http_Request {
|
|||
* LEGACY: Get Root URI (alias for Slim_Http_Request::getScriptName)
|
||||
* @return string
|
||||
*/
|
||||
public function getRootUri() {
|
||||
public function getRootUri()
|
||||
{
|
||||
return $this->getScriptName();
|
||||
}
|
||||
|
||||
|
@ -443,7 +496,8 @@ class Slim_Http_Request {
|
|||
* Get Path (physical path + virtual path)
|
||||
* @return string
|
||||
*/
|
||||
public function getPath() {
|
||||
public function getPath()
|
||||
{
|
||||
return $this->getScriptName() . $this->getPathInfo();
|
||||
}
|
||||
|
||||
|
@ -451,7 +505,8 @@ class Slim_Http_Request {
|
|||
* Get Path Info (virtual path)
|
||||
* @return string
|
||||
*/
|
||||
public function getPathInfo() {
|
||||
public function getPathInfo()
|
||||
{
|
||||
return $this->env['PATH_INFO'];
|
||||
}
|
||||
|
||||
|
@ -459,7 +514,8 @@ class Slim_Http_Request {
|
|||
* LEGACY: Get Resource URI (alias for Slim_Http_Request::getPathInfo)
|
||||
* @return string
|
||||
*/
|
||||
public function getResourceUri() {
|
||||
public function getResourceUri()
|
||||
{
|
||||
return $this->getPathInfo();
|
||||
}
|
||||
|
||||
|
@ -467,11 +523,13 @@ class Slim_Http_Request {
|
|||
* Get URL (scheme + host [ + port if non-standard ])
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl() {
|
||||
public function getUrl()
|
||||
{
|
||||
$url = $this->getScheme() . '://' . $this->getHost();
|
||||
if ( ( $this->getScheme() === 'https' && $this->getPort() !== 443 ) || ( $this->getScheme() === 'http' && $this->getPort() !== 80 ) ) {
|
||||
if (($this->getScheme() === 'https' && $this->getPort() !== 443) || ($this->getScheme() === 'http' && $this->getPort() !== 80)) {
|
||||
$url .= sprintf(':%s', $this->getPort());
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
|
@ -479,7 +537,14 @@ class Slim_Http_Request {
|
|||
* Get IP
|
||||
* @return string
|
||||
*/
|
||||
public function getIp() {
|
||||
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'];
|
||||
}
|
||||
|
||||
|
@ -487,8 +552,9 @@ class Slim_Http_Request {
|
|||
* Get Referrer
|
||||
* @return string|null
|
||||
*/
|
||||
public function getReferrer() {
|
||||
if ( isset($this->env['REFERER']) ) {
|
||||
public function getReferrer()
|
||||
{
|
||||
if (isset($this->env['REFERER'])) {
|
||||
return $this->env['REFERER'];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -499,7 +565,8 @@ class Slim_Http_Request {
|
|||
* Get Referer (for those who can't spell)
|
||||
* @return string|null
|
||||
*/
|
||||
public function getReferer() {
|
||||
public function getReferer()
|
||||
{
|
||||
return $this->getReferrer();
|
||||
}
|
||||
|
||||
|
@ -507,8 +574,9 @@ class Slim_Http_Request {
|
|||
* Get User Agent
|
||||
* @return string|null
|
||||
*/
|
||||
public function getUserAgent() {
|
||||
if ( isset($this->env['USER_AGENT']) ) {
|
||||
public function getUserAgent()
|
||||
{
|
||||
if (isset($this->env['USER_AGENT'])) {
|
||||
return $this->env['USER_AGENT'];
|
||||
} else {
|
||||
return null;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* 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
|
||||
|
@ -42,15 +43,15 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
||||
class Response implements \ArrayAccess, \Countable, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var int HTTP status code
|
||||
*/
|
||||
protected $status;
|
||||
|
||||
/**
|
||||
* @var Slim_Http_Headers List of HTTP response headers
|
||||
* @see Slim_Http_Headers
|
||||
* @var \Slim\Http\Headers List of HTTP response headers
|
||||
*/
|
||||
protected $header;
|
||||
|
||||
|
@ -120,91 +121,103 @@ class Slim_Http_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
|
||||
* @param string $body The HTTP response body
|
||||
* @param int $status The HTTP response status
|
||||
* @param \Slim\Http\Headers|array $header The HTTP response headers
|
||||
*/
|
||||
public function __construct( $body = '', $status = 200, $header = array() ) {
|
||||
$this->status = (int)$status;
|
||||
public function __construct($body = '', $status = 200, $header = array())
|
||||
{
|
||||
$this->status = (int) $status;
|
||||
$headers = array();
|
||||
foreach ( $header as $key => $value ) {
|
||||
foreach ($header as $key => $value) {
|
||||
$headers[$key] = $value;
|
||||
}
|
||||
$this->header = new Slim_Http_Headers(array_merge(array('Content-Type' => 'text/html'), $headers));
|
||||
$this->header = new Headers(array_merge(array('Content-Type' => 'text/html'), $headers));
|
||||
$this->body = '';
|
||||
$this->write($body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set status
|
||||
* @param int|null $status
|
||||
* @return int
|
||||
* @param int|null $status
|
||||
* @return int
|
||||
*/
|
||||
public function status( $status = null ) {
|
||||
if ( !is_null($status) ) {
|
||||
$this->status = (int)$status;
|
||||
public function status($status = null)
|
||||
{
|
||||
if (!is_null($status)) {
|
||||
$this->status = (int) $status;
|
||||
}
|
||||
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set header
|
||||
* @param string $name Header name
|
||||
* @param string|null $value Header value
|
||||
* @return string Header value
|
||||
* @param string $name Header name
|
||||
* @param string|null $value Header value
|
||||
* @return string Header value
|
||||
*/
|
||||
public function header( $name, $value = null ) {
|
||||
if ( !is_null($value) ) {
|
||||
public function header($name, $value = null)
|
||||
{
|
||||
if (!is_null($value)) {
|
||||
$this[$name] = $value;
|
||||
}
|
||||
|
||||
return $this[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get headers
|
||||
* @return Slim_Http_Headers
|
||||
* @return \Slim\Http\Headers
|
||||
*/
|
||||
public function headers() {
|
||||
public function headers()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set body
|
||||
* @param string|null $body Content of HTTP response body
|
||||
* @return string
|
||||
* @param string|null $body Content of HTTP response body
|
||||
* @return string
|
||||
*/
|
||||
public function body( $body = null ) {
|
||||
if ( !is_null($body) ) {
|
||||
public function body($body = null)
|
||||
{
|
||||
if (!is_null($body)) {
|
||||
$this->write($body, true);
|
||||
}
|
||||
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set length
|
||||
* @param int|null $length
|
||||
* @return int
|
||||
* @param int|null $length
|
||||
* @return int
|
||||
*/
|
||||
public function length( $length = null ) {
|
||||
if ( !is_null($length) ) {
|
||||
$this->length = (int)$length;
|
||||
public function length($length = null)
|
||||
{
|
||||
if (!is_null($length)) {
|
||||
$this->length = (int) $length;
|
||||
}
|
||||
|
||||
return $this->length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append HTTP response body
|
||||
* @param string $body Content to append to the current HTTP response body
|
||||
* @param bool $replace Overwrite existing response body?
|
||||
* @return string The updated HTTP response body
|
||||
* @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 ) {
|
||||
public function write($body, $replace = false)
|
||||
{
|
||||
if ($replace) {
|
||||
$this->body = $body;
|
||||
} else {
|
||||
$this->body .= (string)$body;
|
||||
$this->body .= (string) $body;
|
||||
}
|
||||
$this->length = strlen($this->body);
|
||||
|
||||
return $this->body;
|
||||
}
|
||||
|
||||
|
@ -217,9 +230,11 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
*
|
||||
* @return array[int status, array headers, string body]
|
||||
*/
|
||||
public function finalize() {
|
||||
if ( in_array($this->status, array(204, 304)) ) {
|
||||
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);
|
||||
|
@ -235,12 +250,13 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* 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
|
||||
* @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 ) {
|
||||
Slim_Http_Util::setCookieHeader($this->header, $name, $value);
|
||||
public function setCookie($name, $value)
|
||||
{
|
||||
Util::setCookieHeader($this->header, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -258,11 +274,12 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* 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
|
||||
* @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() ) {
|
||||
Slim_Http_Util::deleteCookieHeader($this->header, $name, $value);
|
||||
public function deleteCookie($name, $value = array())
|
||||
{
|
||||
Util::deleteCookieHeader($this->header, $name, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -271,10 +288,11 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* 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
|
||||
* @param string $url The redirect destination
|
||||
* @param int $status The redirect HTTP status code
|
||||
*/
|
||||
public function redirect ( $url, $status = 302 ) {
|
||||
public function redirect ($url, $status = 302)
|
||||
{
|
||||
$this->status = $status;
|
||||
$this['Location'] = $url;
|
||||
}
|
||||
|
@ -283,7 +301,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Empty?
|
||||
* @return bool
|
||||
*/
|
||||
public function isEmpty() {
|
||||
public function isEmpty()
|
||||
{
|
||||
return in_array($this->status, array(201, 204, 304));
|
||||
}
|
||||
|
||||
|
@ -291,7 +310,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Informational?
|
||||
* @return bool
|
||||
*/
|
||||
public function isInformational() {
|
||||
public function isInformational()
|
||||
{
|
||||
return $this->status >= 100 && $this->status < 200;
|
||||
}
|
||||
|
||||
|
@ -299,7 +319,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: OK?
|
||||
* @return bool
|
||||
*/
|
||||
public function isOk() {
|
||||
public function isOk()
|
||||
{
|
||||
return $this->status === 200;
|
||||
}
|
||||
|
||||
|
@ -307,7 +328,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Successful?
|
||||
* @return bool
|
||||
*/
|
||||
public function isSuccessful() {
|
||||
public function isSuccessful()
|
||||
{
|
||||
return $this->status >= 200 && $this->status < 300;
|
||||
}
|
||||
|
||||
|
@ -315,7 +337,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Redirect?
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirect() {
|
||||
public function isRedirect()
|
||||
{
|
||||
return in_array($this->status, array(301, 302, 303, 307));
|
||||
}
|
||||
|
||||
|
@ -323,7 +346,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Redirection?
|
||||
* @return bool
|
||||
*/
|
||||
public function isRedirection() {
|
||||
public function isRedirection()
|
||||
{
|
||||
return $this->status >= 300 && $this->status < 400;
|
||||
}
|
||||
|
||||
|
@ -331,7 +355,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Forbidden?
|
||||
* @return bool
|
||||
*/
|
||||
public function isForbidden() {
|
||||
public function isForbidden()
|
||||
{
|
||||
return $this->status === 403;
|
||||
}
|
||||
|
||||
|
@ -339,7 +364,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Not Found?
|
||||
* @return bool
|
||||
*/
|
||||
public function isNotFound() {
|
||||
public function isNotFound()
|
||||
{
|
||||
return $this->status === 404;
|
||||
}
|
||||
|
||||
|
@ -347,7 +373,8 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Client error?
|
||||
* @return bool
|
||||
*/
|
||||
public function isClientError() {
|
||||
public function isClientError()
|
||||
{
|
||||
return $this->status >= 400 && $this->status < 500;
|
||||
}
|
||||
|
||||
|
@ -355,22 +382,25 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Helpers: Server Error?
|
||||
* @return bool
|
||||
*/
|
||||
public function isServerError() {
|
||||
public function isServerError()
|
||||
{
|
||||
return $this->status >= 500 && $this->status < 600;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
public function offsetExists( $offset )
|
||||
{
|
||||
return isset($this->header[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
if ( isset($this->header[$offset]) ) {
|
||||
public function offsetGet( $offset )
|
||||
{
|
||||
if (isset($this->header[$offset])) {
|
||||
return $this->header[$offset];
|
||||
} else {
|
||||
return null;
|
||||
|
@ -380,33 +410,37 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->header[$offset] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset( $offset ) {
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->header[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Countable: Count
|
||||
*/
|
||||
public function count() {
|
||||
public function count()
|
||||
{
|
||||
return count($this->header);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator
|
||||
*
|
||||
* This returns the contained `Slim_Http_Headers` instance which
|
||||
* This returns the contained `\Slim\Http\Headers` instance which
|
||||
* is itself iterable.
|
||||
*
|
||||
* @return Slim_Http_Headers
|
||||
* @return \Slim\Http\Headers
|
||||
*/
|
||||
public function getIterator() {
|
||||
public function getIterator()
|
||||
{
|
||||
return $this->header;
|
||||
}
|
||||
|
||||
|
@ -414,11 +448,12 @@ class Slim_Http_Response implements ArrayAccess, Countable, IteratorAggregate {
|
|||
* Get message for HTTP status code
|
||||
* @return string|null
|
||||
*/
|
||||
public static function getMessageForCode( $status ) {
|
||||
if ( isset(self::$messages[$status]) ) {
|
||||
public static function getMessageForCode($status)
|
||||
{
|
||||
if (isset(self::$messages[$status])) {
|
||||
return self::$messages[$status];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Http;
|
||||
|
||||
/**
|
||||
* Slim HTTP Utilities
|
||||
|
@ -40,7 +41,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Http_Util {
|
||||
class Util
|
||||
{
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
*
|
||||
|
@ -49,12 +51,13 @@ class Slim_Http_Util {
|
|||
* override the magic quotes setting with either TRUE or FALSE as the send argument
|
||||
* to force this method to strip or not strip slashes from its input.
|
||||
*
|
||||
* @var array|string $rawData
|
||||
* @return array|string
|
||||
* @var array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
public static function stripSlashesIfMagicQuotes( $rawData, $overrideStripSlashes = null ) {
|
||||
public static function stripSlashesIfMagicQuotes($rawData, $overrideStripSlashes = null)
|
||||
{
|
||||
$strip = is_null($overrideStripSlashes) ? get_magic_quotes_gpc() : $overrideStripSlashes;
|
||||
if ( $strip ) {
|
||||
if ($strip) {
|
||||
return self::_stripSlashes($rawData);
|
||||
} else {
|
||||
return $rawData;
|
||||
|
@ -63,10 +66,11 @@ class Slim_Http_Util {
|
|||
|
||||
/**
|
||||
* Strip slashes from string or array
|
||||
* @param array|string $rawData
|
||||
* @return array|string
|
||||
* @param array|string $rawData
|
||||
* @return array|string
|
||||
*/
|
||||
protected static function _stripSlashes( $rawData ) {
|
||||
protected static function _stripSlashes($rawData)
|
||||
{
|
||||
return is_array($rawData) ? array_map(array('self', '_stripSlashes'), $rawData) : stripslashes($rawData);
|
||||
}
|
||||
|
||||
|
@ -78,14 +82,15 @@ class Slim_Http_Util {
|
|||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The unencrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
* @param string $data The unencrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function encrypt( $data, $key, $iv, $settings = array() ) {
|
||||
if ( $data === '' || !extension_loaded('mcrypt') ) {
|
||||
public static function encrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -100,13 +105,13 @@ class Slim_Http_Util {
|
|||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if ( strlen($iv) > $ivSize ) {
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if ( strlen($key) > $keySize ) {
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
|
@ -126,14 +131,15 @@ class Slim_Http_Util {
|
|||
* may override the default cipher and cipher mode by passing your own desired
|
||||
* cipher and cipher mode as the final key-value array argument.
|
||||
*
|
||||
* @param string $data The encrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
* @param string $data The encrypted data
|
||||
* @param string $key The encryption key
|
||||
* @param string $iv The encryption initialization vector
|
||||
* @param array $settings Optional key-value array with custom algorithm and mode
|
||||
* @return string
|
||||
*/
|
||||
public static function decrypt( $data, $key, $iv, $settings = array() ) {
|
||||
if ( $data === '' || !extension_loaded('mcrypt') ) {
|
||||
public static function decrypt($data, $key, $iv, $settings = array())
|
||||
{
|
||||
if ($data === '' || !extension_loaded('mcrypt')) {
|
||||
return $data;
|
||||
}
|
||||
|
||||
|
@ -148,13 +154,13 @@ class Slim_Http_Util {
|
|||
|
||||
//Validate IV
|
||||
$ivSize = mcrypt_enc_get_iv_size($module);
|
||||
if ( strlen($iv) > $ivSize ) {
|
||||
if (strlen($iv) > $ivSize) {
|
||||
$iv = substr($iv, 0, $ivSize);
|
||||
}
|
||||
|
||||
//Validate key
|
||||
$keySize = mcrypt_enc_get_key_size($module);
|
||||
if ( strlen($key) > $keySize ) {
|
||||
if (strlen($key) > $keySize) {
|
||||
$key = substr($key, 0, $keySize);
|
||||
}
|
||||
|
||||
|
@ -174,21 +180,23 @@ class Slim_Http_Util {
|
|||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The unsecure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
* @param string $value The unsecure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
*/
|
||||
public static function encodeSecureCookie( $value, $expires, $secret, $algorithm, $mode ) {
|
||||
public static function encodeSecureCookie($value, $expires, $secret, $algorithm, $mode)
|
||||
{
|
||||
$key = hash_hmac('sha1', $expires, $secret);
|
||||
$iv = md5($expires);
|
||||
$iv = self::get_iv($expires, $secret);
|
||||
$secureString = base64_encode(self::encrypt($value, $key, $iv, array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
)));
|
||||
$verificationString = hash_hmac('sha1', $expires . $value, $key);
|
||||
|
||||
return implode('|', array($expires, $secureString, $verificationString));
|
||||
}
|
||||
|
||||
|
@ -199,29 +207,31 @@ class Slim_Http_Util {
|
|||
* cookie value is encrypted and hashed so that its value is
|
||||
* secure and checked for integrity when read in subsequent requests.
|
||||
*
|
||||
* @param string $value The secure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
* @param string $value The secure HTTP cookie value
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @param int $algorithm The algorithm to use for encryption
|
||||
* @param int $mode The algorithm mode to use for encryption
|
||||
* @param string
|
||||
*/
|
||||
public static function decodeSecureCookie( $value, $secret, $algorithm, $mode ) {
|
||||
if ( $value ) {
|
||||
public static function decodeSecureCookie($value, $secret, $algorithm, $mode)
|
||||
{
|
||||
if ($value) {
|
||||
$value = explode('|', $value);
|
||||
if ( count($value) === 3 && ( (int)$value[0] === 0 || (int)$value[0] > time() ) ) {
|
||||
if (count($value) === 3 && ((int) $value[0] === 0 || (int) $value[0] > time())) {
|
||||
$key = hash_hmac('sha1', $value[0], $secret);
|
||||
$iv = md5($value[0]);
|
||||
$iv = self::get_iv($value[0], $secret);
|
||||
$data = self::decrypt(base64_decode($value[1]), $key, $iv, array(
|
||||
'algorithm' => $algorithm,
|
||||
'mode' => $mode
|
||||
));
|
||||
$verificationString = hash_hmac('sha1', $value[0] . $data, $key);
|
||||
if ( $verificationString === $value[2] ) {
|
||||
if ($verificationString === $value[2]) {
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -237,48 +247,48 @@ class Slim_Http_Util {
|
|||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public static function setCookieHeader( &$header, $name, $value ) {
|
||||
public static function setCookieHeader(&$header, $name, $value)
|
||||
{
|
||||
//Build cookie header
|
||||
if ( is_array($value) ) {
|
||||
if (is_array($value)) {
|
||||
$domain = '';
|
||||
$path = '';
|
||||
$expires = '';
|
||||
$secure = '';
|
||||
$httponly = '';
|
||||
if ( isset($value['domain']) && $value['domain'] ) {
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$domain = '; domain=' . $value['domain'];
|
||||
}
|
||||
if ( isset($value['path']) && $value['path'] ) {
|
||||
if (isset($value['path']) && $value['path']) {
|
||||
$path = '; path=' . $value['path'];
|
||||
}
|
||||
if ( isset($value['expires']) ) {
|
||||
if ( is_string($value['expires']) ) {
|
||||
if (isset($value['expires'])) {
|
||||
if (is_string($value['expires'])) {
|
||||
$timestamp = strtotime($value['expires']);
|
||||
} else {
|
||||
$timestamp = (int)$value['expires'];
|
||||
$timestamp = (int) $value['expires'];
|
||||
}
|
||||
if ( $timestamp !== 0 ) {
|
||||
if ($timestamp !== 0) {
|
||||
$expires = '; expires=' . gmdate('D, d-M-Y H:i:s e', $timestamp);
|
||||
}
|
||||
}
|
||||
if ( isset($value['secure']) && $value['secure'] ) {
|
||||
if (isset($value['secure']) && $value['secure']) {
|
||||
$secure = '; secure';
|
||||
}
|
||||
if ( isset($value['httponly']) && $value['httponly'] ) {
|
||||
if (isset($value['httponly']) && $value['httponly']) {
|
||||
$httponly = '; HttpOnly';
|
||||
}
|
||||
$cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string)$value['value']), $domain . $path . $expires . $secure . $httponly);
|
||||
$cookie = sprintf('%s=%s%s', urlencode($name), urlencode((string) $value['value']), $domain . $path . $expires . $secure . $httponly);
|
||||
} else {
|
||||
$cookie = sprintf('%s=%s', urlencode($name), urlencode((string)$value));
|
||||
$cookie = sprintf('%s=%s', urlencode($name), urlencode((string) $value));
|
||||
}
|
||||
|
||||
//Set cookie header
|
||||
if ( !isset($header['Set-Cookie']) || $header['Set-Cookie'] === '' ) {
|
||||
if (!isset($header['Set-Cookie']) || $header['Set-Cookie'] === '') {
|
||||
$header['Set-Cookie'] = $cookie;
|
||||
} else {
|
||||
$header['Set-Cookie'] = implode("\n", array($header['Set-Cookie'], $cookie));
|
||||
|
@ -298,29 +308,29 @@ class Slim_Http_Util {
|
|||
* first argument; this method directly modifies this object instead of
|
||||
* returning a value.
|
||||
*
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @param array $header
|
||||
* @param string $name
|
||||
* @param string $value
|
||||
*/
|
||||
public static function deleteCookieHeader( &$header, $name, $value = array() ) {
|
||||
public static function deleteCookieHeader(&$header, $name, $value = array())
|
||||
{
|
||||
//Remove affected cookies from current response header
|
||||
$cookiesOld = array();
|
||||
$cookiesNew = array();
|
||||
if ( isset($header['Set-Cookie']) ) {
|
||||
if (isset($header['Set-Cookie'])) {
|
||||
$cookiesOld = explode("\n", $header['Set-Cookie']);
|
||||
}
|
||||
foreach ( $cookiesOld as $c ) {
|
||||
if ( isset($value['domain']) && $value['domain'] ) {
|
||||
foreach ($cookiesOld as $c) {
|
||||
if (isset($value['domain']) && $value['domain']) {
|
||||
$regex = sprintf('@%s=.*domain=%s@', urlencode($name), preg_quote($value['domain']));
|
||||
} else {
|
||||
$regex = sprintf('@%s=@', urlencode($name));
|
||||
}
|
||||
if ( preg_match($regex, $c) === 0 ) {
|
||||
if (preg_match($regex, $c) === 0) {
|
||||
$cookiesNew[] = $c;
|
||||
}
|
||||
}
|
||||
if ( $cookiesNew ) {
|
||||
if ($cookiesNew) {
|
||||
$header['Set-Cookie'] = implode("\n", $cookiesNew);
|
||||
} else {
|
||||
unset($header['Set-Cookie']);
|
||||
|
@ -336,29 +346,44 @@ class Slim_Http_Util {
|
|||
* This method will parse the HTTP requst's `Cookie` header
|
||||
* and extract cookies into an associative array.
|
||||
*
|
||||
* @param string
|
||||
* @return array
|
||||
* @param string
|
||||
* @return array
|
||||
*/
|
||||
public static function parseCookieHeader( $header ) {
|
||||
public static function parseCookieHeader($header)
|
||||
{
|
||||
$cookies = array();
|
||||
$header = rtrim($header, "\r\n");
|
||||
$headerPieces = preg_split('@\s*;\s*@', $header);
|
||||
foreach ( $headerPieces as $c ) {
|
||||
$headerPieces = preg_split('@\s*[;,]\s*@', $header);
|
||||
foreach ($headerPieces as $c) {
|
||||
$cParts = explode('=', $c);
|
||||
if ( count($cParts) === 2 ) {
|
||||
if (count($cParts) === 2) {
|
||||
$key = urldecode($cParts[0]);
|
||||
$value = urldecode($cParts[1]);
|
||||
if ( isset($cookies[$key]) ) {
|
||||
if ( is_array($cookies[$key]) ) {
|
||||
$cookies[$key][] = $value;
|
||||
} else {
|
||||
$cookies[$key] = array($cookies[$key], $value);
|
||||
}
|
||||
} else {
|
||||
if (!isset($cookies[$key])) {
|
||||
$cookies[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $cookies;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a random IV
|
||||
*
|
||||
* This method will generate a non-predictable IV for use with
|
||||
* the cookie encryption
|
||||
*
|
||||
* @param int $expires The UNIX timestamp at which this cookie will expire
|
||||
* @param string $secret The secret key used to hash the cookie value
|
||||
* @return binary string with length 40
|
||||
*/
|
||||
private static function get_iv($expires, $secret)
|
||||
{
|
||||
$data1 = hash_hmac('sha1', 'a'.$expires.'b', $secret);
|
||||
$data2 = hash_hmac('sha1', 'z'.$expires.'y', $secret);
|
||||
|
||||
return pack("h*", $data1.$data2);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
126
Slim/Log.php
126
Slim/Log.php
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* 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
|
||||
|
@ -53,16 +54,23 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Log {
|
||||
class Log
|
||||
{
|
||||
const FATAL = 0;
|
||||
const ERROR = 1;
|
||||
const WARN = 2;
|
||||
const INFO = 3;
|
||||
const DEBUG = 4;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
static protected $levels = array(
|
||||
0 => 'FATAL',
|
||||
1 => 'ERROR',
|
||||
2 => 'WARN',
|
||||
3 => 'INFO',
|
||||
4 => 'DEBUG'
|
||||
protected static $levels = array(
|
||||
self::FATAL => 'FATAL',
|
||||
self::ERROR => 'ERROR',
|
||||
self::WARN => 'WARN',
|
||||
self::INFO => 'INFO',
|
||||
self::DEBUG => 'DEBUG'
|
||||
);
|
||||
|
||||
/**
|
||||
|
@ -82,30 +90,31 @@ class Slim_Log {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param mixed $writer
|
||||
* @return void
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function __construct( $writer ) {
|
||||
public function __construct($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
$this->enabled = true;
|
||||
$this->level = 4;
|
||||
$this->level = self::DEBUG;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function getEnabled() {
|
||||
public function getEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable or disable logging
|
||||
* @param bool $enabled
|
||||
* @return void
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function setEnabled( $enabled ) {
|
||||
if ( $enabled ) {
|
||||
public function setEnabled($enabled)
|
||||
{
|
||||
if ($enabled) {
|
||||
$this->enabled = true;
|
||||
} else {
|
||||
$this->enabled = false;
|
||||
|
@ -114,13 +123,13 @@ class Slim_Log {
|
|||
|
||||
/**
|
||||
* Set level
|
||||
* @param int $level
|
||||
* @return void
|
||||
* @throws InvalidArgumentException
|
||||
* @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');
|
||||
public function setLevel($level)
|
||||
{
|
||||
if (!isset(self::$levels[$level])) {
|
||||
throw new \InvalidArgumentException('Invalid log level');
|
||||
}
|
||||
$this->level = $level;
|
||||
}
|
||||
|
@ -129,16 +138,17 @@ class Slim_Log {
|
|||
* Get level
|
||||
* @return int
|
||||
*/
|
||||
public function getLevel() {
|
||||
public function getLevel()
|
||||
{
|
||||
return $this->level;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set writer
|
||||
* @param mixed $writer
|
||||
* @return void
|
||||
* @param mixed $writer
|
||||
*/
|
||||
public function setWriter( $writer ) {
|
||||
public function setWriter($writer)
|
||||
{
|
||||
$this->writer = $writer;
|
||||
}
|
||||
|
||||
|
@ -146,7 +156,8 @@ class Slim_Log {
|
|||
* Get writer
|
||||
* @return mixed
|
||||
*/
|
||||
public function getWriter() {
|
||||
public function getWriter()
|
||||
{
|
||||
return $this->writer;
|
||||
}
|
||||
|
||||
|
@ -154,66 +165,73 @@ class Slim_Log {
|
|||
* Is logging enabled?
|
||||
* @return bool
|
||||
*/
|
||||
public function isEnabled() {
|
||||
public function isEnabled()
|
||||
{
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log debug message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
* @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, 4);
|
||||
public function debug($object)
|
||||
{
|
||||
return $this->write($object, self::DEBUG);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log info message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
* @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, 3);
|
||||
public function info($object)
|
||||
{
|
||||
return $this->write($object, self::INFO);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log warn message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
* @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, 2);
|
||||
public function warn($object)
|
||||
{
|
||||
return $this->write($object, self::WARN);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log error message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
* @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, 1);
|
||||
public function error($object)
|
||||
{
|
||||
return $this->write($object, self::ERROR);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log fatal message
|
||||
* @param mixed $object
|
||||
* @return mixed|false What the Logger returns, or false if Logger not set or not enabled
|
||||
* @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, 0);
|
||||
public function fatal($object)
|
||||
{
|
||||
return $this->write($object, self::FATAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log message
|
||||
* @param mixed The object to log
|
||||
* @param int The message level
|
||||
* @return int|false
|
||||
* @return int|false
|
||||
*/
|
||||
protected function log( $object, $level ) {
|
||||
if ( $this->enabled && $this->writer && $level <= $this->level ) {
|
||||
return $this->writer->write($object);
|
||||
protected function write($object, $level)
|
||||
{
|
||||
if ($this->enabled && $this->writer && $level <= $this->level) {
|
||||
return $this->writer->write($object, $level);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,75 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining
|
||||
* a copy of this software and associated documentation files (the
|
||||
* "Software"), to deal in the Software without restriction, including
|
||||
* without limitation the rights to use, copy, modify, merge, publish,
|
||||
* distribute, sublicense, and/or sell copies of the Software, and to
|
||||
* permit persons to whom the Software is furnished to do so, subject to
|
||||
* the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be
|
||||
* included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
* LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Log Writer
|
||||
*
|
||||
* This class is used by Slim_Log to write log messages to a valid, writable
|
||||
* resource handle (e.g. a file or STDERR).
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class LogWriter
|
||||
{
|
||||
/**
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param resource $resource
|
||||
* @throws \InvalidArgumentException If invalid resource
|
||||
*/
|
||||
public function __construct($resource)
|
||||
{
|
||||
if (!is_resource($resource)) {
|
||||
throw new \InvalidArgumentException('Cannot create LogWriter. Invalid resource handle.');
|
||||
}
|
||||
$this->resource = $resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write message
|
||||
* @param mixed $message
|
||||
* @param int $level
|
||||
* @return int|false
|
||||
*/
|
||||
public function write($message, $level = null)
|
||||
{
|
||||
return fwrite($this->resource, (string) $message . PHP_EOL);
|
||||
}
|
||||
}
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim;
|
||||
|
||||
/**
|
||||
* Middleware
|
||||
|
@ -38,9 +39,10 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
abstract class Slim_Middleware {
|
||||
abstract class Middleware
|
||||
{
|
||||
/**
|
||||
* @var Slim Reference to the primary Slim application instance
|
||||
* @var \Slim Reference to the primary application instance
|
||||
*/
|
||||
protected $app;
|
||||
|
||||
|
@ -55,10 +57,10 @@ abstract class Slim_Middleware {
|
|||
* This method injects the primary Slim application instance into
|
||||
* this middleware.
|
||||
*
|
||||
* @param Slim $application
|
||||
* @return void
|
||||
* @param \Slim $application
|
||||
*/
|
||||
final public function setApplication( $application ) {
|
||||
final public function setApplication($application)
|
||||
{
|
||||
$this->app = $application;
|
||||
}
|
||||
|
||||
|
@ -68,9 +70,10 @@ abstract class Slim_Middleware {
|
|||
* This method retrieves the application previously injected
|
||||
* into this middleware.
|
||||
*
|
||||
* @return Slim
|
||||
* @return \Slim
|
||||
*/
|
||||
final public function getApplication() {
|
||||
final public function getApplication()
|
||||
{
|
||||
return $this->app;
|
||||
}
|
||||
|
||||
|
@ -81,10 +84,10 @@ abstract class Slim_Middleware {
|
|||
* this middleware so that it may optionally be called
|
||||
* when appropriate.
|
||||
*
|
||||
* @param Slim|Slim_Middleware
|
||||
* @return void
|
||||
* @param \Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function setNextMiddleware( $nextMiddleware ) {
|
||||
final public function setNextMiddleware($nextMiddleware)
|
||||
{
|
||||
$this->next = $nextMiddleware;
|
||||
}
|
||||
|
||||
|
@ -94,9 +97,10 @@ abstract class Slim_Middleware {
|
|||
* This method retrieves the next downstream middleware
|
||||
* previously injected into this middleware.
|
||||
*
|
||||
* @return Slim|Slim_Middleware
|
||||
* @return \Slim|\Slim\Middleware
|
||||
*/
|
||||
final public function getNextMiddleware() {
|
||||
final public function getNextMiddleware()
|
||||
{
|
||||
return $this->next;
|
||||
}
|
||||
|
||||
|
@ -105,8 +109,6 @@ abstract class Slim_Middleware {
|
|||
*
|
||||
* Perform actions specific to this middleware and optionally
|
||||
* call the next downstream middleware.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
abstract public function call();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Content Types
|
||||
|
@ -44,7 +45,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
||||
class ContentTypes extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
@ -54,7 +56,8 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
* Constructor
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings = array() ) {
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->contentTypes = array_merge(array(
|
||||
'application/json' => array($this, 'parseJson'),
|
||||
'application/xml' => array($this, 'parseXml'),
|
||||
|
@ -65,13 +68,14 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Call
|
||||
* @return void
|
||||
*/
|
||||
public function call() {
|
||||
$env = $this->app->environment();
|
||||
if ( isset($env['CONTENT_TYPE']) ) {
|
||||
public function call()
|
||||
{
|
||||
$mediaType = $this->app->request()->getMediaType();
|
||||
if ($mediaType) {
|
||||
$env = $this->app->environment();
|
||||
$env['slim.input_original'] = $env['slim.input'];
|
||||
$env['slim.input'] = $this->parse($env['slim.input'], $env['CONTENT_TYPE']);
|
||||
$env['slim.input'] = $this->parse($env['slim.input'], $mediaType);
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
|
@ -82,17 +86,19 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
* This method will attempt to parse the request body
|
||||
* based on its content type if available.
|
||||
*
|
||||
* @param string $input
|
||||
* @param string $contentType
|
||||
* @return mixed
|
||||
* @param string $input
|
||||
* @param string $contentType
|
||||
* @return mixed
|
||||
*/
|
||||
protected function parse ( $input, $contentType ) {
|
||||
if ( isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType]) ) {
|
||||
protected function parse ($input, $contentType)
|
||||
{
|
||||
if (isset($this->contentTypes[$contentType]) && is_callable($this->contentTypes[$contentType])) {
|
||||
$result = call_user_func($this->contentTypes[$contentType], $input);
|
||||
if ( $result ) {
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
@ -102,13 +108,14 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
* This method converts the raw JSON input
|
||||
* into an associative array.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array|string
|
||||
* @param string $input
|
||||
* @return array|string
|
||||
*/
|
||||
protected function parseJson( $input ) {
|
||||
if ( function_exists('json_decode') ) {
|
||||
protected function parseJson($input)
|
||||
{
|
||||
if (function_exists('json_decode')) {
|
||||
$result = json_decode($input, true);
|
||||
if ( $result ) {
|
||||
if ($result) {
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
@ -122,15 +129,19 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
* extension is not available, the raw input
|
||||
* will be returned unchanged.
|
||||
*
|
||||
* @param string $input
|
||||
* @return SimpleXMLElement|string
|
||||
* @param string $input
|
||||
* @return \SimpleXMLElement|string
|
||||
*/
|
||||
protected function parseXml( $input ) {
|
||||
if ( class_exists('SimpleXMLElement') ) {
|
||||
protected function parseXml($input)
|
||||
{
|
||||
if (class_exists('SimpleXMLElement')) {
|
||||
try {
|
||||
return new SimpleXMLElement($input);
|
||||
} catch ( Exception $e ) {}
|
||||
return new \SimpleXMLElement($input);
|
||||
} catch (\Exception $e) {
|
||||
// Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
return $input;
|
||||
}
|
||||
|
||||
|
@ -140,18 +151,20 @@ class Slim_Middleware_ContentTypes extends Slim_Middleware {
|
|||
* This method parses CSV content into a numeric array
|
||||
* containing an array of data for each CSV line.
|
||||
*
|
||||
* @param string $input
|
||||
* @return array
|
||||
* @param string $input
|
||||
* @return array
|
||||
*/
|
||||
protected function parseCsv( $input ) {
|
||||
protected function parseCsv($input)
|
||||
{
|
||||
$temp = fopen('php://memory', 'rw');
|
||||
fwrite($temp, $input);
|
||||
fseek($temp, 0);
|
||||
$res = array();
|
||||
while ( ($data = fgetcsv($temp)) !== false ) {
|
||||
while (($data = fgetcsv($temp)) !== false) {
|
||||
$res[] = $data;
|
||||
}
|
||||
fclose($temp);
|
||||
|
||||
return $res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Flash
|
||||
|
@ -44,7 +45,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
||||
class Flash extends \Slim\Middleware implements \ArrayAccess, \IteratorAggregate
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
@ -57,14 +59,14 @@ class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Slim $app
|
||||
* @param array $settings
|
||||
* @return void
|
||||
* @param \Slim $app
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings = array() ) {
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => 'slim.flash'), $settings);
|
||||
$this->messages = array(
|
||||
'prev' => isset($_SESSION[$this->settings['key']]) ? $_SESSION[$this->settings['key']] : array(), //flash messages from prev request
|
||||
'prev' => array(), //flash messages from prev request (loaded when middleware called)
|
||||
'next' => array(), //flash messages for next request
|
||||
'now' => array() //flash messages for current request
|
||||
);
|
||||
|
@ -72,9 +74,13 @@ class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
|||
|
||||
/**
|
||||
* Call
|
||||
* @return void
|
||||
*/
|
||||
public function call() {
|
||||
public function call()
|
||||
{
|
||||
//Read flash messaging from previous request if available
|
||||
$this->loadMessages();
|
||||
|
||||
//Prepare flash messaging for current request
|
||||
$env = $this->app->environment();
|
||||
$env['slim.flash'] = $this;
|
||||
$this->next->call();
|
||||
|
@ -86,12 +92,12 @@ class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
|||
*
|
||||
* Specify a flash message for a given key to be shown for the current request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function now( $key, $value ) {
|
||||
$this->messages['now'][(string)$key] = $value;
|
||||
public function now($key, $value)
|
||||
{
|
||||
$this->messages['now'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -99,23 +105,22 @@ class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
|||
*
|
||||
* Specify a flash message for a given key to be shown for the next request
|
||||
*
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return void
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
*/
|
||||
public function set( $key, $value ) {
|
||||
$this->messages['next'][(string)$key] = $value;
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->messages['next'][(string) $key] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep
|
||||
*
|
||||
* Retain flash messages from the previous request for the next request
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function keep() {
|
||||
foreach ( $this->messages['prev'] as $key => $val ) {
|
||||
public function keep()
|
||||
{
|
||||
foreach ($this->messages['prev'] as $key => $val) {
|
||||
$this->messages['next'][$key] = $val;
|
||||
}
|
||||
}
|
||||
|
@ -123,48 +128,75 @@ class Slim_Middleware_Flash extends Slim_Middleware implements ArrayAccess {
|
|||
/**
|
||||
* Save
|
||||
*/
|
||||
public function save() {
|
||||
public function save()
|
||||
{
|
||||
$_SESSION[$this->settings['key']] = $this->messages['next'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get messages
|
||||
*
|
||||
* Load messages from previous request if available
|
||||
*/
|
||||
public function loadMessages()
|
||||
{
|
||||
if (isset($_SESSION[$this->settings['key']])) {
|
||||
$this->messages['prev'] = $_SESSION[$this->settings['key']];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array of flash messages to be shown for the current request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getMessages() {
|
||||
public function getMessages()
|
||||
{
|
||||
return array_merge($this->messages['prev'], $this->messages['now']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Exists
|
||||
*/
|
||||
public function offsetExists( $offset ) {
|
||||
public function offsetExists($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Get
|
||||
*/
|
||||
public function offsetGet( $offset ) {
|
||||
public function offsetGet($offset)
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return isset($messages[$offset]) ? $messages[$offset] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Set
|
||||
*/
|
||||
public function offsetSet( $offset, $value ) {
|
||||
public function offsetSet($offset, $value)
|
||||
{
|
||||
$this->now($offset, $value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Array Access: Offset Unset
|
||||
*/
|
||||
public function offsetUnset( $offset ) {
|
||||
public function offsetUnset($offset)
|
||||
{
|
||||
unset($this->messages['prev'][$offset], $this->messages['now'][$offset]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterator Aggregate: Get Iterator
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getIterator()
|
||||
{
|
||||
$messages = $this->getMessages();
|
||||
|
||||
return new \ArrayIterator($messages);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* HTTP Method Override
|
||||
|
@ -45,7 +46,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Middleware_MethodOverride extends Slim_Middleware {
|
||||
class MethodOverride extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
@ -53,11 +55,11 @@ class Slim_Middleware_MethodOverride extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Slim $app
|
||||
* @param array $settings
|
||||
* @return void
|
||||
* @param \Slim $app
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings = array() ) {
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array('key' => '_METHOD'), $settings);
|
||||
}
|
||||
|
||||
|
@ -65,29 +67,30 @@ class Slim_Middleware_MethodOverride extends Slim_Middleware {
|
|||
* Call
|
||||
*
|
||||
* Implements Slim middleware interface. This method is invoked and passed
|
||||
* an array of environemnt variables. This middleware inspects the environment
|
||||
* an array of environment variables. This middleware inspects the environment
|
||||
* variables for the HTTP method override parameter; if found, this middleware
|
||||
* modifies the environment settings so downstream middleware and/or the Slim
|
||||
* application will treat the request with the desired HTTP method.
|
||||
*
|
||||
* @param array $env
|
||||
* @return array[status, header, body]
|
||||
* @param array $env
|
||||
* @return array[status, header, body]
|
||||
*/
|
||||
public function call() {
|
||||
public function call()
|
||||
{
|
||||
$env = $this->app->environment();
|
||||
if ( isset($env['X_HTTP_METHOD_OVERRIDE']) ) {
|
||||
if (isset($env['X_HTTP_METHOD_OVERRIDE'])) {
|
||||
// Header commonly used by Backbone.js and others
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($env['X_HTTP_METHOD_OVERRIDE']);
|
||||
} else if ( isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST' ) {
|
||||
} elseif (isset($env['REQUEST_METHOD']) && $env['REQUEST_METHOD'] === 'POST') {
|
||||
// HTML Form Override
|
||||
$req = new Slim_Http_Request($env);
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$method = $req->post($this->settings['key']);
|
||||
if ( $method ) {
|
||||
if ($method) {
|
||||
$env['slim.method_override.original_method'] = $env['REQUEST_METHOD'];
|
||||
$env['REQUEST_METHOD'] = strtoupper($method);
|
||||
}
|
||||
}
|
||||
$this->next->call();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Pretty Exceptions
|
||||
|
@ -41,7 +42,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Middleware_PrettyExceptions extends Slim_Middleware {
|
||||
class PrettyExceptions extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
@ -49,23 +51,24 @@ class Slim_Middleware_PrettyExceptions extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Slim|middleware $app
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings = array() ) {
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
* @return void
|
||||
*/
|
||||
public function call() {
|
||||
public function call()
|
||||
{
|
||||
try {
|
||||
$this->next->call();
|
||||
} catch ( Exception $e ) {
|
||||
} catch (\Exception $e) {
|
||||
$env = $this->app->environment();
|
||||
$env['slim.log']->error($e);
|
||||
$this->app->contentType('text/html');
|
||||
$this->app->response()->status(500);
|
||||
$this->app->response()->body($this->renderBody($env, $e));
|
||||
}
|
||||
|
@ -73,11 +76,12 @@ class Slim_Middleware_PrettyExceptions extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Render response body
|
||||
* @param array $env
|
||||
* @param Exception $exception
|
||||
* @param array $env
|
||||
* @param \Exception $exception
|
||||
* @return string
|
||||
*/
|
||||
protected function renderBody( &$env, $exception ) {
|
||||
protected function renderBody(&$env, $exception)
|
||||
{
|
||||
$title = 'Slim Application Error';
|
||||
$code = $exception->getCode();
|
||||
$message = $exception->getMessage();
|
||||
|
@ -87,22 +91,24 @@ class Slim_Middleware_PrettyExceptions extends Slim_Middleware {
|
|||
$html = sprintf('<h1>%s</h1>', $title);
|
||||
$html .= '<p>The application could not run because of the following error:</p>';
|
||||
$html .= '<h2>Details</h2>';
|
||||
if ( $code ) {
|
||||
$html .= sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));
|
||||
if ($code) {
|
||||
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
|
||||
}
|
||||
if ( $message ) {
|
||||
if ($message) {
|
||||
$html .= sprintf('<div><strong>Message:</strong> %s</div>', $message);
|
||||
}
|
||||
if ( $file ) {
|
||||
if ($file) {
|
||||
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
|
||||
}
|
||||
if ( $line ) {
|
||||
if ($line) {
|
||||
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
|
||||
}
|
||||
if ( $trace ) {
|
||||
if ($trace) {
|
||||
$html .= '<h2>Trace</h2>';
|
||||
$html .= sprintf('<pre>%s</pre>', $trace);
|
||||
}
|
||||
|
||||
return sprintf("<html><head><title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{display:inline-block;width:65px;}</style></head><body>%s</body></html>", $title, $html);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,6 +30,7 @@
|
|||
* OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
namespace Slim\Middleware;
|
||||
|
||||
/**
|
||||
* Session Cookie
|
||||
|
@ -57,7 +58,8 @@
|
|||
* @author Josh Lockhart
|
||||
* @since 1.6.0
|
||||
*/
|
||||
class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
||||
class SessionCookie extends \Slim\Middleware
|
||||
{
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
|
@ -66,10 +68,10 @@ class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
|||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $settings
|
||||
* @return void
|
||||
* @param array $settings
|
||||
*/
|
||||
public function __construct( $settings = array() ) {
|
||||
public function __construct($settings = array())
|
||||
{
|
||||
$this->settings = array_merge(array(
|
||||
'expires' => '20 minutes',
|
||||
'path' => '/',
|
||||
|
@ -81,16 +83,35 @@ class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
|||
'cipher' => MCRYPT_RIJNDAEL_256,
|
||||
'cipher_mode' => MCRYPT_MODE_CBC
|
||||
), $settings);
|
||||
if ( is_string($this->settings['expires']) ) {
|
||||
if (is_string($this->settings['expires'])) {
|
||||
$this->settings['expires'] = strtotime($this->settings['expires']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Session
|
||||
*
|
||||
* We must start a native PHP session to initialize the $_SESSION superglobal.
|
||||
* However, we won't be using the native session store for persistence, so we
|
||||
* disable the session cookie and cache limiter. We also set the session
|
||||
* handler to this class instance to avoid PHP's native session file locking.
|
||||
*/
|
||||
ini_set('session.use_cookies', 0);
|
||||
session_cache_limiter(false);
|
||||
session_set_save_handler(
|
||||
array($this, 'open'),
|
||||
array($this, 'close'),
|
||||
array($this, 'read'),
|
||||
array($this, 'write'),
|
||||
array($this, 'destroy'),
|
||||
array($this, 'gc')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Call
|
||||
* @return void
|
||||
*/
|
||||
public function call() {
|
||||
public function call()
|
||||
{
|
||||
$this->loadSession();
|
||||
$this->next->call();
|
||||
$this->saveSession();
|
||||
|
@ -98,17 +119,21 @@ class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Load session
|
||||
* @param array $env
|
||||
* @return void
|
||||
* @param array $env
|
||||
*/
|
||||
protected function loadSession() {
|
||||
$value = Slim_Http_Util::decodeSecureCookie(
|
||||
protected function loadSession()
|
||||
{
|
||||
if (session_id() === '') {
|
||||
session_start();
|
||||
}
|
||||
|
||||
$value = \Slim\Http\Util::decodeSecureCookie(
|
||||
$this->app->request()->cookies($this->settings['name']),
|
||||
$this->settings['secret'],
|
||||
$this->settings['cipher'],
|
||||
$this->settings['cipher_mode']
|
||||
);
|
||||
if ( $value ) {
|
||||
if ($value) {
|
||||
$_SESSION = unserialize($value);
|
||||
} else {
|
||||
$_SESSION = array();
|
||||
|
@ -117,18 +142,18 @@ class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
|||
|
||||
/**
|
||||
* Save session
|
||||
* @return void
|
||||
*/
|
||||
protected function saveSession() {
|
||||
$value = Slim_Http_Util::encodeSecureCookie(
|
||||
protected function saveSession()
|
||||
{
|
||||
$value = \Slim\Http\Util::encodeSecureCookie(
|
||||
serialize($_SESSION),
|
||||
$this->settings['expires'],
|
||||
$this->settings['secret'],
|
||||
$this->settings['cipher'],
|
||||
$this->settings['cipher_mode']
|
||||
);
|
||||
if ( strlen($value) > 4096 ) {
|
||||
$this->app->getLog()->error('WARNING! Slim_Middleware_SessionCookie data size is larger than 4KB. Content save failed.');
|
||||
if (strlen($value) > 4096) {
|
||||
$this->app->getLog()->error('WARNING! Slim\Middleware\SessionCookie data size is larger than 4KB. Content save failed.');
|
||||
} else {
|
||||
$this->app->response()->setCookie($this->settings['name'], array(
|
||||
'value' => $value,
|
||||
|
@ -139,5 +164,40 @@ class Slim_Middleware_SessionCookie extends Slim_Middleware {
|
|||
'httponly' => $this->settings['httponly']
|
||||
));
|
||||
}
|
||||
session_destroy();
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************************
|
||||
* Session Handler
|
||||
*******************************************************************************/
|
||||
|
||||
public function open($savePath, $sessionName)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function close()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function read($id)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
public function write($id, $data)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function destroy($id)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public function gc($maxlifetime)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
330
Slim/Route.php
330
Slim/Route.php
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.0.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,21 +30,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
|
||||
* @author Josh Lockhart, Thomas Bley
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Route {
|
||||
class Route
|
||||
{
|
||||
/**
|
||||
* @var string The route pattern (ie. "/books/:id")
|
||||
* @var string The route pattern (e.g. "/books/:id")
|
||||
*/
|
||||
protected $pattern;
|
||||
|
||||
/**
|
||||
* @var mixed The callable associated with this route
|
||||
* @var mixed The route callable
|
||||
*/
|
||||
protected $callable;
|
||||
|
||||
|
@ -54,7 +56,7 @@ class Slim_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();
|
||||
|
||||
|
@ -68,27 +70,33 @@ class Slim_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 Slim_Router The Router to which this Route belongs
|
||||
*/
|
||||
protected $router;
|
||||
|
||||
/**
|
||||
* @var array[Callable] Middleware
|
||||
* @var array[Callable] Middleware to be run before only this route instance
|
||||
*/
|
||||
protected $middleware = array();
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param string $pattern The URL pattern (ie. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @param string $pattern The URL pattern (e.g. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
*/
|
||||
public function __construct( $pattern, $callable ) {
|
||||
public function __construct($pattern, $callable)
|
||||
{
|
||||
$this->setPattern($pattern);
|
||||
$this->setCallable($callable);
|
||||
$this->setConditions(self::getDefaultConditions());
|
||||
|
@ -96,10 +104,10 @@ class Slim_Route {
|
|||
|
||||
/**
|
||||
* Set default route conditions for all instances
|
||||
* @param array $defaultConditions
|
||||
* @return void
|
||||
* @param array $defaultConditions
|
||||
*/
|
||||
public static function setDefaultConditions( array $defaultConditions ) {
|
||||
public static function setDefaultConditions(array $defaultConditions)
|
||||
{
|
||||
self::$defaultConditions = $defaultConditions;
|
||||
}
|
||||
|
||||
|
@ -107,7 +115,8 @@ class Slim_Route {
|
|||
* Get default route conditions for all instances
|
||||
* @return array
|
||||
*/
|
||||
public static function getDefaultConditions() {
|
||||
public static function getDefaultConditions()
|
||||
{
|
||||
return self::$defaultConditions;
|
||||
}
|
||||
|
||||
|
@ -115,33 +124,40 @@ class Slim_Route {
|
|||
* Get route pattern
|
||||
* @return string
|
||||
*/
|
||||
public function getPattern() {
|
||||
public function getPattern()
|
||||
{
|
||||
return $this->pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route pattern
|
||||
* @param string $pattern
|
||||
* @return void
|
||||
* @param string $pattern
|
||||
*/
|
||||
public function setPattern( $pattern ) {
|
||||
$this->pattern = str_replace(')', ')?', (string)$pattern);
|
||||
public function setPattern($pattern)
|
||||
{
|
||||
$this->pattern = $pattern;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route callable
|
||||
* @return mixed
|
||||
*/
|
||||
public function getCallable() {
|
||||
public function getCallable()
|
||||
{
|
||||
return $this->callable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route callable
|
||||
* @param mixed $callable
|
||||
* @return void
|
||||
* @param mixed $callable
|
||||
* @throws \InvalidArgumentException If argument is not callable
|
||||
*/
|
||||
public function setCallable($callable) {
|
||||
public function setCallable($callable)
|
||||
{
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException('Route callable must be callable');
|
||||
}
|
||||
|
||||
$this->callable = $callable;
|
||||
}
|
||||
|
||||
|
@ -149,16 +165,17 @@ class Slim_Route {
|
|||
* Get route conditions
|
||||
* @return array
|
||||
*/
|
||||
public function getConditions() {
|
||||
public function getConditions()
|
||||
{
|
||||
return $this->conditions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route conditions
|
||||
* @param array $conditions
|
||||
* @return void
|
||||
* @param array $conditions
|
||||
*/
|
||||
public function setConditions( array $conditions ) {
|
||||
public function setConditions(array $conditions)
|
||||
{
|
||||
$this->conditions = $conditions;
|
||||
}
|
||||
|
||||
|
@ -166,33 +183,72 @@ class Slim_Route {
|
|||
* Get route name
|
||||
* @return string|null
|
||||
*/
|
||||
public function getName() {
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
* @param string $name
|
||||
* @return void
|
||||
* @param string $name
|
||||
*/
|
||||
public function setName( $name ) {
|
||||
$this->name = (string)$name;
|
||||
$this->router->addNamedRoute($this->name, $this);
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = (string) $name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route parameters
|
||||
* @return array
|
||||
*/
|
||||
public function getParams() {
|
||||
public function getParams()
|
||||
{
|
||||
return $this->params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add supported HTTP method(s)
|
||||
* @return void
|
||||
* Set route parameters
|
||||
* @param array $params
|
||||
*/
|
||||
public function setHttpMethods() {
|
||||
public function setParams($params)
|
||||
{
|
||||
$this->params = $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get route parameter value
|
||||
* @param string $index Name of URL parameter
|
||||
* @return string
|
||||
* @throws \InvalidArgumentException If route parameter does not exist at index
|
||||
*/
|
||||
public function getParam($index)
|
||||
{
|
||||
if (!isset($this->params[$index])) {
|
||||
throw new \InvalidArgumentException('Route parameter does not exist at specified index');
|
||||
}
|
||||
|
||||
return $this->params[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route parameter value
|
||||
* @param string $index Name of URL parameter
|
||||
* @param mixed $value The new parameter value
|
||||
* @throws \InvalidArgumentException If route parameter does not exist at index
|
||||
*/
|
||||
public function setParam($index, $value)
|
||||
{
|
||||
if (!isset($this->params[$index])) {
|
||||
throw new \InvalidArgumentException('Route parameter does not exist at specified index');
|
||||
}
|
||||
$this->params[$index] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add supported HTTP method(s)
|
||||
*/
|
||||
public function setHttpMethods()
|
||||
{
|
||||
$args = func_get_args();
|
||||
$this->methods = $args;
|
||||
}
|
||||
|
@ -201,26 +257,29 @@ class Slim_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;
|
||||
}
|
||||
|
||||
|
@ -228,32 +287,17 @@ class Slim_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;
|
||||
}
|
||||
|
||||
|
@ -264,22 +308,28 @@ class Slim_Route {
|
|||
* If the method argument `is_callable` (including callable arrays!),
|
||||
* we directly append the argument to `$this->middleware`. Else, we
|
||||
* assume the argument is an array of callables and merge the array
|
||||
* with `$this->middleware`. Even if non-callables are included in the
|
||||
* argument array, we still merge them; we lazily check each item
|
||||
* against `is_callable` during Route::dispatch().
|
||||
* with `$this->middleware`. Each middleware is checked for is_callable()
|
||||
* and an InvalidArgumentException is thrown immediately if it isn't.
|
||||
*
|
||||
* @param Callable|array[Callable]
|
||||
* @return Slim_Route
|
||||
* @throws InvalidArgumentException If argument is not callable or not an array
|
||||
* @param Callable|array[Callable]
|
||||
* @return \Slim\Route
|
||||
* @throws \InvalidArgumentException If argument is not callable or not an array of callables.
|
||||
*/
|
||||
public function setMiddleware( $middleware ) {
|
||||
if ( is_callable($middleware) ) {
|
||||
public function setMiddleware($middleware)
|
||||
{
|
||||
if (is_callable($middleware)) {
|
||||
$this->middleware[] = $middleware;
|
||||
} else if ( is_array($middleware) ) {
|
||||
} elseif (is_array($middleware)) {
|
||||
foreach($middleware as $callable) {
|
||||
if (!is_callable($callable)) {
|
||||
throw new \InvalidArgumentException('All Route middleware must be callable');
|
||||
}
|
||||
}
|
||||
$this->middleware = array_merge($this->middleware, $middleware);
|
||||
} else {
|
||||
throw new InvalidArgumentException('Route middleware must be callable or an array of callables');
|
||||
throw new \InvalidArgumentException('Route middleware must be callable or an array of callables');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
@ -291,110 +341,76 @@ class Slim_Route {
|
|||
*
|
||||
* http://blog.sosedoff.com/2009/09/20/rails-like-php-url-router/
|
||||
*
|
||||
* @param string $resourceUri A Request URI
|
||||
* @return bool
|
||||
* @param string $resourceUri A Request URI
|
||||
* @return bool
|
||||
*/
|
||||
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 . '?';
|
||||
public function matches($resourceUri)
|
||||
{
|
||||
//Convert URL params into regex patterns, construct a regex for this route, init params
|
||||
$patternAsRegex = preg_replace_callback('#:([\w]+)\+?#', array($this, 'matchesCallback'),
|
||||
str_replace(')', ')?', (string) $this->pattern));
|
||||
if (substr($this->pattern, -1) === '/') {
|
||||
$patternAsRegex .= '?';
|
||||
}
|
||||
$patternAsRegex = '@^' . $patternAsRegex . '$@';
|
||||
|
||||
//Cache URL params' names and values if this route matches the current HTTP request
|
||||
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 {
|
||||
if (!preg_match('#^' . $patternAsRegex . '$#', $resourceUri, $paramValues)) {
|
||||
return false;
|
||||
}
|
||||
foreach ($this->paramNames as $name) {
|
||||
if (isset($paramValues[$name])) {
|
||||
if (isset($this->paramNamesPath[ $name ])) {
|
||||
$this->params[$name] = explode('/', urldecode($paramValues[$name]));
|
||||
} else {
|
||||
$this->params[$name] = urldecode($paramValues[$name]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a URL parameter (ie. ":id") into a regular expression
|
||||
* @param array URL parameters
|
||||
* @return string Regular expression for URL parameter
|
||||
* Convert a URL parameter (e.g. ":id", ":id+") into a regular expression
|
||||
* @param array URL parameters
|
||||
* @return string Regular expression for URL parameter
|
||||
*/
|
||||
protected function 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_\-\.\!\~\*\\\'\(\)\:\@\&\=\$\+,%]+)';
|
||||
protected function matchesCallback($m)
|
||||
{
|
||||
$this->paramNames[] = $m[1];
|
||||
if (isset($this->conditions[ $m[1] ])) {
|
||||
return '(?P<' . $m[1] . '>' . $this->conditions[ $m[1] ] . ')';
|
||||
}
|
||||
if (substr($m[0], -1) === '+') {
|
||||
$this->paramNamesPath[ $m[1] ] = 1;
|
||||
|
||||
return '(?P<' . $m[1] . '>.+)';
|
||||
}
|
||||
|
||||
return '(?P<' . $m[1] . '>[^/]+)';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set route name
|
||||
* @param string $name The name of the route
|
||||
* @return Slim_Route
|
||||
* @param string $name The name of the 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
|
||||
* @param array $conditions Key-value array of URL parameter conditions
|
||||
* @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
|
||||
$req = $this->router->getRequest();
|
||||
$res = $this->router->getResponse();
|
||||
foreach ( $this->middleware as $mw ) {
|
||||
if ( is_callable($mw) ) {
|
||||
call_user_func_array($mw, array($req, $res, $this));
|
||||
}
|
||||
}
|
||||
|
||||
//Invoke callable
|
||||
if ( is_callable($this->getCallable()) ) {
|
||||
call_user_func_array($this->callable, array_values($this->params));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
244
Slim/Router.php
244
Slim/Router.php
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,174 +30,186 @@
|
|||
* 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 Route objects and, upon request, will
|
||||
* return an iterator for routes that match the HTTP request URI.
|
||||
* This class organizes, iterates, and dispatches \Slim\Route objects.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_Router implements IteratorAggregate {
|
||||
class Router
|
||||
{
|
||||
/**
|
||||
* @var Slim_Http_Request
|
||||
* @var Route The current route (most recently dispatched)
|
||||
*/
|
||||
protected $request;
|
||||
protected $currentRoute;
|
||||
|
||||
/**
|
||||
* @var Slim_Http_Response
|
||||
*/
|
||||
protected $response;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of all routes
|
||||
* @var array Lookup hash of all route objects
|
||||
*/
|
||||
protected $routes;
|
||||
|
||||
/**
|
||||
* @var array Lookup hash of named routes, keyed by route name
|
||||
* @var array Lookup hash of named route objects, keyed by route name (lazy-loaded)
|
||||
*/
|
||||
protected $namedRoutes;
|
||||
|
||||
/**
|
||||
* @var array Array of routes that match the Request URI (lazy-loaded)
|
||||
* @var array Array of route objects that match the request URI (lazy-loaded)
|
||||
*/
|
||||
protected $matchedRoutes;
|
||||
|
||||
/**
|
||||
* @var mixed Callable to be invoked if no matching routes are found
|
||||
*/
|
||||
protected $notFound;
|
||||
|
||||
/**
|
||||
* @var mixed Callable to be invoked if application error
|
||||
*/
|
||||
protected $error;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param Slim_Http_Request $request The HTTP request object
|
||||
* @param Slim_Http_Response $response The HTTP response object
|
||||
*/
|
||||
public function __construct( Slim_Http_Request $request, Slim_Http_Response $response ) {
|
||||
$this->request = $request;
|
||||
$this->response = $response;
|
||||
public function __construct()
|
||||
{
|
||||
$this->routes = array();
|
||||
$this->namedRoutes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Iterator
|
||||
* @return ArrayIterator
|
||||
* Get Current Route object or the first matched one if matching has been performed
|
||||
* @return \Slim\Route|null
|
||||
*/
|
||||
public function getIterator() {
|
||||
return new ArrayIterator($this->getMatchedRoutes());
|
||||
public function getCurrentRoute()
|
||||
{
|
||||
if ($this->currentRoute !== null) {
|
||||
return $this->currentRoute;
|
||||
}
|
||||
|
||||
if (is_array($this->matchedRoutes) && count($this->matchedRoutes) > 0) {
|
||||
return $this->matchedRoutes[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Request
|
||||
* @return Slim_Http_Request
|
||||
* Return route objects that match the given HTTP method and URI
|
||||
* @param string $httpMethod The HTTP method to match against
|
||||
* @param string $resourceUri The resource URI to match against
|
||||
* @param bool $reload Should matching routes be re-parsed?
|
||||
* @return array[\Slim\Route]
|
||||
*/
|
||||
public function getRequest() {
|
||||
return $this->request;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Response
|
||||
* @return Slim_Http_Response
|
||||
*/
|
||||
public function getResponse() {
|
||||
return $this->response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return routes that match the current request
|
||||
* @return array[Slim_Route]
|
||||
*/
|
||||
public function getMatchedRoutes( $reload = false ) {
|
||||
if ( $reload || is_null($this->matchedRoutes) ) {
|
||||
public function getMatchedRoutes($httpMethod, $resourceUri, $reload = false)
|
||||
{
|
||||
if ($reload || is_null($this->matchedRoutes)) {
|
||||
$this->matchedRoutes = array();
|
||||
foreach ( $this->routes as $route ) {
|
||||
if ( $route->matches($this->request->getResourceUri()) ) {
|
||||
foreach ($this->routes as $route) {
|
||||
if (!$route->supportsHttpMethod($httpMethod)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($route->matches($resourceUri)) {
|
||||
$this->matchedRoutes[] = $route;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->matchedRoutes;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* Map a route object to a callback function
|
||||
* @param string $pattern The URL pattern (ie. "/books/:id")
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return \Slim\Route
|
||||
*/
|
||||
public function map( $pattern, $callable ) {
|
||||
$route = new Slim_Route($pattern, $callable);
|
||||
$route->setRouter($this);
|
||||
public function map($pattern, $callable)
|
||||
{
|
||||
$route = new \Slim\Route($pattern, $callable);
|
||||
$this->routes[] = $route;
|
||||
|
||||
return $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL for named route
|
||||
* @param string $name The name of the route
|
||||
* @param array Associative array of URL parameter names and values
|
||||
* @throws RuntimeException If named route not found
|
||||
* @return string The URL for the given route populated with the given parameters
|
||||
* @param string $name The name of the route
|
||||
* @param array Associative array of URL parameter names and replacement values
|
||||
* @throws RuntimeException If named route not found
|
||||
* @return string The URL for the given route populated with provided replacement values
|
||||
*/
|
||||
public function urlFor( $name, $params = array() ) {
|
||||
if ( !$this->hasNamedRoute($name) ) {
|
||||
throw new RuntimeException('Named route not found for name: ' . $name);
|
||||
public function urlFor($name, $params = array())
|
||||
{
|
||||
if (!$this->hasNamedRoute($name)) {
|
||||
throw new \RuntimeException('Named route not found for name: ' . $name);
|
||||
}
|
||||
$pattern = $this->getNamedRoute($name)->getPattern();
|
||||
$search = $replace = array();
|
||||
foreach ( $params as $key => $value ) {
|
||||
$search[] = ':' . $key;
|
||||
$replace[] = $value;
|
||||
$search = array();
|
||||
foreach (array_keys($params) as $key) {
|
||||
$search[] = '#:' . $key . '\+?(?!\w)#';
|
||||
}
|
||||
$pattern = str_replace($search, $replace, $pattern);
|
||||
$pattern = preg_replace($search, $params, $this->getNamedRoute($name)->getPattern());
|
||||
|
||||
//Remove remnants of unpopulated, trailing optional pattern segments
|
||||
return preg_replace(array(
|
||||
'@\(\/?:.+\/??\)\??@',
|
||||
'@\?|\(|\)@'
|
||||
), '', $this->request->getRootUri() . $pattern);
|
||||
return preg_replace('#\(/?:.+\)|\(|\)#', '', $pattern);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch route
|
||||
*
|
||||
* This method invokes the route object's callable. If middleware is
|
||||
* registered for the route, each callable middleware is invoked in
|
||||
* the order specified.
|
||||
*
|
||||
* @param \Slim\Route $route The route object
|
||||
* @return bool Was route callable invoked successfully?
|
||||
*/
|
||||
public function dispatch(\Slim\Route $route)
|
||||
{
|
||||
$this->currentRoute = $route;
|
||||
|
||||
//Invoke middleware
|
||||
foreach ($route->getMiddleware() as $mw) {
|
||||
call_user_func_array($mw, array($route));
|
||||
}
|
||||
|
||||
//Invoke callable
|
||||
call_user_func_array($route->getCallable(), array_values($route->getParams()));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add named route
|
||||
* @param string $name The route name
|
||||
* @param Slim_Route $route The route object
|
||||
* @throws RuntimeException If a named route already exists with the same name
|
||||
* @return void
|
||||
* @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);
|
||||
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;
|
||||
$this->namedRoutes[(string) $name] = $route;
|
||||
}
|
||||
|
||||
/**
|
||||
* Has named route
|
||||
* @param string $name The route name
|
||||
* @return bool
|
||||
* @param string $name The route name
|
||||
* @return bool
|
||||
*/
|
||||
public function hasNamedRoute( $name ) {
|
||||
return isset($this->namedRoutes[(string)$name]);
|
||||
public function hasNamedRoute($name)
|
||||
{
|
||||
$this->getNamedRoutes();
|
||||
|
||||
return isset($this->namedRoutes[(string) $name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get named route
|
||||
* @param string $name
|
||||
* @return Slim_Route|null
|
||||
* @param string $name
|
||||
* @return \Slim\Route|null
|
||||
*/
|
||||
public function getNamedRoute( $name ) {
|
||||
if ( $this->hasNamedRoute($name) ) {
|
||||
return $this->namedRoutes[(string)$name];
|
||||
public function getNamedRoute($name)
|
||||
{
|
||||
$this->getNamedRoutes();
|
||||
if ($this->hasNamedRoute($name)) {
|
||||
return $this->namedRoutes[(string) $name];
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
@ -205,33 +217,19 @@ class Slim_Router implements IteratorAggregate {
|
|||
|
||||
/**
|
||||
* Get named routes
|
||||
* @return ArrayIterator
|
||||
* @return \ArrayIterator
|
||||
*/
|
||||
public function getNamedRoutes() {
|
||||
return new ArrayIterator($this->namedRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a 404 Not Found callback
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return mixed
|
||||
*/
|
||||
public function notFound( $callable = null ) {
|
||||
if ( is_callable($callable) ) {
|
||||
$this->notFound = $callable;
|
||||
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 $this->notFound;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a 500 Error callback
|
||||
* @param mixed $callable Anything that returns TRUE for is_callable()
|
||||
* @return mixed
|
||||
*/
|
||||
public function error( $callable = null ) {
|
||||
if ( is_callable($callable) ) {
|
||||
$this->error = $callable;
|
||||
}
|
||||
return $this->error;
|
||||
return new \ArrayIterator($this->namedRoutes);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
932
Slim/Slim.php
932
Slim/Slim.php
File diff suppressed because it is too large
Load Diff
168
Slim/View.php
168
Slim/View.php
|
@ -6,7 +6,7 @@
|
|||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 1.6.0
|
||||
* @version 2.2.0
|
||||
* @package Slim
|
||||
*
|
||||
* MIT LICENSE
|
||||
|
@ -30,47 +30,63 @@
|
|||
* 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;
|
||||
|
||||
/**
|
||||
* Slim View
|
||||
* View
|
||||
*
|
||||
* 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.
|
||||
* The view is responsible for rendering a template. The view
|
||||
* should subclass \Slim\View and implement this interface:
|
||||
*
|
||||
* public render(string $template);
|
||||
*
|
||||
* This method should render the specified template and return
|
||||
* the resultant string.
|
||||
*
|
||||
* @package Slim
|
||||
* @author Josh Lockhart
|
||||
* @since 1.0.0
|
||||
*/
|
||||
class Slim_View {
|
||||
class View
|
||||
{
|
||||
/**
|
||||
* @var array Key-value array of data available to the template
|
||||
* @var string Absolute or relative filesystem path to a specific template
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* This variable will be removed in the near future
|
||||
*/
|
||||
protected $templatePath = '';
|
||||
|
||||
/**
|
||||
* @var array Associative array of template variables
|
||||
*/
|
||||
protected $data = array();
|
||||
|
||||
/**
|
||||
* @var string Absolute or relative path to the templates directory
|
||||
* @var string Absolute or relative path to the application's templates directory
|
||||
*/
|
||||
protected $templatesDirectory;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* This is empty but may be overridden in a subclass
|
||||
* This is empty but may be implemented in a subclass
|
||||
*/
|
||||
public function __construct() {}
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get data
|
||||
* @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.
|
||||
* @param string|null $key
|
||||
* @return mixed If key is null, array of template data;
|
||||
* If key exists, value of datum with key;
|
||||
* If key does not exist, null;
|
||||
*/
|
||||
public function getData( $key = null ) {
|
||||
if ( !is_null($key) ) {
|
||||
public function getData($key = null)
|
||||
{
|
||||
if (!is_null($key)) {
|
||||
return isset($this->data[$key]) ? $this->data[$key] : null;
|
||||
} else {
|
||||
return $this->data;
|
||||
|
@ -80,85 +96,121 @@ class Slim_View {
|
|||
/**
|
||||
* Set data
|
||||
*
|
||||
* 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.
|
||||
* If two arguments:
|
||||
* A single datum with key is assigned value;
|
||||
*
|
||||
* USAGE:
|
||||
* $view->setData('color', 'red');
|
||||
*
|
||||
* View::setData('color', 'red');
|
||||
* View::setData(array('color' => 'red', 'number' => 1));
|
||||
* If one argument:
|
||||
* Replace all data with provided array keys and values;
|
||||
*
|
||||
* @param string|array
|
||||
* @param mixed Optional. Only use if first argument is a string.
|
||||
* @return void
|
||||
* @throws InvalidArgumentException If incorrect method signature
|
||||
* $view->setData(array('color' => 'red', 'number' => 1));
|
||||
*
|
||||
* @param mixed
|
||||
* @param mixed
|
||||
* @throws InvalidArgumentException If incorrect method signature
|
||||
*/
|
||||
public function setData() {
|
||||
public function setData()
|
||||
{
|
||||
$args = func_get_args();
|
||||
if ( count($args) === 1 && is_array($args[0]) ) {
|
||||
if (count($args) === 1 && is_array($args[0])) {
|
||||
$this->data = $args[0];
|
||||
} else if ( count($args) === 2 ) {
|
||||
$this->data[(string)$args[0]] = $args[1];
|
||||
} elseif (count($args) === 2) {
|
||||
$this->data[(string) $args[0]] = $args[1];
|
||||
} else {
|
||||
throw new InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
|
||||
throw new \InvalidArgumentException('Cannot set View data with provided arguments. Usage: `View::setData( $key, $value );` or `View::setData([ key => value, ... ]);`');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append data to existing View data
|
||||
* @param array $data
|
||||
* @return void
|
||||
* Append new data to existing template data
|
||||
* @param array
|
||||
* @throws InvalidArgumentException If not given an array argument
|
||||
*/
|
||||
public function appendData( array $data ) {
|
||||
public function appendData($data)
|
||||
{
|
||||
if (!is_array($data)) {
|
||||
throw new \InvalidArgumentException('Cannot append view data. Expected array argument.');
|
||||
}
|
||||
$this->data = array_merge($this->data, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get templates directory
|
||||
* @return string|null Path to templates directory without trailing slash
|
||||
* @return string|null Path to templates directory without trailing slash;
|
||||
* Returns null if templates directory not set;
|
||||
*/
|
||||
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
|
||||
* @param string $dir
|
||||
*/
|
||||
public function setTemplatesDirectory( $dir ) {
|
||||
public function setTemplatesDirectory($dir)
|
||||
{
|
||||
$this->templatesDirectory = rtrim($dir, '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set template
|
||||
* @param string $template
|
||||
* @throws RuntimeException If template file does not exist
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* This method will be removed in the near future.
|
||||
*/
|
||||
public function setTemplate($template)
|
||||
{
|
||||
$this->templatePath = $this->getTemplatesDirectory() . '/' . ltrim($template, '/');
|
||||
if (!file_exists($this->templatePath)) {
|
||||
throw new \RuntimeException('View cannot render template `' . $this->templatePath . '`. Template does not exist.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Display template
|
||||
*
|
||||
* This method echoes the rendered template to the current output buffer
|
||||
*
|
||||
* @param string $template Path to template file relative to templates directoy
|
||||
* @return void
|
||||
* @param string $template Pathname of template file relative to templates directoy
|
||||
*/
|
||||
public function display( $template ) {
|
||||
echo $this->render($template);
|
||||
public function display($template)
|
||||
{
|
||||
echo $this->fetch($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch rendered template
|
||||
*
|
||||
* This method returns the rendered template
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directory
|
||||
* @return string
|
||||
*/
|
||||
public function fetch($template)
|
||||
{
|
||||
return $this->render($template);
|
||||
}
|
||||
|
||||
/**
|
||||
* Render template
|
||||
* @param string $template Path to template file relative to templates directory
|
||||
* @return string Rendered template
|
||||
* @throws RuntimeException If template does not exist
|
||||
*
|
||||
* @param string $template Pathname of template file relative to templates directory
|
||||
* @return string
|
||||
*
|
||||
* DEPRECATION WARNING!
|
||||
* Use `\Slim\View::fetch` to return a rendered template instead of `\Slim\View::render`.
|
||||
*/
|
||||
public function render( $template ) {
|
||||
public function render($template)
|
||||
{
|
||||
$this->setTemplate($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 $templatePath;
|
||||
require $this->templatePath;
|
||||
|
||||
return ob_get_clean();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"name": "slim/slim",
|
||||
"type": "library",
|
||||
"description": "Slim Framework, a PHP micro framework",
|
||||
"keywords": ["microframework","rest","router"],
|
||||
"homepage": "http://github.com/codeguy/Slim",
|
||||
"license": "MIT",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Josh Lockhart",
|
||||
"email": "info@joshlockhart.com",
|
||||
"homepage": "http://www.joshlockhart.com/"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-0": { "Slim": "." }
|
||||
}
|
||||
}
|
27
index.php
27
index.php
|
@ -1,13 +1,30 @@
|
|||
<?php
|
||||
/**
|
||||
* Step 1: Require the Slim Framework
|
||||
*
|
||||
* If you are not using Composer, you need to require the
|
||||
* Slim Framework and register its PSR-0 autoloader.
|
||||
*
|
||||
* If you are using Composer, you can skip this step.
|
||||
*/
|
||||
require 'Slim/Slim.php';
|
||||
require 'Slim/View.php';
|
||||
|
||||
\Slim\Slim::registerAutoloader();
|
||||
|
||||
require 'lib/GopherGetter.php';
|
||||
require_once 'lib/meekrodb.2.0.class.php';
|
||||
|
||||
require_once 'lib/meekrodb.2.1.class.php';
|
||||
require_once 'config.php';
|
||||
|
||||
$app = new Slim();
|
||||
|
||||
/**
|
||||
* Step 2: Instantiate a Slim application
|
||||
*
|
||||
* This example instantiates a Slim application using
|
||||
* its default settings. However, you will usually configure
|
||||
* your Slim application now by passing an associative array
|
||||
* of setting names and values into the application constructor.
|
||||
*/
|
||||
$app = new \Slim\Slim();
|
||||
|
||||
//
|
||||
// default route
|
||||
|
@ -45,8 +62,6 @@ $app->notFound(function () use ($app) {
|
|||
$app->render('home.html', array("class" => "hide"));
|
||||
});
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* handle requests for a gopher page
|
||||
*/
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<?php
|
||||
/*
|
||||
Copyright (C) 2008-2011 Sergey Tsalkov (stsalkov@gmail.com)
|
||||
Copyright (C) 2008-2012 Sergey Tsalkov (stsalkov@gmail.com)
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
|
@ -29,11 +29,13 @@ class DB {
|
|||
// configure workings
|
||||
public static $queryMode = 'queryAllRows';
|
||||
public static $param_char = '%';
|
||||
public static $named_param_seperator = '_';
|
||||
public static $success_handler = false;
|
||||
public static $error_handler = true;
|
||||
public static $throw_exception_on_error = false;
|
||||
public static $nonsql_error_handler = null;
|
||||
public static $throw_exception_on_nonsql_error = false;
|
||||
public static $nested_transactions = false;
|
||||
|
||||
// internal
|
||||
protected static $mdb = null;
|
||||
|
@ -47,15 +49,18 @@ class DB {
|
|||
|
||||
if ($mdb->queryMode !== DB::$queryMode) $mdb->queryMode = DB::$queryMode;
|
||||
if ($mdb->param_char !== DB::$param_char) $mdb->param_char = DB::$param_char;
|
||||
if ($mdb->named_param_seperator !== DB::$named_param_seperator) $mdb->named_param_seperator = DB::$named_param_seperator;
|
||||
if ($mdb->success_handler !== DB::$success_handler) $mdb->success_handler = DB::$success_handler;
|
||||
if ($mdb->error_handler !== DB::$error_handler) $mdb->error_handler = DB::$error_handler;
|
||||
if ($mdb->throw_exception_on_error !== DB::$throw_exception_on_error) $mdb->throw_exception_on_error = DB::$throw_exception_on_error;
|
||||
if ($mdb->nonsql_error_handler !== DB::$nonsql_error_handler) $mdb->nonsql_error_handler = DB::$nonsql_error_handler;
|
||||
if ($mdb->throw_exception_on_nonsql_error !== DB::$throw_exception_on_nonsql_error) $mdb->throw_exception_on_nonsql_error = DB::$throw_exception_on_nonsql_error;
|
||||
if ($mdb->nested_transactions !== DB::$nested_transactions) $mdb->nested_transactions = DB::$nested_transactions;
|
||||
|
||||
return $mdb;
|
||||
}
|
||||
|
||||
public static function get() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'get'), $args); }
|
||||
public static function query() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'query'), $args); }
|
||||
public static function quickPrepare() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'quickPrepare'), $args); }
|
||||
public static function queryFirstRow() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'queryFirstRow'), $args); }
|
||||
|
@ -92,6 +97,10 @@ class DB {
|
|||
public static function sqlEval() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'sqlEval'), $args); }
|
||||
public static function nonSQLError() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'nonSQLError'), $args); }
|
||||
|
||||
public static function serverVersion() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'serverVersion'), $args); }
|
||||
public static function transactionDepth() { $args = func_get_args(); return call_user_func_array(array(DB::getMDB(), 'transactionDepth'), $args); }
|
||||
|
||||
|
||||
public static function debugMode($handler = true) {
|
||||
DB::$success_handler = $handler;
|
||||
}
|
||||
|
@ -111,14 +120,17 @@ class MeekroDB {
|
|||
// configure workings
|
||||
public $queryMode = 'queryAllRows';
|
||||
public $param_char = '%';
|
||||
public $named_param_seperator = '_';
|
||||
public $success_handler = false;
|
||||
public $error_handler = true;
|
||||
public $throw_exception_on_error = false;
|
||||
public $nonsql_error_handler = null;
|
||||
public $throw_exception_on_nonsql_error = false;
|
||||
public $nested_transactions = false;
|
||||
|
||||
// internal
|
||||
public $internal_mysql = null;
|
||||
public $server_info = null;
|
||||
public $insert_id = 0;
|
||||
public $num_rows = 0;
|
||||
public $affected_rows = 0;
|
||||
|
@ -126,6 +138,7 @@ class MeekroDB {
|
|||
public $queryResultType = null;
|
||||
public $old_db = null;
|
||||
public $current_db = null;
|
||||
public $nested_transactions_count = 0;
|
||||
|
||||
|
||||
public function __construct($host=null, $user=null, $password=null, $dbName=null, $port=null, $encoding=null) {
|
||||
|
@ -158,6 +171,7 @@ class MeekroDB {
|
|||
|
||||
$mysql->set_charset($this->encoding);
|
||||
$this->internal_mysql = $mysql;
|
||||
$this->server_info = $mysql->server_info;
|
||||
}
|
||||
|
||||
return $mysql;
|
||||
|
@ -181,6 +195,8 @@ class MeekroDB {
|
|||
$this->success_handler = $handler;
|
||||
}
|
||||
|
||||
public function serverVersion() { return $this->server_info; }
|
||||
public function transactionDepth() { return $this->nested_transactions_count; }
|
||||
public function insertId() { return $this->insert_id; }
|
||||
public function affectedRows() { return $this->affected_rows; }
|
||||
public function count() { $args = func_get_args(); return call_user_func_array(array($this, 'numRows'), $args); }
|
||||
|
@ -196,15 +212,55 @@ class MeekroDB {
|
|||
|
||||
|
||||
public function startTransaction() {
|
||||
$this->queryNull('START TRANSACTION');
|
||||
if ($this->nested_transactions && $this->serverVersion() < '5.5') {
|
||||
return $this->nonSQLError("Nested transactions are only available on MySQL 5.5 and greater. You are using MySQL " . $this->serverVersion());
|
||||
}
|
||||
|
||||
if (!$this->nested_transactions || $this->nested_transactions_count == 0) {
|
||||
$this->queryNull('START TRANSACTION');
|
||||
$this->nested_transactions_count = 1;
|
||||
} else {
|
||||
$this->queryNull("SAVEPOINT LEVEL{$this->nested_transactions_count}");
|
||||
$this->nested_transactions_count++;
|
||||
}
|
||||
|
||||
return $this->nested_transactions_count;
|
||||
}
|
||||
|
||||
public function commit() {
|
||||
$this->queryNull('COMMIT');
|
||||
public function commit($all=false) {
|
||||
if ($this->nested_transactions && $this->serverVersion() < '5.5') {
|
||||
return $this->nonSQLError("Nested transactions are only available on MySQL 5.5 and greater. You are using MySQL " . $this->serverVersion());
|
||||
}
|
||||
|
||||
if ($this->nested_transactions && $this->nested_transactions_count > 0)
|
||||
$this->nested_transactions_count--;
|
||||
|
||||
if (!$this->nested_transactions || $all || $this->nested_transactions_count == 0) {
|
||||
$this->nested_transactions_count = 0;
|
||||
$this->queryNull('COMMIT');
|
||||
} else {
|
||||
$this->queryNull("RELEASE SAVEPOINT LEVEL{$this->nested_transactions_count}");
|
||||
}
|
||||
|
||||
return $this->nested_transactions_count;
|
||||
}
|
||||
|
||||
public function rollback() {
|
||||
$this->queryNull('ROLLBACK');
|
||||
public function rollback($all=false) {
|
||||
if ($this->nested_transactions && $this->serverVersion() < '5.5') {
|
||||
return $this->nonSQLError("Nested transactions are only available on MySQL 5.5 and greater. You are using MySQL " . $this->serverVersion());
|
||||
}
|
||||
|
||||
if ($this->nested_transactions && $this->nested_transactions_count > 0)
|
||||
$this->nested_transactions_count--;
|
||||
|
||||
if (!$this->nested_transactions || $all || $this->nested_transactions_count == 0) {
|
||||
$this->nested_transactions_count = 0;
|
||||
$this->queryNull('ROLLBACK');
|
||||
} else {
|
||||
$this->queryNull("ROLLBACK TO SAVEPOINT LEVEL{$this->nested_transactions_count}");
|
||||
}
|
||||
|
||||
return $this->nested_transactions_count;
|
||||
}
|
||||
|
||||
public function escape($str) {
|
||||
|
@ -299,7 +355,7 @@ class MeekroDB {
|
|||
$insert_values = array();
|
||||
|
||||
foreach ($keys as $key) {
|
||||
if ($many && !isset($data[$key])) $this->nonSQLError('insert/replace many: each assoc array must have the same keys!');
|
||||
if ($many && !array_key_exists($key, $data)) $this->nonSQLError('insert/replace many: each assoc array must have the same keys!');
|
||||
$datum = $data[$key];
|
||||
$datum = $this->sanitize($datum);
|
||||
$insert_values[] = $datum;
|
||||
|
@ -409,6 +465,8 @@ class MeekroDB {
|
|||
$posList = array();
|
||||
$pos_adj = 0;
|
||||
$param_char_length = strlen($this->param_char);
|
||||
$named_seperator_length = strlen($this->named_param_seperator);
|
||||
|
||||
$types = array(
|
||||
$this->param_char . 'll', // list of literals
|
||||
$this->param_char . 'ls', // list of strings
|
||||
|
@ -438,12 +496,25 @@ class MeekroDB {
|
|||
$type = substr($type, $param_char_length);
|
||||
$length_type = strlen($type) + $param_char_length;
|
||||
|
||||
if ($arg_number_length = strspn($sql, '0123456789', $pos + $pos_adj + $length_type)) {
|
||||
$arg_number = substr($sql, $pos + $pos_adj + $length_type, $arg_number_length);
|
||||
$new_pos = $pos + $pos_adj;
|
||||
$new_pos_back = $new_pos + $length_type;
|
||||
|
||||
if ($arg_number_length = strspn($sql, '0123456789', $new_pos_back)) {
|
||||
$arg_number = substr($sql, $new_pos_back, $arg_number_length);
|
||||
if (! isset($args_all[$arg_number])) $this->nonSQLError("Non existent argument reference (arg $arg_number): $sql");
|
||||
|
||||
$arg = $args_all[$arg_number];
|
||||
|
||||
} else if (substr($sql, $new_pos_back, $named_seperator_length) == $this->named_param_seperator) {
|
||||
$arg_number_length = strspn($sql, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_',
|
||||
$new_pos_back + $named_seperator_length) + $named_seperator_length;
|
||||
|
||||
$arg_number = substr($sql, $new_pos_back + $named_seperator_length, $arg_number_length - $named_seperator_length);
|
||||
if (count($args_all) != 1) $this->nonSQLError("If you use named parameters, the second argument must be an array of parameters");
|
||||
if (! isset($args_all[0][$arg_number])) $this->nonSQLError("Non existent argument reference (arg $arg_number): $sql");
|
||||
|
||||
$arg = $args_all[0][$arg_number];
|
||||
|
||||
} else {
|
||||
$arg_number = 0;
|
||||
$arg = array_shift($args);
|
||||
|
@ -463,7 +534,7 @@ class MeekroDB {
|
|||
if ($type == 'ls') $result = $this->wrapStr($arg, "'", true);
|
||||
else if ($type == 'li') $result = array_map('intval', $arg);
|
||||
else if ($type == 'ld') $result = array_map('floatval', $arg);
|
||||
else if ($type == 'lb') $result = array_map('$this->formatTableName', $arg);
|
||||
else if ($type == 'lb') $result = array_map(array($this, 'formatTableName'), $arg);
|
||||
else if ($type == 'll') $result = $arg;
|
||||
else if (! $result) $this->nonSQLError("Badly formatted SQL query: $sql");
|
||||
|
||||
|
@ -472,7 +543,7 @@ class MeekroDB {
|
|||
else $result = '(' . implode(',', $result) . ')';
|
||||
}
|
||||
|
||||
$sql = substr_replace($sql, $result, $pos + $pos_adj, $length_type + $arg_number_length);
|
||||
$sql = substr_replace($sql, $result, $new_pos, $length_type + $arg_number_length);
|
||||
$pos_adj += strlen($result) - ($length_type + $arg_number_length);
|
||||
}
|
||||
return $sql;
|
||||
|
@ -542,7 +613,8 @@ class MeekroDB {
|
|||
|
||||
call_user_func($success_handler, array(
|
||||
'query' => $sql,
|
||||
'runtime' => $runtime
|
||||
'runtime' => $runtime,
|
||||
'affected' => $db->affected_rows
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -770,6 +842,8 @@ class WhereClause {
|
|||
if ($this->negate) $A = '(NOT ' . $A . ')';
|
||||
return $A;
|
||||
}
|
||||
|
||||
function __toString() { return $this->text(); }
|
||||
}
|
||||
|
||||
class DBTransaction {
|
||||
|
@ -800,6 +874,56 @@ class MeekroDBException extends Exception {
|
|||
public function getQuery() { return $this->query; }
|
||||
}
|
||||
|
||||
class DBHelper {
|
||||
/*
|
||||
verticalSlice
|
||||
1. For an array of assoc rays, return an array of values for a particular key
|
||||
2. if $keyfield is given, same as above but use that hash key as the key in new array
|
||||
*/
|
||||
|
||||
public static function verticalSlice($array, $field, $keyfield = null) {
|
||||
$array = (array) $array;
|
||||
|
||||
$R = array();
|
||||
foreach ($array as $obj) {
|
||||
if (! array_key_exists($field, $obj)) die("verticalSlice: array doesn't have requested field\n");
|
||||
|
||||
if ($keyfield) {
|
||||
if (! array_key_exists($keyfield, $obj)) die("verticalSlice: array doesn't have requested field\n");
|
||||
$R[$obj[$keyfield]] = $obj[$field];
|
||||
} else {
|
||||
$R[] = $obj[$field];
|
||||
}
|
||||
}
|
||||
return $R;
|
||||
}
|
||||
|
||||
/*
|
||||
reIndex
|
||||
For an array of assoc rays, return a new array of assoc rays using a certain field for keys
|
||||
*/
|
||||
|
||||
public static function reIndex() {
|
||||
$fields = func_get_args();
|
||||
$array = array_shift($fields);
|
||||
$array = (array) $array;
|
||||
|
||||
$R = array();
|
||||
foreach ($array as $obj) {
|
||||
$target =& $R;
|
||||
|
||||
foreach ($fields as $field) {
|
||||
if (! array_key_exists($field, $obj)) die("reIndex: array doesn't have requested field\n");
|
||||
|
||||
$nextkey = $obj[$field];
|
||||
$target =& $target[$nextkey];
|
||||
}
|
||||
$target = $obj;
|
||||
}
|
||||
return $R;
|
||||
}
|
||||
}
|
||||
|
||||
function meekrodb_error_handler($params) {
|
||||
if (isset($params['query'])) $out[] = "QUERY: " . $params['query'];
|
||||
if (isset($params['error'])) $out[] = "ERROR: " . $params['error'];
|
||||
|
@ -811,8 +935,6 @@ function meekrodb_error_handler($params) {
|
|||
echo implode("<br>\n", $out);
|
||||
}
|
||||
|
||||
debug_print_backtrace();
|
||||
|
||||
die;
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false"
|
||||
syntaxCheck="false"
|
||||
bootstrap="tests/bootstrap.php"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="Slim Test Suite">
|
||||
<directory>./tests/</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
|
||||
<filter>
|
||||
<whitelist>
|
||||
<directory>./Slim/</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
|
@ -0,0 +1,358 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class EnvironmentTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Default server settings assume the Slim app is installed
|
||||
* in a subdirectory `foo/` directly beneath the public document
|
||||
* root directory; URL rewrite is disabled; requested app
|
||||
* resource is GET `/bar/xyz` with three query params.
|
||||
*
|
||||
* These only provide a common baseline for the following
|
||||
* tests; tests are free to override these values.
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$_SERVER['SERVER_NAME'] = 'slim';
|
||||
$_SERVER['SERVER_PORT'] = '80';
|
||||
$_SERVER['SCRIPT_NAME'] = '/foo/index.php';
|
||||
$_SERVER['REQUEST_URI'] = '/foo/index.php/bar/xyz';
|
||||
$_SERVER['PATH_INFO'] = '/bar/xyz';
|
||||
$_SERVER['REQUEST_METHOD'] = 'GET';
|
||||
$_SERVER['QUERY_STRING'] = 'one=1&two=2&three=3';
|
||||
$_SERVER['HTTPS'] = '';
|
||||
$_SERVER['REMOTE_ADDR'] = '127.0.0.1';
|
||||
unset($_SERVER['CONTENT_TYPE'], $_SERVER['CONTENT_LENGTH']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test mock environment
|
||||
*
|
||||
* This should return the custom values where specified
|
||||
* and the default values otherwise.
|
||||
*/
|
||||
public function testMockEnvironment()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'PUT'
|
||||
));
|
||||
$env2 = \Slim\Environment::getInstance();
|
||||
$this->assertSame($env, $env2);
|
||||
$this->assertInstanceOf('\Slim\Environment', $env);
|
||||
$this->assertEquals('PUT', $env['REQUEST_METHOD']);
|
||||
$this->assertEquals(80, $env['SERVER_PORT']);
|
||||
$this->assertNull($env['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sets HTTP method
|
||||
*/
|
||||
public function testSetsHttpMethod()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('GET', $env['REQUEST_METHOD']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite is disabled;
|
||||
* App installed in subdirectory;
|
||||
*/
|
||||
public function testParsesPathsWithoutUrlRewriteInSubdirectory()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/bar/xyz', $env['PATH_INFO']);
|
||||
$this->assertEquals('/foo/index.php', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite is disabled;
|
||||
* App installed in root directory;
|
||||
*/
|
||||
public function testParsesPathsWithoutUrlRewriteInRootDirectory()
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/index.php/bar/xyz';
|
||||
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/bar/xyz', $env['PATH_INFO']);
|
||||
$this->assertEquals('/index.php', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite disabled;
|
||||
* App installed in root directory;
|
||||
* Requested resource is "/";
|
||||
*/
|
||||
public function testParsesPathsWithoutUrlRewriteInRootDirectoryForAppRootUri()
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/index.php';
|
||||
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
||||
unset($_SERVER['PATH_INFO']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/', $env['PATH_INFO']);
|
||||
$this->assertEquals('/index.php', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite enabled;
|
||||
* App installed in subdirectory;
|
||||
*/
|
||||
public function testParsesPathsWithUrlRewriteInSubdirectory()
|
||||
{
|
||||
$_SERVER['SCRIPT_NAME'] = '/foo/index.php';
|
||||
$_SERVER['REQUEST_URI'] = '/foo/bar/xyz';
|
||||
unset($_SERVER['PATH_INFO']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/bar/xyz', $env['PATH_INFO']);
|
||||
$this->assertEquals('/foo', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite enabled;
|
||||
* App installed in root directory;
|
||||
*/
|
||||
public function testParsesPathsWithUrlRewriteInRootDirectory()
|
||||
{
|
||||
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
||||
$_SERVER['REQUEST_URI'] = '/bar/xyz';
|
||||
unset($_SERVER['PATH_INFO']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/bar/xyz', $env['PATH_INFO']);
|
||||
$this->assertEquals('', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses script name and path info
|
||||
*
|
||||
* Pre-conditions:
|
||||
* URL Rewrite enabled;
|
||||
* App installed in root directory;
|
||||
* Requested resource is "/"
|
||||
*/
|
||||
public function testParsesPathsWithUrlRewriteInRootDirectoryForAppRootUri()
|
||||
{
|
||||
$_SERVER['REQUEST_URI'] = '/';
|
||||
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
||||
unset($_SERVER['PATH_INFO']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/', $env['PATH_INFO']);
|
||||
$this->assertEquals('', $env['SCRIPT_NAME']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses query string
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['QUERY_STRING'] exists and is not empty;
|
||||
*/
|
||||
public function testParsesQueryString()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('one=1&two=2&three=3', $env['QUERY_STRING']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test removes query string from PATH_INFO when using URL Rewrite
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['QUERY_STRING'] exists and is not empty;
|
||||
* URL Rewrite enabled;
|
||||
*/
|
||||
public function testRemovesQueryStringFromPathInfo()
|
||||
{
|
||||
$_SERVER['SCRIPT_NAME'] = '/foo/index.php';
|
||||
$_SERVER['REQUEST_URI'] = '/foo/bar/xyz?one=1&two=2&three=3';
|
||||
unset($_SERVER['PATH_INFO']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/bar/xyz', $env['PATH_INFO']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test environment's PATH_INFO retains URL encoded characters (e.g. #)
|
||||
*
|
||||
* In earlier version, \Slim\Environment would use PATH_INFO instead
|
||||
* of REQUEST_URI to determine the root URI and resource URI.
|
||||
* Unfortunately, the server would URL decode the PATH_INFO string
|
||||
* before it was handed to PHP. This prevented certain URL-encoded
|
||||
* characters like the octothorpe from being delivered correctly to
|
||||
* the Slim application environment. This test ensures the
|
||||
* REQUEST_URI is used instead and parsed as expected.
|
||||
*/
|
||||
public function testPathInfoRetainsUrlEncodedCharacters()
|
||||
{
|
||||
$_SERVER['SCRIPT_NAME'] = '/index.php';
|
||||
$_SERVER['REQUEST_URI'] = '/foo/%23bar'; //<-- URL-encoded "#bar"
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('/foo/%23bar', $env['PATH_INFO']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses query string
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['QUERY_STRING'] does not exist;
|
||||
*/
|
||||
public function testParsesQueryStringThatDoesNotExist()
|
||||
{
|
||||
unset($_SERVER['QUERY_STRING']);
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('', $env['QUERY_STRING']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test SERVER_NAME is not empty
|
||||
*/
|
||||
public function testServerNameIsNotEmpty()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertFalse(empty($env['SERVER_NAME']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test SERVER_PORT is not empty
|
||||
*/
|
||||
public function testServerPortIsNotEmpty()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertFalse(empty($env['SERVER_PORT']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unsets HTTP_CONTENT_TYPE and HTTP_CONTENT_LENGTH
|
||||
*
|
||||
* Pre-conditions:
|
||||
* HTTP_CONTENT_TYPE is sent with HTTP request;
|
||||
* HTTP_CONTENT_LENGTH is sent with HTTP request;
|
||||
*/
|
||||
public function testUnsetsContentTypeAndContentLength()
|
||||
{
|
||||
$_SERVER['HTTP_CONTENT_TYPE'] = 'text/csv';
|
||||
$_SERVER['HTTP_CONTENT_LENGTH'] = 150;
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertFalse(isset($env['HTTP_CONTENT_TYPE']));
|
||||
$this->assertFalse(isset($env['HTTP_CONTENT_LENGTH']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sets special request headers if not empty
|
||||
*
|
||||
* Pre-conditions:
|
||||
* CONTENT_TYPE, CONTENT_LENGTH, X_REQUESTED_WITH are sent in client HTTP request;
|
||||
* CONTENT_TYPE, CONTENT_LENGTH, X_REQUESTED_WITH are not empty;
|
||||
*/
|
||||
public function testSetsSpecialHeaders()
|
||||
{
|
||||
$_SERVER['CONTENT_TYPE'] = 'text/csv';
|
||||
$_SERVER['CONTENT_LENGTH'] = '100';
|
||||
$_SERVER['HTTP_X_REQUESTED_WITH'] = 'XmlHttpRequest';
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('text/csv', $env['CONTENT_TYPE']);
|
||||
$this->assertEquals('100', $env['CONTENT_LENGTH']);
|
||||
$this->assertEquals('XmlHttpRequest', $env['X_REQUESTED_WITH']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test detects HTTPS
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['HTTPS'] is set to a non-empty value;
|
||||
*/
|
||||
public function testHttps()
|
||||
{
|
||||
$_SERVER['HTTPS'] = 1;
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('https', $env['slim.url_scheme']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test detects not HTTPS
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['HTTPS'] is set to an empty value;
|
||||
*/
|
||||
public function testNotHttps()
|
||||
{
|
||||
$_SERVER['HTTPS'] = '';
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('http', $env['slim.url_scheme']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test detects not HTTPS on IIS
|
||||
*
|
||||
* Pre-conditions:
|
||||
* $_SERVER['HTTPS'] is set to "off";
|
||||
*/
|
||||
public function testNotHttpsIIS()
|
||||
{
|
||||
$_SERVER['HTTPS'] = 'off';
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('http', $env['slim.url_scheme']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test input is an empty string (and not false)
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Input at php://input may only be read once; subsequent attempts
|
||||
* will return `false`; in which case, use an empty string.
|
||||
*/
|
||||
public function testInputIsEmptyString()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertEquals('', $env['slim.input']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test valid resource handle to php://stdErr
|
||||
*/
|
||||
public function testErrorResource()
|
||||
{
|
||||
$env = \Slim\Environment::getInstance(true);
|
||||
$this->assertTrue(is_resource($env['slim.errors']));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
class Foo
|
||||
{
|
||||
public function __construct()
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,143 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class HeadersTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test constructor without args
|
||||
*/
|
||||
public function testConstructorWithoutArgs()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$this->assertEquals(0, count($h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test constructor with args
|
||||
*/
|
||||
public function testConstructorWithArgs()
|
||||
{
|
||||
$h = new \Slim\Http\Headers(array('Content-Type' => 'text/html'));
|
||||
$this->assertEquals(1, count($h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get and set header
|
||||
*/
|
||||
public function testSetAndGetHeader()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['Content-Type'] = 'text/html';
|
||||
$this->assertEquals('text/html', $h['Content-Type']);
|
||||
$this->assertEquals('text/html', $h['Content-type']);
|
||||
$this->assertEquals('text/html', $h['content-type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get non-existent header
|
||||
*/
|
||||
public function testGetNonExistentHeader()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$this->assertNull($h['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isset header
|
||||
*/
|
||||
public function testHeaderIsSet()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['Content-Type'] = 'text/html';
|
||||
$this->assertTrue(isset($h['Content-Type']));
|
||||
$this->assertTrue(isset($h['Content-type']));
|
||||
$this->assertTrue(isset($h['content-type']));
|
||||
$this->assertFalse(isset($h['foo']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test unset header
|
||||
*/
|
||||
public function testUnsetHeader()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['Content-Type'] = 'text/html';
|
||||
$this->assertEquals(1, count($h));
|
||||
unset($h['Content-Type']);
|
||||
$this->assertEquals(0, count($h));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test merge headers
|
||||
*/
|
||||
public function testMergeHeaders()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['Content-Type'] = 'text/html';
|
||||
$this->assertEquals(1, count($h));
|
||||
$h->merge(array('Content-type' => 'text/csv', 'content-length' => 10));
|
||||
$this->assertEquals(2, count($h));
|
||||
$this->assertEquals('text/csv', $h['content-type']);
|
||||
$this->assertEquals(10, $h['Content-length']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test iteration
|
||||
*/
|
||||
public function testIteration()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['One'] = 'Foo';
|
||||
$h['Two'] = 'Bar';
|
||||
$output = '';
|
||||
foreach ($h as $key => $value) {
|
||||
$output .= $key . $value;
|
||||
}
|
||||
$this->assertEquals('OneFooTwoBar', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test outputs header name in original form, not canonical form
|
||||
*/
|
||||
public function testOutputsOriginalNotCanonicalName()
|
||||
{
|
||||
$h = new \Slim\Http\Headers();
|
||||
$h['X-Powered-By'] = 'Slim';
|
||||
$h['Content-Type'] = 'text/csv';
|
||||
$keys = array();
|
||||
foreach ($h as $name => $value) {
|
||||
$keys[] = $name;
|
||||
}
|
||||
$this->assertContains('X-Powered-By', $keys);
|
||||
$this->assertContains('Content-Type', $keys);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,933 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class RequestTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test sets HTTP method
|
||||
*/
|
||||
public function testGetMethod()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('GET', $req->getMethod());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP GET method detection
|
||||
*/
|
||||
public function testIsGet()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isGet());
|
||||
$this->assertFalse($req->isPost());
|
||||
$this->assertFalse($req->isPut());
|
||||
$this->assertFalse($req->isDelete());
|
||||
$this->assertFalse($req->isOptions());
|
||||
$this->assertFalse($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP POST method detection
|
||||
*/
|
||||
public function testIsPost()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isGet());
|
||||
$this->assertTrue($req->isPost());
|
||||
$this->assertFalse($req->isPut());
|
||||
$this->assertFalse($req->isDelete());
|
||||
$this->assertFalse($req->isOptions());
|
||||
$this->assertFalse($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP PUT method detection
|
||||
*/
|
||||
public function testIsPut()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'PUT',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isGet());
|
||||
$this->assertFalse($req->isPost());
|
||||
$this->assertTrue($req->isPut());
|
||||
$this->assertFalse($req->isDelete());
|
||||
$this->assertFalse($req->isOptions());
|
||||
$this->assertFalse($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP DELETE method detection
|
||||
*/
|
||||
public function testIsDelete()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'DELETE',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isGet());
|
||||
$this->assertFalse($req->isPost());
|
||||
$this->assertFalse($req->isPut());
|
||||
$this->assertTrue($req->isDelete());
|
||||
$this->assertFalse($req->isOptions());
|
||||
$this->assertFalse($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP OPTIONS method detection
|
||||
*/
|
||||
public function testIsOptions()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'OPTIONS',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isGet());
|
||||
$this->assertFalse($req->isPost());
|
||||
$this->assertFalse($req->isPut());
|
||||
$this->assertFalse($req->isDelete());
|
||||
$this->assertTrue($req->isOptions());
|
||||
$this->assertFalse($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test HTTP HEAD method detection
|
||||
*/
|
||||
public function testIsHead()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'HEAD',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isGet());
|
||||
$this->assertFalse($req->isPost());
|
||||
$this->assertFalse($req->isPut());
|
||||
$this->assertFalse($req->isDelete());
|
||||
$this->assertFalse($req->isOptions());
|
||||
$this->assertTrue($req->isHead());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AJAX method detection w/ header
|
||||
*/
|
||||
public function testIsAjaxWithHeader()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'X_REQUESTED_WITH' => 'XMLHttpRequest'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isAjax());
|
||||
$this->assertTrue($req->isXhr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AJAX method detection w/ query parameter
|
||||
*/
|
||||
public function testIsAjaxWithQueryParameter()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3&isajax=1',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isAjax());
|
||||
$this->assertTrue($req->isXhr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AJAX method detection wihtout header or query paramter
|
||||
*/
|
||||
public function testIsAjaxWithoutHeaderOrQueryParameter()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isAjax());
|
||||
$this->assertFalse($req->isXhr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test AJAX method detection with misspelled header
|
||||
*/
|
||||
public function testIsAjaxWithMisspelledHeader()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'X_REQUESTED_WITH' => 'foo'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isAjax());
|
||||
$this->assertFalse($req->isXhr());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test params from query string
|
||||
*/
|
||||
public function testParamsFromQueryString()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(3, count($req->params()));
|
||||
$this->assertEquals('1', $req->params('one'));
|
||||
$this->assertNull($req->params('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test params from request body
|
||||
*/
|
||||
public function testParamsFromRequestBody()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(5, count($req->params())); //Union of GET and POST
|
||||
$this->assertEquals('bar', $req->params('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch GET params
|
||||
*/
|
||||
public function testGet()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(3, count($req->get()));
|
||||
$this->assertEquals('1', $req->get('one'));
|
||||
$this->assertNull($req->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch GET params without multibyte
|
||||
*/
|
||||
public function testGetWithoutMultibyte()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'slim.tests.ignore_multibyte' => true
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(3, count($req->get()));
|
||||
$this->assertEquals('1', $req->get('one'));
|
||||
$this->assertNull($req->get('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch POST params
|
||||
*/
|
||||
public function testPost()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(2, count($req->post()));
|
||||
$this->assertEquals('bar', $req->post('foo'));
|
||||
$this->assertNull($req->post('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch POST params without multibyte
|
||||
*/
|
||||
public function testPostWithoutMultibyte()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15,
|
||||
'slim.tests.ignore_multibyte' => true
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(2, count($req->post()));
|
||||
$this->assertEquals('bar', $req->post('foo'));
|
||||
$this->assertNull($req->post('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch POST without slim.input
|
||||
*/
|
||||
public function testPostWithoutInput()
|
||||
{
|
||||
$this->setExpectedException('RuntimeException');
|
||||
$env = \Slim\Environment::mock();
|
||||
unset($env['slim.input']);
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$req->post('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch POST params even if multipart/form-data request
|
||||
*/
|
||||
public function testPostWithMultipartRequest()
|
||||
{
|
||||
$_POST = array('foo' => 'bar'); //<-- Set by PHP
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'slim.input' => '', //<-- "php://input" is empty for multipart/form-data requests
|
||||
'CONTENT_TYPE' => 'multipart/form-data',
|
||||
'CONTENT_LENGTH' => 0
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(1, count($req->post()));
|
||||
$this->assertEquals('bar', $req->post('foo'));
|
||||
$this->assertNull($req->post('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch PUT params
|
||||
*/
|
||||
public function testPut()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'PUT',
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(2, count($req->put()));
|
||||
$this->assertEquals('bar', $req->put('foo'));
|
||||
$this->assertEquals('bar', $req->params('foo'));
|
||||
$this->assertNull($req->put('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch DELETE params
|
||||
*/
|
||||
public function testDelete()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'DELETE',
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(2, count($req->delete()));
|
||||
$this->assertEquals('bar', $req->delete('foo'));
|
||||
$this->assertEquals('bar', $req->params('foo'));
|
||||
$this->assertNull($req->delete('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test fetch COOKIE params
|
||||
*/
|
||||
public function testCookies()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'COOKIE' => 'foo=bar; abc=123'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(2, count($req->cookies()));
|
||||
$this->assertEquals('bar', $req->cookies('foo'));
|
||||
$this->assertNull($req->cookies('xyz'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is form data
|
||||
*/
|
||||
public function testIsFormDataContentFormUrlencoded()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'PUT',
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isFormData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is form data
|
||||
*/
|
||||
public function testIsFormDataPostContentUnknown()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'slim.input' => '',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isFormData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is form data
|
||||
*/
|
||||
public function testIsFormDataPostContentUnknownWithMethodOverride()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'PUT',
|
||||
));
|
||||
$env['slim.method_override.original_method'] = 'POST';
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue($req->isPut());
|
||||
$this->assertTrue($req->isFormData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test is not form data
|
||||
*/
|
||||
public function testIsNotFormData()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertFalse($req->isFormData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test headers
|
||||
*/
|
||||
public function testHeaders()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'ACCEPT_ENCODING' => 'gzip'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$headers = $req->headers();
|
||||
$this->assertTrue(is_array($headers));
|
||||
$this->assertArrayHasKey('ACCEPT_ENCODING', $headers);
|
||||
$this->assertEquals('gzip', $req->headers('HTTP_ACCEPT_ENCODING'));
|
||||
$this->assertEquals('gzip', $req->headers('HTTP-ACCEPT-ENCODING'));
|
||||
$this->assertEquals('gzip', $req->headers('http_accept_encoding'));
|
||||
$this->assertEquals('gzip', $req->headers('http-accept-encoding'));
|
||||
$this->assertEquals('gzip', $req->headers('ACCEPT_ENCODING'));
|
||||
$this->assertEquals('gzip', $req->headers('ACCEPT-ENCODING'));
|
||||
$this->assertEquals('gzip', $req->headers('accept_encoding'));
|
||||
$this->assertEquals('gzip', $req->headers('accept-encoding'));
|
||||
$this->assertNull($req->headers('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test accurately removes HTTP_ prefix from input header name
|
||||
*/
|
||||
public function testHeaderRemovesHttpPrefix()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'X_HTTP_METHOD_OVERRIDE' => 'PUT',
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
));
|
||||
//fwrite(fopen('php://stdout', 'w'), print_r($env, true));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('PUT', $req->headers('X_HTTP_METHOD_OVERRIDE'));
|
||||
$this->assertNull($req->headers('X_METHOD_OVERRIDE')); //<-- Ensures `HTTP_` is not removed if not prefix
|
||||
$this->assertEquals('application/json', $req->headers('HTTP_CONTENT_TYPE')); //<-- Ensures `HTTP_` is removed if prefix
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get body
|
||||
*/
|
||||
public function testGetBodyWhenExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('foo=bar&abc=123', $req->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get body
|
||||
*/
|
||||
public function testGetBodyWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('', $req->getBody());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content type
|
||||
*/
|
||||
public function testGetContentTypeWhenExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/json; charset=ISO-8859-4'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('application/json; charset=ISO-8859-4', $req->getContentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content type
|
||||
*/
|
||||
public function testGetContentTypeWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertNull($req->getContentType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get media type
|
||||
*/
|
||||
public function testGetMediaTypeWhenExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'CONTENT_TYPE' => 'application/json;charset=utf-8'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('application/json', $req->getMediaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get media type
|
||||
*/
|
||||
public function testGetMediaTypeWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertNull($req->getMediaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get media type
|
||||
*/
|
||||
public function testGetMediaTypeWhenNoParamsExist()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('application/json', $req->getMediaType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get media type params
|
||||
*/
|
||||
public function testGetMediaTypeParams()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'CONTENT_TYPE' => 'application/json; charset=ISO-8859-4'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$params = $req->getMediaTypeParams();
|
||||
$this->assertEquals(1, count($params));
|
||||
$this->assertArrayHasKey('charset', $params);
|
||||
$this->assertEquals('ISO-8859-4', $params['charset']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get media type params
|
||||
*/
|
||||
public function testGetMediaTypeParamsWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$params = $req->getMediaTypeParams();
|
||||
$this->assertTrue(is_array($params));
|
||||
$this->assertEquals(0, count($params));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content charset
|
||||
*/
|
||||
public function testGetContentCharset()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/json; charset=ISO-8859-4'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('ISO-8859-4', $req->getContentCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content charset
|
||||
*/
|
||||
public function testGetContentCharsetWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
'CONTENT_TYPE' => 'application/json'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertNull($req->getContentCharset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content length
|
||||
*/
|
||||
public function testGetContentLength()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => 'foo=bar&abc=123',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONTENT_LENGTH' => 15
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(15, $req->getContentLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get content length
|
||||
*/
|
||||
public function testGetContentLengthWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.input' => '',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals(0, $req->getContentLength());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get host
|
||||
*/
|
||||
public function testGetHost()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SERVER_NAME' => 'slim',
|
||||
'HOST' => 'slimframework.com'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('slimframework.com', $req->getHost()); //Uses HTTP_HOST if available
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get host when it has a port number
|
||||
*/
|
||||
public function testGetHostAndStripPort()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SERVER_NAME' => 'slim',
|
||||
'HOST' => 'slimframework.com:80'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('slimframework.com', $req->getHost()); //Uses HTTP_HOST if available
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get host
|
||||
*/
|
||||
public function testGetHostWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SERVER_NAME' => 'slim',
|
||||
'HOST' => 'slimframework.com'
|
||||
));
|
||||
unset($env['HOST']);
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('slim', $req->getHost()); //Uses SERVER_NAME as backup
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get host with port
|
||||
*/
|
||||
public function testGetHostWithPort()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'HOST' => 'slimframework.com',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('slimframework.com:80', $req->getHostWithPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get host with port doesn't dulplicate port numbers
|
||||
*/
|
||||
public function testGetHostDoesntDulplicatePort()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'HOST' => 'slimframework.com:80',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('slimframework.com:80', $req->getHostWithPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get port
|
||||
*/
|
||||
public function testGetPort()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SERVER_PORT' => 80
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertTrue(is_integer($req->getPort()));
|
||||
$this->assertEquals(80, $req->getPort());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get scheme
|
||||
*/
|
||||
public function testGetSchemeIfHttp()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.url_scheme' => 'http'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('http', $req->getScheme());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get scheme
|
||||
*/
|
||||
public function testGetSchemeIfHttps()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'slim.url_scheme' => 'https',
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('https', $req->getScheme());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get [script name, root uri, path, path info, resource uri] in subdirectory without htaccess
|
||||
*/
|
||||
public function testAppPathsInSubdirectoryWithoutHtaccess()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/foo/index.php', //<-- Physical
|
||||
'PATH_INFO' => '/bar/xyz', //<-- Virtual
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('/foo/index.php', $req->getScriptName());
|
||||
$this->assertEquals('/foo/index.php', $req->getRootUri());
|
||||
$this->assertEquals('/foo/index.php/bar/xyz', $req->getPath());
|
||||
$this->assertEquals('/bar/xyz', $req->getPathInfo());
|
||||
$this->assertEquals('/bar/xyz', $req->getResourceUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get [script name, root uri, path, path info, resource uri] in subdirectory with htaccess
|
||||
*/
|
||||
public function testAppPathsInSubdirectoryWithHtaccess()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/foo', //<-- Physical
|
||||
'PATH_INFO' => '/bar/xyz', //<-- Virtual
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('/foo', $req->getScriptName());
|
||||
$this->assertEquals('/foo', $req->getRootUri());
|
||||
$this->assertEquals('/foo/bar/xyz', $req->getPath());
|
||||
$this->assertEquals('/bar/xyz', $req->getPathInfo());
|
||||
$this->assertEquals('/bar/xyz', $req->getResourceUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get [script name, root uri, path, path info, resource uri] in root directory without htaccess
|
||||
*/
|
||||
public function testAppPathsInRootDirectoryWithoutHtaccess()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php', //<-- Physical
|
||||
'PATH_INFO' => '/bar/xyz', //<-- Virtual
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('/index.php', $req->getScriptName());
|
||||
$this->assertEquals('/index.php', $req->getRootUri());
|
||||
$this->assertEquals('/index.php/bar/xyz', $req->getPath());
|
||||
$this->assertEquals('/bar/xyz', $req->getPathInfo());
|
||||
$this->assertEquals('/bar/xyz', $req->getResourceUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get [script name, root uri, path, path info, resource uri] in root directory with htaccess
|
||||
*/
|
||||
public function testAppPathsInRootDirectoryWithHtaccess()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/bar/xyz', //<-- Virtual
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('', $req->getScriptName());
|
||||
$this->assertEquals('', $req->getRootUri());
|
||||
$this->assertEquals('/bar/xyz', $req->getPath());
|
||||
$this->assertEquals('/bar/xyz', $req->getPathInfo());
|
||||
$this->assertEquals('/bar/xyz', $req->getResourceUri());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get URL
|
||||
*/
|
||||
public function testGetUrl()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'HOST' => 'slimframework.com',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('http://slimframework.com', $req->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get URL
|
||||
*/
|
||||
public function testGetUrlWithCustomPort()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'HOST' => 'slimframework.com',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 8080,
|
||||
'slim.url_scheme' => 'http'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('http://slimframework.com:8080', $req->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get URL
|
||||
*/
|
||||
public function testGetUrlWithHttps()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'HOST' => 'slimframework.com',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 443,
|
||||
'slim.url_scheme' => 'https'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('https://slimframework.com', $req->getUrl());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get IP
|
||||
*/
|
||||
public function testGetIp()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REMOTE_ADDR' => '127.0.0.1'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('127.0.0.1', $req->getIp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get IP with proxy server and Client-Ip header
|
||||
*/
|
||||
public function testGetIpWithClientIp()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'CLIENT_IP' => '127.0.0.2'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('127.0.0.2', $req->getIp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get IP with proxy server and X-Forwarded-For header
|
||||
*/
|
||||
public function testGetIpWithForwardedFor()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'CLIENT_IP' => '127.0.0.2',
|
||||
'X_FORWARDED_FOR' => '127.0.0.3'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('127.0.0.3', $req->getIp());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get refererer
|
||||
*/
|
||||
public function testGetReferrer()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'REFERER' => 'http://foo.com'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('http://foo.com', $req->getReferrer());
|
||||
$this->assertEquals('http://foo.com', $req->getReferer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get refererer
|
||||
*/
|
||||
public function testGetReferrerWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertNull($req->getReferrer());
|
||||
$this->assertNull($req->getReferer());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get user agent string
|
||||
*/
|
||||
public function testGetUserAgent()
|
||||
{
|
||||
$env = \Slim\Environment::mock(array(
|
||||
'USER_AGENT' => 'user-agent-string'
|
||||
));
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertEquals('user-agent-string', $req->getUserAgent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get user agent string when not set
|
||||
*/
|
||||
public function testGetUserAgentWhenNotExists()
|
||||
{
|
||||
$env = \Slim\Environment::mock();
|
||||
unset($env['USER_AGENT']);
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$this->assertNull($req->getUserAgent());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,574 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class ResponseTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test constructor without args
|
||||
*/
|
||||
public function testConstructorWithoutArgs()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$this->assertEquals('', $r->body());
|
||||
$this->assertEquals(200, $r->status());
|
||||
$this->assertEquals(0, $r->length());
|
||||
$this->assertEquals('text/html', $r['Content-Type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test constructor with args
|
||||
*/
|
||||
public function testConstructorWithArgs()
|
||||
{
|
||||
$r = new \Slim\Http\Response('Page Not Found', 404, array('Content-Type' => 'application/json', 'X-Created-By' => 'Slim'));
|
||||
$this->assertEquals('Page Not Found', $r->body());
|
||||
$this->assertEquals(404, $r->status());
|
||||
$this->assertEquals(14, $r->length());
|
||||
$this->assertEquals('application/json', $r['Content-Type']);
|
||||
$this->assertEquals('Slim', $r['X-Created-By']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get status
|
||||
*/
|
||||
public function testGetStatus()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$this->assertEquals(200, $r->status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set status
|
||||
*/
|
||||
public function testSetStatus()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->status(500);
|
||||
$this->assertEquals(500, $r->status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get headers
|
||||
*/
|
||||
public function testGetHeaders()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$headers = $r->headers();
|
||||
$this->assertEquals(1, count($headers));
|
||||
$this->assertEquals('text/html', $headers['Content-Type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get and set header (without Array Access)
|
||||
*/
|
||||
public function testGetAndSetHeader()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->header('X-Foo', 'Bar');
|
||||
$this->assertEquals('Bar', $r->header('X-Foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get body
|
||||
*/
|
||||
public function testGetBody()
|
||||
{
|
||||
$r = new \Slim\Http\Response('Foo');
|
||||
$this->assertEquals('Foo', $r->body());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set body
|
||||
*/
|
||||
public function testSetBody()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->body('Foo');
|
||||
$this->assertEquals('Foo', $r->body());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get length
|
||||
*/
|
||||
public function testGetLength()
|
||||
{
|
||||
$r = new \Slim\Http\Response('Foo');
|
||||
$this->assertEquals(3, $r->length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set length
|
||||
*/
|
||||
public function testSetLength()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->length(3);
|
||||
$this->assertEquals(3, $r->length());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test write for appending
|
||||
*/
|
||||
public function testWriteAppend()
|
||||
{
|
||||
$r = new \Slim\Http\Response('Foo');
|
||||
$r->write('Bar');
|
||||
$this->assertEquals('FooBar', $r->body());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test write for replacing
|
||||
*/
|
||||
public function testWriteReplace()
|
||||
{
|
||||
$r = new \Slim\Http\Response('Foo');
|
||||
$r->write('Bar', true);
|
||||
$this->assertEquals('Bar', $r->body());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finalize
|
||||
*/
|
||||
public function testFinalize()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->status(404);
|
||||
$r['Content-Type'] = 'application/json';
|
||||
$r->write('Foo');
|
||||
$result = $r->finalize();
|
||||
$this->assertEquals(3, count($result));
|
||||
$this->assertEquals(404, $result[0]);
|
||||
$this->assertFalse(is_null($result[1]['Content-Type']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test finalize
|
||||
*/
|
||||
public function testFinalizeWithoutBody()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->status(204);
|
||||
$r['Content-Type'] = 'application/json';
|
||||
$r->write('Foo');
|
||||
$result = $r->finalize();
|
||||
$this->assertEquals(3, count($result));
|
||||
$this->assertEquals('', $result[2]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value
|
||||
*/
|
||||
public function testSetCookieWithNameAndValue()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', 'bar');
|
||||
$this->assertEquals('foo=bar', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set multiple cookies with only name and value
|
||||
*/
|
||||
public function testSetMultipleCookiesWithNameAndValue()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', 'bar');
|
||||
$r->setCookie('abc', '123');
|
||||
$this->assertEquals("foo=bar\nabc=123", $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie only name and value and expires (as int)
|
||||
*/
|
||||
public function testSetMultipleCookiesWithNameAndValueAndExpiresAsInt()
|
||||
{
|
||||
$now = time();
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'expires' => $now
|
||||
));
|
||||
$this->assertEquals("foo=bar; expires=" . gmdate('D, d-M-Y H:i:s e', $now), $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value and expires (as string)
|
||||
*/
|
||||
public function testSetMultipleCookiesWithNameAndValueAndExpiresAsString()
|
||||
{
|
||||
$expires = 'next Tuesday';
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'expires' => $expires
|
||||
));
|
||||
$this->assertEquals("foo=bar; expires=" . gmdate('D, d-M-Y H:i:s e', strtotime($expires)), $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with name, value, domain
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndDomain()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'domain' => '.slimframework.com'
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=.slimframework.com', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with name, value, domain, path
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndDomainAndPath()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'domain' => '.slimframework.com',
|
||||
'path' => '/foo'
|
||||
));
|
||||
$this->assertEquals($r['Set-Cookie'], 'foo=bar; domain=.slimframework.com; path=/foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value and secure flag
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndSecureFlag()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'secure' => true
|
||||
));
|
||||
$this->assertEquals('foo=bar; secure', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value and secure flag (as non-truthy)
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndSecureFlagAsNonTruthy()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'secure' => 0
|
||||
));
|
||||
$this->assertEquals('foo=bar', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value and httponly flag
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndHttpOnlyFlag()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'httponly' => true
|
||||
));
|
||||
$this->assertEquals('foo=bar; HttpOnly', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set cookie with only name and value and httponly flag (as non-truthy)
|
||||
*/
|
||||
public function testSetCookieWithNameAndValueAndHttpOnlyFlagAsNonTruthy()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'httponly' => 0
|
||||
));
|
||||
$this->assertEquals('foo=bar', $r['Set-Cookie']);
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete cookie by name
|
||||
*/
|
||||
public function testDeleteCookieByName()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', 'bar');
|
||||
$r->setCookie('abc', '123');
|
||||
$r->deleteCookie('foo');
|
||||
$this->assertEquals(1, preg_match("@abc=123\nfoo=; expires=@", $r['Set-Cookie']));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete cookie by name and domain
|
||||
*/
|
||||
public function testDeleteCookieByNameAndDomain1()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', 'bar'); //Note: This does not have domain associated with it
|
||||
$r->setCookie('abc', '123');
|
||||
$r->deleteCookie('foo', array('domain' => '.slimframework.com')); //This SHOULD NOT remove the `foo` cookie
|
||||
$this->assertEquals(1, preg_match("@foo=bar\nabc=123\nfoo=; domain=.slimframework.com; expires=@", $r['Set-Cookie']));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test delete cookie by name and domain
|
||||
*/
|
||||
public function testDeleteCookieByNameAndDomain2()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', array(
|
||||
'value' => 'bar',
|
||||
'domain' => '.slimframework.com' //Note: This does have domain associated with it
|
||||
));
|
||||
$r->setCookie('abc', '123');
|
||||
$r->deleteCookie('foo', array('domain' => '.slimframework.com')); //This SHOULD remove the `foo` cookie
|
||||
$this->assertEquals(1, preg_match("@abc=123\nfoo=; domain=.slimframework.com; expires=@", $r['Set-Cookie']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test delete cookie by name and custom props
|
||||
*/
|
||||
public function testDeleteCookieByNameAndCustomProps()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->setCookie('foo', 'bar');
|
||||
$r->setCookie('abc', '123');
|
||||
$r->deleteCookie('foo', array(
|
||||
'secure' => true,
|
||||
'httponly' => true
|
||||
));
|
||||
$this->assertEquals(1, preg_match("@abc=123\nfoo=; expires=.*; secure; HttpOnly@", $r['Set-Cookie']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test redirect
|
||||
*/
|
||||
public function testRedirect()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->redirect('/foo');
|
||||
$this->assertEquals(302, $r->status());
|
||||
$this->assertEquals('/foo', $r['Location']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test redirect with custom status
|
||||
*/
|
||||
public function testRedirectWithCustomStatus()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$r->redirect('/foo', 307);
|
||||
$this->assertEquals(307, $r->status());
|
||||
$this->assertEquals('/foo', $r['Location']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isEmpty
|
||||
*/
|
||||
public function testIsEmpty()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(404);
|
||||
$r2->status(201);
|
||||
$this->assertFalse($r1->isEmpty());
|
||||
$this->assertTrue($r2->isEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isClientError
|
||||
*/
|
||||
public function testIsClientError()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(404);
|
||||
$r2->status(500);
|
||||
$this->assertTrue($r1->isClientError());
|
||||
$this->assertFalse($r2->isClientError());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isForbidden
|
||||
*/
|
||||
public function testIsForbidden()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(403);
|
||||
$r2->status(500);
|
||||
$this->assertTrue($r1->isForbidden());
|
||||
$this->assertFalse($r2->isForbidden());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isInformational
|
||||
*/
|
||||
public function testIsInformational()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(100);
|
||||
$r2->status(200);
|
||||
$this->assertTrue($r1->isInformational());
|
||||
$this->assertFalse($r2->isInformational());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isInformational
|
||||
*/
|
||||
public function testIsNotFound()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(404);
|
||||
$r2->status(200);
|
||||
$this->assertTrue($r1->isNotFound());
|
||||
$this->assertFalse($r2->isNotFound());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isOk
|
||||
*/
|
||||
public function testIsOk()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(200);
|
||||
$r2->status(201);
|
||||
$this->assertTrue($r1->isOk());
|
||||
$this->assertFalse($r2->isOk());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isSuccessful
|
||||
*/
|
||||
public function testIsSuccessful()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r3 = new \Slim\Http\Response();
|
||||
$r1->status(200);
|
||||
$r2->status(201);
|
||||
$r3->status(302);
|
||||
$this->assertTrue($r1->isSuccessful());
|
||||
$this->assertTrue($r2->isSuccessful());
|
||||
$this->assertFalse($r3->isSuccessful());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isRedirect
|
||||
*/
|
||||
public function testIsRedirect()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(307);
|
||||
$r2->status(304);
|
||||
$this->assertTrue($r1->isRedirect());
|
||||
$this->assertFalse($r2->isRedirect());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isRedirection
|
||||
*/
|
||||
public function testIsRedirection()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r3 = new \Slim\Http\Response();
|
||||
$r1->status(307);
|
||||
$r2->status(304);
|
||||
$r3->status(200);
|
||||
$this->assertTrue($r1->isRedirection());
|
||||
$this->assertTrue($r2->isRedirection());
|
||||
$this->assertFalse($r3->isRedirection());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test isServerError
|
||||
*/
|
||||
public function testIsServerError()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$r2 = new \Slim\Http\Response();
|
||||
$r1->status(500);
|
||||
$r2->status(400);
|
||||
$this->assertTrue($r1->isServerError());
|
||||
$this->assertFalse($r2->isServerError());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test offset exists and offset get
|
||||
*/
|
||||
public function testOffsetExistsAndGet()
|
||||
{
|
||||
$r = new \Slim\Http\Response();
|
||||
$this->assertFalse(empty($r['Content-Type']));
|
||||
$this->assertNull($r['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test iteration
|
||||
*/
|
||||
public function testIteration()
|
||||
{
|
||||
$h = new \Slim\Http\Response();
|
||||
$output = '';
|
||||
foreach ($h as $key => $value) {
|
||||
$output .= $key . $value;
|
||||
}
|
||||
$this->assertEquals('Content-Typetext/html', $output);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test countable
|
||||
*/
|
||||
public function testCountable()
|
||||
{
|
||||
$r1 = new \Slim\Http\Response();
|
||||
$this->assertEquals(1, count($r1)); //Content-Type
|
||||
}
|
||||
|
||||
/**
|
||||
* Test message for code when message exists
|
||||
*/
|
||||
public function testMessageForCode()
|
||||
{
|
||||
$this->assertEquals('200 OK', \Slim\Http\Response::getMessageForCode(200));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test message for code when message exists
|
||||
*/
|
||||
public function testMessageForCodeWithInvalidCode()
|
||||
{
|
||||
$this->assertNull(\Slim\Http\Response::getMessageForCode(600));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,388 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class SlimHttpUtilTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test strip slashes when magic quotes disabled
|
||||
*/
|
||||
public function testStripSlashesWithoutMagicQuotes()
|
||||
{
|
||||
$data = "This should have \"quotes\" in it";
|
||||
$stripped = \Slim\Http\Util::stripSlashesIfMagicQuotes($data, false);
|
||||
$this->assertEquals($data, $stripped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test strip slashes from array when magic quotes disabled
|
||||
*/
|
||||
public function testStripSlashesFromArrayWithoutMagicQuotes()
|
||||
{
|
||||
$data = array("This should have \"quotes\" in it", "And this \"too\" has quotes");
|
||||
$stripped = \Slim\Http\Util::stripSlashesIfMagicQuotes($data, false);
|
||||
$this->assertEquals($data, $stripped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test strip slashes when magic quotes enabled
|
||||
*/
|
||||
public function testStripSlashesWithMagicQuotes()
|
||||
{
|
||||
$data = "This should have \"quotes\" in it";
|
||||
$stripped = \Slim\Http\Util::stripSlashesIfMagicQuotes($data, true);
|
||||
$this->assertEquals('This should have "quotes" in it', $stripped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test strip slashes from array when magic quotes enabled
|
||||
*/
|
||||
public function testStripSlashesFromArrayWithMagicQuotes()
|
||||
{
|
||||
$data = array("This should have \"quotes\" in it", "And this \"too\" has quotes");
|
||||
$stripped = \Slim\Http\Util::stripSlashesIfMagicQuotes($data, true);
|
||||
$this->assertEquals($data = array('This should have "quotes" in it', 'And this "too" has quotes'), $stripped);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test encrypt and decrypt with valid data
|
||||
*/
|
||||
public function testEncryptAndDecryptWithValidData()
|
||||
{
|
||||
$data = 'foo';
|
||||
$key = 'secret';
|
||||
$iv = md5('initializationVector');
|
||||
$encrypted = \Slim\Http\Util::encrypt($data, $key, $iv);
|
||||
$decrypted = \Slim\Http\Util::decrypt($encrypted, $key, $iv);
|
||||
$this->assertEquals($data, $decrypted);
|
||||
$this->assertTrue($data !== $encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test encrypt when data is empty string
|
||||
*/
|
||||
public function testEncryptWhenDataIsEmptyString()
|
||||
{
|
||||
$data = '';
|
||||
$key = 'secret';
|
||||
$iv = md5('initializationVector');
|
||||
$encrypted = \Slim\Http\Util::encrypt($data, $key, $iv);
|
||||
$this->assertEquals('', $encrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test decrypt when data is empty string
|
||||
*/
|
||||
public function testDecryptWhenDataIsEmptyString()
|
||||
{
|
||||
$data = '';
|
||||
$key = 'secret';
|
||||
$iv = md5('initializationVector');
|
||||
$decrypted = \Slim\Http\Util::decrypt($data, $key, $iv);
|
||||
$this->assertEquals('', $decrypted);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test encrypt when IV and key sizes are too long
|
||||
*/
|
||||
public function testEncryptAndDecryptWhenKeyAndIvAreTooLong()
|
||||
{
|
||||
$data = 'foo';
|
||||
$key = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
|
||||
$iv = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz';
|
||||
$encrypted = \Slim\Http\Util::encrypt($data, $key, $iv);
|
||||
$decrypted = \Slim\Http\Util::decrypt($encrypted, $key, $iv);
|
||||
$this->assertEquals($data, $decrypted);
|
||||
$this->assertTrue($data !== $encrypted);
|
||||
}
|
||||
|
||||
public function testEncodeAndDecodeSecureCookieWithValidData()
|
||||
{
|
||||
//Prepare cookie value
|
||||
$value = 'foo';
|
||||
$expires = time() + 86400;
|
||||
$secret = 'password';
|
||||
$algorithm = MCRYPT_RIJNDAEL_256;
|
||||
$mode = MCRYPT_MODE_CBC;
|
||||
$encodedValue = \Slim\Http\Util::encodeSecureCookie($value, $expires, $secret, $algorithm, $mode);
|
||||
$decodedValue = \Slim\Http\Util::decodeSecureCookie($encodedValue, $secret, $algorithm, $mode);
|
||||
|
||||
//Test secure cookie value
|
||||
$parts = explode('|', $encodedValue);
|
||||
$this->assertEquals(3, count($parts));
|
||||
$this->assertEquals($expires, $parts[0]);
|
||||
$this->assertEquals($value, $decodedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test encode/decode secure cookie with old expiration
|
||||
*
|
||||
* In this test, the expiration date is purposefully set to a time before now.
|
||||
* When decoding the encoded cookie value, FALSE is returned since the cookie
|
||||
* will have expired before it is decoded.
|
||||
*/
|
||||
public function testEncodeAndDecodeSecureCookieWithOldExpiration()
|
||||
{
|
||||
$value = 'foo';
|
||||
$expires = time() - 100;
|
||||
$secret = 'password';
|
||||
$algorithm = MCRYPT_RIJNDAEL_256;
|
||||
$mode = MCRYPT_MODE_CBC;
|
||||
$encodedValue = \Slim\Http\Util::encodeSecureCookie($value, $expires, $secret, $algorithm, $mode);
|
||||
$decodedValue = \Slim\Http\Util::decodeSecureCookie($encodedValue, $secret, $algorithm, $mode);
|
||||
$this->assertFalse($decodedValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test encode/decode secure cookie with tampered data
|
||||
*
|
||||
* In this test, the encoded data is purposefully changed to simulate someone
|
||||
* tampering with the client-side cookie data. When decoding the encoded cookie value,
|
||||
* FALSE is returned since the verification key will not match.
|
||||
*/
|
||||
public function testEncodeAndDecodeSecureCookieWithTamperedData()
|
||||
{
|
||||
$value = 'foo';
|
||||
$expires = time() + 86400;
|
||||
$secret = 'password';
|
||||
$algorithm = MCRYPT_RIJNDAEL_256;
|
||||
$mode = MCRYPT_MODE_CBC;
|
||||
$encodedValue = \Slim\Http\Util::encodeSecureCookie($value, $expires, $secret, $algorithm, $mode);
|
||||
$encodedValueParts = explode('|', $encodedValue);
|
||||
$encodedValueParts[1] = $encodedValueParts[1] . 'changed';
|
||||
$encodedValue = implode('|', $encodedValueParts);
|
||||
$decodedValue = \Slim\Http\Util::decodeSecureCookie($encodedValue, $secret, $algorithm, $mode);
|
||||
$this->assertFalse($decodedValue);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValue()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, $value);
|
||||
$this->assertEquals('foo=bar', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueWhenCookieAlreadySet()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$header = array('Set-Cookie' => 'one=two');
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, $value);
|
||||
$this->assertEquals("one=two\nfoo=bar", $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomain()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPath()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => $path
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPathAndExpiresAsString()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$expires = '2 days';
|
||||
$expiresFormat = gmdate('D, d-M-Y H:i:s e', strtotime($expires));
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => '/foo',
|
||||
'expires' => $expires
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo; expires=' . $expiresFormat, $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPathAndExpiresAsInteger()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$expires = strtotime('2 days');
|
||||
$expiresFormat = gmdate('D, d-M-Y H:i:s e', $expires);
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => '/foo',
|
||||
'expires' => $expires
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo; expires=' . $expiresFormat, $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPathAndExpiresAsZero()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$expires = 0;
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => '/foo',
|
||||
'expires' => $expires
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPathAndExpiresAndSecure()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$expires = strtotime('2 days');
|
||||
$expiresFormat = gmdate('D, d-M-Y H:i:s e', $expires);
|
||||
$secure = true;
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => '/foo',
|
||||
'expires' => $expires,
|
||||
'secure' => $secure
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo; expires=' . $expiresFormat . '; secure', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testSetCookieHeaderWithNameAndValueAndDomainAndPathAndExpiresAndSecureAndHttpOnly()
|
||||
{
|
||||
$name = 'foo';
|
||||
$value = 'bar';
|
||||
$domain = 'foo.com';
|
||||
$path = '/foo';
|
||||
$expires = strtotime('2 days');
|
||||
$expiresFormat = gmdate('D, d-M-Y H:i:s e', $expires);
|
||||
$secure = true;
|
||||
$httpOnly = true;
|
||||
$header = array();
|
||||
\Slim\Http\Util::setCookieHeader($header, $name, array(
|
||||
'value' => $value,
|
||||
'domain' => $domain,
|
||||
'path' => '/foo',
|
||||
'expires' => $expires,
|
||||
'secure' => $secure,
|
||||
'httponly' => $httpOnly
|
||||
));
|
||||
$this->assertEquals('foo=bar; domain=foo.com; path=/foo; expires=' . $expiresFormat . '; secure; HttpOnly', $header['Set-Cookie']);
|
||||
}
|
||||
|
||||
public function testDeleteCookieHeaderWithSurvivingCookie()
|
||||
{
|
||||
$header = array('Set-Cookie' => "foo=bar\none=two");
|
||||
\Slim\Http\Util::deleteCookieHeader($header, 'foo');
|
||||
$this->assertEquals(1, preg_match("@^one=two\nfoo=; expires=@", $header['Set-Cookie']));
|
||||
}
|
||||
|
||||
public function testDeleteCookieHeaderWithoutSurvivingCookie()
|
||||
{
|
||||
$header = array('Set-Cookie' => "foo=bar");
|
||||
\Slim\Http\Util::deleteCookieHeader($header, 'foo');
|
||||
$this->assertEquals(1, preg_match("@foo=; expires=@", $header['Set-Cookie']));
|
||||
}
|
||||
|
||||
public function testDeleteCookieHeaderWithMatchingDomain()
|
||||
{
|
||||
$header = array('Set-Cookie' => "foo=bar; domain=foo.com");
|
||||
\Slim\Http\Util::deleteCookieHeader($header, 'foo', array(
|
||||
'domain' => 'foo.com'
|
||||
));
|
||||
$this->assertEquals(1, preg_match("@foo=; domain=foo.com; expires=@", $header['Set-Cookie']));
|
||||
}
|
||||
|
||||
public function testDeleteCookieHeaderWithoutMatchingDomain()
|
||||
{
|
||||
$header = array('Set-Cookie' => "foo=bar; domain=foo.com");
|
||||
\Slim\Http\Util::deleteCookieHeader($header, 'foo', array(
|
||||
'domain' => 'bar.com'
|
||||
));
|
||||
$this->assertEquals(1, preg_match("@foo=bar; domain=foo\.com\nfoo=; domain=bar\.com@", $header['Set-Cookie']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses Cookie: HTTP header
|
||||
*/
|
||||
public function testParsesCookieHeader()
|
||||
{
|
||||
$header = 'foo=bar; one=two; colors=blue';
|
||||
$result = \Slim\Http\Util::parseCookieHeader($header);
|
||||
$this->assertEquals(3, count($result));
|
||||
$this->assertEquals('bar', $result['foo']);
|
||||
$this->assertEquals('two', $result['one']);
|
||||
$this->assertEquals('blue', $result['colors']);
|
||||
}
|
||||
|
||||
public function testParsesCookieHeaderWithCommaSeparator()
|
||||
{
|
||||
$header = 'foo=bar, one=two, colors=blue';
|
||||
$result = \Slim\Http\Util::parseCookieHeader($header);
|
||||
$this->assertEquals(3, count($result));
|
||||
$this->assertEquals('bar', $result['foo']);
|
||||
$this->assertEquals('two', $result['one']);
|
||||
$this->assertEquals('blue', $result['colors']);
|
||||
}
|
||||
|
||||
public function testPrefersLeftmostCookieWhenManyCookiesWithSameName()
|
||||
{
|
||||
$header = 'foo=bar; foo=beer';
|
||||
$result = \Slim\Http\Util::parseCookieHeader($header);
|
||||
$this->assertEquals('bar', $result['foo']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,152 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class MyWriter
|
||||
{
|
||||
public function write( $object, $level )
|
||||
{
|
||||
echo (string) $object;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class LogTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testEnabled()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$this->assertTrue($log->isEnabled()); //<-- Default case
|
||||
$log->setEnabled(true);
|
||||
$this->assertTrue($log->isEnabled());
|
||||
$log->setEnabled(false);
|
||||
$this->assertFalse($log->isEnabled());
|
||||
}
|
||||
|
||||
public function testGetLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$this->assertEquals(\Slim\Log::DEBUG, $log->getLevel());
|
||||
}
|
||||
|
||||
public function testSetLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::WARN);
|
||||
$this->assertEquals(\Slim\Log::WARN, $log->getLevel());
|
||||
}
|
||||
|
||||
public function testSetInvalidLevel()
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::DEBUG + 1);
|
||||
}
|
||||
|
||||
public function testLogDebug()
|
||||
{
|
||||
$this->expectOutputString('Debug');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$result = $log->debug('Debug');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testLogDebugExcludedByLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::INFO);
|
||||
$this->assertFalse($log->debug('Debug'));
|
||||
}
|
||||
|
||||
public function testLogInfo()
|
||||
{
|
||||
$this->expectOutputString('Info');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$result = $log->info('Info');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testLogInfoExcludedByLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::WARN);
|
||||
$this->assertFalse($log->info('Info'));
|
||||
}
|
||||
|
||||
public function testLogWarn()
|
||||
{
|
||||
$this->expectOutputString('Warn');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$result = $log->warn('Warn');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testLogWarnExcludedByLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::ERROR);
|
||||
$this->assertFalse($log->warn('Warn'));
|
||||
}
|
||||
|
||||
public function testLogError()
|
||||
{
|
||||
$this->expectOutputString('Error');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$result = $log->error('Error');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testLogErrorExcludedByLevel()
|
||||
{
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$log->setLevel(\Slim\Log::FATAL);
|
||||
$this->assertFalse($log->error('Error'));
|
||||
}
|
||||
|
||||
public function testLogFatal()
|
||||
{
|
||||
$this->expectOutputString('Fatal');
|
||||
$log = new \Slim\Log(new MyWriter());
|
||||
$result = $log->fatal('Fatal');
|
||||
$this->assertTrue($result);
|
||||
}
|
||||
|
||||
public function testGetAndSetWriter()
|
||||
{
|
||||
$writer1 = new MyWriter();
|
||||
$writer2 = new MyWriter();
|
||||
$log = new \Slim\Log($writer1);
|
||||
$this->assertSame($writer1, $log->getWriter());
|
||||
$log->setWriter($writer2);
|
||||
$this->assertSame($writer2, $log->getWriter());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class LogWriterTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testInstantiation()
|
||||
{
|
||||
$this->expectOutputString('Hello!' . PHP_EOL);
|
||||
$handle = fopen('php://output', 'w');
|
||||
$fw = new \Slim\LogWriter($handle);
|
||||
$this->assertTrue($fw->write('Hello!') > 0); //<-- Returns number of bytes written if successful
|
||||
}
|
||||
|
||||
public function testInstantiationWithNonResource()
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$fw = new \Slim\LogWriter(@fopen('/foo/bar.txt', 'w'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class ContentTypesTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
ob_start();
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
ob_end_clean();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses JSON
|
||||
*/
|
||||
public function testParsesJson()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
'CONENT_LENGTH' => 13,
|
||||
'slim.input' => '{"foo":"bar"}'
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertTrue(is_array($body));
|
||||
$this->assertEquals('bar', $body['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ignores JSON with errors
|
||||
*/
|
||||
public function testParsesJsonWithError()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
'CONENT_LENGTH' => 12,
|
||||
'slim.input' => '{"foo":"bar"' //<-- This should be incorrect!
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertTrue(is_string($body));
|
||||
$this->assertEquals('{"foo":"bar"', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses XML
|
||||
*/
|
||||
public function testParsesXml()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/xml',
|
||||
'CONENT_LENGTH' => 68,
|
||||
'slim.input' => '<books><book><id>1</id><author>Clive Cussler</author></book></books>'
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertInstanceOf('SimpleXMLElement', $body);
|
||||
$this->assertEquals('Clive Cussler', (string) $body->book->author);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test ignores XML with errors
|
||||
*/
|
||||
public function testParsesXmlWithError()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/xml',
|
||||
'CONENT_LENGTH' => 68,
|
||||
'slim.input' => '<books><book><id>1</id><author>Clive Cussler</book></books>' //<-- This should be incorrect!
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertTrue(is_string($body));
|
||||
$this->assertEquals('<books><book><id>1</id><author>Clive Cussler</book></books>', $body);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses CSV
|
||||
*/
|
||||
public function testParsesCsv()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'text/csv',
|
||||
'CONENT_LENGTH' => 44,
|
||||
'slim.input' => "John,Doe,000-111-2222\nJane,Doe,111-222-3333"
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertTrue(is_array($body));
|
||||
$this->assertEquals(2, count($body));
|
||||
$this->assertEquals('000-111-2222', $body[0][2]);
|
||||
$this->assertEquals('Doe', $body[1][1]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test parses request body based on media-type only, disregarding
|
||||
* any extra content-type header parameters
|
||||
*/
|
||||
public function testParsesRequestBodyWithMediaType()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/json; charset=ISO-8859-4',
|
||||
'CONENT_LENGTH' => 13,
|
||||
'slim.input' => '{"foo":"bar"}'
|
||||
));
|
||||
$s = new \Slim\Slim();
|
||||
$s->add(new \Slim\Middleware\ContentTypes());
|
||||
$s->run();
|
||||
$body = $s->request()->getBody();
|
||||
$this->assertTrue(is_array($body));
|
||||
$this->assertEquals('bar', $body['foo']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class SlimFlashTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Setup
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
$_SESSION = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set flash message for next request
|
||||
*/
|
||||
public function testSetFlashForNextRequest()
|
||||
{
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->set('foo', 'bar');
|
||||
$f->save();
|
||||
$this->assertEquals('bar', $_SESSION['slim.flash']['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set flash message for current request
|
||||
*/
|
||||
public function testSetFlashForCurrentRequest()
|
||||
{
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->now('foo', 'bar');
|
||||
$this->assertEquals('bar', $f['foo']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test loads flash from previous request
|
||||
*/
|
||||
public function testLoadsFlashFromPreviousRequest()
|
||||
{
|
||||
$_SESSION['slim.flash'] = array('info' => 'foo');
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->loadMessages();
|
||||
$this->assertEquals('foo', $f['info']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test keep flash message for next request
|
||||
*/
|
||||
public function testKeepFlashFromPreviousRequest()
|
||||
{
|
||||
$_SESSION['slim.flash'] = array('info' => 'foo');
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->loadMessages();
|
||||
$f->keep();
|
||||
$f->save();
|
||||
$this->assertEquals('foo', $_SESSION['slim.flash']['info']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test flash messages from preivous request do not persist to next request
|
||||
*/
|
||||
public function testFlashMessagesFromPreviousRequestDoNotPersist()
|
||||
{
|
||||
$_SESSION['slim.flash'] = array('info' => 'foo');
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->save();
|
||||
$this->assertEmpty($_SESSION['slim.flash']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test set Flash using array access
|
||||
*/
|
||||
public function testFlashArrayAccess()
|
||||
{
|
||||
$_SESSION['slim.flash'] = array('info' => 'foo');
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f['info'] = 'bar';
|
||||
$f->save();
|
||||
$this->assertTrue(isset($f['info']));
|
||||
$this->assertEquals('bar', $f['info']);
|
||||
unset($f['info']);
|
||||
$this->assertFalse(isset($f['info']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test iteration
|
||||
*/
|
||||
public function testIteration()
|
||||
{
|
||||
$_SESSION['slim.flash'] = array('info' => 'foo', 'error' => 'bar');
|
||||
$f = new \Slim\Middleware\Flash();
|
||||
$f->loadMessages();
|
||||
$output = '';
|
||||
foreach ($f as $key => $value) {
|
||||
$output .= $key . $value;
|
||||
}
|
||||
$this->assertEquals('infofooerrorbar', $output);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* We use a mock application, instead of a Slim application.
|
||||
* so that we may easily test the Method Override middleware
|
||||
* in isolation.
|
||||
*/
|
||||
class CustomAppMethod
|
||||
{
|
||||
protected $environment;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->environment = \Slim\Environment::getInstance();
|
||||
}
|
||||
|
||||
public function &environment() {
|
||||
return $this->environment;
|
||||
}
|
||||
|
||||
public function call()
|
||||
{
|
||||
//Do nothing
|
||||
}
|
||||
}
|
||||
|
||||
class MethodOverrideTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test overrides method as POST
|
||||
*/
|
||||
public function testOverrideMethodAsPost()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/x-www-form-urlencoded',
|
||||
'CONENT_LENGTH' => 11,
|
||||
'slim.input' => '_METHOD=PUT'
|
||||
));
|
||||
$app = new CustomAppMethod();
|
||||
$mw = new \Slim\Middleware\MethodOverride();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$env =& $app->environment();
|
||||
$this->assertEquals('PUT', $env['REQUEST_METHOD']);
|
||||
$this->assertTrue(isset($env['slim.method_override.original_method']));
|
||||
$this->assertEquals('POST', $env['slim.method_override.original_method']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test does not override method if not POST
|
||||
*/
|
||||
public function testDoesNotOverrideMethodIfNotPost()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'slim.input' => ''
|
||||
));
|
||||
$app = new CustomAppMethod();
|
||||
$mw = new \Slim\Middleware\MethodOverride();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$env =& $app->environment();
|
||||
$this->assertEquals('GET', $env['REQUEST_METHOD']);
|
||||
$this->assertFalse(isset($env['slim.method_override.original_method']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test does not override method if no method ovveride parameter
|
||||
*/
|
||||
public function testDoesNotOverrideMethodAsPostWithoutParameter()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '/foo/index.php', //<-- Physical
|
||||
'PATH_INFO' => '/bar', //<-- Virtual
|
||||
'QUERY_STRING' => 'foo=bar',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w')
|
||||
));
|
||||
$app = new CustomAppMethod();
|
||||
$mw = new \Slim\Middleware\MethodOverride();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$env =& $app->environment();
|
||||
$this->assertEquals('POST', $env['REQUEST_METHOD']);
|
||||
$this->assertFalse(isset($env['slim.method_override.original_method']));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test overrides method with X-Http-Method-Override header
|
||||
*/
|
||||
public function testOverrideMethodAsHeader()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'POST',
|
||||
'CONTENT_TYPE' => 'application/json',
|
||||
'CONENT_LENGTH' => 0,
|
||||
'slim.input' => '',
|
||||
'X_HTTP_METHOD_OVERRIDE' => 'DELETE'
|
||||
));
|
||||
$app = new CustomAppMethod();
|
||||
$mw = new \Slim\Middleware\MethodOverride();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$env =& $app->environment();
|
||||
$this->assertEquals('DELETE', $env['REQUEST_METHOD']);
|
||||
$this->assertTrue(isset($env['slim.method_override.original_method']));
|
||||
$this->assertEquals('POST', $env['slim.method_override.original_method']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class PrettyExceptionsTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Test middleware returns successful response unchanged
|
||||
*/
|
||||
public function testReturnsUnchangedSuccessResponse()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$app->get('/foo', function () {
|
||||
echo "Success";
|
||||
});
|
||||
$mw = new \Slim\Middleware\PrettyExceptions();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$this->assertEquals(200, $app->response()->status());
|
||||
$this->assertEquals('Success', $app->response()->body());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware returns diagnostic screen for error response
|
||||
*/
|
||||
public function testReturnsDiagnosticsForErrorResponse()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim(array(
|
||||
'log.enabled' => false
|
||||
));
|
||||
$app->get('/foo', function () {
|
||||
throw new \Exception('Test Message', 100);
|
||||
});
|
||||
$mw = new \Slim\Middleware\PrettyExceptions();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$this->assertEquals(1, preg_match('@Slim Application Error@', $app->response()->body()));
|
||||
$this->assertEquals(500, $app->response()->status());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test middleware overrides response content type to html
|
||||
*/
|
||||
public function testResponseContentTypeIsOverriddenToHtml()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim(array(
|
||||
'log.enabled' => false
|
||||
));
|
||||
$app->get('/foo', function () use ($app) {
|
||||
$app->contentType('application/json;charset=utf-8'); //<-- set content type to something else
|
||||
throw new \Exception('Test Message', 100);
|
||||
});
|
||||
$mw = new \Slim\Middleware\PrettyExceptions();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$response = $app->response();
|
||||
$this->assertEquals('text/html', $response['Content-Type']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test exception type is in response body
|
||||
*/
|
||||
public function testExceptionTypeIsInResponseBody()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim(array(
|
||||
'log.enabled' => false
|
||||
));
|
||||
$app->get('/foo', function () use ($app) {
|
||||
throw new \LogicException('Test Message', 100);
|
||||
});
|
||||
$mw = new \Slim\Middleware\PrettyExceptions();
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
|
||||
$this->assertContains('LogicException', $app->response()->body());
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class SessionCookieTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
if ( session_id() !== '' ) {
|
||||
session_unset();
|
||||
session_destroy();
|
||||
}
|
||||
$_SESSION = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test session cookie is set and constructed correctly
|
||||
*
|
||||
* We test for two things:
|
||||
* 1) That the HTTP cookie is added to the `Set-Cookie:` response header;
|
||||
* 2) That the HTTP cookie is constructed in the expected format;
|
||||
*/
|
||||
public function testSessionCookieIsCreatedAndEncrypted()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$app->get('/foo', function () {
|
||||
echo "Success";
|
||||
});
|
||||
$mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years'));
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
list($status, $header, $body) = $app->response()->finalize();
|
||||
$matches = array();
|
||||
preg_match_all('@^slim_session=.+|.+|.+; expires=@', $header['Set-Cookie'], $matches, PREG_SET_ORDER);
|
||||
$this->assertEquals(1, count($matches));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test $_SESSION is populated from HTTP cookie
|
||||
*
|
||||
* The HTTP cookie in this test was created using the previous test; the encrypted cookie contains
|
||||
* the serialized array ['foo' => 'bar']. The middleware secret, cipher, and cipher mode are assumed
|
||||
* to be the default values.
|
||||
*/
|
||||
public function testSessionIsPopulatedFromCookie()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo',
|
||||
'COOKIE' => 'slim_session=1644004961%7CLKkYPwqKIMvBK7MWl6D%2BxeuhLuMaW4quN%2F512ZAaVIY%3D%7Ce0f007fa852c7101e8224bb529e26be4d0dfbd63',
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$app->get('/foo', function () {
|
||||
echo "Success";
|
||||
});
|
||||
$mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years'));
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$this->assertEquals(array('foo' => 'bar'), $_SESSION);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test $_SESSION is populated as empty array if no HTTP cookie
|
||||
*/
|
||||
public function testSessionIsPopulatedAsEmptyIfNoCookie()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '/index.php',
|
||||
'PATH_INFO' => '/foo'
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$app->get('/foo', function () {
|
||||
echo "Success";
|
||||
});
|
||||
$mw = new \Slim\Middleware\SessionCookie(array('expires' => '10 years'));
|
||||
$mw->setApplication($app);
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
$this->assertEquals(array(), $_SESSION);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class My_Middleware extends \Slim\Middleware
|
||||
{
|
||||
public function call()
|
||||
{
|
||||
echo "Before";
|
||||
$this->next->call();
|
||||
echo "After";
|
||||
}
|
||||
}
|
||||
|
||||
class My_Application
|
||||
{
|
||||
public function call()
|
||||
{
|
||||
echo "Application";
|
||||
}
|
||||
}
|
||||
|
||||
class MiddlewareTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Get and set application
|
||||
*/
|
||||
public function testGetAndSetApplication()
|
||||
{
|
||||
$app = new My_Application();
|
||||
$mw = new My_Middleware();
|
||||
$mw->setApplication($app);
|
||||
$this->assertSame($app, $mw->getApplication());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get and set next middleware
|
||||
*/
|
||||
public function testGetAndSetNextMiddleware()
|
||||
{
|
||||
$mw1 = new My_Middleware();
|
||||
$mw2 = new My_Middleware();
|
||||
$mw1->setNextMiddleware($mw2);
|
||||
$this->assertSame($mw2, $mw1->getNextMiddleware());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test call
|
||||
*/
|
||||
public function testCall()
|
||||
{
|
||||
$this->expectOutputString('BeforeApplicationAfter');
|
||||
$app = new My_Application();
|
||||
$mw = new My_Middleware();
|
||||
$mw->setNextMiddleware($app);
|
||||
$mw->call();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
Slim Framework Unit Tests
|
||||
|
||||
Follow the directions below to run the Slim Framework unit tests. You'll need the latest version of PHPUnit. To save development time, these unit tests require PHP >= 5.3. However, the Slim Framework itself requires only PHP >= 5.2.
|
||||
|
||||
1. Install the latest version of PHPUnit
|
||||
Visit http://www.phpunit.de/ for installation instructions.
|
||||
|
||||
2. Run PHPUnit
|
||||
From the filesystem directory that contains the `tests` directory, you may run all unit tests or specific unit tests. Here are several examples. The '$>' in the examples below is your command prompt.
|
||||
|
||||
To run all tests:
|
||||
$> phpunit tests
|
||||
|
||||
To run all HTTP-related tests:
|
||||
$> phpunit tests/Http
|
||||
|
||||
To run only the HTTP Request tests:
|
||||
$> phpunit tests/Http/RequestTest
|
|
@ -0,0 +1,559 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// Used for passing callable via string
|
||||
function testCallable() {}
|
||||
|
||||
class RouteTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* Route should set name
|
||||
*/
|
||||
public function testRouteSetsName()
|
||||
{
|
||||
$route = new \Slim\Route('/foo/bar', function () {});
|
||||
$route->name('foo');
|
||||
$this->assertEquals('foo', $route->getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route should set pattern
|
||||
*/
|
||||
public function testRouteSetsPattern()
|
||||
{
|
||||
$route1 = new \Slim\Route('/foo/bar', function () {});
|
||||
$this->assertEquals('/foo/bar', $route1->getPattern());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route sets pattern with params
|
||||
*/
|
||||
public function testRouteSetsPatternWithParams()
|
||||
{
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
$this->assertEquals('/hello/:first/:last', $route->getPattern());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route sets custom pattern that overrides pattern
|
||||
*/
|
||||
public function testRouteSetsCustomTemplate()
|
||||
{
|
||||
$route = new \Slim\Route('/hello/*', function () {});
|
||||
$route->setPattern('/hello/:name');
|
||||
$this->assertEquals('/hello/:name', $route->getPattern());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route should store a reference to the callable
|
||||
* anonymous function.
|
||||
*/
|
||||
public function testRouteSetsCallableAsFunction()
|
||||
{
|
||||
$callable = function () { echo "Foo!"; };
|
||||
$route = new \Slim\Route('/foo/bar', $callable);
|
||||
$this->assertSame($callable, $route->getCallable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route should store a reference to the callable
|
||||
* regular function (for PHP 5 < 5.3)
|
||||
*/
|
||||
public function testRouteSetsCallableAsString()
|
||||
{
|
||||
$route = new \Slim\Route('/foo/bar', 'testCallable');
|
||||
$this->assertEquals('testCallable', $route->getCallable());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route should throw exception when creating with an invalid callable
|
||||
*/
|
||||
public function testRouteThrowsExecptionWithInvalidCallable()
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
$route = new \Slim\Route('/foo/bar', 'fnDoesNotExist');
|
||||
}
|
||||
|
||||
/**
|
||||
* Route should throw exception when setting an invalid callable
|
||||
*/
|
||||
public function testRouteThrowsExecptionWhenSettingInvalidCallable()
|
||||
{
|
||||
$route = new \Slim\Route('/foo/bar', function () {});
|
||||
try
|
||||
{
|
||||
$route->setCallable('fnDoesNotExist');
|
||||
$this->fail('Did not catch InvalidArgumentException when setting invalid callable');
|
||||
} catch(\InvalidArgumentException $e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test gets all params
|
||||
*/
|
||||
public function testGetRouteParams()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get params
|
||||
$params = $route->getParams();
|
||||
$this->assertEquals(2, count($params));
|
||||
$this->assertEquals('mr', $params['first']);
|
||||
$this->assertEquals('anderson', $params['last']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sets all params
|
||||
*/
|
||||
public function testSetRouteParams()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get params
|
||||
$params = $route->getParams();
|
||||
$this->assertEquals(2, count($params));
|
||||
$this->assertEquals('mr', $params['first']);
|
||||
$this->assertEquals('anderson', $params['last']);
|
||||
|
||||
// Replace params
|
||||
$route->setParams(array(
|
||||
'first' => 'john',
|
||||
'last' => 'smith'
|
||||
));
|
||||
|
||||
// Get new params
|
||||
$params = $route->getParams();
|
||||
$this->assertEquals(2, count($params));
|
||||
$this->assertEquals('john', $params['first']);
|
||||
$this->assertEquals('smith', $params['last']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test gets param when exists
|
||||
*/
|
||||
public function testGetRouteParamWhenExists()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get param
|
||||
$this->assertEquals('anderson', $route->getParam('last'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test gets param when not exists
|
||||
*/
|
||||
public function testGetRouteParamWhenNotExists()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get param
|
||||
try {
|
||||
$param = $route->getParam('foo');
|
||||
$this->fail('Did not catch expected InvalidArgumentException');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sets param when exists
|
||||
*/
|
||||
public function testSetRouteParamWhenExists()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get param
|
||||
$this->assertEquals('anderson', $route->getParam('last'));
|
||||
|
||||
// Set param
|
||||
$route->setParam('last', 'smith');
|
||||
|
||||
// Get new param
|
||||
$this->assertEquals('smith', $route->getParam('last'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test sets param when not exists
|
||||
*/
|
||||
public function testSetRouteParamWhenNotExists()
|
||||
{
|
||||
// Prepare route
|
||||
$requestUri = '/hello/mr/anderson';
|
||||
$route = new \Slim\Route('/hello/:first/:last', function () {});
|
||||
|
||||
// Parse route params
|
||||
$this->assertTrue($route->matches($requestUri));
|
||||
|
||||
// Get param
|
||||
try {
|
||||
$param = $route->setParam('foo', 'bar');
|
||||
$this->fail('Did not catch expected InvalidArgumentException');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* If route matches a resource URI, param should be extracted.
|
||||
*/
|
||||
public function testRouteMatchesAndParamExtracted()
|
||||
{
|
||||
$resource = '/hello/Josh';
|
||||
$route = new \Slim\Route('/hello/:name', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('name' => 'Josh'), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* If route matches a resource URI, multiple params should be extracted.
|
||||
*/
|
||||
public function testRouteMatchesAndMultipleParamsExtracted()
|
||||
{
|
||||
$resource = '/hello/Josh/and/John';
|
||||
$route = new \Slim\Route('/hello/:first/and/:second', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('first' => 'Josh', 'second' => 'John'), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* If route does not match a resource URI, params remain an empty array
|
||||
*/
|
||||
public function testRouteDoesNotMatchAndParamsNotExtracted()
|
||||
{
|
||||
$resource = '/foo/bar';
|
||||
$route = new \Slim\Route('/hello/:name', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(array(), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with trailing slash
|
||||
*
|
||||
*/
|
||||
public function testRouteMatchesWithTrailingSlash()
|
||||
{
|
||||
$resource1 = '/foo/bar/';
|
||||
$resource2 = '/foo/bar';
|
||||
$route = new \Slim\Route('/foo/:one/', function () {});
|
||||
$this->assertTrue($route->matches($resource1));
|
||||
$this->assertTrue($route->matches($resource2));
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with conditions
|
||||
*/
|
||||
public function testRouteMatchesResourceWithConditions()
|
||||
{
|
||||
$resource = '/hello/Josh/and/John';
|
||||
$route = new \Slim\Route('/hello/:first/and/:second', function () {});
|
||||
$route->conditions(array('first' => '[a-zA-Z]{3,}'));
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('first' => 'Josh', 'second' => 'John'), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route does not match URI with conditions
|
||||
*/
|
||||
public function testRouteDoesNotMatchResourceWithConditions()
|
||||
{
|
||||
$resource = '/hello/Josh/and/John';
|
||||
$route = new \Slim\Route('/hello/:first/and/:second', function () {});
|
||||
$route->conditions(array('first' => '[a-z]{3,}'));
|
||||
$result = $route->matches($resource);
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(array(), $route->getParams());
|
||||
}
|
||||
|
||||
/*
|
||||
* Route should match URI with valid path component according to rfc2396
|
||||
*
|
||||
* "Uniform Resource Identifiers (URI): Generic Syntax" http://www.ietf.org/rfc/rfc2396.txt
|
||||
*
|
||||
* Excludes "+" which is valid but decodes into a space character
|
||||
*/
|
||||
public function testRouteMatchesResourceWithValidRfc2396PathComponent()
|
||||
{
|
||||
$symbols = ':@&=$,';
|
||||
$resource = '/rfc2386/' . $symbols;
|
||||
$route = new \Slim\Route('/rfc2386/:symbols', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('symbols' => $symbols), $route->getParams());
|
||||
}
|
||||
|
||||
/*
|
||||
* Route should match URI including unreserved punctuation marks from rfc2396
|
||||
*
|
||||
* "Uniform Resource Identifiers (URI): Generic Syntax" http://www.ietf.org/rfc/rfc2396.txt
|
||||
*/
|
||||
public function testRouteMatchesResourceWithUnreservedMarks()
|
||||
{
|
||||
$marks = "-_.!~*'()";
|
||||
$resource = '/marks/' . $marks;
|
||||
$route = new \Slim\Route('/marks/:marks', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('marks' => $marks), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route optional parameters
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Route pattern requires :year, optionally accepts :month and :day
|
||||
*
|
||||
* Post-conditions:
|
||||
* All: Year is 2010
|
||||
* Case A: Month and day default values are used
|
||||
* Case B: Month is "05" and day default value is used
|
||||
* Case C: Month is "05" and day is "13"
|
||||
*/
|
||||
public function testRouteOptionalParameters()
|
||||
{
|
||||
$pattern = '/archive/:year(/:month(/:day))';
|
||||
|
||||
//Case A
|
||||
$routeA = new \Slim\Route($pattern, function () {});
|
||||
$resourceA = '/archive/2010';
|
||||
$resultA = $routeA->matches($resourceA);
|
||||
$this->assertTrue($resultA);
|
||||
$this->assertEquals(array('year' => '2010'), $routeA->getParams());
|
||||
|
||||
//Case B
|
||||
$routeB = new \Slim\Route($pattern, function () {});
|
||||
$resourceB = '/archive/2010/05';
|
||||
$resultB = $routeB->matches($resourceB);
|
||||
$this->assertTrue($resultB);
|
||||
$this->assertEquals(array('year' => '2010', 'month' => '05'), $routeB->getParams());
|
||||
|
||||
//Case C
|
||||
$routeC = new \Slim\Route($pattern, function () {});
|
||||
$resourceC = '/archive/2010/05/13';
|
||||
$resultC = $routeC->matches($resourceC);
|
||||
$this->assertTrue($resultC);
|
||||
$this->assertEquals(array('year' => '2010', 'month' => '05', 'day' => '13'), $routeC->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test route default conditions
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Route class has default conditions;
|
||||
*
|
||||
* Post-conditions:
|
||||
* Case A: Route instance has default conditions;
|
||||
* Case B: Route instance has newly merged conditions;
|
||||
*/
|
||||
public function testRouteDefaultConditions()
|
||||
{
|
||||
\Slim\Route::setDefaultConditions(array('id' => '\d+'));
|
||||
$r = new \Slim\Route('/foo', function () {});
|
||||
//Case A
|
||||
$this->assertEquals(\Slim\Route::getDefaultConditions(), $r->getConditions());
|
||||
//Case B
|
||||
$r->conditions(array('name' => '[a-z]{2,5}'));
|
||||
$c = $r->getConditions();
|
||||
$this->assertArrayHasKey('id', $c);
|
||||
$this->assertArrayHasKey('name', $c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with wildcard
|
||||
*/
|
||||
public function testRouteMatchesResourceWithWildcard()
|
||||
{
|
||||
$resource = '/hello/foo/bar/world';
|
||||
$route = new \Slim\Route('/hello/:path+/world', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('path'=>array('foo', 'bar')), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with more than one wildcard
|
||||
*/
|
||||
public function testRouteMatchesResourceWithMultipleWildcards()
|
||||
{
|
||||
$resource = '/hello/foo/bar/world/2012/03/10';
|
||||
$route = new \Slim\Route('/hello/:path+/world/:date+', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('path'=>array('foo', 'bar'), 'date'=>array('2012', '03', '10')), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with wildcards and parameters
|
||||
*/
|
||||
public function testRouteMatchesResourceWithWildcardsAndParams()
|
||||
{
|
||||
$resource = '/hello/foo/bar/world/2012/03/10/first/second';
|
||||
$route = new \Slim\Route('/hello/:path+/world/:year/:month/:day/:path2+', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertTrue($result);
|
||||
$this->assertEquals(array('path'=>array('foo', 'bar'), 'year'=>'2012', 'month'=>'03', 'day'=>'10', 'path2'=>array('first', 'second')), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route matches URI with optional wildcard and parameter
|
||||
*/
|
||||
public function testRouteMatchesResourceWithOptionalWildcardsAndParams()
|
||||
{
|
||||
$resourceA = '/hello/world/foo/bar';
|
||||
$routeA = new \Slim\Route('/hello(/:world(/:path+))', function () {});
|
||||
$this->assertTrue($routeA->matches($resourceA));
|
||||
$this->assertEquals(array('world'=>'world', 'path'=>array('foo', 'bar')), $routeA->getParams());
|
||||
|
||||
$resourceB = '/hello/world';
|
||||
$routeB = new \Slim\Route('/hello(/:world(/:path))', function () {});
|
||||
$this->assertTrue($routeB->matches($resourceB));
|
||||
$this->assertEquals(array('world'=>'world'), $routeB->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Route does not match URI with wildcard
|
||||
*/
|
||||
public function testRouteDoesNotMatchResourceWithWildcard()
|
||||
{
|
||||
$resource = '/hello';
|
||||
$route = new \Slim\Route('/hello/:path+', function () {});
|
||||
$result = $route->matches($resource);
|
||||
$this->assertFalse($result);
|
||||
$this->assertEquals(array(), $route->getParams());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test route sets and gets middleware
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Route instantiated
|
||||
*
|
||||
* Post-conditions:
|
||||
* Case A: Middleware set as callable, not array
|
||||
* Case B: Middleware set after other middleware already set
|
||||
* Case C: Middleware set as array of callables
|
||||
* Case D: Middleware set as a callable array
|
||||
* Case E: Middleware is invalid; throws InvalidArgumentException
|
||||
* Case F: Middleware is an array with one invalid callable; throws InvalidArgumentException
|
||||
*/
|
||||
public function testRouteMiddleware()
|
||||
{
|
||||
$callable1 = function () {};
|
||||
$callable2 = function () {};
|
||||
//Case A
|
||||
$r1 = new \Slim\Route('/foo', function () {});
|
||||
$r1->setMiddleware($callable1);
|
||||
$mw = $r1->getMiddleware();
|
||||
$this->assertInternalType('array', $mw);
|
||||
$this->assertEquals(1, count($mw));
|
||||
//Case B
|
||||
$r1->setMiddleware($callable2);
|
||||
$mw = $r1->getMiddleware();
|
||||
$this->assertEquals(2, count($mw));
|
||||
//Case C
|
||||
$r2 = new \Slim\Route('/foo', function () {});
|
||||
$r2->setMiddleware(array($callable1, $callable2));
|
||||
$mw = $r2->getMiddleware();
|
||||
$this->assertInternalType('array', $mw);
|
||||
$this->assertEquals(2, count($mw));
|
||||
//Case D
|
||||
$r3 = new \Slim\Route('/foo', function () {});
|
||||
$r3->setMiddleware(array($this, 'callableTestFunction'));
|
||||
$mw = $r3->getMiddleware();
|
||||
$this->assertInternalType('array', $mw);
|
||||
$this->assertEquals(1, count($mw));
|
||||
//Case E
|
||||
try {
|
||||
$r3->setMiddleware('sdjfsoi788');
|
||||
$this->fail('Did not catch InvalidArgumentException when setting invalid route middleware');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
//Case F
|
||||
try {
|
||||
$r3->setMiddleware(array($callable1, $callable2, 'sdjfsoi788'));
|
||||
$this->fail('Did not catch InvalidArgumentException when setting an array with one invalid route middleware');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
public function callableTestFunction() {}
|
||||
|
||||
/**
|
||||
* Test that a Route manages the HTTP methods that it supports
|
||||
*
|
||||
* Case A: Route initially supports no HTTP methods
|
||||
* Case B: Route can set its supported HTTP methods
|
||||
* Case C: Route can append supported HTTP methods
|
||||
* Case D: Route can test if it supports an HTTP method
|
||||
* Case E: Route can lazily declare supported HTTP methods with `via`
|
||||
*/
|
||||
public function testHttpMethods()
|
||||
{
|
||||
//Case A
|
||||
$r = new \Slim\Route('/foo', function () {});
|
||||
$this->assertEmpty($r->getHttpMethods());
|
||||
//Case B
|
||||
$r->setHttpMethods('GET');
|
||||
$this->assertEquals(array('GET'), $r->getHttpMethods());
|
||||
//Case C
|
||||
$r->appendHttpMethods('POST', 'PUT');
|
||||
$this->assertEquals(array('GET', 'POST', 'PUT'), $r->getHttpMethods());
|
||||
//Case D
|
||||
$this->assertTrue($r->supportsHttpMethod('GET'));
|
||||
$this->assertFalse($r->supportsHttpMethod('DELETE'));
|
||||
//Case E
|
||||
$viaResult = $r->via('DELETE');
|
||||
$this->assertTrue($viaResult instanceof \Slim\Route);
|
||||
$this->assertTrue($r->supportsHttpMethod('DELETE'));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,602 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class RouterTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
protected $env;
|
||||
protected $req;
|
||||
protected $res;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/bar', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
}
|
||||
|
||||
/**
|
||||
* Router::urlFor should return a full route pattern
|
||||
* even if no params data is provided.
|
||||
*/
|
||||
public function testUrlForNamedRouteWithoutParams()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route = $router->map('/foo/bar', function () {})->via('GET');
|
||||
$router->addNamedRoute('foo', $route);
|
||||
$this->assertEquals('/foo/bar', $router->urlFor('foo'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Router::urlFor should return a full route pattern if
|
||||
* param data is provided.
|
||||
*/
|
||||
public function testUrlForNamedRouteWithParams()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route = $router->map('/foo/:one/and/:two', function ($one, $two) {})->via('GET');
|
||||
$router->addNamedRoute('foo', $route);
|
||||
$this->assertEquals('/foo/Josh/and/John', $router->urlFor('foo', array('one' => 'Josh', 'two' => 'John')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Router::urlFor should throw an exception if Route with name
|
||||
* does not exist.
|
||||
* @expectedException \RuntimeException
|
||||
*/
|
||||
public function testUrlForNamedRouteThatDoesNotExist()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route = $router->map('/foo/bar', function () {})->via('GET');
|
||||
$router->addNamedRoute('bar', $route);
|
||||
$router->urlFor('foo');
|
||||
}
|
||||
|
||||
/**
|
||||
* Router::addNamedRoute should throw an exception if named Route
|
||||
* with same name already exists.
|
||||
*/
|
||||
public function testNamedRouteWithExistingName()
|
||||
{
|
||||
$this->setExpectedException('\RuntimeException');
|
||||
$router = new \Slim\Router();
|
||||
$route1 = $router->map('/foo/bar', function () {})->via('GET');
|
||||
$route2 = $router->map('/foo/bar/2', function () {})->via('GET');
|
||||
$router->addNamedRoute('bar', $route1);
|
||||
$router->addNamedRoute('bar', $route2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if named route exists
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Slim app instantiated;
|
||||
* Named route created;
|
||||
*
|
||||
* Post-conditions:
|
||||
* Named route found to exist;
|
||||
* Non-existant route found not to exist;
|
||||
*/
|
||||
public function testHasNamedRoute()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route = $router->map('/foo', function () {})->via('GET');
|
||||
$router->addNamedRoute('foo', $route);
|
||||
$this->assertTrue($router->hasNamedRoute('foo'));
|
||||
$this->assertFalse($router->hasNamedRoute('bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test Router gets named route
|
||||
*
|
||||
* Pre-conditions;
|
||||
* Slim app instantiated;
|
||||
* Named route created;
|
||||
*
|
||||
* Post-conditions:
|
||||
* Named route fetched by named;
|
||||
* NULL is returned if named route does not exist;
|
||||
*/
|
||||
public function testGetNamedRoute()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route1 = $router->map('/foo', function () {})->via('GET');
|
||||
$router->addNamedRoute('foo', $route1);
|
||||
$this->assertSame($route1, $router->getNamedRoute('foo'));
|
||||
$this->assertNull($router->getNamedRoute('bar'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test external iterator for Router's named routes
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Slim app instantiated;
|
||||
* Named routes created;
|
||||
*
|
||||
* Post-conditions:
|
||||
* Array iterator returned for named routes;
|
||||
*/
|
||||
public function testGetNamedRoutes()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route1 = $router->map('/foo', function () {})->via('GET');
|
||||
$route2 = $router->map('/bar', function () {})->via('POST');
|
||||
$router->addNamedRoute('foo', $route1);
|
||||
$router->addNamedRoute('bar', $route2);
|
||||
$namedRoutesIterator = $router->getNamedRoutes();
|
||||
$this->assertInstanceOf('ArrayIterator', $namedRoutesIterator);
|
||||
$this->assertEquals(2, $namedRoutesIterator->count());
|
||||
}
|
||||
|
||||
/**
|
||||
* Router considers HEAD requests as GET requests
|
||||
*/
|
||||
public function testRouterConsidersHeadAsGet()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'HEAD',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/bar', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
$router = new \Slim\Router();
|
||||
$route = $router->map('/bar', function () {})->via('GET', 'HEAD');
|
||||
$numberOfMatchingRoutes = count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri()));
|
||||
$this->assertEquals(1, $numberOfMatchingRoutes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Router::urlFor
|
||||
*/
|
||||
public function testRouterUrlFor()
|
||||
{
|
||||
$router = new \Slim\Router();
|
||||
$route1 = $router->map('/foo/bar', function () {})->via('GET');
|
||||
$route2 = $router->map('/foo/:one/:two', function () {})->via('GET');
|
||||
$route3 = $router->map('/foo/:one(/:two)', function () {})->via('GET');
|
||||
$route4 = $router->map('/foo/:one/(:two/)', function () {})->via('GET');
|
||||
$route5 = $router->map('/foo/:one/(:two/(:three/))', function () {})->via('GET');
|
||||
$route6 = $router->map('/foo/:path+/bar', function (){})->via('GET');
|
||||
$route7 = $router->map('/foo/:path+/:path2+/bar', function (){})->via('GET');
|
||||
$route8 = $router->map('/foo/:path+', function (){})->via('GET');
|
||||
$route9 = $router->map('/foo/:var/:var2', function (){})->via('GET');
|
||||
$route1->setName('route1');
|
||||
$route2->setName('route2');
|
||||
$route3->setName('route3');
|
||||
$route4->setName('route4');
|
||||
$route5->setName('route5');
|
||||
$route6->setName('route6');
|
||||
$route7->setName('route7');
|
||||
$route8->setName('route8');
|
||||
$route9->setName('route9');
|
||||
//Route
|
||||
$this->assertEquals('/foo/bar', $router->urlFor('route1'));
|
||||
//Route with params
|
||||
$this->assertEquals('/foo/foo/bar', $router->urlFor('route2', array('one' => 'foo', 'two' => 'bar')));
|
||||
$this->assertEquals('/foo/foo/:two', $router->urlFor('route2', array('one' => 'foo')));
|
||||
$this->assertEquals('/foo/:one/bar', $router->urlFor('route2', array('two' => 'bar')));
|
||||
//Route with params and optional segments
|
||||
$this->assertEquals('/foo/foo/bar', $router->urlFor('route3', array('one' => 'foo', 'two' => 'bar')));
|
||||
$this->assertEquals('/foo/foo', $router->urlFor('route3', array('one' => 'foo')));
|
||||
$this->assertEquals('/foo/:one/bar', $router->urlFor('route3', array('two' => 'bar')));
|
||||
$this->assertEquals('/foo/:one', $router->urlFor('route3'));
|
||||
//Route with params and optional segments
|
||||
$this->assertEquals('/foo/foo/bar/', $router->urlFor('route4', array('one' => 'foo', 'two' => 'bar')));
|
||||
$this->assertEquals('/foo/foo/', $router->urlFor('route4', array('one' => 'foo')));
|
||||
$this->assertEquals('/foo/:one/bar/', $router->urlFor('route4', array('two' => 'bar')));
|
||||
$this->assertEquals('/foo/:one/', $router->urlFor('route4'));
|
||||
//Route with params and optional segments
|
||||
$this->assertEquals('/foo/foo/bar/what/', $router->urlFor('route5', array('one' => 'foo', 'two' => 'bar', 'three' => 'what')));
|
||||
$this->assertEquals('/foo/foo/', $router->urlFor('route5', array('one' => 'foo')));
|
||||
$this->assertEquals('/foo/:one/bar/', $router->urlFor('route5', array('two' => 'bar')));
|
||||
$this->assertEquals('/foo/:one/bar/what/', $router->urlFor('route5', array('two' => 'bar', 'three' => 'what')));
|
||||
$this->assertEquals('/foo/:one/', $router->urlFor('route5'));
|
||||
//Route with wildcard params
|
||||
$this->assertEquals('/foo/bar/bar', $router->urlFor('route6', array('path'=>'bar')));
|
||||
$this->assertEquals('/foo/foo/bar/bar', $router->urlFor('route7', array('path'=>'foo', 'path2'=>'bar')));
|
||||
$this->assertEquals('/foo/bar', $router->urlFor('route8', array('path'=>'bar')));
|
||||
//Route with similar param names, test greedy matching
|
||||
$this->assertEquals('/foo/1/2', $router->urlFor('route9', array('var2'=>'2', 'var'=>'1')));
|
||||
$this->assertEquals('/foo/1/2', $router->urlFor('route9', array('var'=>'1', 'var2'=>'2')));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that router returns no matches when neither HTTP method nor URI match.
|
||||
*/
|
||||
public function testRouterMatchesRoutesNone()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
$router = new \Slim\Router();
|
||||
$router->map('/bar', function () {})->via('POST');
|
||||
$router->map('/foo', function () {})->via('POST');
|
||||
$router->map('/foo', function () {})->via('PUT');
|
||||
$router->map('/foo/bar/xyz', function () {})->via('DELETE');
|
||||
$this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that router returns no matches when HTTP method matches but URI does not.
|
||||
*/
|
||||
public function testRouterMatchesRoutesNoneWhenMethodMatchesUriDoesNot()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
$router = new \Slim\Router();
|
||||
$router->map('/fooNOMATCH', function () {})->via('GET');
|
||||
$router->map('/foo', function () {})->via('POST');
|
||||
$router->map('/foo', function () {})->via('PUT');
|
||||
$router->map('/foo/bar/xyz', function () {})->via('DELETE');
|
||||
$this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that router returns no matches when HTTP method does not match but URI does.
|
||||
*/
|
||||
public function testRouterMatchesRoutesNoneWhenMethodDoesNotMatchUriMatches()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
$router = new \Slim\Router();
|
||||
$router->map('/foo', function () {})->via('OPTIONS');
|
||||
$router->map('/foo', function () {})->via('POST');
|
||||
$router->map('/foo', function () {})->via('PUT');
|
||||
$router->map('/foo/bar/xyz', function () {})->via('DELETE');
|
||||
$this->assertEquals(0, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that router returns matched routes based on HTTP method and URI.
|
||||
*/
|
||||
public function testRouterMatchesRoutes()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$this->env = \Slim\Environment::getInstance();
|
||||
$this->req = new \Slim\Http\Request($this->env);
|
||||
$this->res = new \Slim\Http\Response();
|
||||
$router = new \Slim\Router();
|
||||
$router->map('/foo', function () {})->via('GET');
|
||||
$router->map('/foo', function () {})->via('POST');
|
||||
$router->map('/foo', function () {})->via('PUT');
|
||||
$router->map('/foo/bar/xyz', function () {})->via('DELETE');
|
||||
$this->assertEquals(1, count($router->getMatchedRoutes($this->req->getMethod(), $this->req->getResourceUri())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get current route
|
||||
*/
|
||||
public function testGetCurrentRoute()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () {
|
||||
echo "Foo";
|
||||
});
|
||||
$app->call();
|
||||
$this->assertSame($route2, $app->router()->getCurrentRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test calling get current route before routing doesn't cause errors
|
||||
*/
|
||||
public function testGetCurrentRouteBeforeRoutingDoesntError()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () {
|
||||
echo "Foo";
|
||||
});
|
||||
|
||||
$app->router()->getCurrentRoute();
|
||||
|
||||
$app->call();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get current route before routing returns null
|
||||
*/
|
||||
public function testGetCurrentRouteBeforeRoutingReturnsNull()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () {
|
||||
echo "Foo";
|
||||
});
|
||||
|
||||
$this->assertSame(null, $app->router()->getCurrentRoute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get current route during slim.before.dispatch hook
|
||||
*/
|
||||
public function testGetCurrentRouteDuringBeforeDispatchHook()
|
||||
{
|
||||
$route = null;
|
||||
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$app->hook('slim.before.dispatch', function() use(&$route, $app) {
|
||||
$route = $app->router()->getCurrentRoute();
|
||||
});
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () {
|
||||
echo "Foo";
|
||||
});
|
||||
|
||||
$app->call();
|
||||
$this->assertSame($route2, $route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get current route during routing
|
||||
*/
|
||||
public function testGetCurrentRouteDuringRouting()
|
||||
{
|
||||
$route = null;
|
||||
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () use (&$route, $app) {
|
||||
echo "Foo";
|
||||
$route = $app->router()->getCurrentRoute();
|
||||
});
|
||||
|
||||
$app->call();
|
||||
$this->assertSame($route2, $route);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test get current route after routing
|
||||
*/
|
||||
public function testGetCurrentRouteAfterRouting()
|
||||
{
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$app = new \Slim\Slim();
|
||||
$route1 = $app->get('/bar', function () {
|
||||
echo "Bar";
|
||||
});
|
||||
$route2 = $app->get('/foo', function () {
|
||||
echo "Foo";
|
||||
});
|
||||
$app->call();
|
||||
$this->assertSame($route2, $app->router()->getCurrentRoute());
|
||||
}
|
||||
|
||||
public function testDispatch()
|
||||
{
|
||||
$this->expectOutputString('Hello josh');
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/hello/josh', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$env = \Slim\Environment::getInstance();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$router = new \Slim\Router();
|
||||
$route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; });
|
||||
$route->matches($req->getResourceUri()); //<-- Extracts params from resource URI
|
||||
$router->dispatch($route);
|
||||
}
|
||||
|
||||
public function testDispatchWithMiddlware()
|
||||
{
|
||||
$this->expectOutputString('First! Second! Hello josh');
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/hello/josh', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$env = \Slim\Environment::getInstance();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$router = new \Slim\Router();
|
||||
$route = new \Slim\Route('/hello/:name', function ($name) { echo "Hello $name"; });
|
||||
$route->setMiddleware(function () {
|
||||
echo "First! ";
|
||||
});
|
||||
$route->setMiddleware(function () {
|
||||
echo "Second! ";
|
||||
});
|
||||
$route->matches($req->getResourceUri()); //<-- Extracts params from resource URI
|
||||
$router->dispatch($route);
|
||||
}
|
||||
|
||||
public function testRouteMiddlwareArguments()
|
||||
{
|
||||
$this->expectOutputString('foobar');
|
||||
\Slim\Environment::mock(array(
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/foo' //<-- Virtual
|
||||
));
|
||||
$env = \Slim\Environment::getInstance();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$router = new \Slim\Router();
|
||||
$route = new \Slim\Route('/foo', function () { echo "bar"; });
|
||||
$route->setName('foo');
|
||||
$route->setMiddleware(function ($route) {
|
||||
echo $route->getName();
|
||||
});
|
||||
$route->matches($req->getResourceUri()); //<-- Extracts params from resource URI
|
||||
$router->dispatch($route);
|
||||
}
|
||||
|
||||
public function testDispatchWithoutCallable()
|
||||
{
|
||||
$this->setExpectedException('InvalidArgumentException');
|
||||
\Slim\Environment::mock(array(
|
||||
'REQUEST_METHOD' => 'GET',
|
||||
'REMOTE_ADDR' => '127.0.0.1',
|
||||
'SCRIPT_NAME' => '', //<-- Physical
|
||||
'PATH_INFO' => '/hello/josh', //<-- Virtual
|
||||
'QUERY_STRING' => 'one=1&two=2&three=3',
|
||||
'SERVER_NAME' => 'slim',
|
||||
'SERVER_PORT' => 80,
|
||||
'slim.url_scheme' => 'http',
|
||||
'slim.input' => '',
|
||||
'slim.errors' => fopen('php://stderr', 'w'),
|
||||
'HTTP_HOST' => 'slim'
|
||||
));
|
||||
$env = \Slim\Environment::getInstance();
|
||||
$req = new \Slim\Http\Request($env);
|
||||
$router = new \Slim\Router();
|
||||
$route = new \Slim\Route('/hello/:name', 'foo'); // <-- Fail fast
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,195 @@
|
|||
<?php
|
||||
/**
|
||||
* Slim - a micro PHP 5 framework
|
||||
*
|
||||
* @author Josh Lockhart <info@slimframework.com>
|
||||
* @copyright 2011 Josh Lockhart
|
||||
* @link http://www.slimframework.com
|
||||
* @license http://www.slimframework.com/license
|
||||
* @version 2.2.0
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
class ViewTest extends PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->view = new \Slim\View();
|
||||
}
|
||||
|
||||
public function generateTestData()
|
||||
{
|
||||
return array('a' => 1, 'b' => 2, 'c' => 3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test initial View data is an empty array
|
||||
*
|
||||
* Pre-conditions:
|
||||
* None
|
||||
*
|
||||
* Post-conditions:
|
||||
* The View object's data attribute is an empty array
|
||||
*/
|
||||
public function testViewIsConstructedWithDataArray()
|
||||
{
|
||||
$this->assertEquals(array(), $this->view->getData());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View sets and gets data
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Case A: Set view data key/value
|
||||
* Case B: Set view data as array
|
||||
* Case C: Set view data with one argument that is not an array
|
||||
*
|
||||
* Post-conditions:
|
||||
* Case A: Data key/value are set
|
||||
* Case B: Data is set to array
|
||||
* Case C: An InvalidArgumentException is thrown
|
||||
*/
|
||||
public function testViewSetAndGetData()
|
||||
{
|
||||
//Case A
|
||||
$this->view->setData('one', 1);
|
||||
$this->assertEquals(1, $this->view->getData('one'));
|
||||
|
||||
//Case B
|
||||
$data = array('foo' => 'bar', 'a' => 'A');
|
||||
$this->view->setData($data);
|
||||
$this->assertSame($data, $this->view->getData());
|
||||
|
||||
//Case C
|
||||
try {
|
||||
$this->view->setData('foo');
|
||||
$this->fail('Setting View data with non-array single argument did not throw exception');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View appends data
|
||||
*
|
||||
* Pre-conditions:
|
||||
* Case A: Append data to View several times
|
||||
* Case B: Append view data which is not an array
|
||||
*
|
||||
* Post-conditions:
|
||||
* Case A: The View data contains all appended data
|
||||
* Case B: An InvalidArgumentException is thrown
|
||||
*/
|
||||
public function testViewAppendsData()
|
||||
{
|
||||
//Case A
|
||||
$this->view->appendData(array('a' => 'A'));
|
||||
$this->view->appendData(array('b' => 'B'));
|
||||
$this->assertEquals(array('a' => 'A', 'b' => 'B'), $this->view->getData());
|
||||
|
||||
//Case B
|
||||
try {
|
||||
$this->view->appendData('not an array');
|
||||
$this->fail('Appending View data with non-array argument did not throw exception');
|
||||
} catch ( \InvalidArgumentException $e ) {}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View templates directory
|
||||
*
|
||||
* Pre-conditions:
|
||||
* View templates directory is set to an existing directory
|
||||
*
|
||||
* Post-conditions:
|
||||
* The templates directory is set correctly.
|
||||
*/
|
||||
public function testSetsTemplatesDirectory()
|
||||
{
|
||||
$templatesDirectory = dirname(__FILE__) . '/templates';
|
||||
$this->view->setTemplatesDirectory($templatesDirectory);
|
||||
$this->assertEquals($templatesDirectory, $this->view->getTemplatesDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View templates directory may have a trailing slash when set
|
||||
*
|
||||
* Pre-conditions:
|
||||
* View templates directory is set to an existing directory with a trailing slash
|
||||
*
|
||||
* Post-conditions:
|
||||
* The View templates directory is set correctly without a trailing slash
|
||||
*/
|
||||
public function testTemplatesDirectoryWithTrailingSlash()
|
||||
{
|
||||
$this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates/');
|
||||
$this->assertEquals(dirname(__FILE__) . '/templates', $this->view->getTemplatesDirectory());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View renders template
|
||||
*
|
||||
* Pre-conditions:
|
||||
* View templates directory is set to an existing directory.
|
||||
* View data is set without errors
|
||||
* Case A: View renders an existing template
|
||||
* Case B: View renders a non-existing template
|
||||
*
|
||||
* Post-conditions:
|
||||
* Case A: The rendered template is returned as a string
|
||||
* Case B: A RuntimeException is thrown
|
||||
*/
|
||||
public function testRendersTemplateWithData()
|
||||
{
|
||||
$this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates');
|
||||
$this->view->setData(array('foo' => 'bar'));
|
||||
|
||||
//Case A
|
||||
$output = $this->view->render('test.php');
|
||||
$this->assertEquals('test output bar', $output);
|
||||
|
||||
//Case B
|
||||
try {
|
||||
$output = $this->view->render('foo.php');
|
||||
$this->fail('Rendering non-existent template did not throw exception');
|
||||
} catch ( \RuntimeException $e ) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test View displays template
|
||||
*
|
||||
* Pre-conditions:
|
||||
* View templates directory is set to an existing directory.
|
||||
* View data is set without errors
|
||||
* View is displayed
|
||||
*
|
||||
* Post-conditions:
|
||||
* The output buffer contains the rendered template
|
||||
*/
|
||||
public function testDisplaysTemplateWithData()
|
||||
{
|
||||
$this->expectOutputString('test output bar');
|
||||
$this->view->setTemplatesDirectory(dirname(__FILE__) . '/templates');
|
||||
$this->view->setData(array('foo' => 'bar'));
|
||||
$this->view->display('test.php');
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?php
|
||||
set_include_path(dirname(__FILE__) . '/../' . PATH_SEPARATOR . get_include_path());
|
||||
|
||||
require_once 'Slim/Slim.php';
|
||||
|
||||
// Register Slim's autoloader
|
||||
\Slim\Slim::registerAutoloader();
|
||||
|
||||
//Register non-Slim autoloader
|
||||
function customAutoLoader( $class )
|
||||
{
|
||||
$file = rtrim(dirname(__FILE__), '/') . '/' . $class . '.php';
|
||||
if ( file_exists($file) ) {
|
||||
require $file;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
spl_autoload_register('customAutoLoader');
|
|
@ -0,0 +1 @@
|
|||
test output <?php echo $foo; ?>
|
Loading…
Reference in New Issue