Update Kohana to 3.1.3.1
This commit is contained in:
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Remote extends Kohana_Remote {}
|
||||
class Config extends Kohana_Config {}
|
3
includes/kohana/system/classes/config/file.php
Normal file
3
includes/kohana/system/classes/config/file.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Config_File extends Kohana_Config_File {}
|
3
includes/kohana/system/classes/config/reader.php
Normal file
3
includes/kohana/system/classes/config/reader.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Config_Reader extends Kohana_Config_Reader {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Validate extends Kohana_Validate {}
|
||||
class Debug extends Kohana_Debug {}
|
3
includes/kohana/system/classes/http.php
Normal file
3
includes/kohana/system/classes/http.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class HTTP extends Kohana_HTTP {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Validate_Exception extends Kohana_Validate_Exception {}
|
||||
class HTTP_Exception extends Kohana_HTTP_Exception {}
|
3
includes/kohana/system/classes/http/exception/400.php
Normal file
3
includes/kohana/system/classes/http/exception/400.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_400 extends Kohana_HTTP_Exception_400 {}
|
3
includes/kohana/system/classes/http/exception/401.php
Normal file
3
includes/kohana/system/classes/http/exception/401.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_401 extends Kohana_HTTP_Exception_401 {}
|
3
includes/kohana/system/classes/http/exception/402.php
Normal file
3
includes/kohana/system/classes/http/exception/402.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_402 extends Kohana_HTTP_Exception_402 {}
|
3
includes/kohana/system/classes/http/exception/403.php
Normal file
3
includes/kohana/system/classes/http/exception/403.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_403 extends Kohana_HTTP_Exception_403 {}
|
3
includes/kohana/system/classes/http/exception/404.php
Normal file
3
includes/kohana/system/classes/http/exception/404.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_404 extends Kohana_HTTP_Exception_404 {}
|
3
includes/kohana/system/classes/http/exception/405.php
Normal file
3
includes/kohana/system/classes/http/exception/405.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_405 extends Kohana_HTTP_Exception_405 {}
|
3
includes/kohana/system/classes/http/exception/406.php
Normal file
3
includes/kohana/system/classes/http/exception/406.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_406 extends Kohana_HTTP_Exception_406 {}
|
3
includes/kohana/system/classes/http/exception/407.php
Normal file
3
includes/kohana/system/classes/http/exception/407.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_407 extends Kohana_HTTP_Exception_407 {}
|
3
includes/kohana/system/classes/http/exception/408.php
Normal file
3
includes/kohana/system/classes/http/exception/408.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_408 extends Kohana_HTTP_Exception_408 {}
|
3
includes/kohana/system/classes/http/exception/409.php
Normal file
3
includes/kohana/system/classes/http/exception/409.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_409 extends Kohana_HTTP_Exception_409 {}
|
3
includes/kohana/system/classes/http/exception/410.php
Normal file
3
includes/kohana/system/classes/http/exception/410.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_410 extends Kohana_HTTP_Exception_410 {}
|
3
includes/kohana/system/classes/http/exception/411.php
Normal file
3
includes/kohana/system/classes/http/exception/411.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_411 extends Kohana_HTTP_Exception_411 {}
|
3
includes/kohana/system/classes/http/exception/412.php
Normal file
3
includes/kohana/system/classes/http/exception/412.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_412 extends Kohana_HTTP_Exception_412 {}
|
3
includes/kohana/system/classes/http/exception/413.php
Normal file
3
includes/kohana/system/classes/http/exception/413.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_413 extends Kohana_HTTP_Exception_413 {}
|
3
includes/kohana/system/classes/http/exception/414.php
Normal file
3
includes/kohana/system/classes/http/exception/414.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_414 extends Kohana_HTTP_Exception_414 {}
|
3
includes/kohana/system/classes/http/exception/415.php
Normal file
3
includes/kohana/system/classes/http/exception/415.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_415 extends Kohana_HTTP_Exception_415 {}
|
3
includes/kohana/system/classes/http/exception/416.php
Normal file
3
includes/kohana/system/classes/http/exception/416.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_416 extends Kohana_HTTP_Exception_416 {}
|
3
includes/kohana/system/classes/http/exception/417.php
Normal file
3
includes/kohana/system/classes/http/exception/417.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_417 extends Kohana_HTTP_Exception_417 {}
|
3
includes/kohana/system/classes/http/exception/500.php
Normal file
3
includes/kohana/system/classes/http/exception/500.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_500 extends Kohana_HTTP_Exception_500 {}
|
3
includes/kohana/system/classes/http/exception/501.php
Normal file
3
includes/kohana/system/classes/http/exception/501.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_501 extends Kohana_HTTP_Exception_501 {}
|
3
includes/kohana/system/classes/http/exception/502.php
Normal file
3
includes/kohana/system/classes/http/exception/502.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_502 extends Kohana_HTTP_Exception_502 {}
|
3
includes/kohana/system/classes/http/exception/503.php
Normal file
3
includes/kohana/system/classes/http/exception/503.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_503 extends Kohana_HTTP_Exception_503 {}
|
3
includes/kohana/system/classes/http/exception/504.php
Normal file
3
includes/kohana/system/classes/http/exception/504.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_504 extends Kohana_HTTP_Exception_504 {}
|
3
includes/kohana/system/classes/http/exception/505.php
Normal file
3
includes/kohana/system/classes/http/exception/505.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Exception_505 extends Kohana_HTTP_Exception_505 {}
|
3
includes/kohana/system/classes/http/header.php
Normal file
3
includes/kohana/system/classes/http/header.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Header extends Kohana_HTTP_Header {}
|
3
includes/kohana/system/classes/http/header/value.php
Normal file
3
includes/kohana/system/classes/http/header/value.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTTP_Header_Value extends Kohana_HTTP_Header_Value {}
|
3
includes/kohana/system/classes/http/interaction.php
Normal file
3
includes/kohana/system/classes/http/interaction.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
interface HTTP_Interaction extends Kohana_HTTP_Interaction {}
|
3
includes/kohana/system/classes/http/request.php
Normal file
3
includes/kohana/system/classes/http/request.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
interface HTTP_Request extends Kohana_HTTP_Request {}
|
3
includes/kohana/system/classes/http/response.php
Normal file
3
includes/kohana/system/classes/http/response.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
interface HTTP_Response extends Kohana_HTTP_Response {}
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Array helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Arr {
|
||||
@@ -190,6 +190,49 @@ class Kohana_Arr {
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value on an array by path.
|
||||
*
|
||||
* @see Arr::path()
|
||||
* @param array $array Array to update
|
||||
* @param string $path Path
|
||||
* @param mixed $value Value to set
|
||||
* @param string $delimiter Path delimiter
|
||||
*/
|
||||
public static function set_path( & $array, $path, $value, $delimiter = NULL)
|
||||
{
|
||||
if ( ! $delimiter)
|
||||
{
|
||||
// Use the default delimiter
|
||||
$delimiter = Arr::$delimiter;
|
||||
}
|
||||
|
||||
// Split the keys by delimiter
|
||||
$keys = explode($delimiter, $path);
|
||||
|
||||
// Set current $array to inner-most array path
|
||||
while (count($keys) > 1)
|
||||
{
|
||||
$key = array_shift($keys);
|
||||
|
||||
if (ctype_digit($key))
|
||||
{
|
||||
// Make the key an integer
|
||||
$key = (int) $key;
|
||||
}
|
||||
|
||||
if ( ! isset($array[$key]))
|
||||
{
|
||||
$array[$key] = array();
|
||||
}
|
||||
|
||||
$array = & $array[$key];
|
||||
}
|
||||
|
||||
// Set key on inner-most array
|
||||
$array[array_shift($keys)] = $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fill an array with a range of numbers.
|
||||
*
|
||||
@@ -285,27 +328,11 @@ class Kohana_Arr {
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary search algorithm.
|
||||
*
|
||||
* @deprecated Use [array_search](http://php.net/array_search) instead
|
||||
*
|
||||
* @param mixed the value to search for
|
||||
* @param array an array of values to search in
|
||||
* @param boolean sort the array now
|
||||
* @return integer the index of the match
|
||||
* @return FALSE no matching index found
|
||||
*/
|
||||
public static function binary_search($needle, $haystack, $sort = FALSE)
|
||||
{
|
||||
return array_search($needle, $haystack);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a value to the beginning of an associative array.
|
||||
*
|
||||
* // Add an empty value to the start of a select list
|
||||
* Arr::unshift_assoc($array, 'none', 'Select a value');
|
||||
* Arr::unshift($array, 'none', 'Select a value');
|
||||
*
|
||||
* @param array array to modify
|
||||
* @param string array key name
|
||||
@@ -437,7 +464,7 @@ class Kohana_Arr {
|
||||
* $array = Arr::overwrite($a1, $a2);
|
||||
*
|
||||
* // The output of $array will now be:
|
||||
* array('name' => 'jack', 'mood' => 'happy', 'food' => 'bacon')
|
||||
* array('name' => 'jack', 'mood' => 'happy', 'food' => 'tacos')
|
||||
*
|
||||
* @param array master array
|
||||
* @param array input arrays that will overwrite existing values
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_CLI {
|
||||
|
@@ -6,7 +6,7 @@
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config {
|
||||
@@ -17,21 +17,21 @@ class Kohana_Config {
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of Kohana_Config.
|
||||
* Get the singleton instance of Config.
|
||||
*
|
||||
* $config = Kohana_Config::instance();
|
||||
* $config = Config::instance();
|
||||
*
|
||||
* @return Kohana_Config
|
||||
* @return Config
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (self::$_instance === NULL)
|
||||
if (Config::$_instance === NULL)
|
||||
{
|
||||
// Create a new instance
|
||||
self::$_instance = new self;
|
||||
Config::$_instance = new Config;
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
return Config::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -47,11 +47,11 @@ class Kohana_Config {
|
||||
* $config->attach($reader); // Try first
|
||||
* $config->attach($reader, FALSE); // Try last
|
||||
*
|
||||
* @param object Kohana_Config_Reader instance
|
||||
* @param object Config_Reader instance
|
||||
* @param boolean add the reader as the first used object
|
||||
* @return $this
|
||||
*/
|
||||
public function attach(Kohana_Config_Reader $reader, $first = TRUE)
|
||||
public function attach(Config_Reader $reader, $first = TRUE)
|
||||
{
|
||||
if ($first === TRUE)
|
||||
{
|
||||
@@ -72,10 +72,10 @@ class Kohana_Config {
|
||||
*
|
||||
* $config->detach($reader);
|
||||
*
|
||||
* @param object Kohana_Config_Reader instance
|
||||
* @param object Config_Reader instance
|
||||
* @return $this
|
||||
*/
|
||||
public function detach(Kohana_Config_Reader $reader)
|
||||
public function detach(Config_Reader $reader)
|
||||
{
|
||||
if (($key = array_search($reader, $this->_readers)) !== FALSE)
|
||||
{
|
||||
@@ -94,7 +94,7 @@ class Kohana_Config {
|
||||
* $array = $config->load($name);
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @return object Kohana_Config_Reader
|
||||
* @return Config_Reader
|
||||
* @throws Kohana_Exception
|
||||
*/
|
||||
public function load($group)
|
||||
|
@@ -1,15 +1,15 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* File-based configuration reader. Multiple configuration directories can be
|
||||
* used by attaching multiple instances of this class to [Kohana_Config].
|
||||
* used by attaching multiple instances of this class to [Config].
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config_File extends Kohana_Config_Reader {
|
||||
class Kohana_Config_File extends Config_Reader {
|
||||
|
||||
/**
|
||||
* @var string Configuration group name
|
||||
@@ -57,4 +57,4 @@ class Kohana_Config_File extends Kohana_Config_Reader {
|
||||
return parent::load($group, $config);
|
||||
}
|
||||
|
||||
} // End Kohana_Config
|
||||
} // End Kohana_Config_File
|
||||
|
@@ -6,7 +6,7 @@
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Config_Reader extends ArrayObject {
|
||||
|
@@ -11,13 +11,13 @@
|
||||
* $controller->after();
|
||||
*
|
||||
* The controller action should add the output it creates to
|
||||
* `$this->request->response`, typically in the form of a [View], during the
|
||||
* `$this->response->body($output)`, typically in the form of a [View], during the
|
||||
* "action" part of execution.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller {
|
||||
@@ -27,17 +27,26 @@ abstract class Kohana_Controller {
|
||||
*/
|
||||
public $request;
|
||||
|
||||
/**
|
||||
* @var Response The response that will be returned from controller
|
||||
*/
|
||||
public $response;
|
||||
|
||||
/**
|
||||
* Creates a new controller instance. Each controller must be constructed
|
||||
* with the request object that created it.
|
||||
*
|
||||
* @param Request Request that created the controller
|
||||
* @param Request $request Request that created the controller
|
||||
* @param Response $response The request's response
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Request $request)
|
||||
public function __construct(Request $request, Response $response)
|
||||
{
|
||||
// Assign the request to the controller
|
||||
$this->request = $request;
|
||||
|
||||
// Assign a response to the controller
|
||||
$this->response = $response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -25,7 +25,7 @@
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller_REST extends Controller {
|
||||
@@ -35,10 +35,10 @@ abstract class Kohana_Controller_REST extends Controller {
|
||||
*/
|
||||
protected $_action_map = array
|
||||
(
|
||||
'GET' => 'index',
|
||||
'PUT' => 'update',
|
||||
'POST' => 'create',
|
||||
'DELETE' => 'delete',
|
||||
HTTP_Request::GET => 'index',
|
||||
HTTP_Request::PUT => 'update',
|
||||
HTTP_Request::POST => 'create',
|
||||
HTTP_Request::DELETE => 'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -53,28 +53,44 @@ abstract class Kohana_Controller_REST extends Controller {
|
||||
*/
|
||||
public function before()
|
||||
{
|
||||
$this->_action_requested = $this->request->action;
|
||||
$this->_action_requested = $this->request->action();
|
||||
|
||||
if ( ! isset($this->_action_map[Request::$method]))
|
||||
$method = Arr::get($_SERVER, 'HTTP_X_HTTP_METHOD_OVERRIDE', $this->request->method());
|
||||
|
||||
if ( ! isset($this->_action_map[$method]))
|
||||
{
|
||||
$this->request->action = 'invalid';
|
||||
$this->request->action('invalid');
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->request->action = $this->_action_map[Request::$method];
|
||||
$this->request->action($this->_action_map[$method]);
|
||||
}
|
||||
|
||||
return parent::before();
|
||||
}
|
||||
|
||||
/**
|
||||
* undocumented function
|
||||
*/
|
||||
public function after()
|
||||
{
|
||||
if (in_array(Arr::get($_SERVER, 'HTTP_X_HTTP_METHOD_OVERRIDE', $this->request->method()), array(
|
||||
HTTP_Request::PUT,
|
||||
HTTP_Request::POST,
|
||||
HTTP_Request::DELETE)))
|
||||
{
|
||||
$this->response->headers('cache-control', 'no-cache, no-store, max-age=0, must-revalidate');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a 405 "Method Not Allowed" response and a list of allowed actions.
|
||||
*/
|
||||
public function action_invalid()
|
||||
{
|
||||
// Send the "Method Not Allowed" response
|
||||
$this->request->status = 405;
|
||||
$this->request->headers['Allow'] = implode(', ', array_keys($this->_action_map));
|
||||
$this->response->status(405)
|
||||
->headers('Allow', implode(', ', array_keys($this->_action_map)));
|
||||
}
|
||||
|
||||
} // End REST
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller_Template extends Controller {
|
||||
@@ -41,7 +41,7 @@ abstract class Kohana_Controller_Template extends Controller {
|
||||
{
|
||||
if ($this->auto_render === TRUE)
|
||||
{
|
||||
$this->request->response = $this->template;
|
||||
$this->response->body($this->template->render());
|
||||
}
|
||||
|
||||
return parent::after();
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Cookie {
|
||||
@@ -13,7 +13,7 @@ class Kohana_Cookie {
|
||||
/**
|
||||
* @var string Magic salt to add to the cookie
|
||||
*/
|
||||
public static $salt = 'kooky';
|
||||
public static $salt = NULL;
|
||||
|
||||
/**
|
||||
* @var integer Number of seconds before the cookie expires
|
||||
@@ -132,7 +132,7 @@ class Kohana_Cookie {
|
||||
unset($_COOKIE[$name]);
|
||||
|
||||
// Nullify the cookie and make it expire
|
||||
return Cookie::set($name, NULL, -86400);
|
||||
return setcookie($name, NULL, -86400, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,6 +146,12 @@ class Kohana_Cookie {
|
||||
*/
|
||||
public static function salt($name, $value)
|
||||
{
|
||||
// Require a valid salt
|
||||
if ( ! Cookie::$salt)
|
||||
{
|
||||
throw new Kohana_Exception('A valid cookie salt is required. Please set Cookie::$salt.');
|
||||
}
|
||||
|
||||
// Determine the user agent
|
||||
$agent = isset($_SERVER['HTTP_USER_AGENT']) ? strtolower($_SERVER['HTTP_USER_AGENT']) : 'unknown';
|
||||
|
||||
|
@@ -10,28 +10,20 @@
|
||||
* @package Kohana
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Core {
|
||||
|
||||
// Release version and codename
|
||||
const VERSION = '3.0.8';
|
||||
const CODENAME = 'großen jäger';
|
||||
|
||||
// Log message types
|
||||
const ERROR = 'ERROR';
|
||||
const DEBUG = 'DEBUG';
|
||||
const INFO = 'INFO';
|
||||
const CRITICAL = 'CRITICAL';
|
||||
const STRACE = 'STRACE';
|
||||
const ALERT = 'ALERT';
|
||||
const VERSION = '3.1.3.1';
|
||||
const CODENAME = 'araea';
|
||||
|
||||
// Common environment type constants for consistency and convenience
|
||||
const PRODUCTION = 'production';
|
||||
const STAGING = 'staging';
|
||||
const TESTING = 'testing';
|
||||
const DEVELOPMENT = 'development';
|
||||
const PRODUCTION = 1;
|
||||
const STAGING = 2;
|
||||
const TESTING = 3;
|
||||
const DEVELOPMENT = 4;
|
||||
|
||||
// Security check that is added to all generated PHP files
|
||||
const FILE_SECURITY = '<?php defined(\'SYSPATH\') or die(\'No direct script access.\');';
|
||||
@@ -39,20 +31,6 @@ class Kohana_Core {
|
||||
// Format of cache files: header, cache name, and data
|
||||
const FILE_CACHE = ":header \n\n// :name\n\n:data\n";
|
||||
|
||||
/**
|
||||
* @var array Codes to turn PHP error codes into readable names.
|
||||
*/
|
||||
public static $php_errors = array(
|
||||
E_ERROR => 'Fatal Error',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_PARSE => 'Parse Error',
|
||||
E_WARNING => 'Warning',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_STRICT => 'Strict',
|
||||
E_NOTICE => 'Notice',
|
||||
E_RECOVERABLE_ERROR => 'Recoverable Error',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string Current environment name
|
||||
*/
|
||||
@@ -84,12 +62,27 @@ class Kohana_Core {
|
||||
public static $safe_mode = FALSE;
|
||||
|
||||
/**
|
||||
* @var string Character set of input and output. Set by [Kohana::init]
|
||||
* @var string
|
||||
*/
|
||||
public static $content_type = 'text/html';
|
||||
|
||||
/**
|
||||
* @var string character set of input and output
|
||||
*/
|
||||
public static $charset = 'utf-8';
|
||||
|
||||
/**
|
||||
* @var string Base URL to the application. Set by [Kohana::init]
|
||||
* @var string the name of the server Kohana is hosted upon
|
||||
*/
|
||||
public static $server_name = '';
|
||||
|
||||
/**
|
||||
* @var array list of valid host names for this instance
|
||||
*/
|
||||
public static $hostnames = array();
|
||||
|
||||
/**
|
||||
* @var string base URL to the application
|
||||
*/
|
||||
public static $base_url = '/';
|
||||
|
||||
@@ -123,28 +116,23 @@ class Kohana_Core {
|
||||
*/
|
||||
public static $errors = TRUE;
|
||||
|
||||
/**
|
||||
* @var string Error rendering view when Kohana catches PHP errors and exceptions. Set by [Kohana::init]
|
||||
*/
|
||||
public static $error_view = 'kohana/error';
|
||||
|
||||
/**
|
||||
* @var array Types of errors to display at shutdown
|
||||
*/
|
||||
public static $shutdown_errors = array(E_PARSE, E_ERROR, E_USER_ERROR);
|
||||
|
||||
/**
|
||||
* @var boolean escape quotes in Kohana::debug?
|
||||
* @var boolean set the X-Powered-By header
|
||||
*/
|
||||
public static $debug_escape_quotes = FALSE;
|
||||
public static $expose = FALSE;
|
||||
|
||||
/**
|
||||
* @var Kohana_Log logging object
|
||||
* @var Log logging object
|
||||
*/
|
||||
public static $log;
|
||||
|
||||
/**
|
||||
* @var Kohana_Config config object
|
||||
* @var Config config object
|
||||
*/
|
||||
public static $config;
|
||||
|
||||
@@ -192,9 +180,7 @@ class Kohana_Core {
|
||||
* `string` | cache_dir | Kohana's cache directory. Used by [Kohana::cache] for simple internal caching, like [Fragments](kohana/fragments) and **\[caching database queries](this should link somewhere)**. This has nothing to do with the [Cache module](cache). | `APPPATH."cache"`
|
||||
* `integer` | cache_life | Lifetime, in seconds, of items cached by [Kohana::cache] | `60`
|
||||
* `boolean` | errors | Should Kohana catch PHP errors and uncaught Exceptions and show the `error_view`. See [Error Handling](kohana/errors) for more info. <br /> <br /> Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE`
|
||||
* `string` | error_view | The view to use to display errors. Only used when `errors` is `TRUE`. | `"kohana/error"`
|
||||
* `boolean` | profile | Whether to enable the [Profiler](kohana/profiling). <br /> <br />Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE`
|
||||
* `boolean` | caching | Cache file locations to speed up [Kohana::find_file]. This has nothing to do with [Kohana::cache], [Fragments](kohana/fragments) or the [Cache module](cache). <br /> <br /> Recommended setting: `FALSE` while developing, `TRUE` on production servers. | `FALSE`
|
||||
* `boolean` | profile | Whether to enable the [Profiler](kohana/profiling). <br /> <br />Recommended setting: `TRUE` while developing, `FALSE` on production servers. | `TRUE` * `boolean` | caching | Cache file locations to speed up [Kohana::find_file]. This has nothing to do with [Kohana::cache], [Fragments](kohana/fragments) or the [Cache module](cache). <br /> <br /> Recommended setting: `FALSE` while developing, `TRUE` on production servers. | `FALSE`
|
||||
*
|
||||
* @throws Kohana_Exception
|
||||
* @param array Array of settings. See above.
|
||||
@@ -224,12 +210,6 @@ class Kohana_Core {
|
||||
// Start an output buffer
|
||||
ob_start();
|
||||
|
||||
if (defined('E_DEPRECATED'))
|
||||
{
|
||||
// E_DEPRECATED only exists in PHP >= 5.3.0
|
||||
Kohana::$php_errors[E_DEPRECATED] = 'Deprecated';
|
||||
}
|
||||
|
||||
if (isset($settings['errors']))
|
||||
{
|
||||
// Enable error handling
|
||||
@@ -239,7 +219,7 @@ class Kohana_Core {
|
||||
if (Kohana::$errors === TRUE)
|
||||
{
|
||||
// Enable Kohana exception handling, adds stack traces and error source.
|
||||
set_exception_handler(array('Kohana', 'exception_handler'));
|
||||
set_exception_handler(array('Kohana_Exception', 'handler'));
|
||||
|
||||
// Enable Kohana error handling, converts all PHP errors to exceptions.
|
||||
set_error_handler(array('Kohana', 'error_handler'));
|
||||
@@ -248,25 +228,17 @@ class Kohana_Core {
|
||||
// Enable the Kohana shutdown handler, which catches E_FATAL errors.
|
||||
register_shutdown_function(array('Kohana', 'shutdown_handler'));
|
||||
|
||||
if (isset($settings['error_view']))
|
||||
{
|
||||
if ( ! Kohana::find_file('views', $settings['error_view']))
|
||||
{
|
||||
throw new Kohana_Exception('Error view file does not exist: views/:file', array(
|
||||
':file' => $settings['error_view'],
|
||||
));
|
||||
}
|
||||
|
||||
// Change the default error rendering
|
||||
Kohana::$error_view = (string) $settings['error_view'];
|
||||
}
|
||||
|
||||
if (ini_get('register_globals'))
|
||||
{
|
||||
// Reverse the effects of register_globals
|
||||
Kohana::globals();
|
||||
}
|
||||
|
||||
if (isset($settings['expose']))
|
||||
{
|
||||
Kohana::$expose = (bool) $settings['expose'];
|
||||
}
|
||||
|
||||
// Determine if we are running in a command line environment
|
||||
Kohana::$is_cli = (PHP_SAPI === 'cli');
|
||||
|
||||
@@ -291,7 +263,7 @@ class Kohana_Core {
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw new Kohana_Exception('Could not create cache directory :dir',
|
||||
array(':dir' => Kohana::debug_path($settings['cache_dir'])));
|
||||
array(':dir' => Debug::path($settings['cache_dir'])));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -307,7 +279,7 @@ class Kohana_Core {
|
||||
if ( ! is_writable(Kohana::$cache_dir))
|
||||
{
|
||||
throw new Kohana_Exception('Directory :dir must be writable',
|
||||
array(':dir' => Kohana::debug_path(Kohana::$cache_dir)));
|
||||
array(':dir' => Debug::path(Kohana::$cache_dir)));
|
||||
}
|
||||
|
||||
if (isset($settings['cache_life']))
|
||||
@@ -361,10 +333,10 @@ class Kohana_Core {
|
||||
$_COOKIE = Kohana::sanitize($_COOKIE);
|
||||
|
||||
// Load the logger
|
||||
Kohana::$log = Kohana_Log::instance();
|
||||
Kohana::$log = Log::instance();
|
||||
|
||||
// Load the config
|
||||
Kohana::$config = Kohana_Config::instance();
|
||||
Kohana::$config = Config::instance();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,7 +504,7 @@ class Kohana_Core {
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
Kohana::exception_handler($e);
|
||||
Kohana_Exception::handler($e);
|
||||
die;
|
||||
}
|
||||
}
|
||||
@@ -655,10 +627,10 @@ class Kohana_Core {
|
||||
// Create a partial path of the filename
|
||||
$path = $dir.DIRECTORY_SEPARATOR.$file.$ext;
|
||||
|
||||
if (Kohana::$caching === TRUE AND isset(Kohana::$_files[$path]))
|
||||
if (Kohana::$caching === TRUE AND isset(Kohana::$_files[$path.($array ? '_array' : '_path')]))
|
||||
{
|
||||
// This path has been cached
|
||||
return Kohana::$_files[$path];
|
||||
return Kohana::$_files[$path.($array ? '_array' : '_path')];
|
||||
}
|
||||
|
||||
if (Kohana::$profiling === TRUE AND class_exists('Profiler', FALSE))
|
||||
@@ -705,7 +677,7 @@ class Kohana_Core {
|
||||
if (Kohana::$caching === TRUE)
|
||||
{
|
||||
// Add the path to the cache
|
||||
Kohana::$_files[$path] = $found;
|
||||
Kohana::$_files[$path.($array ? '_array' : '_path')] = $found;
|
||||
|
||||
// Files have been changed
|
||||
Kohana::$_files_changed = TRUE;
|
||||
@@ -831,7 +803,7 @@ class Kohana_Core {
|
||||
* $host = Kohana::config('database.default.connection.hostname')
|
||||
*
|
||||
* @param string group name
|
||||
* @return Kohana_Config
|
||||
* @return Config
|
||||
*/
|
||||
public static function config($group)
|
||||
{
|
||||
@@ -1024,108 +996,10 @@ class Kohana_Core {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline exception handler, displays the error message, source of the
|
||||
* exception, and the stack trace of the error.
|
||||
*
|
||||
* @uses Kohana::exception_text
|
||||
* @param object exception object
|
||||
* @return boolean
|
||||
*/
|
||||
public static function exception_handler(Exception $e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the exception information
|
||||
$type = get_class($e);
|
||||
$code = $e->getCode();
|
||||
$message = $e->getMessage();
|
||||
$file = $e->getFile();
|
||||
$line = $e->getLine();
|
||||
|
||||
// Create a text version of the exception
|
||||
$error = Kohana::exception_text($e);
|
||||
|
||||
if (is_object(Kohana::$log))
|
||||
{
|
||||
// Add this exception to the log
|
||||
Kohana::$log->add(Kohana::ERROR, $error);
|
||||
|
||||
// Make sure the logs are written
|
||||
Kohana::$log->write();
|
||||
}
|
||||
|
||||
if (Kohana::$is_cli)
|
||||
{
|
||||
// Just display the text of the exception
|
||||
echo "\n{$error}\n";
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
// Get the exception backtrace
|
||||
$trace = $e->getTrace();
|
||||
|
||||
if ($e instanceof ErrorException)
|
||||
{
|
||||
if (isset(Kohana::$php_errors[$code]))
|
||||
{
|
||||
// Use the human-readable error name
|
||||
$code = Kohana::$php_errors[$code];
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3', '<'))
|
||||
{
|
||||
// Workaround for a bug in ErrorException::getTrace() that exists in
|
||||
// all PHP 5.2 versions. @see http://bugs.php.net/bug.php?id=45895
|
||||
for ($i = count($trace) - 1; $i > 0; --$i)
|
||||
{
|
||||
if (isset($trace[$i - 1]['args']))
|
||||
{
|
||||
// Re-position the args
|
||||
$trace[$i]['args'] = $trace[$i - 1]['args'];
|
||||
|
||||
// Remove the args
|
||||
unset($trace[$i - 1]['args']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
// Make sure the proper content type is sent with a 500 status
|
||||
header('Content-Type: text/html; charset='.Kohana::$charset, TRUE, 500);
|
||||
}
|
||||
|
||||
// Start an output buffer
|
||||
ob_start();
|
||||
|
||||
// Include the exception HTML
|
||||
include Kohana::find_file('views', Kohana::$error_view);
|
||||
|
||||
// Display the contents of the output buffer
|
||||
echo ob_get_clean();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Clean the output buffer if one exists
|
||||
ob_get_level() and ob_clean();
|
||||
|
||||
// Display the exception text
|
||||
echo Kohana::exception_text($e), "\n";
|
||||
|
||||
// Exit with an error status
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Catches errors that are not caught by the error handler, such as E_PARSE.
|
||||
*
|
||||
* @uses Kohana::exception_handler
|
||||
* @uses Kohana_Exception::handler
|
||||
* @return void
|
||||
*/
|
||||
public static function shutdown_handler()
|
||||
@@ -1147,7 +1021,7 @@ class Kohana_Core {
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Pass the exception to the handler
|
||||
Kohana::exception_handler($e);
|
||||
Kohana_Exception::handler($e);
|
||||
}
|
||||
|
||||
if (Kohana::$errors AND $error = error_get_last() AND in_array($error['type'], Kohana::$shutdown_errors))
|
||||
@@ -1156,482 +1030,11 @@ class Kohana_Core {
|
||||
ob_get_level() and ob_clean();
|
||||
|
||||
// Fake an exception for nice debugging
|
||||
Kohana::exception_handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
|
||||
Kohana_Exception::handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line']));
|
||||
|
||||
// Shutdown now to avoid a "death loop"
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single line of text representing the exception:
|
||||
*
|
||||
* Error [ Code ]: Message ~ File [ Line ]
|
||||
*
|
||||
* @param object Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function exception_text(Exception $e)
|
||||
{
|
||||
return sprintf('%s [ %s ]: %s ~ %s [ %d ]',
|
||||
get_class($e), $e->getCode(), strip_tags($e->getMessage()), Kohana::debug_path($e->getFile()), $e->getLine());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string of debugging information about any number of
|
||||
* variables, each wrapped in a "pre" tag:
|
||||
*
|
||||
* // Displays the type and value of each variable
|
||||
* echo Kohana::debug($foo, $bar, $baz);
|
||||
*
|
||||
* @param mixed variable to debug
|
||||
* @param ...
|
||||
* @return string
|
||||
*/
|
||||
public static function debug()
|
||||
{
|
||||
if (func_num_args() === 0)
|
||||
return;
|
||||
|
||||
// Get all passed variables
|
||||
$variables = func_get_args();
|
||||
|
||||
$output = array();
|
||||
foreach ($variables as $var)
|
||||
{
|
||||
$output[] = Kohana::_dump($var, 1024);
|
||||
}
|
||||
|
||||
return '<pre class="debug">'.implode("\n", $output).'</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string of information about a single variable.
|
||||
*
|
||||
* Borrows heavily on concepts from the Debug class of [Nette](http://nettephp.com/).
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @return string
|
||||
*/
|
||||
public static function dump($value, $length = 128)
|
||||
{
|
||||
return Kohana::_dump($value, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for Kohana::dump(), handles recursion in arrays and objects.
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @param integer recursion level (internal)
|
||||
* @return string
|
||||
*/
|
||||
protected static function _dump( & $var, $length = 128, $level = 0)
|
||||
{
|
||||
if ($var === NULL)
|
||||
{
|
||||
return '<small>NULL</small>';
|
||||
}
|
||||
elseif (is_bool($var))
|
||||
{
|
||||
return '<small>bool</small> '.($var ? 'TRUE' : 'FALSE');
|
||||
}
|
||||
elseif (is_float($var))
|
||||
{
|
||||
return '<small>float</small> '.$var;
|
||||
}
|
||||
elseif (is_resource($var))
|
||||
{
|
||||
if (($type = get_resource_type($var)) === 'stream' AND $meta = stream_get_meta_data($var))
|
||||
{
|
||||
$meta = stream_get_meta_data($var);
|
||||
|
||||
if (isset($meta['uri']))
|
||||
{
|
||||
$file = $meta['uri'];
|
||||
|
||||
if (function_exists('stream_is_local'))
|
||||
{
|
||||
// Only exists on PHP >= 5.2.4
|
||||
if (stream_is_local($file))
|
||||
{
|
||||
$file = Kohana::debug_path($file);
|
||||
}
|
||||
}
|
||||
|
||||
return '<small>resource</small><span>('.$type.')</span> '.htmlspecialchars($file, ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>resource</small><span>('.$type.')</span>';
|
||||
}
|
||||
}
|
||||
elseif (is_string($var))
|
||||
{
|
||||
// Clean invalid multibyte characters. iconv is only invoked
|
||||
// if there are non ASCII characters in the string, so this
|
||||
// isn't too much of a hit.
|
||||
$var = UTF8::clean($var, Kohana::$charset);
|
||||
|
||||
if (UTF8::strlen($var) > $length)
|
||||
{
|
||||
// Encode the truncated string
|
||||
$str = htmlspecialchars(UTF8::substr($var, 0, $length), ENT_NOQUOTES, Kohana::$charset).' …';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Encode the string
|
||||
$str = htmlspecialchars($var, ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
|
||||
if (Kohana::$debug_escape_quotes)
|
||||
{
|
||||
// Escape strings (for syntax highlighters, mostly)
|
||||
$str = str_replace('"', '\\"', $str);
|
||||
}
|
||||
|
||||
return '<small>string</small><span>('.strlen($var).')</span> "'.$str.'"';
|
||||
}
|
||||
elseif (is_array($var))
|
||||
{
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
static $marker;
|
||||
|
||||
if ($marker === NULL)
|
||||
{
|
||||
// Make a unique marker
|
||||
$marker = uniqid("\x00");
|
||||
}
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($var[$marker]))
|
||||
{
|
||||
$output[] = "(\n$space$s*RECURSION*\n$space)";
|
||||
}
|
||||
elseif ($level < 5)
|
||||
{
|
||||
$output[] = "<span>(";
|
||||
|
||||
$var[$marker] = TRUE;
|
||||
foreach ($var as $key => & $val)
|
||||
{
|
||||
if ($key === $marker) continue;
|
||||
if ( ! is_int($key))
|
||||
{
|
||||
$key = '"'.htmlspecialchars($key, ENT_NOQUOTES, self::$charset).'"';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$key => ".Kohana::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($var[$marker]);
|
||||
|
||||
$output[] = "$space)</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "(\n$space$s...\n$space)";
|
||||
}
|
||||
|
||||
return '<small>array</small><span>('.count($var).')</span> '.implode("\n", $output);
|
||||
}
|
||||
elseif (is_object($var))
|
||||
{
|
||||
// Copy the object as an array
|
||||
$array = (array) $var;
|
||||
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
$hash = spl_object_hash($var);
|
||||
|
||||
// Objects that are being dumped
|
||||
static $objects = array();
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($objects[$hash]))
|
||||
{
|
||||
$output[] = "{\n$space$s*RECURSION*\n$space}";
|
||||
}
|
||||
elseif ($level < 10)
|
||||
{
|
||||
$output[] = "<code>{";
|
||||
|
||||
$objects[$hash] = TRUE;
|
||||
foreach ($array as $key => & $val)
|
||||
{
|
||||
if ($key[0] === "\x00")
|
||||
{
|
||||
// Determine if the access is protected or protected
|
||||
$access = '<small>'.(($key[1] === '*') ? 'protected' : 'private').'</small>';
|
||||
|
||||
// Remove the access level from the variable name
|
||||
$key = substr($key, strrpos($key, "\x00") + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$access = '<small>public</small>';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$access $key => ".Kohana::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($objects[$hash]);
|
||||
|
||||
$output[] = "$space}</code>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "{\n$space$s...\n$space}";
|
||||
}
|
||||
|
||||
return '<small>object</small> <span>'.get_class($var).'('.count($array).')</span> '.implode("\n", $output);
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>'.gettype($var).'</small> '.htmlspecialchars(print_r($var, TRUE), ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes application, system, modpath, or docroot from a filename,
|
||||
* replacing them with the plain text equivalents. Useful for debugging
|
||||
* when you want to display a shorter path.
|
||||
*
|
||||
* // Displays SYSPATH/classes/kohana.php
|
||||
* echo Kohana::debug_path(Kohana::find_file('classes', 'kohana'));
|
||||
*
|
||||
* @param string path to debug
|
||||
* @return string
|
||||
*/
|
||||
public static function debug_path($file)
|
||||
{
|
||||
if (strpos($file, APPPATH) === 0)
|
||||
{
|
||||
$file = 'APPPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(APPPATH));
|
||||
}
|
||||
elseif (strpos($file, SYSPATH) === 0)
|
||||
{
|
||||
$file = 'SYSPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(SYSPATH));
|
||||
}
|
||||
elseif (strpos($file, MODPATH) === 0)
|
||||
{
|
||||
$file = 'MODPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(MODPATH));
|
||||
}
|
||||
elseif (strpos($file, DOCROOT) === 0)
|
||||
{
|
||||
$file = 'DOCROOT'.DIRECTORY_SEPARATOR.substr($file, strlen(DOCROOT));
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string, highlighting a specific line of a file, with some
|
||||
* number of lines padded above and below.
|
||||
*
|
||||
* // Highlights the current line of the current file
|
||||
* echo Kohana::debug_source(__FILE__, __LINE__);
|
||||
*
|
||||
* @param string file to open
|
||||
* @param integer line number to highlight
|
||||
* @param integer number of padding lines
|
||||
* @return string source of file
|
||||
* @return FALSE file is unreadable
|
||||
*/
|
||||
public static function debug_source($file, $line_number, $padding = 5)
|
||||
{
|
||||
if ( ! $file OR ! is_readable($file))
|
||||
{
|
||||
// Continuing will cause errors
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Open the file and set the line position
|
||||
$file = fopen($file, 'r');
|
||||
$line = 0;
|
||||
|
||||
// Set the reading range
|
||||
$range = array('start' => $line_number - $padding, 'end' => $line_number + $padding);
|
||||
|
||||
// Set the zero-padding amount for line numbers
|
||||
$format = '% '.strlen($range['end']).'d';
|
||||
|
||||
$source = '';
|
||||
while (($row = fgets($file)) !== FALSE)
|
||||
{
|
||||
// Increment the line number
|
||||
if (++$line > $range['end'])
|
||||
break;
|
||||
|
||||
if ($line >= $range['start'])
|
||||
{
|
||||
// Make the row safe for output
|
||||
$row = htmlspecialchars($row, ENT_NOQUOTES, Kohana::$charset);
|
||||
|
||||
// Trim whitespace and sanitize the row
|
||||
$row = '<span class="number">'.sprintf($format, $line).'</span> '.$row;
|
||||
|
||||
if ($line === $line_number)
|
||||
{
|
||||
// Apply highlighting to this row
|
||||
$row = '<span class="line highlight">'.$row.'</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$row = '<span class="line">'.$row.'</span>';
|
||||
}
|
||||
|
||||
// Add to the captured source
|
||||
$source .= $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the file
|
||||
fclose($file);
|
||||
|
||||
return '<pre class="source"><code>'.$source.'</code></pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of HTML strings that represent each step in the backtrace.
|
||||
*
|
||||
* // Displays the entire current backtrace
|
||||
* echo implode('<br/>', Kohana::trace());
|
||||
*
|
||||
* @param string path to debug
|
||||
* @return string
|
||||
*/
|
||||
public static function trace(array $trace = NULL)
|
||||
{
|
||||
if ($trace === NULL)
|
||||
{
|
||||
// Start a new trace
|
||||
$trace = debug_backtrace();
|
||||
}
|
||||
|
||||
// Non-standard function calls
|
||||
$statements = array('include', 'include_once', 'require', 'require_once');
|
||||
|
||||
$output = array();
|
||||
foreach ($trace as $step)
|
||||
{
|
||||
if ( ! isset($step['function']))
|
||||
{
|
||||
// Invalid trace step
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($step['file']) AND isset($step['line']))
|
||||
{
|
||||
// Include the source of this step
|
||||
$source = Kohana::debug_source($step['file'], $step['line']);
|
||||
}
|
||||
|
||||
if (isset($step['file']))
|
||||
{
|
||||
$file = $step['file'];
|
||||
|
||||
if (isset($step['line']))
|
||||
{
|
||||
$line = $step['line'];
|
||||
}
|
||||
}
|
||||
|
||||
// function()
|
||||
$function = $step['function'];
|
||||
|
||||
if (in_array($step['function'], $statements))
|
||||
{
|
||||
if (empty($step['args']))
|
||||
{
|
||||
// No arguments
|
||||
$args = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sanitize the file path
|
||||
$args = array(Kohana::debug_path($step['args'][0]));
|
||||
}
|
||||
}
|
||||
elseif (isset($step['args']))
|
||||
{
|
||||
if ( ! function_exists($step['function']) OR strpos($step['function'], '{closure}') !== FALSE)
|
||||
{
|
||||
// Introspection on closures or language constructs in a stack trace is impossible
|
||||
$params = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($step['class']))
|
||||
{
|
||||
if (method_exists($step['class'], $step['function']))
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], $step['function']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], '__call');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionFunction($step['function']);
|
||||
}
|
||||
|
||||
// Get the function parameters
|
||||
$params = $reflection->getParameters();
|
||||
}
|
||||
|
||||
$args = array();
|
||||
|
||||
foreach ($step['args'] as $i => $arg)
|
||||
{
|
||||
if (isset($params[$i]))
|
||||
{
|
||||
// Assign the argument by the parameter name
|
||||
$args[$params[$i]->name] = $arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assign the argument by number
|
||||
$args[$i] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($step['class']))
|
||||
{
|
||||
// Class->method() or Class::method()
|
||||
$function = $step['class'].$step['type'].$step['function'];
|
||||
}
|
||||
|
||||
$output[] = array(
|
||||
'function' => $function,
|
||||
'args' => isset($args) ? $args : NULL,
|
||||
'file' => isset($file) ? $file : NULL,
|
||||
'line' => isset($line) ? $line : NULL,
|
||||
'source' => isset($source) ? $source : NULL,
|
||||
);
|
||||
|
||||
unset($function, $args, $file, $line, $source);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
} // End Kohana
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Date {
|
||||
@@ -18,6 +18,10 @@ class Kohana_Date {
|
||||
const HOUR = 3600;
|
||||
const MINUTE = 60;
|
||||
|
||||
// Available formats for Date::months()
|
||||
const MONTHS_LONG = '%B';
|
||||
const MONTHS_SHORT = '%b';
|
||||
|
||||
/**
|
||||
* Default timestamp format for formatted_time
|
||||
* @var string
|
||||
@@ -250,14 +254,42 @@ class Kohana_Date {
|
||||
* Number of months in a year. Typically used as a shortcut for generating
|
||||
* a list that can be used in a form.
|
||||
*
|
||||
* Date::months(); // 01, 02, 03, ..., 10, 11, 12
|
||||
* By default a mirrored array of $month_number => $month_number is returned
|
||||
*
|
||||
* Date::months();
|
||||
* // aray(1 => 1, 2 => 2, 3 => 3, ..., 12 => 12)
|
||||
*
|
||||
* But you can customise this by passing in either Date::MONTHS_LONG
|
||||
*
|
||||
* Date::months(Date::MONTHS_LONG);
|
||||
* // array(1 => 'January', 2 => 'February', ..., 12 => 'December')
|
||||
*
|
||||
* Or Date::MONTHS_SHORT
|
||||
*
|
||||
* Date::months(Date::MONTHS_SHORT);
|
||||
* // array(1 => 'Jan', 2 => 'Feb', ..., 12 => 'Dec')
|
||||
*
|
||||
* @uses Date::hours
|
||||
* @return array A mirrored (foo => foo) array from 1-12.
|
||||
* @param string The format to use for months
|
||||
* @return array An array of months based on the specified format
|
||||
*/
|
||||
public static function months()
|
||||
public static function months($format = NULL)
|
||||
{
|
||||
return Date::hours();
|
||||
$months = array();
|
||||
|
||||
if ($format === DATE::MONTHS_LONG OR $format === DATE::MONTHS_SHORT)
|
||||
{
|
||||
for ($i = 1; $i <= 12; ++$i)
|
||||
{
|
||||
$months[$i] = strftime($format, mktime(0, 0, 0, $i, 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$months = Date::hours();
|
||||
}
|
||||
|
||||
return $months;
|
||||
}
|
||||
|
||||
/**
|
||||
|
468
includes/kohana/system/classes/kohana/debug.php
Normal file
468
includes/kohana/system/classes/kohana/debug.php
Normal file
@@ -0,0 +1,468 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Contains debugging and dumping tools.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Debug {
|
||||
|
||||
/**
|
||||
* Returns an HTML string of debugging information about any number of
|
||||
* variables, each wrapped in a "pre" tag:
|
||||
*
|
||||
* // Displays the type and value of each variable
|
||||
* echo Debug::vars($foo, $bar, $baz);
|
||||
*
|
||||
* @param mixed variable to debug
|
||||
* @param ...
|
||||
* @return string
|
||||
*/
|
||||
public static function vars()
|
||||
{
|
||||
if (func_num_args() === 0)
|
||||
return;
|
||||
|
||||
// Get all passed variables
|
||||
$variables = func_get_args();
|
||||
|
||||
$output = array();
|
||||
foreach ($variables as $var)
|
||||
{
|
||||
$output[] = Debug::_dump($var, 1024);
|
||||
}
|
||||
|
||||
return '<pre class="debug">'.implode("\n", $output).'</pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string of information about a single variable.
|
||||
*
|
||||
* Borrows heavily on concepts from the Debug class of [Nette](http://nettephp.com/).
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @return string
|
||||
*/
|
||||
public static function dump($value, $length = 128)
|
||||
{
|
||||
return Debug::_dump($value, $length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper for Debug::dump(), handles recursion in arrays and objects.
|
||||
*
|
||||
* @param mixed variable to dump
|
||||
* @param integer maximum length of strings
|
||||
* @param integer recursion level (internal)
|
||||
* @return string
|
||||
*/
|
||||
protected static function _dump( & $var, $length = 128, $level = 0)
|
||||
{
|
||||
if ($var === NULL)
|
||||
{
|
||||
return '<small>NULL</small>';
|
||||
}
|
||||
elseif (is_bool($var))
|
||||
{
|
||||
return '<small>bool</small> '.($var ? 'TRUE' : 'FALSE');
|
||||
}
|
||||
elseif (is_float($var))
|
||||
{
|
||||
return '<small>float</small> '.$var;
|
||||
}
|
||||
elseif (is_resource($var))
|
||||
{
|
||||
if (($type = get_resource_type($var)) === 'stream' AND $meta = stream_get_meta_data($var))
|
||||
{
|
||||
$meta = stream_get_meta_data($var);
|
||||
|
||||
if (isset($meta['uri']))
|
||||
{
|
||||
$file = $meta['uri'];
|
||||
|
||||
if (function_exists('stream_is_local'))
|
||||
{
|
||||
// Only exists on PHP >= 5.2.4
|
||||
if (stream_is_local($file))
|
||||
{
|
||||
$file = Debug::path($file);
|
||||
}
|
||||
}
|
||||
|
||||
return '<small>resource</small><span>('.$type.')</span> '.htmlspecialchars($file, ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>resource</small><span>('.$type.')</span>';
|
||||
}
|
||||
}
|
||||
elseif (is_string($var))
|
||||
{
|
||||
// Clean invalid multibyte characters. iconv is only invoked
|
||||
// if there are non ASCII characters in the string, so this
|
||||
// isn't too much of a hit.
|
||||
$var = UTF8::clean($var, Kohana::$charset);
|
||||
|
||||
if (UTF8::strlen($var) > $length)
|
||||
{
|
||||
// Encode the truncated string
|
||||
$str = htmlspecialchars(UTF8::substr($var, 0, $length), ENT_NOQUOTES, Kohana::$charset).' …';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Encode the string
|
||||
$str = htmlspecialchars($var, ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
|
||||
return '<small>string</small><span>('.strlen($var).')</span> "'.$str.'"';
|
||||
}
|
||||
elseif (is_array($var))
|
||||
{
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
static $marker;
|
||||
|
||||
if ($marker === NULL)
|
||||
{
|
||||
// Make a unique marker
|
||||
$marker = uniqid("\x00");
|
||||
}
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($var[$marker]))
|
||||
{
|
||||
$output[] = "(\n$space$s*RECURSION*\n$space)";
|
||||
}
|
||||
elseif ($level < 5)
|
||||
{
|
||||
$output[] = "<span>(";
|
||||
|
||||
$var[$marker] = TRUE;
|
||||
foreach ($var as $key => & $val)
|
||||
{
|
||||
if ($key === $marker) continue;
|
||||
if ( ! is_int($key))
|
||||
{
|
||||
$key = '"'.htmlspecialchars($key, ENT_NOQUOTES, Kohana::$charset).'"';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$key => ".Debug::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($var[$marker]);
|
||||
|
||||
$output[] = "$space)</span>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "(\n$space$s...\n$space)";
|
||||
}
|
||||
|
||||
return '<small>array</small><span>('.count($var).')</span> '.implode("\n", $output);
|
||||
}
|
||||
elseif (is_object($var))
|
||||
{
|
||||
// Copy the object as an array
|
||||
$array = (array) $var;
|
||||
|
||||
$output = array();
|
||||
|
||||
// Indentation for this variable
|
||||
$space = str_repeat($s = ' ', $level);
|
||||
|
||||
$hash = spl_object_hash($var);
|
||||
|
||||
// Objects that are being dumped
|
||||
static $objects = array();
|
||||
|
||||
if (empty($var))
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
elseif (isset($objects[$hash]))
|
||||
{
|
||||
$output[] = "{\n$space$s*RECURSION*\n$space}";
|
||||
}
|
||||
elseif ($level < 10)
|
||||
{
|
||||
$output[] = "<code>{";
|
||||
|
||||
$objects[$hash] = TRUE;
|
||||
foreach ($array as $key => & $val)
|
||||
{
|
||||
if ($key[0] === "\x00")
|
||||
{
|
||||
// Determine if the access is protected or protected
|
||||
$access = '<small>'.(($key[1] === '*') ? 'protected' : 'private').'</small>';
|
||||
|
||||
// Remove the access level from the variable name
|
||||
$key = substr($key, strrpos($key, "\x00") + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
$access = '<small>public</small>';
|
||||
}
|
||||
|
||||
$output[] = "$space$s$access $key => ".Debug::_dump($val, $length, $level + 1);
|
||||
}
|
||||
unset($objects[$hash]);
|
||||
|
||||
$output[] = "$space}</code>";
|
||||
}
|
||||
else
|
||||
{
|
||||
// Depth too great
|
||||
$output[] = "{\n$space$s...\n$space}";
|
||||
}
|
||||
|
||||
return '<small>object</small> <span>'.get_class($var).'('.count($array).')</span> '.implode("\n", $output);
|
||||
}
|
||||
else
|
||||
{
|
||||
return '<small>'.gettype($var).'</small> '.htmlspecialchars(print_r($var, TRUE), ENT_NOQUOTES, Kohana::$charset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes application, system, modpath, or docroot from a filename,
|
||||
* replacing them with the plain text equivalents. Useful for debugging
|
||||
* when you want to display a shorter path.
|
||||
*
|
||||
* // Displays SYSPATH/classes/kohana.php
|
||||
* echo Debug::path(Kohana::find_file('classes', 'kohana'));
|
||||
*
|
||||
* @param string path to debug
|
||||
* @return string
|
||||
*/
|
||||
public static function path($file)
|
||||
{
|
||||
if (strpos($file, APPPATH) === 0)
|
||||
{
|
||||
$file = 'APPPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(APPPATH));
|
||||
}
|
||||
elseif (strpos($file, MODPATH) === 0)
|
||||
{
|
||||
$file = 'MODPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(MODPATH));
|
||||
}
|
||||
elseif (strpos($file, SYSPATH) === 0)
|
||||
{
|
||||
$file = 'SYSPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(SYSPATH));
|
||||
}
|
||||
elseif (strpos($file, SMDPATH) === 0)
|
||||
{
|
||||
$file = 'SMDPATH'.DIRECTORY_SEPARATOR.substr($file, strlen(SMDPATH));
|
||||
}
|
||||
elseif (strpos($file, DOCROOT) === 0)
|
||||
{
|
||||
$file = 'DOCROOT'.DIRECTORY_SEPARATOR.substr($file, strlen(DOCROOT));
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an HTML string, highlighting a specific line of a file, with some
|
||||
* number of lines padded above and below.
|
||||
*
|
||||
* // Highlights the current line of the current file
|
||||
* echo Debug::source(__FILE__, __LINE__);
|
||||
*
|
||||
* @param string file to open
|
||||
* @param integer line number to highlight
|
||||
* @param integer number of padding lines
|
||||
* @return string source of file
|
||||
* @return FALSE file is unreadable
|
||||
*/
|
||||
public static function source($file, $line_number, $padding = 5)
|
||||
{
|
||||
if ( ! $file OR ! is_readable($file))
|
||||
{
|
||||
// Continuing will cause errors
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Open the file and set the line position
|
||||
$file = fopen($file, 'r');
|
||||
$line = 0;
|
||||
|
||||
// Set the reading range
|
||||
$range = array('start' => $line_number - $padding, 'end' => $line_number + $padding);
|
||||
|
||||
// Set the zero-padding amount for line numbers
|
||||
$format = '% '.strlen($range['end']).'d';
|
||||
|
||||
$source = '';
|
||||
while (($row = fgets($file)) !== FALSE)
|
||||
{
|
||||
// Increment the line number
|
||||
if (++$line > $range['end'])
|
||||
break;
|
||||
|
||||
if ($line >= $range['start'])
|
||||
{
|
||||
// Make the row safe for output
|
||||
$row = htmlspecialchars($row, ENT_NOQUOTES, Kohana::$charset);
|
||||
|
||||
// Trim whitespace and sanitize the row
|
||||
$row = '<span class="number">'.sprintf($format, $line).'</span> '.$row;
|
||||
|
||||
if ($line === $line_number)
|
||||
{
|
||||
// Apply highlighting to this row
|
||||
$row = '<span class="line highlight">'.$row.'</span>';
|
||||
}
|
||||
else
|
||||
{
|
||||
$row = '<span class="line">'.$row.'</span>';
|
||||
}
|
||||
|
||||
// Add to the captured source
|
||||
$source .= $row;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the file
|
||||
fclose($file);
|
||||
|
||||
return '<pre class="source"><code>'.$source.'</code></pre>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of HTML strings that represent each step in the backtrace.
|
||||
*
|
||||
* // Displays the entire current backtrace
|
||||
* echo implode('<br/>', Debug::trace());
|
||||
*
|
||||
* @param string path to debug
|
||||
* @return string
|
||||
*/
|
||||
public static function trace(array $trace = NULL)
|
||||
{
|
||||
if ($trace === NULL)
|
||||
{
|
||||
// Start a new trace
|
||||
$trace = debug_backtrace();
|
||||
}
|
||||
|
||||
// Non-standard function calls
|
||||
$statements = array('include', 'include_once', 'require', 'require_once');
|
||||
|
||||
$output = array();
|
||||
foreach ($trace as $step)
|
||||
{
|
||||
if ( ! isset($step['function']))
|
||||
{
|
||||
// Invalid trace step
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($step['file']) AND isset($step['line']))
|
||||
{
|
||||
// Include the source of this step
|
||||
$source = Debug::source($step['file'], $step['line']);
|
||||
}
|
||||
|
||||
if (isset($step['file']))
|
||||
{
|
||||
$file = $step['file'];
|
||||
|
||||
if (isset($step['line']))
|
||||
{
|
||||
$line = $step['line'];
|
||||
}
|
||||
}
|
||||
|
||||
// function()
|
||||
$function = $step['function'];
|
||||
|
||||
if (in_array($step['function'], $statements))
|
||||
{
|
||||
if (empty($step['args']))
|
||||
{
|
||||
// No arguments
|
||||
$args = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Sanitize the file path
|
||||
$args = array($step['args'][0]);
|
||||
}
|
||||
}
|
||||
elseif (isset($step['args']))
|
||||
{
|
||||
if ( ! function_exists($step['function']) OR strpos($step['function'], '{closure}') !== FALSE)
|
||||
{
|
||||
// Introspection on closures or language constructs in a stack trace is impossible
|
||||
$params = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isset($step['class']))
|
||||
{
|
||||
if (method_exists($step['class'], $step['function']))
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], $step['function']);
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionMethod($step['class'], '__call');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$reflection = new ReflectionFunction($step['function']);
|
||||
}
|
||||
|
||||
// Get the function parameters
|
||||
$params = $reflection->getParameters();
|
||||
}
|
||||
|
||||
$args = array();
|
||||
|
||||
foreach ($step['args'] as $i => $arg)
|
||||
{
|
||||
if (isset($params[$i]))
|
||||
{
|
||||
// Assign the argument by the parameter name
|
||||
$args[$params[$i]->name] = $arg;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Assign the argument by number
|
||||
$args[$i] = $arg;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($step['class']))
|
||||
{
|
||||
// Class->method() or Class::method()
|
||||
$function = $step['class'].$step['type'].$step['function'];
|
||||
}
|
||||
|
||||
$output[] = array(
|
||||
'function' => $function,
|
||||
'args' => isset($args) ? $args : NULL,
|
||||
'file' => isset($file) ? $file : NULL,
|
||||
'line' => isset($line) ? $line : NULL,
|
||||
'source' => isset($source) ? $source : NULL,
|
||||
);
|
||||
|
||||
unset($function, $args, $file, $line, $source);
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
}
|
@@ -1,4 +1,4 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* The Encrypt library provides two-way encryption of text and binary strings
|
||||
* using the [Mcrypt](http://php.net/mcrypt) extension, which consists of three
|
||||
@@ -20,7 +20,7 @@
|
||||
* @package Kohana
|
||||
* @category Security
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Encrypt {
|
||||
|
@@ -1,46 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct access');
|
||||
/**
|
||||
* Kohana exception class. Translates exceptions using the [I18n] class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Exceptions
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Exception extends Exception {
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* throw new Kohana_Exception('Something went terrible wrong, :user',
|
||||
* array(':user' => $user));
|
||||
*
|
||||
* @param string error message
|
||||
* @param array translation variables
|
||||
* @param integer the exception code
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message, array $variables = NULL, $code = 0)
|
||||
{
|
||||
// Set the message
|
||||
$message = __($message, $variables);
|
||||
|
||||
// Pass the message to the parent
|
||||
parent::__construct($message, $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic object-to-string method.
|
||||
*
|
||||
* echo $exception;
|
||||
*
|
||||
* @uses Kohana::exception_text
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return Kohana::exception_text($this);
|
||||
}
|
||||
|
||||
} // End Kohana_Exception
|
||||
class Kohana_Exception extends Kohana_Kohana_Exception {}
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* RSS and Atom feed helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Feed {
|
||||
@@ -30,7 +30,7 @@ class Kohana_Feed {
|
||||
$error_level = error_reporting(0);
|
||||
|
||||
// Allow loading by filename or raw XML string
|
||||
$load = (is_file($feed) OR validate::url($feed)) ? 'simplexml_load_file' : 'simplexml_load_string';
|
||||
$load = (is_file($feed) OR Valid::url($feed)) ? 'simplexml_load_file' : 'simplexml_load_string';
|
||||
|
||||
// Load the feed
|
||||
$feed = $load($feed, 'SimpleXMLElement', LIBXML_NOCDATA);
|
||||
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* File helper class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_File {
|
||||
@@ -78,6 +78,70 @@ class Kohana_File {
|
||||
return isset($mimes[$extension]) ? $mimes[$extension][0] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup MIME types for a file
|
||||
*
|
||||
* @see Kohana_File::mime_by_ext()
|
||||
* @param string $extension Extension to lookup
|
||||
* @return array Array of MIMEs associated with the specified extension
|
||||
*/
|
||||
public static function mimes_by_ext($extension)
|
||||
{
|
||||
// Load all of the mime types
|
||||
$mimes = Kohana::config('mimes');
|
||||
|
||||
return isset($mimes[$extension]) ? ( (array) $mimes[$extension]) : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup file extensions by MIME type
|
||||
*
|
||||
* @param string $type File MIME type
|
||||
* @return array File extensions matching MIME type
|
||||
*/
|
||||
public static function exts_by_mime($type)
|
||||
{
|
||||
static $types = array();
|
||||
|
||||
// Fill the static array
|
||||
if (empty($types))
|
||||
{
|
||||
foreach (Kohana::config('mimes') as $ext => $mimes)
|
||||
{
|
||||
foreach ($mimes as $mime)
|
||||
{
|
||||
if ($mime == 'application/octet-stream')
|
||||
{
|
||||
// octet-stream is a generic binary
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! isset($types[$mime]))
|
||||
{
|
||||
$types[$mime] = array( (string) $ext);
|
||||
}
|
||||
elseif ( ! in_array($ext, $types[$mime]))
|
||||
{
|
||||
$types[$mime][] = (string) $ext;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return isset($types[$type]) ? $types[$type] : FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lookup a single file extension by MIME type.
|
||||
*
|
||||
* @param string $type MIME type to lookup
|
||||
* @return mixed First file extension matching or false
|
||||
*/
|
||||
public static function ext_by_mime($type)
|
||||
{
|
||||
return current(File::exts_by_mime($type));
|
||||
}
|
||||
|
||||
/**
|
||||
* Split a file into pieces matching a specific size. Used when you need to
|
||||
* split large files into smaller pieces for easy transmission.
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Form helper class. Unless otherwise noted, all generated HTML will be made
|
||||
* safe using the [HTML::chars] method. This prevents against simple XSS
|
||||
@@ -8,7 +8,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Form {
|
||||
@@ -25,7 +25,7 @@ class Kohana_Form {
|
||||
* // When "file" inputs are present, you must include the "enctype"
|
||||
* echo Form::open(NULL, array('enctype' => 'multipart/form-data'));
|
||||
*
|
||||
* @param string form action, defaults to the current request URI
|
||||
* @param mixed form action, defaults to the current request URI, or [Request] class to use
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Request::instance
|
||||
@@ -34,10 +34,10 @@ class Kohana_Form {
|
||||
*/
|
||||
public static function open($action = NULL, array $attributes = NULL)
|
||||
{
|
||||
if ($action === NULL)
|
||||
if ($action instanceof Request)
|
||||
{
|
||||
// Use the current URI
|
||||
$action = Request::current()->uri;
|
||||
$action = $action->uri();
|
||||
}
|
||||
|
||||
if ($action === '')
|
||||
@@ -241,7 +241,7 @@ class Kohana_Form {
|
||||
* echo Form::select('country', $countries, $country);
|
||||
*
|
||||
* [!!] Support for multiple selected options was added in v3.0.7.
|
||||
*
|
||||
*
|
||||
* @param string input name
|
||||
* @param array available options
|
||||
* @param mixed selected option string, or an array of selected options
|
||||
|
@@ -13,7 +13,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
* @uses Kohana::cache
|
||||
*/
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* HTML helper class. Provides generic methods for generating various HTML
|
||||
* tags and making output HTML safe.
|
||||
@@ -6,7 +6,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_HTML {
|
||||
@@ -88,16 +88,17 @@ class Kohana_HTML {
|
||||
*
|
||||
* echo HTML::anchor('/user/profile', 'My Profile');
|
||||
*
|
||||
* @param string URL or URI string
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @param string use a specific protocol
|
||||
* @param string URL or URI string
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @param mixed protocol to pass to URL::base()
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
* @uses URL::base
|
||||
* @uses URL::site
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function anchor($uri, $title = NULL, array $attributes = NULL, $protocol = NULL)
|
||||
public static function anchor($uri, $title = NULL, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if ($title === NULL)
|
||||
{
|
||||
@@ -108,7 +109,7 @@ class Kohana_HTML {
|
||||
if ($uri === '')
|
||||
{
|
||||
// Only use the base URL
|
||||
$uri = URL::base(FALSE, $protocol);
|
||||
$uri = URL::base($protocol, $index);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -123,7 +124,7 @@ class Kohana_HTML {
|
||||
elseif ($uri[0] !== '#')
|
||||
{
|
||||
// Make the URI absolute for non-id anchors
|
||||
$uri = URL::site($uri, $protocol);
|
||||
$uri = URL::site($uri, $protocol, $index);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,12 +143,13 @@ class Kohana_HTML {
|
||||
* @param string name of file to link to
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @param string non-default protocol, eg: ftp
|
||||
* @param mixed protocol to pass to URL::base()
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
* @uses URL::base
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function file_anchor($file, $title = NULL, array $attributes = NULL, $protocol = NULL)
|
||||
public static function file_anchor($file, $title = NULL, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if ($title === NULL)
|
||||
{
|
||||
@@ -156,7 +158,7 @@ class Kohana_HTML {
|
||||
}
|
||||
|
||||
// Add the file link to the attributes
|
||||
$attributes['href'] = URL::base(FALSE, $protocol).$file;
|
||||
$attributes['href'] = URL::base($protocol, $index).$file;
|
||||
|
||||
return '<a'.HTML::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
@@ -247,19 +249,20 @@ class Kohana_HTML {
|
||||
*
|
||||
* echo HTML::style('media/css/screen.css');
|
||||
*
|
||||
* @param string file name
|
||||
* @param array default attributes
|
||||
* @param string file name
|
||||
* @param array default attributes
|
||||
* @param mixed protocol to pass to URL::base()
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
* @uses URL::base
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function style($file, array $attributes = NULL, $index = FALSE)
|
||||
public static function style($file, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($index).$file;
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Set the stylesheet link
|
||||
@@ -281,17 +284,18 @@ class Kohana_HTML {
|
||||
*
|
||||
* @param string file name
|
||||
* @param array default attributes
|
||||
* @param mixed protocol to pass to URL::base()
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
* @uses URL::base
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function script($file, array $attributes = NULL, $index = FALSE)
|
||||
public static function script($file, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($index).$file;
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Set the script link
|
||||
@@ -310,16 +314,18 @@ class Kohana_HTML {
|
||||
*
|
||||
* @param string file name
|
||||
* @param array default attributes
|
||||
* @param mixed protocol to pass to URL::base()
|
||||
* @param boolean include the index page
|
||||
* @return string
|
||||
* @uses URL::base
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function image($file, array $attributes = NULL, $index = FALSE)
|
||||
public static function image($file, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($index).$file;
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Add the image link
|
||||
|
160
includes/kohana/system/classes/kohana/http.php
Normal file
160
includes/kohana/system/classes/kohana/http.php
Normal file
@@ -0,0 +1,160 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Contains the most low-level helpers methods in Kohana:
|
||||
*
|
||||
* - Environment initialization
|
||||
* - Locating files within the cascading filesystem
|
||||
* - Auto-loading and transparent extension of classes
|
||||
* - Variable and path debugging
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Kohana_HTTP {
|
||||
|
||||
/**
|
||||
* @var The default protocol to use if it cannot be detected
|
||||
*/
|
||||
public static $protocol = 'http';
|
||||
|
||||
/**
|
||||
* @var The default protocol version to use if cannot be detected
|
||||
*/
|
||||
public static $version = '1.1';
|
||||
|
||||
/**
|
||||
* Parses a HTTP header string into an associative array
|
||||
*
|
||||
* @param string $header_string Header string to parse
|
||||
* @return HTTP_Header
|
||||
*/
|
||||
public static function parse_header_string($header_string)
|
||||
{
|
||||
// If the PECL HTTP extension is loaded
|
||||
if (extension_loaded('http'))
|
||||
{
|
||||
// Use the fast method to parse header string
|
||||
return new HTTP_Header(http_parse_headers($header_string));
|
||||
}
|
||||
|
||||
// Otherwise we use the slower PHP parsing
|
||||
$headers = array();
|
||||
|
||||
// Match all HTTP headers
|
||||
if (preg_match_all('/(\w[^\s:]*):[ ]*([^\r\n]*(?:\r\n[ \t][^\r\n]*)*)/', $header_string, $matches))
|
||||
{
|
||||
// Parse each matched header
|
||||
foreach ($matches[0] as $key => $value)
|
||||
{
|
||||
// If the header has not already been set
|
||||
if ( ! isset($headers[$matches[1][$key]]))
|
||||
{
|
||||
// Apply the header directly
|
||||
$headers[$matches[1][$key]] = $matches[2][$key];
|
||||
}
|
||||
// Otherwise there is an existing entry
|
||||
else
|
||||
{
|
||||
// If the entry is an array
|
||||
if (is_array($headers[$matches[1][$key]]))
|
||||
{
|
||||
// Apply the new entry to the array
|
||||
$headers[$matches[1][$key]][] = $matches[2][$key];
|
||||
}
|
||||
// Otherwise create a new array with the entries
|
||||
else
|
||||
{
|
||||
$headers[$matches[1][$key]] = array(
|
||||
$headers[$matches[1][$key]],
|
||||
$matches[2][$key],
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return the headers
|
||||
return new HTTP_Header($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the the HTTP request headers and returns an array containing
|
||||
* key value pairs. This method is slow, but provides an accurate
|
||||
* representation of the HTTP request.
|
||||
*
|
||||
* // Get http headers into the request
|
||||
* $request->headers = HTTP::request_headers();
|
||||
*
|
||||
* @return HTTP_Header
|
||||
*/
|
||||
public static function request_headers()
|
||||
{
|
||||
// If running on apache server
|
||||
if (function_exists('apache_request_headers'))
|
||||
{
|
||||
// Return the much faster method
|
||||
return new HTTP_Header(apache_request_headers());
|
||||
}
|
||||
// If the PECL HTTP tools are installed
|
||||
elseif (extension_loaded('http'))
|
||||
{
|
||||
// Return the much faster method
|
||||
return new HTTP_Header(http_get_request_headers());
|
||||
}
|
||||
|
||||
// Setup the output
|
||||
$headers = array();
|
||||
|
||||
// Parse the content type
|
||||
if ( ! empty($_SERVER['CONTENT_TYPE']))
|
||||
{
|
||||
$headers['content-type'] = $_SERVER['CONTENT_TYPE'];
|
||||
}
|
||||
|
||||
// Parse the content length
|
||||
if ( ! empty($_SERVER['CONTENT_LENGTH']))
|
||||
{
|
||||
$headers['content-length'] = $_SERVER['CONTENT_LENGTH'];
|
||||
}
|
||||
|
||||
foreach ($_SERVER as $key => $value)
|
||||
{
|
||||
// If there is no HTTP header here, skip
|
||||
if (strpos($key, 'HTTP_') !== 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is a dirty hack to ensure HTTP_X_FOO_BAR becomes x-foo-bar
|
||||
$headers[str_replace(array('HTTP_', '_'), array('', '-'), $key)] = $value;
|
||||
}
|
||||
|
||||
return new HTTP_Header($headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes an array of key value pairs and encodes
|
||||
* the values to meet RFC 3986
|
||||
*
|
||||
* @param array $params Params
|
||||
* @return string
|
||||
*/
|
||||
public static function www_form_urlencode(array $params = array())
|
||||
{
|
||||
if ( ! $params)
|
||||
return;
|
||||
|
||||
$encoded = array();
|
||||
|
||||
foreach ($params as $key => $value)
|
||||
{
|
||||
$encoded[] = $key.'='.rawurlencode($value);
|
||||
}
|
||||
|
||||
return implode('&', $encoded);
|
||||
}
|
||||
} // End Kohana_HTTP
|
34
includes/kohana/system/classes/kohana/http/exception.php
Normal file
34
includes/kohana/system/classes/kohana/http/exception.php
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception extends Kohana_Exception {
|
||||
|
||||
/**
|
||||
* @var int http status code
|
||||
*/
|
||||
protected $_code = 0;
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* throw new Kohana_Exception('Something went terrible wrong, :user',
|
||||
* array(':user' => $user));
|
||||
*
|
||||
* @param string status message, custom content to display with error
|
||||
* @param array translation variables
|
||||
* @param integer the http status code
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message = NULL, array $variables = NULL, $code = 0)
|
||||
{
|
||||
if ($code == 0)
|
||||
{
|
||||
$code = $this->_code;
|
||||
}
|
||||
|
||||
if ( ! isset(Response::$messages[$code]))
|
||||
throw new Kohana_Exception('Unrecognized HTTP status code: :code . Only valid HTTP status codes are acceptable, see RFC 2616.', array(':code' => $code));
|
||||
|
||||
parent::__construct($message, $variables, $code);
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Exception
|
10
includes/kohana/system/classes/kohana/http/exception/400.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/400.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_400 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 400 Bad Request
|
||||
*/
|
||||
protected $_code = 400;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/401.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/401.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_401 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 401 Unauthorized
|
||||
*/
|
||||
protected $_code = 401;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/402.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/402.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_402 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 402 Payment Required
|
||||
*/
|
||||
protected $_code = 402;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/403.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/403.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_403 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 403 Forbidden
|
||||
*/
|
||||
protected $_code = 403;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/404.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/404.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_404 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 404 Not Found
|
||||
*/
|
||||
protected $_code = 404;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/405.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/405.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_405 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 405 Method Not Allowed
|
||||
*/
|
||||
protected $_code = 405;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/406.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/406.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_406 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 406 Not Acceptable
|
||||
*/
|
||||
protected $_code = 406;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/407.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/407.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_407 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 407 Proxy Authentication Required
|
||||
*/
|
||||
protected $_code = 407;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/408.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/408.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_408 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 408 Request Timeout
|
||||
*/
|
||||
protected $_code = 408;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/409.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/409.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_409 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 409 Conflict
|
||||
*/
|
||||
protected $_code = 409;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/410.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/410.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_410 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 410 Gone
|
||||
*/
|
||||
protected $_code = 410;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/411.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/411.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_411 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 411 Length Required
|
||||
*/
|
||||
protected $_code = 411;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/412.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/412.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_412 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 412 Precondition Failed
|
||||
*/
|
||||
protected $_code = 412;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/413.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/413.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_413 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 413 Request Entity Too Large
|
||||
*/
|
||||
protected $_code = 413;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/414.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/414.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_414 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 414 Request-URI Too Long
|
||||
*/
|
||||
protected $_code = 414;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/415.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/415.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_415 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 415 Unsupported Media Type
|
||||
*/
|
||||
protected $_code = 415;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/416.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/416.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_416 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 416 Request Range Not Satisfiable
|
||||
*/
|
||||
protected $_code = 416;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/417.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/417.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_417 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 417 Expectation Failed
|
||||
*/
|
||||
protected $_code = 417;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/500.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/500.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_500 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 500 Internal Server Error
|
||||
*/
|
||||
protected $_code = 500;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/501.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/501.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_501 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 501 Not Implemented
|
||||
*/
|
||||
protected $_code = 501;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/502.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/502.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_502 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 502 Bad Gateway
|
||||
*/
|
||||
protected $_code = 502;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/503.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/503.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_503 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 503 Service Unavailable
|
||||
*/
|
||||
protected $_code = 503;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/504.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/504.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_504 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 504 Gateway Timeout
|
||||
*/
|
||||
protected $_code = 504;
|
||||
|
||||
}
|
10
includes/kohana/system/classes/kohana/http/exception/505.php
Normal file
10
includes/kohana/system/classes/kohana/http/exception/505.php
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_HTTP_Exception_505 extends HTTP_Exception {
|
||||
|
||||
/**
|
||||
* @var integer HTTP 505 HTTP Version Not Supported
|
||||
*/
|
||||
protected $_code = 505;
|
||||
|
||||
}
|
310
includes/kohana/system/classes/kohana/http/header.php
Normal file
310
includes/kohana/system/classes/kohana/http/header.php
Normal file
@@ -0,0 +1,310 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* The Kohana_HTTP_Header class provides an Object-Orientated interface
|
||||
* to HTTP headers. This can parse header arrays returned from the
|
||||
* PHP functions `apache_request_headers()` or the `http_parse_headers()`
|
||||
* function available within the PECL HTTP library.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_HTTP_Header extends ArrayObject {
|
||||
|
||||
/**
|
||||
* @var boolean Controls whether to automatically sort headers by quality value
|
||||
*/
|
||||
public static $sort_by_quality = FALSE;
|
||||
|
||||
/**
|
||||
* @var array Default positive filter for sorting header values
|
||||
*/
|
||||
public static $default_sort_filter = array('accept','accept-charset','accept-encoding','accept-language');
|
||||
|
||||
/**
|
||||
* Parses HTTP Header values and creating an appropriate object
|
||||
* depending on type; i.e. accept-type, accept-char, cache-control etc.
|
||||
*
|
||||
* $header_values_array = HTTP_Header::parse_header_values(array('cache-control' => 'max-age=200; public'));
|
||||
*
|
||||
* @param array $header_values Values to parse
|
||||
* @param array $header_commas_allowed Header values where commas are not delimiters (usually date)
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_header_values(array $header_values, array $header_commas_allowed = array('user-agent', 'date', 'expires', 'last-modified'))
|
||||
{
|
||||
/**
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616.html
|
||||
*
|
||||
* HTTP header declarations should be treated as case-insensitive
|
||||
*/
|
||||
$header_values = array_change_key_case($header_values, CASE_LOWER);
|
||||
|
||||
// Foreach of the header values applied
|
||||
foreach ($header_values as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$values = array();
|
||||
|
||||
if (Arr::is_assoc($value))
|
||||
{
|
||||
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
$values[] = HTTP_Header::parse_header_values($v);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// RFC 2616 allows multiple headers with same name if they can be
|
||||
// concatinated using commas without altering the original message.
|
||||
// This usually occurs with multiple Set-Cookie: headers
|
||||
$array = array();
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
// Break value into component parts
|
||||
$v = explode(';', $v);
|
||||
|
||||
// Do some nasty parsing to flattern the array into components,
|
||||
// parsing key values
|
||||
$array = Arr::flatten(array_map('HTTP_Header_Value::parse_key_value', $v));
|
||||
|
||||
// Get the K/V component and extract the first element
|
||||
$key_value_component = array_slice($array, 0, 1, TRUE);
|
||||
array_shift($array);
|
||||
|
||||
// Create the HTTP_Header_Value component array
|
||||
$http_header['key'] = key($key_value_component);
|
||||
$http_header['value'] = current($key_value_component);
|
||||
$http_header['properties'] = $array;
|
||||
|
||||
// Create the HTTP_Header_Value
|
||||
$values[] = new HTTP_Header_Value($http_header);
|
||||
}
|
||||
}
|
||||
|
||||
// Assign HTTP_Header_Value array to the header
|
||||
$header_values[$key] = $values;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If the key allows commas or no commas are found
|
||||
if (in_array($key, $header_commas_allowed) or (strpos($value, ',') === FALSE))
|
||||
{
|
||||
// If the key is user-agent, we don't want to parse the string
|
||||
if ($key === 'user-agent')
|
||||
{
|
||||
$header_values[$key] = new HTTP_Header_Value($value, TRUE);
|
||||
}
|
||||
// Else, behave normally
|
||||
else
|
||||
{
|
||||
$header_values[$key] = new HTTP_Header_Value($value);
|
||||
}
|
||||
|
||||
// Move to next header
|
||||
continue;
|
||||
}
|
||||
|
||||
// Create an array of the values and clear any whitespace
|
||||
$value = array_map('trim', explode(',', $value));
|
||||
|
||||
$parsed_values = array();
|
||||
|
||||
// Foreach value
|
||||
foreach ($value as $v)
|
||||
{
|
||||
$v = new HTTP_Header_Value($v);
|
||||
|
||||
// Convert the value string into an object
|
||||
if ($v->key === NULL)
|
||||
{
|
||||
$parsed_values[] = $v;
|
||||
}
|
||||
else
|
||||
{
|
||||
$parsed_values[$v->key] = $v;
|
||||
}
|
||||
}
|
||||
|
||||
// Apply parsed value to the header
|
||||
$header_values[$key] = $parsed_values;
|
||||
}
|
||||
|
||||
// Return the parsed header values
|
||||
return $header_values;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor method for [Kohana_HTTP_Header]. Uses the standard constructor
|
||||
* of the parent `ArrayObject` class.
|
||||
*
|
||||
* $header_object = new HTTP_Header(array('x-powered-by' => 'Kohana 3.1.x', 'expires' => '...'));
|
||||
*
|
||||
* @param mixed Input array
|
||||
* @param int Flags
|
||||
* @param string The iterator class to use
|
||||
*/
|
||||
public function __construct($input, $flags = NULL, $iterator_class = 'ArrayIterator')
|
||||
{
|
||||
// Parse the values into [HTTP_Header_Values]
|
||||
parent::__construct(HTTP_Header::parse_header_values($input), $flags, $iterator_class);
|
||||
|
||||
// If sort by quality is set, sort the fields by q=0.0 value
|
||||
if (HTTP_Header::$sort_by_quality)
|
||||
{
|
||||
$this->sort_values_by_quality();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the header object as a string, including
|
||||
* the terminating new line
|
||||
*
|
||||
* // Return the header as a string
|
||||
* echo (string) $request->headers();
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$header = '';
|
||||
|
||||
foreach ($this as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$header .= $key.': '.(implode(', ', $value))."\r\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
$header .= $key.': '.$value."\r\n";
|
||||
}
|
||||
}
|
||||
|
||||
return $header."\n";
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads the `ArrayObject::exchangeArray()` method to ensure all
|
||||
* values passed are parsed correctly into a [Kohana_HTTP_Header_Value].
|
||||
*
|
||||
* // Input new headers
|
||||
* $headers->exchangeArray(array(
|
||||
* 'date' => 'Wed, 24 Nov 2010 21:09:23 GMT',
|
||||
* 'cache-control' => 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
|
||||
* ));
|
||||
*
|
||||
* @param array $array Array to exchange
|
||||
* @return array
|
||||
*/
|
||||
public function exchangeArray($array)
|
||||
{
|
||||
return parent::exchangeArray(HTTP_Header::parse_header_values($array));
|
||||
}
|
||||
|
||||
/**
|
||||
* Overloads the `ArrayObject::offsetSet` method to ensure any
|
||||
* access is correctly converted to the correct object type.
|
||||
*
|
||||
* // Add a new header from encoded string
|
||||
* $headers['cache-control'] = 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
|
||||
*
|
||||
* @param mixed $index Key
|
||||
* @param mixed $newval Value
|
||||
* @return void
|
||||
*/
|
||||
public function offsetSet($index, $newval)
|
||||
{
|
||||
if (is_array($newval) AND (current($newval) instanceof HTTP_Header_Value))
|
||||
return parent::offsetSet(strtolower($index), $newval);
|
||||
elseif ( ! $newval instanceof HTTP_Header_Value)
|
||||
{
|
||||
$newval = new HTTP_Header_Value($newval);
|
||||
}
|
||||
|
||||
parent::offsetSet(strtolower($index), $newval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort the headers by quality property if the header matches the
|
||||
* [Kohana_HTTP_Header::$default_sort_filter] definition.
|
||||
*
|
||||
* #### Default sort values
|
||||
*
|
||||
* - Accept
|
||||
* - Accept-Chars
|
||||
* - Accept-Encoding
|
||||
* - Accept-Lang
|
||||
*
|
||||
* @param array $filter Header fields to parse
|
||||
* @return self
|
||||
*/
|
||||
public function sort_values_by_quality(array $filter = array())
|
||||
{
|
||||
// If a filter argument is supplied
|
||||
if ($filter)
|
||||
{
|
||||
// Apply filter and store previous
|
||||
$previous_filter = HTTP_Header::$default_sort_filter;
|
||||
HTTP_Header::$default_sort_filter = $filter;
|
||||
}
|
||||
|
||||
// Get a copy of this ArrayObject
|
||||
$values = $this->getArrayCopy();
|
||||
|
||||
foreach ($values as $key => $value)
|
||||
{
|
||||
if ( ! is_array($value) or ! in_array($key, HTTP_Header::$default_sort_filter))
|
||||
{
|
||||
unset($values[$key]);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Sort them by comparison
|
||||
uasort($value, array($this, '_sort_by_comparison'));
|
||||
|
||||
$values[$key] = $value;
|
||||
}
|
||||
|
||||
// Return filter to previous state if required
|
||||
if ($filter)
|
||||
{
|
||||
HTTP_Header::$default_sort_filter = $previous_filter;
|
||||
}
|
||||
|
||||
foreach ($values as $key => $value)
|
||||
{
|
||||
$this[$key] = $value;
|
||||
}
|
||||
|
||||
// Return this
|
||||
return $this;
|
||||
}
|
||||
|
||||
protected function _sort_by_comparison($value_a, $value_b)
|
||||
{
|
||||
// Test for correct instance type
|
||||
if ( ! $value_a instanceof HTTP_Header_Value OR ! $value_b instanceof HTTP_Header_Value)
|
||||
{
|
||||
// Return neutral if cannot test value
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Extract the qualities
|
||||
$a = (float) Arr::get($value_a->properties, 'q', HTTP_Header_Value::$default_quality);
|
||||
$b = (float) Arr::get($value_b->properties, 'q', HTTP_Header_Value::$default_quality);
|
||||
|
||||
if ($a == $b)
|
||||
return 0;
|
||||
elseif ($a < $b)
|
||||
return 1;
|
||||
elseif ($a > $b)
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Header
|
219
includes/kohana/system/classes/kohana/http/header/value.php
Normal file
219
includes/kohana/system/classes/kohana/http/header/value.php
Normal file
@@ -0,0 +1,219 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana_HTTP_Header_Value represents a value assigned to an HTTP header, i.e.
|
||||
*
|
||||
* Accept: [key=]value[; property[=property_value][; ...]]
|
||||
*
|
||||
* Values are either single values,
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_HTTP_Header_Value {
|
||||
|
||||
/**
|
||||
* @var float The default quality header property value
|
||||
*/
|
||||
public static $default_quality = 1.0;
|
||||
|
||||
/**
|
||||
* Detects and returns key/value pairs
|
||||
*
|
||||
* @param string $string String to parse
|
||||
* @param string $separator
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_key_value($string, $separator = '=')
|
||||
{
|
||||
$parts = explode($separator, trim($string), 2);
|
||||
|
||||
if (count($parts) == 1)
|
||||
{
|
||||
return $parts;
|
||||
}
|
||||
else
|
||||
{
|
||||
return array($parts[0] => $parts[1]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $properties = array();
|
||||
|
||||
/**
|
||||
* @var void|string
|
||||
*/
|
||||
public $key;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
public $value = array();
|
||||
|
||||
/**
|
||||
* Builds the header field
|
||||
*
|
||||
* @param mixed value configuration array passed
|
||||
* @param boolean no_parse skip parsing of the string (i.e. user-agent)
|
||||
* @throws Kohana_HTTP_Exception
|
||||
*/
|
||||
public function __construct($value, $no_parse = FALSE)
|
||||
{
|
||||
// If no parse is set, set the value and get out of here (user-agent)
|
||||
if ($no_parse)
|
||||
{
|
||||
$this->key = NULL;
|
||||
$this->value = $value;
|
||||
return;
|
||||
}
|
||||
|
||||
// If configuration array passed
|
||||
if (is_array($value))
|
||||
{
|
||||
// Parse each value
|
||||
foreach ($value as $k => $v)
|
||||
{
|
||||
// If the key is a property
|
||||
if (property_exists($this, $k))
|
||||
{
|
||||
// Map values
|
||||
$this->$k = $v;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
// If value is a string
|
||||
elseif (is_string($value))
|
||||
{
|
||||
// Detect properties
|
||||
if (strpos($value, ';') !== FALSE)
|
||||
{
|
||||
// Remove properties from the string
|
||||
$parts = explode(';', $value);
|
||||
$value = array_shift($parts);
|
||||
|
||||
// Parse the properties
|
||||
$properties = array();
|
||||
|
||||
// Foreach part
|
||||
foreach ($parts as $part)
|
||||
{
|
||||
// Merge the parsed values
|
||||
$properties = array_merge(HTTP_Header_Value::parse_key_value($part), $properties);
|
||||
}
|
||||
|
||||
// Apply the parsed values
|
||||
$this->properties = $properties;
|
||||
}
|
||||
|
||||
// Parse the value and get key
|
||||
$value = HTTP_Header_Value::parse_key_value($value);
|
||||
$key = key($value);
|
||||
|
||||
// If the key is a string
|
||||
if (is_string($key))
|
||||
{
|
||||
// Apply the key as a property
|
||||
$this->key = $key;
|
||||
}
|
||||
|
||||
// Apply the value
|
||||
$this->value = current($value);
|
||||
}
|
||||
// Unrecognised value type
|
||||
else
|
||||
{
|
||||
throw new HTTP_Exception_500(__METHOD__.' unknown header value type: :type. array or string allowed.', array(':type' => gettype($value)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides direct access to the key of this header value
|
||||
*
|
||||
* @param string $key Key value to set
|
||||
* @return mixed
|
||||
*/
|
||||
public function key($key = NULL)
|
||||
{
|
||||
if ($key === NULL)
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->key = $key;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides direct access to the value of this header value
|
||||
*
|
||||
* @param string $value Value to set
|
||||
* @return mixed
|
||||
*/
|
||||
public function value($value = NULL)
|
||||
{
|
||||
if ($value === NULL)
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->value = $value;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides direct access to the properties of this header value
|
||||
*
|
||||
* @param array $properties Properties to set to this value
|
||||
* @return mixed
|
||||
*/
|
||||
public function properties(array $properties = array())
|
||||
{
|
||||
if ( ! $properties)
|
||||
{
|
||||
return $this->properties;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->properties = $properties;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic method to handle object being cast to
|
||||
* string. Produces the following header value syntax
|
||||
*
|
||||
* [key=]value[; property[=property_value][; ... ]]
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
|
||||
$string = ($this->key !== NULL) ? ($this->key.'='.$this->value) : $this->value;
|
||||
|
||||
if ($this->properties)
|
||||
{
|
||||
$props = array($string);
|
||||
foreach ($this->properties as $k => $v)
|
||||
{
|
||||
$props[] = is_int($k) ? $v : ($k.'='.$v);
|
||||
}
|
||||
$string = implode('; ', $props);
|
||||
}
|
||||
|
||||
return $string;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Header_Value
|
56
includes/kohana/system/classes/kohana/http/interaction.php
Normal file
56
includes/kohana/system/classes/kohana/http/interaction.php
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* The HTTP Interaction interface providing the core HTTP methods that
|
||||
* should be implemented by any HTTP request or response class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Interaction {
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP protocol. The standard protocol to use
|
||||
* is `HTTP/1.1`.
|
||||
*
|
||||
* @param string $protocol Protocol to set to the request/response
|
||||
* @return mixed
|
||||
*/
|
||||
public function protocol($protocol = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP headers to the request or response. All headers
|
||||
* are included immediately after the HTTP protocol definition during
|
||||
* transmission. This method provides a simple array or key/value
|
||||
* interface to the headers.
|
||||
*
|
||||
* @param mixed $key Key or array of key/value pairs to set
|
||||
* @param string $value Value to set to the supplied key
|
||||
* @return mixed
|
||||
*/
|
||||
public function headers($key = NULL, $value = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP body to the request or response. The body is
|
||||
* included after the header, separated by a single empty new line.
|
||||
*
|
||||
* @param string $content Content to set to the object
|
||||
* @return string
|
||||
* @return void
|
||||
*/
|
||||
public function body($content = NULL);
|
||||
|
||||
/**
|
||||
* Renders the HTTP_Interaction to a string, producing
|
||||
*
|
||||
* - Protocol
|
||||
* - Headers
|
||||
* - Body
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render();
|
||||
}
|
64
includes/kohana/system/classes/kohana/http/request.php
Normal file
64
includes/kohana/system/classes/kohana/http/request.php
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* A HTTP Request specific interface that adds the methods required
|
||||
* by HTTP requests. Over and above [Kohana_HTTP_Interaction], this
|
||||
* interface provides method, uri, get and post methods.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Request extends HTTP_Interaction {
|
||||
|
||||
// HTTP Methods
|
||||
const GET = 'GET';
|
||||
const POST = 'POST';
|
||||
const PUT = 'PUT';
|
||||
const DELETE = 'DELETE';
|
||||
const HEAD = 'HEAD';
|
||||
const OPTIONS = 'OPTIONS';
|
||||
const TRACE = 'TRACE';
|
||||
const CONNECT = 'CONNECT';
|
||||
|
||||
/**
|
||||
* Gets or sets the HTTP method. Usually GET, POST, PUT or DELETE in
|
||||
* traditional CRUD applications.
|
||||
*
|
||||
* @param string $method Method to use for this request
|
||||
* @return mixed
|
||||
*/
|
||||
public function method($method = NULL);
|
||||
|
||||
/**
|
||||
* Gets the URI of this request, optionally allows setting
|
||||
* of [Route] specific parameters during the URI generation.
|
||||
* If no parameters are passed, the request will use the
|
||||
* default values defined in the Route.
|
||||
*
|
||||
* @param array $params Optional parameters to include in uri generation
|
||||
* @return string
|
||||
*/
|
||||
public function uri(array $params = array());
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP query string.
|
||||
*
|
||||
* @param mixed $key Key or key value pairs to set
|
||||
* @param string $value Value to set to a key
|
||||
* @return mixed
|
||||
*/
|
||||
public function query($key = NULL, $value = NULL);
|
||||
|
||||
/**
|
||||
* Gets or sets HTTP POST parameters to the request.
|
||||
*
|
||||
* @param mixed $key Key or key value pairs to set
|
||||
* @param string $value Value to set to a key
|
||||
* @return mixed
|
||||
*/
|
||||
public function post($key = NULL, $value = NULL);
|
||||
|
||||
}
|
31
includes/kohana/system/classes/kohana/http/response.php
Normal file
31
includes/kohana/system/classes/kohana/http/response.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* A HTTP Reponse specific interface that adds the methods required
|
||||
* by HTTP responses. Over and above [Kohana_HTTP_Interaction], this
|
||||
* interface provides status.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category HTTP
|
||||
* @author Kohana Team
|
||||
* @since 3.1.0
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_HTTP_Response extends HTTP_Interaction {
|
||||
|
||||
/**
|
||||
* Sets or gets the HTTP status from this response.
|
||||
*
|
||||
* // Set the HTTP status to 404 Not Found
|
||||
* $response = Response::factory()
|
||||
* ->status(404);
|
||||
*
|
||||
* // Get the current status
|
||||
* $status = $response->status();
|
||||
*
|
||||
* @param integer $code Status to set to this response
|
||||
* @return mixed
|
||||
*/
|
||||
public function status($code = NULL);
|
||||
|
||||
}
|
@@ -12,12 +12,10 @@
|
||||
* // With parameter replacement
|
||||
* echo __('Hello, :user', array(':user' => $username));
|
||||
*
|
||||
* [!!] The __() function is declared in `SYSPATH/base.php`.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_I18n {
|
||||
@@ -137,3 +135,32 @@ class Kohana_I18n {
|
||||
}
|
||||
|
||||
} // End I18n
|
||||
|
||||
if ( ! function_exists('__'))
|
||||
{
|
||||
/**
|
||||
* Kohana translation/internationalization function. The PHP function
|
||||
* [strtr](http://php.net/strtr) is used for replacing parameters.
|
||||
*
|
||||
* __('Welcome back, :user', array(':user' => $username));
|
||||
*
|
||||
* [!!] The target language is defined by [I18n::$lang].
|
||||
*
|
||||
* @uses I18n::get
|
||||
* @param string text to translate
|
||||
* @param array values to replace in the translated text
|
||||
* @param string source language
|
||||
* @return string
|
||||
*/
|
||||
function __($string, array $values = NULL, $lang = 'en-us')
|
||||
{
|
||||
if ($lang !== I18n::$lang)
|
||||
{
|
||||
// The message and target languages are different
|
||||
// Get the translation for this message
|
||||
$string = I18n::get($string);
|
||||
}
|
||||
|
||||
return empty($values) ? $string : strtr($string, $values);
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Inflector helper class. Inflection is changing the form of a word based on
|
||||
* the context it is used in. For example, changing a word into a plural form.
|
||||
@@ -8,7 +8,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Inflector {
|
||||
|
206
includes/kohana/system/classes/kohana/kohana/exception.php
Normal file
206
includes/kohana/system/classes/kohana/kohana/exception.php
Normal file
@@ -0,0 +1,206 @@
|
||||
<?php defined('SYSPATH') or die('No direct access');
|
||||
/**
|
||||
* Kohana exception class. Translates exceptions using the [I18n] class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Exceptions
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Kohana_Exception extends Exception {
|
||||
|
||||
/**
|
||||
* @var array PHP error code => human readable name
|
||||
*/
|
||||
public static $php_errors = array(
|
||||
E_ERROR => 'Fatal Error',
|
||||
E_USER_ERROR => 'User Error',
|
||||
E_PARSE => 'Parse Error',
|
||||
E_WARNING => 'Warning',
|
||||
E_USER_WARNING => 'User Warning',
|
||||
E_STRICT => 'Strict',
|
||||
E_NOTICE => 'Notice',
|
||||
E_RECOVERABLE_ERROR => 'Recoverable Error',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string error rendering view
|
||||
*/
|
||||
public static $error_view = 'kohana/error';
|
||||
|
||||
/**
|
||||
* Creates a new translated exception.
|
||||
*
|
||||
* throw new Kohana_Exception('Something went terrible wrong, :user',
|
||||
* array(':user' => $user));
|
||||
*
|
||||
* @param string error message
|
||||
* @param array translation variables
|
||||
* @param integer|string the exception code
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($message, array $variables = NULL, $code = 0)
|
||||
{
|
||||
if (defined('E_DEPRECATED'))
|
||||
{
|
||||
// E_DEPRECATED only exists in PHP >= 5.3.0
|
||||
Kohana_Exception::$php_errors[E_DEPRECATED] = 'Deprecated';
|
||||
}
|
||||
|
||||
// Save the unmodified code
|
||||
// @link http://bugs.php.net/39615
|
||||
$this->code = $code;
|
||||
|
||||
// Set the message
|
||||
$message = __($message, $variables);
|
||||
|
||||
// Pass the message and integer code to the parent
|
||||
parent::__construct($message, (int) $code);
|
||||
}
|
||||
|
||||
/**
|
||||
* Magic object-to-string method.
|
||||
*
|
||||
* echo $exception;
|
||||
*
|
||||
* @uses Kohana_Exception::text
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return Kohana_Exception::text($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline exception handler, displays the error message, source of the
|
||||
* exception, and the stack trace of the error.
|
||||
*
|
||||
* @uses Kohana_Exception::text
|
||||
* @param object exception object
|
||||
* @return boolean
|
||||
*/
|
||||
public static function handler(Exception $e)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get the exception information
|
||||
$type = get_class($e);
|
||||
$code = $e->getCode();
|
||||
$message = $e->getMessage();
|
||||
$file = $e->getFile();
|
||||
$line = $e->getLine();
|
||||
|
||||
// Get the exception backtrace
|
||||
$trace = $e->getTrace();
|
||||
|
||||
if ($e instanceof ErrorException)
|
||||
{
|
||||
if (isset(Kohana_Exception::$php_errors[$code]))
|
||||
{
|
||||
// Use the human-readable error name
|
||||
$code = Kohana_Exception::$php_errors[$code];
|
||||
}
|
||||
|
||||
if (version_compare(PHP_VERSION, '5.3', '<'))
|
||||
{
|
||||
// Workaround for a bug in ErrorException::getTrace() that exists in
|
||||
// all PHP 5.2 versions. @see http://bugs.php.net/bug.php?id=45895
|
||||
for ($i = count($trace) - 1; $i > 0; --$i)
|
||||
{
|
||||
if (isset($trace[$i - 1]['args']))
|
||||
{
|
||||
// Re-position the args
|
||||
$trace[$i]['args'] = $trace[$i - 1]['args'];
|
||||
|
||||
// Remove the args
|
||||
unset($trace[$i - 1]['args']);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create a text version of the exception
|
||||
$error = Kohana_Exception::text($e);
|
||||
|
||||
if (is_object(Kohana::$log))
|
||||
{
|
||||
// Add this exception to the log
|
||||
Kohana::$log->add(Log::ERROR, $error);
|
||||
|
||||
// Make sure the logs are written
|
||||
Kohana::$log->write();
|
||||
}
|
||||
|
||||
if (Kohana::$is_cli)
|
||||
{
|
||||
// Just display the text of the exception
|
||||
echo "\n{$error}\n";
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ( ! headers_sent())
|
||||
{
|
||||
// Make sure the proper http header is sent
|
||||
$http_header_status = ($e instanceof HTTP_Exception) ? $code : 500;
|
||||
|
||||
header('Content-Type: text/html; charset='.Kohana::$charset, TRUE, $http_header_status);
|
||||
}
|
||||
|
||||
if (Request::$current !== NULL AND Request::current()->is_ajax() === TRUE)
|
||||
{
|
||||
// Just display the text of the exception
|
||||
echo "\n{$error}\n";
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Start an output buffer
|
||||
ob_start();
|
||||
|
||||
// Include the exception HTML
|
||||
if ($view_file = Kohana::find_file('views', Kohana_Exception::$error_view))
|
||||
{
|
||||
include $view_file;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Kohana_Exception('Error view file does not exist: views/:file', array(
|
||||
':file' => Kohana_Exception::$error_view,
|
||||
));
|
||||
}
|
||||
|
||||
// Display the contents of the output buffer
|
||||
echo ob_get_clean();
|
||||
|
||||
exit(1);
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
// Clean the output buffer if one exists
|
||||
ob_get_level() and ob_clean();
|
||||
|
||||
// Display the exception text
|
||||
echo Kohana_Exception::text($e), "\n";
|
||||
|
||||
// Exit with an error status
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a single line of text representing the exception:
|
||||
*
|
||||
* Error [ Code ]: Message ~ File [ Line ]
|
||||
*
|
||||
* @param object Exception
|
||||
* @return string
|
||||
*/
|
||||
public static function text(Exception $e)
|
||||
{
|
||||
return sprintf('%s [ %s ]: %s ~ %s [ %d ]',
|
||||
get_class($e), $e->getCode(), strip_tags($e->getMessage()), Debug::path($e->getFile()), $e->getLine());
|
||||
}
|
||||
|
||||
} // End Kohana_Exception
|
@@ -7,11 +7,21 @@
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Log {
|
||||
|
||||
// Log message levels - Windows users see PHP Bug #18090
|
||||
const EMERGENCY = LOG_EMERG; // 0
|
||||
const ALERT = LOG_ALERT; // 1
|
||||
const CRITICAL = LOG_CRIT; // 2
|
||||
const ERROR = LOG_ERR; // 3
|
||||
const WARNING = LOG_WARNING; // 4
|
||||
const NOTICE = LOG_NOTICE; // 5
|
||||
const INFO = LOG_INFO; // 6
|
||||
const DEBUG = LOG_DEBUG; // 7
|
||||
|
||||
/**
|
||||
* @var string timestamp format for log entries
|
||||
*/
|
||||
@@ -28,57 +38,63 @@ class Kohana_Log {
|
||||
public static $write_on_add = FALSE;
|
||||
|
||||
/**
|
||||
* @var Kohana_Log Singleton instance container
|
||||
* @var Log Singleton instance container
|
||||
*/
|
||||
private static $_instance;
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of this class and enable writing at shutdown.
|
||||
*
|
||||
* $log = Kohana_Log::instance();
|
||||
* $log = Log::instance();
|
||||
*
|
||||
* @return Kohana_Log
|
||||
* @return Log
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (self::$_instance === NULL)
|
||||
if (Log::$_instance === NULL)
|
||||
{
|
||||
// Create a new instance
|
||||
self::$_instance = new self;
|
||||
Log::$_instance = new Log;
|
||||
|
||||
// Write the logs at shutdown
|
||||
register_shutdown_function(array(self::$_instance, 'write'));
|
||||
register_shutdown_function(array(Log::$_instance, 'write'));
|
||||
}
|
||||
|
||||
return self::$_instance;
|
||||
return Log::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array list of added messages
|
||||
*/
|
||||
private $_messages = array();
|
||||
protected $_messages = array();
|
||||
|
||||
/**
|
||||
* @var array list of log writers
|
||||
*/
|
||||
private $_writers = array();
|
||||
protected $_writers = array();
|
||||
|
||||
/**
|
||||
* Attaches a log writer, and optionally limits the types of messages that
|
||||
* Attaches a log writer, and optionally limits the levels of messages that
|
||||
* will be written by the writer.
|
||||
*
|
||||
* $log->attach($writer);
|
||||
*
|
||||
* @param object Kohana_Log_Writer instance
|
||||
* @param array messages types to write
|
||||
* @return Kohana_Log
|
||||
* @param object Log_Writer instance
|
||||
* @param mixed array of messages levels to write OR max level to write
|
||||
* @param integer min level to write IF $levels is not an array
|
||||
* @return Log
|
||||
*/
|
||||
public function attach(Kohana_Log_Writer $writer, array $types = NULL)
|
||||
public function attach(Log_Writer $writer, $levels = array(), $min_level = 0)
|
||||
{
|
||||
if ( ! is_array($levels))
|
||||
{
|
||||
$levels = range($min_level, $levels);
|
||||
}
|
||||
|
||||
$this->_writers["{$writer}"] = array
|
||||
(
|
||||
'object' => $writer,
|
||||
'types' => $types
|
||||
'levels' => $levels
|
||||
);
|
||||
|
||||
return $this;
|
||||
@@ -89,10 +105,10 @@ class Kohana_Log {
|
||||
*
|
||||
* $log->detach($writer);
|
||||
*
|
||||
* @param object Kohana_Log_Writer instance
|
||||
* @return Kohana_Log
|
||||
* @param object Log_Writer instance
|
||||
* @return Log
|
||||
*/
|
||||
public function detach(Kohana_Log_Writer $writer)
|
||||
public function detach(Log_Writer $writer)
|
||||
{
|
||||
// Remove the writer
|
||||
unset($this->_writers["{$writer}"]);
|
||||
@@ -104,16 +120,16 @@ class Kohana_Log {
|
||||
* Adds a message to the log. Replacement values must be passed in to be
|
||||
* replaced using [strtr](http://php.net/strtr).
|
||||
*
|
||||
* $log->add('error', 'Could not locate user: :user', array(
|
||||
* $log->add(Log::ERROR, 'Could not locate user: :user', array(
|
||||
* ':user' => $username,
|
||||
* ));
|
||||
*
|
||||
* @param string type of message
|
||||
* @param string level of message
|
||||
* @param string message body
|
||||
* @param array values to replace in the message
|
||||
* @return Kohana_Log
|
||||
* @return Log
|
||||
*/
|
||||
public function add($type, $message, array $values = NULL)
|
||||
public function add($level, $message, array $values = NULL)
|
||||
{
|
||||
if ($values)
|
||||
{
|
||||
@@ -124,12 +140,12 @@ class Kohana_Log {
|
||||
// Create a new message and timestamp it
|
||||
$this->_messages[] = array
|
||||
(
|
||||
'time' => Date::formatted_time('now', self::$timestamp, self::$timezone),
|
||||
'type' => $type,
|
||||
'body' => $message,
|
||||
'time' => Date::formatted_time('now', Log::$timestamp, Log::$timezone),
|
||||
'level' => $level,
|
||||
'body' => $message,
|
||||
);
|
||||
|
||||
if (self::$write_on_add)
|
||||
if (Log::$write_on_add)
|
||||
{
|
||||
// Write logs as they are added
|
||||
$this->write();
|
||||
@@ -161,7 +177,7 @@ class Kohana_Log {
|
||||
|
||||
foreach ($this->_writers as $writer)
|
||||
{
|
||||
if (empty($writer['types']))
|
||||
if (empty($writer['levels']))
|
||||
{
|
||||
// Write all of the messages
|
||||
$writer['object']->write($messages);
|
||||
@@ -173,7 +189,7 @@ class Kohana_Log {
|
||||
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
if (in_array($message['type'], $writer['types']))
|
||||
if (in_array($message['level'], $writer['levels']))
|
||||
{
|
||||
// Writer accepts this kind of message
|
||||
$filtered[] = $message;
|
||||
|
@@ -5,10 +5,10 @@
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Log_File extends Kohana_Log_Writer {
|
||||
class Kohana_Log_File extends Log_Writer {
|
||||
|
||||
/**
|
||||
* @var string Directory to place log files in
|
||||
@@ -19,7 +19,7 @@ class Kohana_Log_File extends Kohana_Log_Writer {
|
||||
* Creates a new file logger. Checks that the directory exists and
|
||||
* is writable.
|
||||
*
|
||||
* $writer = new Kohana_Log_File($directory);
|
||||
* $writer = new Log_File($directory);
|
||||
*
|
||||
* @param string log directory
|
||||
* @return void
|
||||
@@ -29,7 +29,7 @@ class Kohana_Log_File extends Kohana_Log_Writer {
|
||||
if ( ! is_dir($directory) OR ! is_writable($directory))
|
||||
{
|
||||
throw new Kohana_Exception('Directory :dir must be writable',
|
||||
array(':dir' => Kohana::debug_path($directory)));
|
||||
array(':dir' => Debug::path($directory)));
|
||||
}
|
||||
|
||||
// Determine the directory path
|
||||
@@ -84,13 +84,11 @@ class Kohana_Log_File extends Kohana_Log_Writer {
|
||||
chmod($filename, 0666);
|
||||
}
|
||||
|
||||
// Set the log line format
|
||||
$format = 'time --- type: body';
|
||||
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
// Write each message into the log file
|
||||
file_put_contents($filename, PHP_EOL.strtr($format, $message), FILE_APPEND);
|
||||
// Format: time --- level: body
|
||||
file_put_contents($filename, PHP_EOL.$message['time'].' --- '.$this->_log_levels[$message['level']].': '.$message['body'], FILE_APPEND);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Log_StdErr extends Kohana_Log_Writer {
|
||||
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Log_StdOut extends Kohana_Log_Writer {
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* @copyright (c) 2010 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Log_Syslog extends Kohana_Log_Writer {
|
||||
class Kohana_Log_Syslog extends Log_Writer {
|
||||
|
||||
/**
|
||||
* @var string The syslog identifier
|
||||
@@ -52,7 +52,7 @@ class Kohana_Log_Syslog extends Kohana_Log_Writer {
|
||||
{
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
syslog($this->_syslog_levels[$message['type']], $message['body']);
|
||||
syslog($message['level'], $message['body']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,4 +67,4 @@ class Kohana_Log_Syslog extends Kohana_Log_Writer {
|
||||
closelog();
|
||||
}
|
||||
|
||||
} // End Kohana_Log_Syslog
|
||||
} // End Kohana_Log_Syslog
|
||||
|
@@ -1,15 +1,29 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Log writer abstract class. All [Kohana_Log] writers must extend this class.
|
||||
* Log writer abstract class. All [Log] writers must extend this class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Log_Writer {
|
||||
|
||||
/**
|
||||
* Numeric log level to string lookup table.
|
||||
* @var array
|
||||
*/
|
||||
protected $_log_levels = array(
|
||||
LOG_EMERG => 'EMERGENCY',
|
||||
LOG_CRIT => 'CRITICAL',
|
||||
LOG_ERR => 'ERROR',
|
||||
LOG_WARNING => 'WARNING',
|
||||
LOG_NOTICE => 'NOTICE',
|
||||
LOG_INFO => 'INFO',
|
||||
LOG_DEBUG => 'DEBUG',
|
||||
);
|
||||
|
||||
/**
|
||||
* Write an array of messages.
|
||||
*
|
||||
|
@@ -5,61 +5,25 @@
|
||||
* @package Kohana
|
||||
* @category Models
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Model {
|
||||
|
||||
/**
|
||||
* Create a new model instance. A [Database] instance or configuration
|
||||
* group name can be passed to the model. If no database is defined, the
|
||||
* "default" database group will be used.
|
||||
* Create a new model instance.
|
||||
*
|
||||
* $model = Model::factory($name);
|
||||
*
|
||||
* @param string model name
|
||||
* @param mixed Database instance object or string
|
||||
* @return Model
|
||||
*/
|
||||
public static function factory($name, $db = NULL)
|
||||
public static function factory($name)
|
||||
{
|
||||
// Add the model prefix
|
||||
$class = 'Model_'.$name;
|
||||
|
||||
return new $class($db);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Database database instance
|
||||
*/
|
||||
protected $_db;
|
||||
|
||||
/**
|
||||
* Loads the database.
|
||||
*
|
||||
* $model = new Foo_Model($db);
|
||||
*
|
||||
* @param mixed Database instance object or string
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($db = NULL)
|
||||
{
|
||||
if ($db)
|
||||
{
|
||||
// Set the database instance to use
|
||||
$this->_db = $db;
|
||||
}
|
||||
elseif ( ! $this->_db)
|
||||
{
|
||||
// Use the global database
|
||||
$this->_db = Database::$default;
|
||||
}
|
||||
|
||||
if (is_string($this->_db))
|
||||
{
|
||||
// Load the database
|
||||
$this->_db = Database::instance($this->_db);
|
||||
}
|
||||
return new $class;
|
||||
}
|
||||
|
||||
} // End Model
|
||||
|
@@ -6,11 +6,56 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Num {
|
||||
|
||||
const ROUND_HALF_UP = 1;
|
||||
const ROUND_HALF_DOWN = 2;
|
||||
const ROUND_HALF_EVEN = 3;
|
||||
const ROUND_HALF_ODD = 4;
|
||||
|
||||
/**
|
||||
* @var array Valid byte units => power of 2 that defines the unit's size
|
||||
*/
|
||||
public static $byte_units = array
|
||||
(
|
||||
'B' => 0,
|
||||
'K' => 10,
|
||||
'Ki' => 10,
|
||||
'KB' => 10,
|
||||
'KiB' => 10,
|
||||
'M' => 20,
|
||||
'Mi' => 20,
|
||||
'MB' => 20,
|
||||
'MiB' => 20,
|
||||
'G' => 30,
|
||||
'Gi' => 30,
|
||||
'GB' => 30,
|
||||
'GiB' => 30,
|
||||
'T' => 40,
|
||||
'Ti' => 40,
|
||||
'TB' => 40,
|
||||
'TiB' => 40,
|
||||
'P' => 50,
|
||||
'Pi' => 50,
|
||||
'PB' => 50,
|
||||
'PiB' => 50,
|
||||
'E' => 60,
|
||||
'Ei' => 60,
|
||||
'EB' => 60,
|
||||
'EiB' => 60,
|
||||
'Z' => 70,
|
||||
'Zi' => 70,
|
||||
'ZB' => 70,
|
||||
'ZiB' => 70,
|
||||
'Y' => 80,
|
||||
'Yi' => 80,
|
||||
'YB' => 80,
|
||||
'YiB' => 80,
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the English ordinal suffix (th, st, nd, etc) of a number.
|
||||
*
|
||||
@@ -78,4 +123,112 @@ class Kohana_Num {
|
||||
return number_format($number, $places, $decimal, $thousands);
|
||||
}
|
||||
|
||||
/**
|
||||
* Round a number to a specified precision, using a specified tie breaking technique
|
||||
*
|
||||
* @param float $value Number to round
|
||||
* @param integer $precision Desired precision
|
||||
* @param integer $mode Tie breaking mode, accepts the PHP_ROUND_HALF_* constants
|
||||
* @param boolean $native Set to false to force use of the userland implementation
|
||||
* @return float Rounded number
|
||||
*/
|
||||
public static function round($value, $precision = 0, $mode = self::ROUND_HALF_UP, $native = true)
|
||||
{
|
||||
if (version_compare(PHP_VERSION, '5.3', '>=') AND $native)
|
||||
{
|
||||
return round($value, $precision, $mode);
|
||||
}
|
||||
|
||||
if ($mode === self::ROUND_HALF_UP)
|
||||
{
|
||||
return round($value, $precision);
|
||||
}
|
||||
else
|
||||
{
|
||||
$factor = ($precision === 0) ? 1 : pow(10, $precision);
|
||||
|
||||
switch ($mode)
|
||||
{
|
||||
case self::ROUND_HALF_DOWN:
|
||||
case self::ROUND_HALF_EVEN:
|
||||
case self::ROUND_HALF_ODD:
|
||||
// Check if we have a rounding tie, otherwise we can just call round()
|
||||
if (($value * $factor) - floor($value * $factor) === 0.5)
|
||||
{
|
||||
if ($mode === self::ROUND_HALF_DOWN)
|
||||
{
|
||||
// Round down operation, so we round down unless the value
|
||||
// is -ve because up is down and down is up down there. ;)
|
||||
$up = ($value < 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Round up if the integer is odd and the round mode is set to even
|
||||
// or the integer is even and the round mode is set to odd.
|
||||
// Any other instance round down.
|
||||
$up = ( ! ( ! (floor($value * $factor) & 1)) === ($mode === self::ROUND_HALF_EVEN));
|
||||
}
|
||||
|
||||
if ($up)
|
||||
{
|
||||
$value = ceil($value * $factor);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = floor($value * $factor);
|
||||
}
|
||||
return $value / $factor;
|
||||
}
|
||||
else
|
||||
{
|
||||
return round($value, $precision);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a file size number to a byte value. File sizes are defined in
|
||||
* the format: SB, where S is the size (1, 8.5, 300, etc.) and B is the
|
||||
* byte unit (K, MiB, GB, etc.). All valid byte units are defined in
|
||||
* Num::$byte_units
|
||||
*
|
||||
* echo Num::bytes('200K'); // 204800
|
||||
* echo Num::bytes('5MiB'); // 5242880
|
||||
* echo Num::bytes('1000'); // 1000
|
||||
* echo Num::bytes('2.5GB'); // 2684354560
|
||||
*
|
||||
* @param string file size in SB format
|
||||
* @return float
|
||||
*/
|
||||
public static function bytes($size)
|
||||
{
|
||||
// Prepare the size
|
||||
$size = trim( (string) $size);
|
||||
|
||||
// Construct an OR list of byte units for the regex
|
||||
$accepted = implode('|', array_keys(Num::$byte_units));
|
||||
|
||||
// Construct the regex pattern for verifying the size format
|
||||
$pattern = '/^([0-9]+(?:\.[0-9]+)?)('.$accepted.')?$/Di';
|
||||
|
||||
// Verify the size format and store the matching parts
|
||||
if ( ! preg_match($pattern, $size, $matches))
|
||||
throw new Kohana_Exception('The byte unit size, ":size", is improperly formatted.', array(
|
||||
':size' => $size,
|
||||
));
|
||||
|
||||
// Find the float value of the size
|
||||
$size = (float) $matches[1];
|
||||
|
||||
// Find the actual unit, assume B if no unit specified
|
||||
$unit = Arr::get($matches, 2, 'B');
|
||||
|
||||
// Convert the size into bytes
|
||||
$bytes = $size * pow(2, Num::$byte_units[$unit]);
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
} // End num
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Profiler {
|
||||
|
@@ -1,154 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Provides remote server communications options using [curl](http://php.net/curl).
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2010 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Remote {
|
||||
|
||||
/**
|
||||
* @var array default cURL options
|
||||
*/
|
||||
public static $default_options = array
|
||||
(
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Kohana v3.0 +http://kohanaframework.org/)',
|
||||
CURLOPT_CONNECTTIMEOUT => 5,
|
||||
CURLOPT_TIMEOUT => 5,
|
||||
);
|
||||
|
||||
/**
|
||||
* Returns the output of a remote URL. Any [curl option](http://php.net/curl_setopt)
|
||||
* may be used.
|
||||
*
|
||||
* // Do a simple GET request
|
||||
* $data = Remote::get($url);
|
||||
*
|
||||
* // Do a POST request
|
||||
* $data = Remote::get($url, array(
|
||||
* CURLOPT_POST => TRUE,
|
||||
* CURLOPT_POSTFIELDS => http_build_query($array),
|
||||
* ));
|
||||
*
|
||||
* @param string remote URL
|
||||
* @param array curl options
|
||||
* @return string
|
||||
* @throws Kohana_Exception
|
||||
*/
|
||||
public static function get($url, array $options = NULL)
|
||||
{
|
||||
if ($options === NULL)
|
||||
{
|
||||
// Use default options
|
||||
$options = Remote::$default_options;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Add default options
|
||||
$options = $options + Remote::$default_options;
|
||||
}
|
||||
|
||||
// The transfer must always be returned
|
||||
$options[CURLOPT_RETURNTRANSFER] = TRUE;
|
||||
|
||||
// Open a new remote connection
|
||||
$remote = curl_init($url);
|
||||
|
||||
// Set connection options
|
||||
if ( ! curl_setopt_array($remote, $options))
|
||||
{
|
||||
throw new Kohana_Exception('Failed to set CURL options, check CURL documentation: :url',
|
||||
array(':url' => 'http://php.net/curl_setopt_array'));
|
||||
}
|
||||
|
||||
// Get the response
|
||||
$response = curl_exec($remote);
|
||||
|
||||
// Get the response information
|
||||
$code = curl_getinfo($remote, CURLINFO_HTTP_CODE);
|
||||
|
||||
if ($code AND $code < 200 OR $code > 299)
|
||||
{
|
||||
$error = $response;
|
||||
}
|
||||
elseif ($response === FALSE)
|
||||
{
|
||||
$error = curl_error($remote);
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
curl_close($remote);
|
||||
|
||||
if (isset($error))
|
||||
{
|
||||
throw new Kohana_Exception('Error fetching remote :url [ status :code ] :error',
|
||||
array(':url' => $url, ':code' => $code, ':error' => $error));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the status code (200, 500, etc) for a URL.
|
||||
*
|
||||
* $status = Remote::status($url);
|
||||
*
|
||||
* @param string URL to check
|
||||
* @return integer
|
||||
*/
|
||||
public static function status($url)
|
||||
{
|
||||
// Get the hostname and path
|
||||
$url = parse_url($url);
|
||||
|
||||
if (empty($url['path']))
|
||||
{
|
||||
// Request the root document
|
||||
$url['path'] = '/';
|
||||
}
|
||||
|
||||
// Open a remote connection
|
||||
$port = isset($url['port']) ? $url['port'] : 80;
|
||||
$remote = fsockopen($url['host'], $port, $errno, $errstr, 5);
|
||||
|
||||
if ( ! is_resource($remote))
|
||||
return FALSE;
|
||||
|
||||
// Set CRLF
|
||||
$line_feed = "\r\n";
|
||||
|
||||
// Send request
|
||||
fwrite($remote, 'HEAD '.$url['path'].' HTTP/1.0'.$line_feed);
|
||||
fwrite($remote, 'Host: '.$url['host'].$line_feed);
|
||||
fwrite($remote, 'Connection: close'.$line_feed);
|
||||
fwrite($remote, 'User-Agent: Kohana Framework (+http://kohanaframework.org/)'.$line_feed);
|
||||
|
||||
// Send one more CRLF to terminate the headers
|
||||
fwrite($remote, $line_feed);
|
||||
|
||||
// Remote is offline
|
||||
$response = FALSE;
|
||||
|
||||
while ( ! feof($remote))
|
||||
{
|
||||
// Get the line
|
||||
$line = trim(fgets($remote, 512));
|
||||
|
||||
if ($line !== '' AND preg_match('#^HTTP/1\.[01] (\d{3})#', $line, $matches))
|
||||
{
|
||||
// Response code found
|
||||
$response = (int) $matches[1];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Close the connection
|
||||
fclose($remote);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
} // End remote
|
File diff suppressed because it is too large
Load Diff
328
includes/kohana/system/classes/kohana/request/client.php
Normal file
328
includes/kohana/system/classes/kohana/request/client.php
Normal file
@@ -0,0 +1,328 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Request Client
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
* @since 3.1.0
|
||||
*/
|
||||
abstract class Kohana_Request_Client {
|
||||
|
||||
/**
|
||||
* @var Cache Caching library for request caching
|
||||
*/
|
||||
protected $_cache;
|
||||
|
||||
/**
|
||||
* @var boolean Defines whether this client should cache `private` cache directives
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
||||
*/
|
||||
protected $_allow_private_cache = FALSE;
|
||||
|
||||
/**
|
||||
* @var int The timestamp of the request
|
||||
*/
|
||||
protected $_request_time;
|
||||
|
||||
/**
|
||||
* @var int The timestamp of the response
|
||||
*/
|
||||
protected $_response_time;
|
||||
|
||||
/**
|
||||
* Creates a new `Request_Client` object,
|
||||
* allows for dependency injection.
|
||||
*
|
||||
* @param array $params Params
|
||||
*/
|
||||
public function __construct(array $params = array())
|
||||
{
|
||||
if ($params)
|
||||
{
|
||||
foreach ($params as $key => $value)
|
||||
{
|
||||
if (method_exists($this, $key))
|
||||
{
|
||||
if (property_exists($this, $key) OR property_exists($this, '_'.$key))
|
||||
{
|
||||
$method = trim($key, '_');
|
||||
$this->$method($value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the request, executing the controller action that handles this
|
||||
* request, determined by the [Route].
|
||||
*
|
||||
* 1. Before the controller action is called, the [Controller::before] method
|
||||
* will be called.
|
||||
* 2. Next the controller action will be called.
|
||||
* 3. After the controller action is called, the [Controller::after] method
|
||||
* will be called.
|
||||
*
|
||||
* By default, the output from the controller is captured and returned, and
|
||||
* no headers are sent.
|
||||
*
|
||||
* $request->execute();
|
||||
*
|
||||
* @param Request $request
|
||||
* @return Response
|
||||
* @throws Kohana_Exception
|
||||
* @uses [Kohana::$profiling]
|
||||
* @uses [Profiler]
|
||||
*/
|
||||
abstract public function execute(Request $request);
|
||||
|
||||
/**
|
||||
* Invalidate a cached response for the [Request] supplied.
|
||||
* This has the effect of deleting the response from the
|
||||
* [Cache] entry.
|
||||
*
|
||||
* @param Request $request Response to remove from cache
|
||||
* @return void
|
||||
*/
|
||||
public function invalidate_cache(Request $request)
|
||||
{
|
||||
if ( ! $this->_cache instanceof Cache)
|
||||
return;
|
||||
|
||||
$this->_cache->delete($this->_create_cache_key($request));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter and setter for the internal caching engine,
|
||||
* used to cache responses if available and valid.
|
||||
*
|
||||
* @param Kohana_Cache cache engine to use for caching
|
||||
* @return Kohana_Cache
|
||||
* @return Kohana_Request_Client
|
||||
*/
|
||||
public function cache(Cache $cache = NULL)
|
||||
{
|
||||
if ($cache === NULL)
|
||||
return $this->_cache;
|
||||
|
||||
$this->_cache = $cache;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the [Request_Client::allow_private_cache] setting.
|
||||
* If set to `TRUE`, the client will also cache cache-control directives
|
||||
* that have the `private` setting.
|
||||
*
|
||||
* @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
||||
* @param boolean allow caching of privately marked responses
|
||||
* @return boolean
|
||||
* @return [Request_Client]
|
||||
*/
|
||||
public function allow_private_cache($setting = NULL)
|
||||
{
|
||||
if ($setting === NULL)
|
||||
return $this->_allow_private_cache;
|
||||
|
||||
$this->_allow_private_cache = (bool) $setting;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache key for the request to use for caching
|
||||
* [Kohana_Response] returned by [Request::execute].
|
||||
*
|
||||
* @param Request request
|
||||
* @return string
|
||||
* @return boolean
|
||||
*/
|
||||
public function create_cache_key(Request $request)
|
||||
{
|
||||
return sha1($request->url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether the response can be cached. Uses HTTP
|
||||
* protocol to determine whether the response can be cached.
|
||||
*
|
||||
* @see RFC 2616 http://www.w3.org/Protocols/rfc2616/
|
||||
* @param Response $response The Response
|
||||
* @return boolean
|
||||
*/
|
||||
public function set_cache(Response $response)
|
||||
{
|
||||
$headers = (array) $response->headers();
|
||||
if ($cache_control = arr::get($headers, 'cache-control'))
|
||||
{
|
||||
// Parse the cache control
|
||||
$cache_control = Response::parse_cache_control( (string) $cache_control);
|
||||
|
||||
// If the no-cache or no-store directive is set, return
|
||||
if (array_intersect_key($cache_control, array('no-cache' => NULL, 'no-store' => NULL)))
|
||||
return FALSE;
|
||||
|
||||
// Get the directives
|
||||
$directives = array_keys($cache_control);
|
||||
|
||||
// Check for private cache and get out of here if invalid
|
||||
if ( ! $this->_allow_private_cache and in_array('private', $directives))
|
||||
{
|
||||
if ( ! isset($cache_control['s-maxage']))
|
||||
return FALSE;
|
||||
|
||||
// If there is a s-maxage directive we can use that
|
||||
$cache_control['max-age'] = $cache_control['s-maxage'];
|
||||
}
|
||||
|
||||
// Check that max-age has been set and if it is valid for caching
|
||||
if (isset($cache_control['max-age']) and (int) $cache_control['max-age'] < 1)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($expires = arr::get($headers, 'expires') and ! isset($cache_control['max-age']))
|
||||
{
|
||||
// Can't cache things that have expired already
|
||||
if (strtotime( (string) $expires) <= time())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches a [Response] using the supplied [Cache]
|
||||
* and the key generated by [Request_Client::_create_cache_key].
|
||||
*
|
||||
* If not response is supplied, the cache will be checked for an existing
|
||||
* one that is available.
|
||||
*
|
||||
* @param Request $request The request
|
||||
* @param Response $response Response
|
||||
* @return mixed
|
||||
*/
|
||||
public function cache_response(Request $request, Response $response = NULL)
|
||||
{
|
||||
if ( ! $this->_cache instanceof Cache)
|
||||
return FALSE;
|
||||
|
||||
// Check for Pragma: no-cache
|
||||
if ($pragma = $request->headers('pragma'))
|
||||
{
|
||||
if ($pragma instanceof HTTP_Header_Value and $pragma->key == 'no-cache')
|
||||
return FALSE;
|
||||
elseif (is_array($pragma) and isset($pragma['no-cache']))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ( ! $response)
|
||||
{
|
||||
$response = $this->_cache->get($this->create_cache_key($request));
|
||||
return ($response !== NULL) ? $response : FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($ttl = $this->cache_lifetime($response)) === FALSE)
|
||||
return FALSE;
|
||||
|
||||
return $this->_cache->set($this->create_cache_key($request), $response, $ttl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total Time To Live based on the specification
|
||||
* RFC 2616 cache lifetime rules.
|
||||
*
|
||||
* @param Response $response Response to evaluate
|
||||
* @return mixed TTL value or false if the response should not be cached
|
||||
*/
|
||||
public function cache_lifetime(Response $response)
|
||||
{
|
||||
// Get out of here if this cannot be cached
|
||||
if ( ! $this->set_cache($response))
|
||||
return FALSE;
|
||||
|
||||
// Calculate apparent age
|
||||
if ($date = $response->headers('date'))
|
||||
{
|
||||
$apparent_age = max(0, $this->_response_time - strtotime( (string) $date));
|
||||
}
|
||||
else
|
||||
{
|
||||
$apparent_age = max(0, $this->_response_time);
|
||||
}
|
||||
|
||||
// Calculate corrected received age
|
||||
if ($age = $response->headers('age'))
|
||||
{
|
||||
$corrected_received_age = max($apparent_age, intval( (string) $age));
|
||||
}
|
||||
else
|
||||
{
|
||||
$corrected_received_age = $apparent_age;
|
||||
}
|
||||
|
||||
// Corrected initial age
|
||||
$corrected_initial_age = $corrected_received_age + $this->request_execution_time();
|
||||
|
||||
// Resident time
|
||||
$resident_time = time() - $this->_response_time;
|
||||
|
||||
// Current age
|
||||
$current_age = $corrected_initial_age + $resident_time;
|
||||
|
||||
// Prepare the cache freshness lifetime
|
||||
$ttl = NULL;
|
||||
|
||||
// Cache control overrides
|
||||
if ($cache_control = $response->headers('cache-control'))
|
||||
{
|
||||
// Parse the cache control header
|
||||
$cache_control = Response::parse_cache_control( (string) $cache_control);
|
||||
|
||||
if (isset($cache_control['max-age']))
|
||||
{
|
||||
$ttl = (int) $cache_control['max-age'];
|
||||
}
|
||||
|
||||
if (isset($cache_control['s-maxage']) AND isset($cache_control['private']) AND $this->_allow_private_cache)
|
||||
{
|
||||
$ttl = (int) $cache_control['s-maxage'];
|
||||
}
|
||||
|
||||
if (isset($cache_control['max-stale']) AND ! isset($cache_control['must-revalidate']))
|
||||
{
|
||||
$ttl = $current_age + (int) $cache_control['max-stale'];
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a TTL at this point, return
|
||||
if ($ttl !== NULL)
|
||||
return $ttl;
|
||||
|
||||
if ($expires = $response->headers('expires'))
|
||||
return strtotime( (string) $expires) - $current_age;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the last request execution.
|
||||
* Either returns the time of completed requests or
|
||||
* `FALSE` if the request hasn't finished executing, or
|
||||
* is yet to be run.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function request_execution_time()
|
||||
{
|
||||
if ($this->_request_time === NULL OR $this->_response_time === NULL)
|
||||
return FALSE;
|
||||
|
||||
return $this->_response_time - $this->_request_time;
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user