Update Kohana to 3.1.3.1
This commit is contained in:
@@ -1,50 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
if ( ! defined('KOHANA_START_TIME'))
|
||||
{
|
||||
/**
|
||||
* Define the start time of the application, used for profiling.
|
||||
*/
|
||||
define('KOHANA_START_TIME', microtime(TRUE));
|
||||
}
|
||||
|
||||
if ( ! defined('KOHANA_START_MEMORY'))
|
||||
{
|
||||
/**
|
||||
* Define the memory usage at the start of the application, used for profiling.
|
||||
*/
|
||||
define('KOHANA_START_MEMORY', memory_get_usage());
|
||||
}
|
||||
|
||||
/**
|
||||
* 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]. The default source
|
||||
* language is defined by [I18n::$source].
|
||||
*
|
||||
* @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, $source = NULL)
|
||||
{
|
||||
if ( ! $source)
|
||||
{
|
||||
// Use the default source language
|
||||
$source = I18n::$source;
|
||||
}
|
||||
|
||||
if ($source !== 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,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
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user