Upgrade to KH 3.1.3.1
This commit is contained in:
@@ -1,43 +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].
|
||||
*
|
||||
* @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,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,12 +1,12 @@
|
||||
<?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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Arr {
|
||||
|
||||
@@ -37,6 +37,35 @@ class Kohana_Arr {
|
||||
return array_keys($keys) !== $keys;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a value is an array with an additional check for array-like objects.
|
||||
*
|
||||
* // Returns TRUE
|
||||
* Arr::is_array(array());
|
||||
* Arr::is_array(new ArrayObject);
|
||||
*
|
||||
* // Returns FALSE
|
||||
* Arr::is_array(FALSE);
|
||||
* Arr::is_array('not an array!');
|
||||
* Arr::is_array(Database::instance());
|
||||
*
|
||||
* @param mixed value to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_array($value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
// Definitely an array
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Possibly a Traversable object, functionally the same as an array
|
||||
return (is_object($value) AND $value instanceof Traversable);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from an array using a dot separated path.
|
||||
*
|
||||
@@ -48,31 +77,51 @@ class Kohana_Arr {
|
||||
* // Get the values of "color" in theme
|
||||
* $colors = Arr::path($array, 'theme.*.color');
|
||||
*
|
||||
* // Using an array of keys
|
||||
* $colors = Arr::path($array, array('theme', '*', 'color'));
|
||||
*
|
||||
* @param array array to search
|
||||
* @param string key path, delimiter separated
|
||||
* @param mixed key path string (delimiter separated) or array of keys
|
||||
* @param mixed default value if the path is not set
|
||||
* @param string key path delimiter
|
||||
* @return mixed
|
||||
*/
|
||||
public static function path($array, $path, $default = NULL, $delimiter = NULL)
|
||||
{
|
||||
if (array_key_exists($path, $array))
|
||||
if ( ! Arr::is_array($array))
|
||||
{
|
||||
// No need to do extra processing
|
||||
return $array[$path];
|
||||
// This is not an array!
|
||||
return $default;
|
||||
}
|
||||
|
||||
if ($delimiter === NULL)
|
||||
if (is_array($path))
|
||||
{
|
||||
// Use the default delimiter
|
||||
$delimiter = Arr::$delimiter;
|
||||
// The path has already been separated into keys
|
||||
$keys = $path;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (array_key_exists($path, $array))
|
||||
{
|
||||
// No need to do extra processing
|
||||
return $array[$path];
|
||||
}
|
||||
|
||||
// Remove outer delimiters, wildcards, or spaces
|
||||
$path = trim($path, "{$delimiter}* ");
|
||||
if ($delimiter === NULL)
|
||||
{
|
||||
// Use the default delimiter
|
||||
$delimiter = Arr::$delimiter;
|
||||
}
|
||||
|
||||
// Split the keys by delimiter
|
||||
$keys = explode($delimiter, $path);
|
||||
// Remove starting delimiters and spaces
|
||||
$path = ltrim($path, "{$delimiter} ");
|
||||
|
||||
// Remove ending delimiters, spaces, and wildcards
|
||||
$path = rtrim($path, "{$delimiter} *");
|
||||
|
||||
// Split the keys by delimiter
|
||||
$keys = explode($delimiter, $path);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
@@ -88,7 +137,7 @@ class Kohana_Arr {
|
||||
{
|
||||
if ($keys)
|
||||
{
|
||||
if (is_array($array[$key]))
|
||||
if (Arr::is_array($array[$key]))
|
||||
{
|
||||
// Dig down into the next part of the path
|
||||
$array = $array[$key];
|
||||
@@ -141,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.
|
||||
*
|
||||
@@ -209,26 +301,38 @@ class Kohana_Arr {
|
||||
}
|
||||
|
||||
/**
|
||||
* Binary search algorithm.
|
||||
* Retrieves muliple single-key values from a list of arrays.
|
||||
*
|
||||
* @deprecated Use [array_search](http://php.net/array_search) instead
|
||||
* // Get all of the "id" values from a result
|
||||
* $ids = Arr::pluck($result, 'id');
|
||||
*
|
||||
* @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
|
||||
* [!!] A list of arrays is an array that contains arrays, eg: array(array $a, array $b, array $c, ...)
|
||||
*
|
||||
* @param array list of arrays to check
|
||||
* @param string key to pluck
|
||||
* @return array
|
||||
*/
|
||||
public static function binary_search($needle, $haystack, $sort = FALSE)
|
||||
public static function pluck($array, $key)
|
||||
{
|
||||
return array_search($needle, $haystack);
|
||||
$values = array();
|
||||
|
||||
foreach ($array as $row)
|
||||
{
|
||||
if (isset($row[$key]))
|
||||
{
|
||||
// Found a value in this row
|
||||
$values[] = $row[$key];
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -308,7 +412,7 @@ class Kohana_Arr {
|
||||
{
|
||||
if (isset($result[$key]))
|
||||
{
|
||||
if (is_array($val) && is_array($result[$key]))
|
||||
if (is_array($val) AND is_array($result[$key]))
|
||||
{
|
||||
if (Arr::is_assoc($val))
|
||||
{
|
||||
@@ -360,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,8 +5,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_CLI {
|
||||
|
||||
|
@@ -6,33 +6,37 @@
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config {
|
||||
|
||||
// Singleton static instance
|
||||
/**
|
||||
* @var Kohana_Config Singleton static instance
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
// Configuration readers
|
||||
/**
|
||||
* @var array Configuration readers
|
||||
*/
|
||||
protected $_readers = array();
|
||||
|
||||
/**
|
||||
@@ -43,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)
|
||||
{
|
||||
@@ -68,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)
|
||||
{
|
||||
@@ -90,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,20 +1,24 @@
|
||||
<?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 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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 {
|
||||
|
||||
// Configuration group name
|
||||
/**
|
||||
* @var string Configuration group name
|
||||
*/
|
||||
protected $_configuration_group;
|
||||
|
||||
// Has the config group changed?
|
||||
/**
|
||||
* @var bool Has the config group changed?
|
||||
*/
|
||||
protected $_configuration_modified = FALSE;
|
||||
|
||||
public function __construct($directory = 'config')
|
||||
@@ -53,4 +57,4 @@ class Kohana_Config_File extends Kohana_Config_Reader {
|
||||
return parent::load($group, $config);
|
||||
}
|
||||
|
||||
} // End Kohana_Config
|
||||
} // End Kohana_Config_File
|
||||
|
@@ -6,12 +6,14 @@
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Config_Reader extends ArrayObject {
|
||||
|
||||
// Configuration group name
|
||||
/**
|
||||
* @var string Configuration group name
|
||||
*/
|
||||
protected $_configuration_group;
|
||||
|
||||
/**
|
||||
|
@@ -11,33 +11,42 @@
|
||||
* $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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller {
|
||||
|
||||
/**
|
||||
* @var object Request that created the controller
|
||||
* @var Request Request that created the 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 object 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(Kohana_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,19 +25,25 @@
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller_REST extends Controller {
|
||||
|
||||
/**
|
||||
* @var array REST types
|
||||
*/
|
||||
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',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string requested action
|
||||
*/
|
||||
protected $_action_requested = '';
|
||||
|
||||
/**
|
||||
@@ -47,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,13 +5,13 @@
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller_Template extends Controller {
|
||||
|
||||
/**
|
||||
* @var string page template
|
||||
* @var View page template
|
||||
*/
|
||||
public $template = 'template';
|
||||
|
||||
@@ -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,15 +5,15 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
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';
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@@ -5,8 +5,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Date {
|
||||
|
||||
@@ -17,7 +17,11 @@ class Kohana_Date {
|
||||
const DAY = 86400;
|
||||
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
|
||||
@@ -27,7 +31,7 @@ class Kohana_Date {
|
||||
/**
|
||||
* Timezone for formatted_time
|
||||
* @link http://uk2.php.net/manual/en/timezones.php
|
||||
* @var string
|
||||
* @var string
|
||||
*/
|
||||
public static $timezone;
|
||||
|
||||
@@ -190,11 +194,15 @@ class Kohana_Date {
|
||||
{
|
||||
case 'am':
|
||||
if ($hour == 12)
|
||||
{
|
||||
$hour = 0;
|
||||
}
|
||||
break;
|
||||
case 'pm':
|
||||
if ($hour < 12)
|
||||
{
|
||||
$hour += 12;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -246,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;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -270,8 +306,8 @@ class Kohana_Date {
|
||||
public static function years($start = FALSE, $end = FALSE)
|
||||
{
|
||||
// Default values
|
||||
$start = ($start === FALSE) ? date('Y') - 5 : (int) $start;
|
||||
$end = ($end === FALSE) ? date('Y') + 5 : (int) $end;
|
||||
$start = ($start === FALSE) ? (date('Y') - 5) : (int) $start;
|
||||
$end = ($end === FALSE) ? (date('Y') + 5) : (int) $end;
|
||||
|
||||
$years = array();
|
||||
|
||||
@@ -300,7 +336,7 @@ class Kohana_Date {
|
||||
public static function span($remote, $local = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
|
||||
{
|
||||
// Normalize output
|
||||
$output = trim(strtolower((string) $output));
|
||||
$output = trim(strtolower( (string) $output));
|
||||
|
||||
if ( ! $output)
|
||||
{
|
||||
@@ -374,20 +410,25 @@ class Kohana_Date {
|
||||
|
||||
/**
|
||||
* Returns the difference between a time and now in a "fuzzy" way.
|
||||
* Note that unlike [Date::span], the "local" timestamp will always be the
|
||||
* current time. Displaying a fuzzy time instead of a date is usually
|
||||
* faster to read and understand.
|
||||
* Displaying a fuzzy time instead of a date is usually faster to read and understand.
|
||||
*
|
||||
* $span = Date::fuzzy_span(time() - 10); // "moments ago"
|
||||
* $span = Date::fuzzy_span(time() + 20); // "in moments"
|
||||
*
|
||||
* A second parameter is available to manually set the "local" timestamp,
|
||||
* however this parameter shouldn't be needed in normal usage and is only
|
||||
* included for unit tests
|
||||
*
|
||||
* @param integer "remote" timestamp
|
||||
* @param integer "local" timestamp, defaults to time()
|
||||
* @return string
|
||||
*/
|
||||
public static function fuzzy_span($timestamp)
|
||||
public static function fuzzy_span($timestamp, $local_timestamp = NULL)
|
||||
{
|
||||
$local_timestamp = ($local_timestamp === NULL) ? time() : (int) $local_timestamp;
|
||||
|
||||
// Determine the difference in seconds
|
||||
$offset = abs(time() - $timestamp);
|
||||
$offset = abs($local_timestamp - $timestamp);
|
||||
|
||||
if ($offset <= Date::MINUTE)
|
||||
{
|
||||
@@ -470,7 +511,7 @@ class Kohana_Date {
|
||||
$span = 'a long time';
|
||||
}
|
||||
|
||||
if ($timestamp <= time())
|
||||
if ($timestamp <= $local_timestamp)
|
||||
{
|
||||
// This is in the past
|
||||
return $span.' ago';
|
||||
@@ -531,7 +572,7 @@ class Kohana_Date {
|
||||
|
||||
return mktime($hrs, $min, $sec, $mon, $day, $year + 1980);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a date/time string with the specified timestamp format
|
||||
*
|
||||
@@ -544,13 +585,13 @@ class Kohana_Date {
|
||||
*/
|
||||
public static function formatted_time($datetime_str = 'now', $timestamp_format = NULL, $timezone = NULL)
|
||||
{
|
||||
$timestamp_format = $timestamp_format == NULL ? Date::$timestamp_format : $timestamp_format;
|
||||
$timezone = $timezone === NULL ? Date::$timezone : $timezone;
|
||||
|
||||
$timestamp_format = ($timestamp_format == NULL) ? Date::$timestamp_format : $timestamp_format;
|
||||
$timezone = ($timezone === NULL) ? Date::$timezone : $timezone;
|
||||
|
||||
$time = new DateTime($datetime_str, new DateTimeZone(
|
||||
$timezone ? $timezone : date_default_timezone_get()
|
||||
));
|
||||
|
||||
|
||||
return $time->format($timestamp_format);
|
||||
}
|
||||
|
||||
|
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,8 +20,8 @@
|
||||
* @package Kohana
|
||||
* @category Security
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Encrypt {
|
||||
|
||||
@@ -35,7 +35,9 @@ class Kohana_Encrypt {
|
||||
*/
|
||||
public static $instances = array();
|
||||
|
||||
// OS-dependent RAND type to use
|
||||
/**
|
||||
* @var string OS-dependent RAND type to use
|
||||
*/
|
||||
protected static $_rand;
|
||||
|
||||
/**
|
||||
@@ -45,7 +47,7 @@ class Kohana_Encrypt {
|
||||
* $encrypt = Encrypt::instance();
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @return object
|
||||
* @return Encrypt
|
||||
*/
|
||||
public static function instance($name = NULL)
|
||||
{
|
||||
|
@@ -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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/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,12 +1,12 @@
|
||||
<?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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Feed {
|
||||
|
||||
@@ -20,23 +20,23 @@ class Kohana_Feed {
|
||||
public static function parse($feed, $limit = 0)
|
||||
{
|
||||
// Check if SimpleXML is installed
|
||||
if( ! function_exists('simplexml_load_file'))
|
||||
if ( ! function_exists('simplexml_load_file'))
|
||||
throw new Kohana_Exception('SimpleXML must be installed!');
|
||||
|
||||
// Make limit an integer
|
||||
$limit = (int) $limit;
|
||||
|
||||
// Disable error reporting while opening the feed
|
||||
$ER = error_reporting(0);
|
||||
$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);
|
||||
|
||||
// Restore error reporting
|
||||
error_reporting($ER);
|
||||
error_reporting($error_level);
|
||||
|
||||
// Feed could not be loaded
|
||||
if ($feed === FALSE)
|
||||
|
@@ -1,12 +1,12 @@
|
||||
<?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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_File {
|
||||
|
||||
@@ -40,7 +40,7 @@ class Kohana_File {
|
||||
|
||||
if (class_exists('finfo', FALSE))
|
||||
{
|
||||
if ($info = new finfo(FILEINFO_MIME_TYPE))
|
||||
if ($info = new finfo(defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME))
|
||||
{
|
||||
return $info->file($filename);
|
||||
}
|
||||
@@ -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,8 +8,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2008 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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
|
||||
@@ -270,7 +270,7 @@ class Kohana_Form {
|
||||
else
|
||||
{
|
||||
// Convert the selected options to an array
|
||||
$selected = array((string) $selected);
|
||||
$selected = array( (string) $selected);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -13,8 +13,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
* @uses Kohana::cache
|
||||
*/
|
||||
class Kohana_Fragment {
|
||||
@@ -29,7 +29,9 @@ class Kohana_Fragment {
|
||||
*/
|
||||
public static $i18n = FALSE;
|
||||
|
||||
// List of buffer => cache key
|
||||
/**
|
||||
* @var array list of buffer => cache key
|
||||
*/
|
||||
protected static $_caches = array();
|
||||
|
||||
/**
|
||||
|
@@ -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,8 +6,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_HTML {
|
||||
|
||||
@@ -63,7 +63,7 @@ class Kohana_HTML {
|
||||
*/
|
||||
public static function chars($value, $double_encode = TRUE)
|
||||
{
|
||||
return htmlspecialchars((string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
return htmlspecialchars( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,7 +79,7 @@ class Kohana_HTML {
|
||||
*/
|
||||
public static function entities($value, $double_encode = TRUE)
|
||||
{
|
||||
return htmlentities((string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
return htmlentities( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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>';
|
||||
}
|
||||
@@ -181,11 +183,18 @@ class Kohana_HTML {
|
||||
switch (rand(1, 3))
|
||||
{
|
||||
// HTML entity code
|
||||
case 1: $safe .= '&#'.ord($letter).';'; break;
|
||||
case 1:
|
||||
$safe .= '&#'.ord($letter).';';
|
||||
break;
|
||||
|
||||
// Hex character code
|
||||
case 2: $safe .= '&#x'.dechex(ord($letter)).';'; break;
|
||||
case 2:
|
||||
$safe .= '&#x'.dechex(ord($letter)).';';
|
||||
break;
|
||||
|
||||
// Raw (no) encoding
|
||||
case 3: $safe .= $letter;
|
||||
case 3:
|
||||
$safe .= $letter;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -240,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
|
||||
@@ -274,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
|
||||
@@ -303,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
|
||||
@@ -357,6 +370,12 @@ class Kohana_HTML {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_int($key))
|
||||
{
|
||||
// Assume non-associative keys are mirrored attributes
|
||||
$key = $value;
|
||||
}
|
||||
|
||||
// Add the attribute value
|
||||
$compiled .= ' '.$key.'="'.HTML::chars($value).'"';
|
||||
}
|
||||
|
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,13 +12,11 @@
|
||||
* // 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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_I18n {
|
||||
|
||||
@@ -27,7 +25,14 @@ class Kohana_I18n {
|
||||
*/
|
||||
public static $lang = 'en-us';
|
||||
|
||||
// Cache of loaded languages
|
||||
/**
|
||||
* @var string source language: en-us, es-es, zh-cn, etc
|
||||
*/
|
||||
public static $source = 'en-us';
|
||||
|
||||
/**
|
||||
* @var array cache of loaded languages
|
||||
*/
|
||||
protected static $_cache = array();
|
||||
|
||||
/**
|
||||
@@ -130,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,16 +8,24 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Inflector {
|
||||
|
||||
// Cached inflections
|
||||
/**
|
||||
* @var array cached inflections
|
||||
*/
|
||||
protected static $cache = array();
|
||||
|
||||
// Uncountable and irregular words
|
||||
/**
|
||||
* @var array uncountable words
|
||||
*/
|
||||
protected static $uncountable;
|
||||
|
||||
/**
|
||||
* @var array irregular words
|
||||
*/
|
||||
protected static $irregular;
|
||||
|
||||
/**
|
||||
@@ -151,11 +159,14 @@ class Kohana_Inflector {
|
||||
return $str;
|
||||
|
||||
// Remove garbage
|
||||
$str = strtolower(trim($str));
|
||||
$str = trim($str);
|
||||
|
||||
// Cache key name
|
||||
$key = 'plural_'.$str.$count;
|
||||
|
||||
// Check uppercase
|
||||
$is_uppercase = ctype_upper($str);
|
||||
|
||||
if (isset(Inflector::$cache[$key]))
|
||||
return Inflector::$cache[$key];
|
||||
|
||||
@@ -186,6 +197,12 @@ class Kohana_Inflector {
|
||||
$str .= 's';
|
||||
}
|
||||
|
||||
// Convert to uppsecase if nessasary
|
||||
if ($is_uppercase)
|
||||
{
|
||||
$str = strtoupper($str);
|
||||
}
|
||||
|
||||
// Set the cache and return
|
||||
return Inflector::$cache[$key] = $str;
|
||||
}
|
||||
@@ -207,6 +224,21 @@ class Kohana_Inflector {
|
||||
return substr(str_replace(' ', '', $str), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a camel case phrase into a spaced phrase.
|
||||
*
|
||||
* $str = Inflector::decamelize('houseCat'); // "house cat"
|
||||
* $str = Inflector::decamelize('kingAllyCat'); // "king ally cat"
|
||||
*
|
||||
* @param string phrase to camelize
|
||||
* @param string word separator
|
||||
* @return string
|
||||
*/
|
||||
public static function decamelize($str, $sep = ' ')
|
||||
{
|
||||
return strtolower(preg_replace('/([a-z])([A-Z])/', '$1'.$sep.'$2', trim($str)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Makes a phrase underscored instead of spaced.
|
||||
*
|
||||
|
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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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,53 +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;
|
||||
}
|
||||
|
||||
// List of added messages
|
||||
private $_messages = array();
|
||||
|
||||
// List of log writers
|
||||
private $_writers = array();
|
||||
/**
|
||||
* @var array list of added messages
|
||||
*/
|
||||
protected $_messages = array();
|
||||
|
||||
/**
|
||||
* Attaches a log writer, and optionally limits the types of messages that
|
||||
* @var array list of log writers
|
||||
*/
|
||||
protected $_writers = array();
|
||||
|
||||
/**
|
||||
* 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 $this
|
||||
* @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;
|
||||
@@ -85,10 +105,10 @@ class Kohana_Log {
|
||||
*
|
||||
* $log->detach($writer);
|
||||
*
|
||||
* @param object Kohana_Log_Writer instance
|
||||
* @return $this
|
||||
* @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}"]);
|
||||
@@ -100,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 $this
|
||||
* @return Log
|
||||
*/
|
||||
public function add($type, $message, array $values = NULL)
|
||||
public function add($level, $message, array $values = NULL)
|
||||
{
|
||||
if ($values)
|
||||
{
|
||||
@@ -120,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();
|
||||
@@ -157,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);
|
||||
@@ -169,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,19 +5,21 @@
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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 {
|
||||
|
||||
// Directory to place log files in
|
||||
/**
|
||||
* @var string Directory to place log files in
|
||||
*/
|
||||
protected $_directory;
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -27,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
|
||||
@@ -47,31 +49,31 @@ class Kohana_Log_File extends Kohana_Log_Writer {
|
||||
public function write(array $messages)
|
||||
{
|
||||
// Set the yearly directory name
|
||||
$directory = $this->_directory.date('Y').DIRECTORY_SEPARATOR;
|
||||
$directory = $this->_directory.date('Y');
|
||||
|
||||
if ( ! is_dir($directory))
|
||||
{
|
||||
// Create the yearly directory
|
||||
mkdir($directory, 0777);
|
||||
mkdir($directory, 02777);
|
||||
|
||||
// Set permissions (must be manually set to fix umask issues)
|
||||
chmod($directory, 0777);
|
||||
chmod($directory, 02777);
|
||||
}
|
||||
|
||||
// Add the month to the directory
|
||||
$directory .= date('m').DIRECTORY_SEPARATOR;
|
||||
$directory .= DIRECTORY_SEPARATOR.date('m');
|
||||
|
||||
if ( ! is_dir($directory))
|
||||
{
|
||||
// Create the yearly directory
|
||||
mkdir($directory, 0777);
|
||||
mkdir($directory, 02777);
|
||||
|
||||
// Set permissions (must be manually set to fix umask issues)
|
||||
chmod($directory, 0777);
|
||||
chmod($directory, 02777);
|
||||
}
|
||||
|
||||
// Set the name of the log file
|
||||
$filename = $directory.date('d').EXT;
|
||||
$filename = $directory.DIRECTORY_SEPARATOR.date('d').EXT;
|
||||
|
||||
if ( ! file_exists($filename))
|
||||
{
|
||||
@@ -82,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);
|
||||
}
|
||||
}
|
||||
|
||||
|
31
includes/kohana/system/classes/kohana/log/stderr.php
Normal file
31
includes/kohana/system/classes/kohana/log/stderr.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* STDERR log writer. Writes out messages to STDERR.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Log_StdErr extends Kohana_Log_Writer {
|
||||
/**
|
||||
* Writes each of the messages to STDERR.
|
||||
*
|
||||
* $writer->write($messages);
|
||||
*
|
||||
* @param array messages
|
||||
* @return void
|
||||
*/
|
||||
public function write(array $messages)
|
||||
{
|
||||
// Set the log line format
|
||||
$format = 'time --- type: body';
|
||||
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
// Writes out each message
|
||||
fwrite(STDERR, PHP_EOL.strtr($format, $message));
|
||||
}
|
||||
}
|
||||
} // End Kohana_Log_StdErr
|
31
includes/kohana/system/classes/kohana/log/stdout.php
Normal file
31
includes/kohana/system/classes/kohana/log/stdout.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* STDOUT log writer. Writes out messages to STDOUT.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Logging
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Log_StdOut extends Kohana_Log_Writer {
|
||||
/**
|
||||
* Writes each of the messages to STDOUT.
|
||||
*
|
||||
* $writer->write($messages);
|
||||
*
|
||||
* @param array messages
|
||||
* @return void
|
||||
*/
|
||||
public function write(array $messages)
|
||||
{
|
||||
// Set the log line format
|
||||
$format = 'time --- type: body';
|
||||
|
||||
foreach ($messages as $message)
|
||||
{
|
||||
// Writes out each message
|
||||
fwrite(STDOUT, PHP_EOL.strtr($format, $message));
|
||||
}
|
||||
}
|
||||
} // End Kohana_Log_StdOut
|
@@ -6,13 +6,18 @@
|
||||
* @category Logging
|
||||
* @author Jeremy Bush
|
||||
* @copyright (c) 2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Log_Syslog extends Kohana_Log_Writer {
|
||||
class Kohana_Log_Syslog extends Log_Writer {
|
||||
|
||||
// The syslog identifier
|
||||
/**
|
||||
* @var string The syslog identifier
|
||||
*/
|
||||
protected $_ident;
|
||||
|
||||
/**
|
||||
* @var array log levels
|
||||
*/
|
||||
protected $_syslog_levels = array('ERROR' => LOG_ERR,
|
||||
'CRITICAL' => LOG_CRIT,
|
||||
'STRACE' => LOG_ALERT,
|
||||
@@ -47,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']);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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,54 +5,25 @@
|
||||
* @package Kohana
|
||||
* @category Models
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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);
|
||||
}
|
||||
|
||||
// Database instance
|
||||
protected $_db = 'default';
|
||||
|
||||
/**
|
||||
* Loads the database.
|
||||
*
|
||||
* $model = new Foo_Model($db);
|
||||
*
|
||||
* @param mixed Database instance object or string
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($db = NULL)
|
||||
{
|
||||
if ($db !== NULL)
|
||||
{
|
||||
// Set the database instance name
|
||||
$this->_db = $db;
|
||||
}
|
||||
|
||||
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 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @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,8 +8,8 @@
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Profiler {
|
||||
|
||||
@@ -18,7 +18,9 @@ class Kohana_Profiler {
|
||||
*/
|
||||
public static $rollover = 1000;
|
||||
|
||||
// Collected benchmarks
|
||||
/**
|
||||
* @var array collected benchmarks
|
||||
*/
|
||||
protected static $_marks = array();
|
||||
|
||||
/**
|
||||
@@ -193,7 +195,7 @@ class Kohana_Profiler {
|
||||
// Which groups do we need to calculate stats for?
|
||||
$groups = ($groups === NULL)
|
||||
? Profiler::groups()
|
||||
: array_intersect_key(Profiler::groups(), array_flip((array) $groups));
|
||||
: array_intersect_key(Profiler::groups(), array_flip( (array) $groups));
|
||||
|
||||
// All statistics
|
||||
$stats = array();
|
||||
@@ -332,22 +334,30 @@ class Kohana_Profiler {
|
||||
|
||||
// Calculate max time
|
||||
if ($stats['max']['time'] === NULL OR $time > $stats['max']['time'])
|
||||
{
|
||||
$stats['max']['time'] = $time;
|
||||
}
|
||||
|
||||
// Calculate min time
|
||||
if ($stats['min']['time'] === NULL OR $time < $stats['min']['time'])
|
||||
{
|
||||
$stats['min']['time'] = $time;
|
||||
}
|
||||
|
||||
// Add to total time
|
||||
$stats['total']['time'] += $time;
|
||||
|
||||
// Calculate max memory
|
||||
if ($stats['max']['memory'] === NULL OR $memory > $stats['max']['memory'])
|
||||
{
|
||||
$stats['max']['memory'] = $memory;
|
||||
}
|
||||
|
||||
// Calculate min memory
|
||||
if ($stats['min']['memory'] === NULL OR $memory < $stats['min']['memory'])
|
||||
{
|
||||
$stats['min']['memory'] = $memory;
|
||||
}
|
||||
|
||||
// Add to total memory
|
||||
$stats['total']['memory'] += $memory;
|
||||
|
@@ -1,174 +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-2009 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Remote {
|
||||
// Store our curl session resource
|
||||
static $remote = NULL;
|
||||
|
||||
// Default curl options
|
||||
public static $default_options = array
|
||||
(
|
||||
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; Kohana v3.0 +http://kohanaphp.com/)',
|
||||
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, $session = FALSE)
|
||||
{
|
||||
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;
|
||||
|
||||
// If we have an old session, lets auto close it.
|
||||
if (! $session AND Remote::$remote)
|
||||
Remote::clear();
|
||||
|
||||
// Open a new remote connection
|
||||
if (! $session OR is_null(Remote::$remote))
|
||||
{
|
||||
$remote = Remote::$remote = curl_init($url);
|
||||
}
|
||||
else
|
||||
{
|
||||
$remote = Remote::$remote;
|
||||
curl_setopt($remote,CURLOPT_URL,$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);
|
||||
}
|
||||
|
||||
if (isset($error))
|
||||
{
|
||||
throw new Kohana_Exception('Error fetching remote :url [ status :code ] :error',
|
||||
array(':url' => $url, ':code' => $code, ':error' => $error));
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clear an existing curl session
|
||||
*/
|
||||
public static function clear()
|
||||
{
|
||||
if (is_resource(Remote::$remote))
|
||||
curl_close(Remote::$remote);
|
||||
|
||||
Remote::$remote = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
$CRLF = "\r\n";
|
||||
|
||||
// Send request
|
||||
fwrite($remote, 'HEAD '.$url['path'].' HTTP/1.0'.$CRLF);
|
||||
fwrite($remote, 'Host: '.$url['host'].$CRLF);
|
||||
fwrite($remote, 'Connection: close'.$CRLF);
|
||||
fwrite($remote, 'User-Agent: Kohana Framework (+http://kohanaphp.com/)'.$CRLF);
|
||||
|
||||
// Send one more CRLF to terminate the headers
|
||||
fwrite($remote, $CRLF);
|
||||
|
||||
// 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