Init with KH 3.1.3.1
This commit is contained in:
3
includes/kohana/system/classes/arr.php
Normal file
3
includes/kohana/system/classes/arr.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Arr extends Kohana_Arr {}
|
3
includes/kohana/system/classes/cli.php
Normal file
3
includes/kohana/system/classes/cli.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class CLI extends Kohana_CLI {}
|
3
includes/kohana/system/classes/config.php
Normal file
3
includes/kohana/system/classes/config.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
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 {}
|
3
includes/kohana/system/classes/controller.php
Normal file
3
includes/kohana/system/classes/controller.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class Controller extends Kohana_Controller {}
|
3
includes/kohana/system/classes/controller/rest.php
Normal file
3
includes/kohana/system/classes/controller/rest.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class Controller_REST extends Kohana_Controller_REST {}
|
3
includes/kohana/system/classes/controller/template.php
Normal file
3
includes/kohana/system/classes/controller/template.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class Controller_Template extends Kohana_Controller_Template {}
|
3
includes/kohana/system/classes/cookie.php
Normal file
3
includes/kohana/system/classes/cookie.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Cookie extends Kohana_Cookie {}
|
3
includes/kohana/system/classes/date.php
Normal file
3
includes/kohana/system/classes/date.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Date extends Kohana_Date {}
|
3
includes/kohana/system/classes/debug.php
Normal file
3
includes/kohana/system/classes/debug.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Debug extends Kohana_Debug {}
|
3
includes/kohana/system/classes/encrypt.php
Normal file
3
includes/kohana/system/classes/encrypt.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Encrypt extends Kohana_Encrypt {}
|
3
includes/kohana/system/classes/feed.php
Normal file
3
includes/kohana/system/classes/feed.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Feed extends Kohana_Feed {}
|
3
includes/kohana/system/classes/file.php
Normal file
3
includes/kohana/system/classes/file.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class File extends Kohana_File {}
|
3
includes/kohana/system/classes/form.php
Normal file
3
includes/kohana/system/classes/form.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Form extends Kohana_Form {}
|
3
includes/kohana/system/classes/fragment.php
Normal file
3
includes/kohana/system/classes/fragment.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Fragment extends Kohana_Fragment {}
|
3
includes/kohana/system/classes/html.php
Normal file
3
includes/kohana/system/classes/html.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class HTML extends Kohana_HTML {}
|
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 {}
|
3
includes/kohana/system/classes/http/exception.php
Normal file
3
includes/kohana/system/classes/http/exception.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
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 {}
|
3
includes/kohana/system/classes/i18n.php
Normal file
3
includes/kohana/system/classes/i18n.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class I18n extends Kohana_I18n {}
|
3
includes/kohana/system/classes/inflector.php
Normal file
3
includes/kohana/system/classes/inflector.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Inflector extends Kohana_Inflector {}
|
3
includes/kohana/system/classes/kohana.php
Normal file
3
includes/kohana/system/classes/kohana.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana extends Kohana_Core {}
|
574
includes/kohana/system/classes/kohana/arr.php
Normal file
574
includes/kohana/system/classes/kohana/arr.php
Normal file
@@ -0,0 +1,574 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Array helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Arr {
|
||||
|
||||
/**
|
||||
* @var string default delimiter for path()
|
||||
*/
|
||||
public static $delimiter = '.';
|
||||
|
||||
/**
|
||||
* Tests if an array is associative or not.
|
||||
*
|
||||
* // Returns TRUE
|
||||
* Arr::is_assoc(array('username' => 'john.doe'));
|
||||
*
|
||||
* // Returns FALSE
|
||||
* Arr::is_assoc('foo', 'bar');
|
||||
*
|
||||
* @param array array to check
|
||||
* @return boolean
|
||||
*/
|
||||
public static function is_assoc(array $array)
|
||||
{
|
||||
// Keys of the array
|
||||
$keys = array_keys($array);
|
||||
|
||||
// If the array keys of the keys match the keys, then the array must
|
||||
// not be associative (e.g. the keys array looked like {0:0, 1:1...}).
|
||||
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.
|
||||
*
|
||||
* // Get the value of $array['foo']['bar']
|
||||
* $value = Arr::path($array, 'foo.bar');
|
||||
*
|
||||
* Using a wildcard "*" will search intermediate arrays and return an array.
|
||||
*
|
||||
* // 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 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 ( ! Arr::is_array($array))
|
||||
{
|
||||
// This is not an array!
|
||||
return $default;
|
||||
}
|
||||
|
||||
if (is_array($path))
|
||||
{
|
||||
// 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];
|
||||
}
|
||||
|
||||
if ($delimiter === NULL)
|
||||
{
|
||||
// Use the default delimiter
|
||||
$delimiter = Arr::$delimiter;
|
||||
}
|
||||
|
||||
// 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
|
||||
{
|
||||
$key = array_shift($keys);
|
||||
|
||||
if (ctype_digit($key))
|
||||
{
|
||||
// Make the key an integer
|
||||
$key = (int) $key;
|
||||
}
|
||||
|
||||
if (isset($array[$key]))
|
||||
{
|
||||
if ($keys)
|
||||
{
|
||||
if (Arr::is_array($array[$key]))
|
||||
{
|
||||
// Dig down into the next part of the path
|
||||
$array = $array[$key];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unable to dig deeper
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Found the path requested
|
||||
return $array[$key];
|
||||
}
|
||||
}
|
||||
elseif ($key === '*')
|
||||
{
|
||||
// Handle wildcards
|
||||
|
||||
$values = array();
|
||||
foreach ($array as $arr)
|
||||
{
|
||||
if ($value = Arr::path($arr, implode('.', $keys)))
|
||||
{
|
||||
$values[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
if ($values)
|
||||
{
|
||||
// Found the values requested
|
||||
return $values;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unable to dig deeper
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Unable to dig deeper
|
||||
break;
|
||||
}
|
||||
}
|
||||
while ($keys);
|
||||
|
||||
// Unable to find the value requested
|
||||
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.
|
||||
*
|
||||
* // Fill an array with values 5, 10, 15, 20
|
||||
* $values = Arr::range(5, 20);
|
||||
*
|
||||
* @param integer stepping
|
||||
* @param integer ending number
|
||||
* @return array
|
||||
*/
|
||||
public static function range($step = 10, $max = 100)
|
||||
{
|
||||
if ($step < 1)
|
||||
return array();
|
||||
|
||||
$array = array();
|
||||
for ($i = $step; $i <= $max; $i += $step)
|
||||
{
|
||||
$array[$i] = $i;
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a single key from an array. If the key does not exist in the
|
||||
* array, the default value will be returned instead.
|
||||
*
|
||||
* // Get the value "username" from $_POST, if it exists
|
||||
* $username = Arr::get($_POST, 'username');
|
||||
*
|
||||
* // Get the value "sorting" from $_GET, if it exists
|
||||
* $sorting = Arr::get($_GET, 'sorting');
|
||||
*
|
||||
* @param array array to extract from
|
||||
* @param string key name
|
||||
* @param mixed default value
|
||||
* @return mixed
|
||||
*/
|
||||
public static function get($array, $key, $default = NULL)
|
||||
{
|
||||
return isset($array[$key]) ? $array[$key] : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves multiple keys from an array. If the key does not exist in the
|
||||
* array, the default value will be added instead.
|
||||
*
|
||||
* // Get the values "username", "password" from $_POST
|
||||
* $auth = Arr::extract($_POST, array('username', 'password'));
|
||||
*
|
||||
* @param array array to extract keys from
|
||||
* @param array list of key names
|
||||
* @param mixed default value
|
||||
* @return array
|
||||
*/
|
||||
public static function extract($array, array $keys, $default = NULL)
|
||||
{
|
||||
$found = array();
|
||||
foreach ($keys as $key)
|
||||
{
|
||||
$found[$key] = isset($array[$key]) ? $array[$key] : $default;
|
||||
}
|
||||
|
||||
return $found;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves muliple single-key values from a list of arrays.
|
||||
*
|
||||
* // Get all of the "id" values from a result
|
||||
* $ids = Arr::pluck($result, 'id');
|
||||
*
|
||||
* [!!] 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 pluck($array, $key)
|
||||
{
|
||||
$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($array, 'none', 'Select a value');
|
||||
*
|
||||
* @param array array to modify
|
||||
* @param string array key name
|
||||
* @param mixed array value
|
||||
* @return array
|
||||
*/
|
||||
public static function unshift( array & $array, $key, $val)
|
||||
{
|
||||
$array = array_reverse($array, TRUE);
|
||||
$array[$key] = $val;
|
||||
$array = array_reverse($array, TRUE);
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursive version of [array_map](http://php.net/array_map), applies the
|
||||
* same callback to all elements in an array, including sub-arrays.
|
||||
*
|
||||
* // Apply "strip_tags" to every element in the array
|
||||
* $array = Arr::map('strip_tags', $array);
|
||||
*
|
||||
* [!!] Unlike `array_map`, this method requires a callback and will only map
|
||||
* a single array.
|
||||
*
|
||||
* @param mixed callback applied to every element in the array
|
||||
* @param array array to map
|
||||
* @return array
|
||||
*/
|
||||
public static function map($callback, $array)
|
||||
{
|
||||
foreach ($array as $key => $val)
|
||||
{
|
||||
if (is_array($val))
|
||||
{
|
||||
$array[$key] = Arr::map($callback, $val);
|
||||
}
|
||||
else
|
||||
{
|
||||
$array[$key] = call_user_func($callback, $val);
|
||||
}
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges one or more arrays recursively and preserves all keys.
|
||||
* Note that this does not work the same as [array_merge_recursive](http://php.net/array_merge_recursive)!
|
||||
*
|
||||
* $john = array('name' => 'john', 'children' => array('fred', 'paul', 'sally', 'jane'));
|
||||
* $mary = array('name' => 'mary', 'children' => array('jane'));
|
||||
*
|
||||
* // John and Mary are married, merge them together
|
||||
* $john = Arr::merge($john, $mary);
|
||||
*
|
||||
* // The output of $john will now be:
|
||||
* array('name' => 'mary', 'children' => array('fred', 'paul', 'sally', 'jane'))
|
||||
*
|
||||
* @param array initial array
|
||||
* @param array array to merge
|
||||
* @param array ...
|
||||
* @return array
|
||||
*/
|
||||
public static function merge(array $a1, array $a2)
|
||||
{
|
||||
$result = array();
|
||||
for ($i = 0, $total = func_num_args(); $i < $total; $i++)
|
||||
{
|
||||
// Get the next array
|
||||
$arr = func_get_arg($i);
|
||||
|
||||
// Is the array associative?
|
||||
$assoc = Arr::is_assoc($arr);
|
||||
|
||||
foreach ($arr as $key => $val)
|
||||
{
|
||||
if (isset($result[$key]))
|
||||
{
|
||||
if (is_array($val) AND is_array($result[$key]))
|
||||
{
|
||||
if (Arr::is_assoc($val))
|
||||
{
|
||||
// Associative arrays are merged recursively
|
||||
$result[$key] = Arr::merge($result[$key], $val);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Find the values that are not already present
|
||||
$diff = array_diff($val, $result[$key]);
|
||||
|
||||
// Indexed arrays are merged to prevent duplicates
|
||||
$result[$key] = array_merge($result[$key], $diff);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($assoc)
|
||||
{
|
||||
// Associative values are replaced
|
||||
$result[$key] = $val;
|
||||
}
|
||||
elseif ( ! in_array($val, $result, TRUE))
|
||||
{
|
||||
// Indexed values are added only if they do not yet exist
|
||||
$result[] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// New values are added
|
||||
$result[$key] = $val;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overwrites an array with values from input arrays.
|
||||
* Keys that do not exist in the first array will not be added!
|
||||
*
|
||||
* $a1 = array('name' => 'john', 'mood' => 'happy', 'food' => 'bacon');
|
||||
* $a2 = array('name' => 'jack', 'food' => 'tacos', 'drink' => 'beer');
|
||||
*
|
||||
* // Overwrite the values of $a1 with $a2
|
||||
* $array = Arr::overwrite($a1, $a2);
|
||||
*
|
||||
* // The output of $array will now be:
|
||||
* array('name' => 'jack', 'mood' => 'happy', 'food' => 'tacos')
|
||||
*
|
||||
* @param array master array
|
||||
* @param array input arrays that will overwrite existing values
|
||||
* @return array
|
||||
*/
|
||||
public static function overwrite($array1, $array2)
|
||||
{
|
||||
foreach (array_intersect_key($array2, $array1) as $key => $value)
|
||||
{
|
||||
$array1[$key] = $value;
|
||||
}
|
||||
|
||||
if (func_num_args() > 2)
|
||||
{
|
||||
foreach (array_slice(func_get_args(), 2) as $array2)
|
||||
{
|
||||
foreach (array_intersect_key($array2, $array1) as $key => $value)
|
||||
{
|
||||
$array1[$key] = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $array1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a callable function and parameter list from a string representation.
|
||||
* Note that this function does not validate the callback string.
|
||||
*
|
||||
* // Get the callback function and parameters
|
||||
* list($func, $params) = Arr::callback('Foo::bar(apple,orange)');
|
||||
*
|
||||
* // Get the result of the callback
|
||||
* $result = call_user_func_array($func, $params);
|
||||
*
|
||||
* @param string callback string
|
||||
* @return array function, params
|
||||
*/
|
||||
public static function callback($str)
|
||||
{
|
||||
// Overloaded as parts are found
|
||||
$command = $params = NULL;
|
||||
|
||||
// command[param,param]
|
||||
if (preg_match('/^([^\(]*+)\((.*)\)$/', $str, $match))
|
||||
{
|
||||
// command
|
||||
$command = $match[1];
|
||||
|
||||
if ($match[2] !== '')
|
||||
{
|
||||
// param,param
|
||||
$params = preg_split('/(?<!\\\\),/', $match[2]);
|
||||
$params = str_replace('\,', ',', $params);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// command
|
||||
$command = $str;
|
||||
}
|
||||
|
||||
if (strpos($command, '::') !== FALSE)
|
||||
{
|
||||
// Create a static method callable command
|
||||
$command = explode('::', $command, 2);
|
||||
}
|
||||
|
||||
return array($command, $params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a multi-dimensional array into a single-dimensional array.
|
||||
*
|
||||
* $array = array('set' => array('one' => 'something'), 'two' => 'other');
|
||||
*
|
||||
* // Flatten the array
|
||||
* $array = Arr::flatten($array);
|
||||
*
|
||||
* // The array will now be
|
||||
* array('one' => 'something', 'two' => 'other');
|
||||
*
|
||||
* [!!] The keys of array values will be discarded.
|
||||
*
|
||||
* @param array array to flatten
|
||||
* @return array
|
||||
* @since 3.0.6
|
||||
*/
|
||||
public static function flatten($array)
|
||||
{
|
||||
$flat = array();
|
||||
foreach ($array as $key => $value)
|
||||
{
|
||||
if (is_array($value))
|
||||
{
|
||||
$flat += Arr::flatten($value);
|
||||
}
|
||||
else
|
||||
{
|
||||
$flat[$key] = $value;
|
||||
}
|
||||
}
|
||||
return $flat;
|
||||
}
|
||||
|
||||
} // End arr
|
75
includes/kohana/system/classes/kohana/cli.php
Normal file
75
includes/kohana/system/classes/kohana/cli.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Helper functions for working in a command-line environment.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_CLI {
|
||||
|
||||
/**
|
||||
* Returns one or more command-line options. Options are specified using
|
||||
* standard CLI syntax:
|
||||
*
|
||||
* php index.php --username=john.smith --password=secret --var="some value with spaces"
|
||||
*
|
||||
* // Get the values of "username" and "password"
|
||||
* $auth = CLI::options('username', 'password');
|
||||
*
|
||||
* @param string option name
|
||||
* @param ...
|
||||
* @return array
|
||||
*/
|
||||
public static function options($options)
|
||||
{
|
||||
// Get all of the requested options
|
||||
$options = func_get_args();
|
||||
|
||||
// Found option values
|
||||
$values = array();
|
||||
|
||||
// Skip the first option, it is always the file executed
|
||||
for ($i = 1; $i < $_SERVER['argc']; $i++)
|
||||
{
|
||||
if ( ! isset($_SERVER['argv'][$i]))
|
||||
{
|
||||
// No more args left
|
||||
break;
|
||||
}
|
||||
|
||||
// Get the option
|
||||
$opt = $_SERVER['argv'][$i];
|
||||
|
||||
if (substr($opt, 0, 2) !== '--')
|
||||
{
|
||||
// This is not an option argument
|
||||
continue;
|
||||
}
|
||||
|
||||
// Remove the "--" prefix
|
||||
$opt = substr($opt, 2);
|
||||
|
||||
if (strpos($opt, '='))
|
||||
{
|
||||
// Separate the name and value
|
||||
list ($opt, $value) = explode('=', $opt, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
$value = NULL;
|
||||
}
|
||||
|
||||
if (in_array($opt, $options))
|
||||
{
|
||||
// Set the given value
|
||||
$values[$opt] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
return $values;
|
||||
}
|
||||
|
||||
} // End CLI
|
157
includes/kohana/system/classes/kohana/config.php
Normal file
157
includes/kohana/system/classes/kohana/config.php
Normal file
@@ -0,0 +1,157 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Wrapper for configuration arrays. Multiple configuration readers can be
|
||||
* attached to allow loading configuration from files, database, etc.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config {
|
||||
|
||||
/**
|
||||
* @var Kohana_Config Singleton static instance
|
||||
*/
|
||||
protected static $_instance;
|
||||
|
||||
/**
|
||||
* Get the singleton instance of Config.
|
||||
*
|
||||
* $config = Config::instance();
|
||||
*
|
||||
* @return Config
|
||||
*/
|
||||
public static function instance()
|
||||
{
|
||||
if (Config::$_instance === NULL)
|
||||
{
|
||||
// Create a new instance
|
||||
Config::$_instance = new Config;
|
||||
}
|
||||
|
||||
return Config::$_instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* @var array Configuration readers
|
||||
*/
|
||||
protected $_readers = array();
|
||||
|
||||
/**
|
||||
* Attach a configuration reader. By default, the reader will be added as
|
||||
* the first used reader. However, if the reader should be used only when
|
||||
* all other readers fail, use `FALSE` for the second parameter.
|
||||
*
|
||||
* $config->attach($reader); // Try first
|
||||
* $config->attach($reader, FALSE); // Try last
|
||||
*
|
||||
* @param object Config_Reader instance
|
||||
* @param boolean add the reader as the first used object
|
||||
* @return $this
|
||||
*/
|
||||
public function attach(Config_Reader $reader, $first = TRUE)
|
||||
{
|
||||
if ($first === TRUE)
|
||||
{
|
||||
// Place the log reader at the top of the stack
|
||||
array_unshift($this->_readers, $reader);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Place the reader at the bottom of the stack
|
||||
$this->_readers[] = $reader;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detach a configuration reader.
|
||||
*
|
||||
* $config->detach($reader);
|
||||
*
|
||||
* @param object Config_Reader instance
|
||||
* @return $this
|
||||
*/
|
||||
public function detach(Config_Reader $reader)
|
||||
{
|
||||
if (($key = array_search($reader, $this->_readers)) !== FALSE)
|
||||
{
|
||||
// Remove the writer
|
||||
unset($this->_readers[$key]);
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a configuration group. Searches the readers in order until the
|
||||
* group is found. If the group does not exist, an empty configuration
|
||||
* array will be loaded using the first reader.
|
||||
*
|
||||
* $array = $config->load($name);
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @return Config_Reader
|
||||
* @throws Kohana_Exception
|
||||
*/
|
||||
public function load($group)
|
||||
{
|
||||
foreach ($this->_readers as $reader)
|
||||
{
|
||||
if ($config = $reader->load($group))
|
||||
{
|
||||
// Found a reader for this configuration group
|
||||
return $config;
|
||||
}
|
||||
}
|
||||
|
||||
// Reset the iterator
|
||||
reset($this->_readers);
|
||||
|
||||
if ( ! is_object($config = current($this->_readers)))
|
||||
{
|
||||
throw new Kohana_Exception('No configuration readers attached');
|
||||
}
|
||||
|
||||
// Load the reader as an empty array
|
||||
return $config->load($group, array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy one configuration group to all of the other readers.
|
||||
*
|
||||
* $config->copy($name);
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @return $this
|
||||
*/
|
||||
public function copy($group)
|
||||
{
|
||||
// Load the configuration group
|
||||
$config = $this->load($group);
|
||||
|
||||
foreach ($this->_readers as $reader)
|
||||
{
|
||||
if ($config instanceof $reader)
|
||||
{
|
||||
// Do not copy the config to the same group
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load the configuration object
|
||||
$object = $reader->load($group, array());
|
||||
|
||||
foreach ($config as $key => $value)
|
||||
{
|
||||
// Copy each value in the config
|
||||
$object->offsetSet($key, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Kohana_Config
|
60
includes/kohana/system/classes/kohana/config/file.php
Normal file
60
includes/kohana/system/classes/kohana/config/file.php
Normal file
@@ -0,0 +1,60 @@
|
||||
<?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 [Config].
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Config_File extends Config_Reader {
|
||||
|
||||
/**
|
||||
* @var string Configuration group name
|
||||
*/
|
||||
protected $_configuration_group;
|
||||
|
||||
/**
|
||||
* @var bool Has the config group changed?
|
||||
*/
|
||||
protected $_configuration_modified = FALSE;
|
||||
|
||||
public function __construct($directory = 'config')
|
||||
{
|
||||
// Set the configuration directory name
|
||||
$this->_directory = trim($directory, '/');
|
||||
|
||||
// Load the empty array
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Load and merge all of the configuration files in this group.
|
||||
*
|
||||
* $config->load($name);
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @param array configuration array
|
||||
* @return $this clone of the current object
|
||||
* @uses Kohana::load
|
||||
*/
|
||||
public function load($group, array $config = NULL)
|
||||
{
|
||||
if ($files = Kohana::find_file($this->_directory, $group, NULL, TRUE))
|
||||
{
|
||||
// Initialize the config array
|
||||
$config = array();
|
||||
|
||||
foreach ($files as $file)
|
||||
{
|
||||
// Merge each file to the configuration array
|
||||
$config = Arr::merge($config, Kohana::load($file));
|
||||
}
|
||||
}
|
||||
|
||||
return parent::load($group, $config);
|
||||
}
|
||||
|
||||
} // End Kohana_Config_File
|
115
includes/kohana/system/classes/kohana/config/reader.php
Normal file
115
includes/kohana/system/classes/kohana/config/reader.php
Normal file
@@ -0,0 +1,115 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Abstract configuration reader. All configuration readers must extend
|
||||
* this class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Config_Reader extends ArrayObject {
|
||||
|
||||
/**
|
||||
* @var string Configuration group name
|
||||
*/
|
||||
protected $_configuration_group;
|
||||
|
||||
/**
|
||||
* Loads an empty array as the initial configuration and enables array
|
||||
* keys to be used as properties.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct(array(), ArrayObject::ARRAY_AS_PROPS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the current group in serialized form.
|
||||
*
|
||||
* echo $config;
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return serialize($this->getArrayCopy());
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads a configuration group.
|
||||
*
|
||||
* $config->load($name, $array);
|
||||
*
|
||||
* This method must be extended by all readers. After the group has been
|
||||
* loaded, call `parent::load($group, $config)` for final preparation.
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @param array configuration array
|
||||
* @return $this a clone of this object
|
||||
*/
|
||||
public function load($group, array $config = NULL)
|
||||
{
|
||||
if ($config === NULL)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Clone the current object
|
||||
$object = clone $this;
|
||||
|
||||
// Set the group name
|
||||
$object->_configuration_group = $group;
|
||||
|
||||
// Swap the array with the actual configuration
|
||||
$object->exchangeArray($config);
|
||||
|
||||
return $object;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the raw array that is being used for this object.
|
||||
*
|
||||
* $array = $config->as_array();
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function as_array()
|
||||
{
|
||||
return $this->getArrayCopy();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a variable from the configuration or return the default value.
|
||||
*
|
||||
* $value = $config->get($key);
|
||||
*
|
||||
* @param string array key
|
||||
* @param mixed default value
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($key, $default = NULL)
|
||||
{
|
||||
return $this->offsetExists($key) ? $this->offsetGet($key) : $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value in the configuration array.
|
||||
*
|
||||
* $config->set($key, $new_value);
|
||||
*
|
||||
* @param string array key
|
||||
* @param mixed array value
|
||||
* @return $this
|
||||
*/
|
||||
public function set($key, $value)
|
||||
{
|
||||
$this->offsetSet($key, $value);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
} // End Kohana_Config_Reader
|
75
includes/kohana/system/classes/kohana/controller.php
Normal file
75
includes/kohana/system/classes/kohana/controller.php
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Abstract controller class. Controllers should only be created using a [Request].
|
||||
*
|
||||
* Controllers methods will be automatically called in the following order by
|
||||
* the request:
|
||||
*
|
||||
* $controller = new Controller_Foo($request);
|
||||
* $controller->before();
|
||||
* $controller->action_bar();
|
||||
* $controller->after();
|
||||
*
|
||||
* The controller action should add the output it creates to
|
||||
* `$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-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_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 Request $request Request that created the controller
|
||||
* @param Response $response The request's response
|
||||
* @return void
|
||||
*/
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically executed before the controller action. Can be used to set
|
||||
* class properties, do authorization checks, and execute other custom code.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function before()
|
||||
{
|
||||
// Nothing by default
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically executed after the controller action. Can be used to apply
|
||||
* transformation to the request response, add extra output, and execute
|
||||
* other custom code.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function after()
|
||||
{
|
||||
// Nothing by default
|
||||
}
|
||||
|
||||
} // End Controller
|
96
includes/kohana/system/classes/kohana/controller/rest.php
Normal file
96
includes/kohana/system/classes/kohana/controller/rest.php
Normal file
@@ -0,0 +1,96 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Abstract Controller class for RESTful controller mapping. Supports GET, PUT,
|
||||
* POST, and DELETE. By default, these methods will be mapped to these actions:
|
||||
*
|
||||
* GET
|
||||
* : Mapped to the "index" action, lists all objects
|
||||
*
|
||||
* POST
|
||||
* : Mapped to the "create" action, creates a new object
|
||||
*
|
||||
* PUT
|
||||
* : Mapped to the "update" action, update an existing object
|
||||
*
|
||||
* DELETE
|
||||
* : Mapped to the "delete" action, delete an existing object
|
||||
*
|
||||
* Additional methods can be supported by adding the method and action to
|
||||
* the `$_action_map` property.
|
||||
*
|
||||
* [!!] Using this class within a website will require heavy modification,
|
||||
* due to most web browsers only supporting the GET and POST methods.
|
||||
* Generally, this class should only be used for web services and APIs.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @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
|
||||
(
|
||||
HTTP_Request::GET => 'index',
|
||||
HTTP_Request::PUT => 'update',
|
||||
HTTP_Request::POST => 'create',
|
||||
HTTP_Request::DELETE => 'delete',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var string requested action
|
||||
*/
|
||||
protected $_action_requested = '';
|
||||
|
||||
/**
|
||||
* Checks the requested method against the available methods. If the method
|
||||
* is supported, sets the request action from the map. If not supported,
|
||||
* the "invalid" action will be called.
|
||||
*/
|
||||
public function before()
|
||||
{
|
||||
$this->_action_requested = $this->request->action();
|
||||
|
||||
$method = Arr::get($_SERVER, 'HTTP_X_HTTP_METHOD_OVERRIDE', $this->request->method());
|
||||
|
||||
if ( ! isset($this->_action_map[$method]))
|
||||
{
|
||||
$this->request->action('invalid');
|
||||
}
|
||||
else
|
||||
{
|
||||
$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->response->status(405)
|
||||
->headers('Allow', implode(', ', array_keys($this->_action_map)));
|
||||
}
|
||||
|
||||
} // End REST
|
@@ -0,0 +1,50 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Abstract controller class for automatic templating.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Controller
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Controller_Template extends Controller {
|
||||
|
||||
/**
|
||||
* @var View page template
|
||||
*/
|
||||
public $template = 'template';
|
||||
|
||||
/**
|
||||
* @var boolean auto render template
|
||||
**/
|
||||
public $auto_render = TRUE;
|
||||
|
||||
/**
|
||||
* Loads the template [View] object.
|
||||
*/
|
||||
public function before()
|
||||
{
|
||||
if ($this->auto_render === TRUE)
|
||||
{
|
||||
// Load the template
|
||||
$this->template = View::factory($this->template);
|
||||
}
|
||||
|
||||
return parent::before();
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the template [View] as the request response.
|
||||
*/
|
||||
public function after()
|
||||
{
|
||||
if ($this->auto_render === TRUE)
|
||||
{
|
||||
$this->response->body($this->template->render());
|
||||
}
|
||||
|
||||
return parent::after();
|
||||
}
|
||||
|
||||
} // End Controller_Template
|
161
includes/kohana/system/classes/kohana/cookie.php
Normal file
161
includes/kohana/system/classes/kohana/cookie.php
Normal file
@@ -0,0 +1,161 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Cookie helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @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 = NULL;
|
||||
|
||||
/**
|
||||
* @var integer Number of seconds before the cookie expires
|
||||
*/
|
||||
public static $expiration = 0;
|
||||
|
||||
/**
|
||||
* @var string Restrict the path that the cookie is available to
|
||||
*/
|
||||
public static $path = '/';
|
||||
|
||||
/**
|
||||
* @var string Restrict the domain that the cookie is available to
|
||||
*/
|
||||
public static $domain = NULL;
|
||||
|
||||
/**
|
||||
* @var boolean Only transmit cookies over secure connections
|
||||
*/
|
||||
public static $secure = FALSE;
|
||||
|
||||
/**
|
||||
* @var boolean Only transmit cookies over HTTP, disabling Javascript access
|
||||
*/
|
||||
public static $httponly = FALSE;
|
||||
|
||||
/**
|
||||
* Gets the value of a signed cookie. Cookies without signatures will not
|
||||
* be returned. If the cookie signature is present, but invalid, the cookie
|
||||
* will be deleted.
|
||||
*
|
||||
* // Get the "theme" cookie, or use "blue" if the cookie does not exist
|
||||
* $theme = Cookie::get('theme', 'blue');
|
||||
*
|
||||
* @param string cookie name
|
||||
* @param mixed default value to return
|
||||
* @return string
|
||||
*/
|
||||
public static function get($key, $default = NULL)
|
||||
{
|
||||
if ( ! isset($_COOKIE[$key]))
|
||||
{
|
||||
// The cookie does not exist
|
||||
return $default;
|
||||
}
|
||||
|
||||
// Get the cookie value
|
||||
$cookie = $_COOKIE[$key];
|
||||
|
||||
// Find the position of the split between salt and contents
|
||||
$split = strlen(Cookie::salt($key, NULL));
|
||||
|
||||
if (isset($cookie[$split]) AND $cookie[$split] === '~')
|
||||
{
|
||||
// Separate the salt and the value
|
||||
list ($hash, $value) = explode('~', $cookie, 2);
|
||||
|
||||
if (Cookie::salt($key, $value) === $hash)
|
||||
{
|
||||
// Cookie signature is valid
|
||||
return $value;
|
||||
}
|
||||
|
||||
// The cookie signature is invalid, delete it
|
||||
Cookie::delete($key);
|
||||
}
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a signed cookie. Note that all cookie values must be strings and no
|
||||
* automatic serialization will be performed!
|
||||
*
|
||||
* // Set the "theme" cookie
|
||||
* Cookie::set('theme', 'red');
|
||||
*
|
||||
* @param string name of cookie
|
||||
* @param string value of cookie
|
||||
* @param integer lifetime in seconds
|
||||
* @return boolean
|
||||
* @uses Cookie::salt
|
||||
*/
|
||||
public static function set($name, $value, $expiration = NULL)
|
||||
{
|
||||
if ($expiration === NULL)
|
||||
{
|
||||
// Use the default expiration
|
||||
$expiration = Cookie::$expiration;
|
||||
}
|
||||
|
||||
if ($expiration !== 0)
|
||||
{
|
||||
// The expiration is expected to be a UNIX timestamp
|
||||
$expiration += time();
|
||||
}
|
||||
|
||||
// Add the salt to the cookie value
|
||||
$value = Cookie::salt($name, $value).'~'.$value;
|
||||
|
||||
return setcookie($name, $value, $expiration, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a cookie by making the value NULL and expiring it.
|
||||
*
|
||||
* Cookie::delete('theme');
|
||||
*
|
||||
* @param string cookie name
|
||||
* @return boolean
|
||||
* @uses Cookie::set
|
||||
*/
|
||||
public static function delete($name)
|
||||
{
|
||||
// Remove the cookie
|
||||
unset($_COOKIE[$name]);
|
||||
|
||||
// Nullify the cookie and make it expire
|
||||
return setcookie($name, NULL, -86400, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a salt string for a cookie based on the name and value.
|
||||
*
|
||||
* $salt = Cookie::salt('theme', 'red');
|
||||
*
|
||||
* @param string name of cookie
|
||||
* @param string value of cookie
|
||||
* @return string
|
||||
*/
|
||||
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';
|
||||
|
||||
return sha1($agent.$name.$value.Cookie::$salt);
|
||||
}
|
||||
|
||||
} // End cookie
|
1040
includes/kohana/system/classes/kohana/core.php
Normal file
1040
includes/kohana/system/classes/kohana/core.php
Normal file
File diff suppressed because it is too large
Load Diff
598
includes/kohana/system/classes/kohana/date.php
Normal file
598
includes/kohana/system/classes/kohana/date.php
Normal file
@@ -0,0 +1,598 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Date helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Date {
|
||||
|
||||
// Second amounts for various time increments
|
||||
const YEAR = 31556926;
|
||||
const MONTH = 2629744;
|
||||
const WEEK = 604800;
|
||||
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
|
||||
*/
|
||||
public static $timestamp_format = 'Y-m-d H:i:s';
|
||||
|
||||
/**
|
||||
* Timezone for formatted_time
|
||||
* @link http://uk2.php.net/manual/en/timezones.php
|
||||
* @var string
|
||||
*/
|
||||
public static $timezone;
|
||||
|
||||
/**
|
||||
* Returns the offset (in seconds) between two time zones. Use this to
|
||||
* display dates to users in different time zones.
|
||||
*
|
||||
* $seconds = Date::offset('America/Chicago', 'GMT');
|
||||
*
|
||||
* [!!] A list of time zones that PHP supports can be found at
|
||||
* <http://php.net/timezones>.
|
||||
*
|
||||
* @param string timezone that to find the offset of
|
||||
* @param string timezone used as the baseline
|
||||
* @param mixed UNIX timestamp or date string
|
||||
* @return integer
|
||||
*/
|
||||
public static function offset($remote, $local = NULL, $now = NULL)
|
||||
{
|
||||
if ($local === NULL)
|
||||
{
|
||||
// Use the default timezone
|
||||
$local = date_default_timezone_get();
|
||||
}
|
||||
|
||||
if (is_int($now))
|
||||
{
|
||||
// Convert the timestamp into a string
|
||||
$now = date(DateTime::RFC2822, $now);
|
||||
}
|
||||
|
||||
// Create timezone objects
|
||||
$zone_remote = new DateTimeZone($remote);
|
||||
$zone_local = new DateTimeZone($local);
|
||||
|
||||
// Create date objects from timezones
|
||||
$time_remote = new DateTime($now, $zone_remote);
|
||||
$time_local = new DateTime($now, $zone_local);
|
||||
|
||||
// Find the offset
|
||||
$offset = $zone_remote->getOffset($time_remote) - $zone_local->getOffset($time_local);
|
||||
|
||||
return $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of seconds in a minute, incrementing by a step. Typically used as
|
||||
* a shortcut for generating a list that can used in a form.
|
||||
*
|
||||
* $seconds = Date::seconds(); // 01, 02, 03, ..., 58, 59, 60
|
||||
*
|
||||
* @param integer amount to increment each step by, 1 to 30
|
||||
* @param integer start value
|
||||
* @param integer end value
|
||||
* @return array A mirrored (foo => foo) array from 1-60.
|
||||
*/
|
||||
public static function seconds($step = 1, $start = 0, $end = 60)
|
||||
{
|
||||
// Always integer
|
||||
$step = (int) $step;
|
||||
|
||||
$seconds = array();
|
||||
|
||||
for ($i = $start; $i < $end; $i += $step)
|
||||
{
|
||||
$seconds[$i] = sprintf('%02d', $i);
|
||||
}
|
||||
|
||||
return $seconds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of minutes in an hour, incrementing by a step. Typically used as
|
||||
* a shortcut for generating a list that can be used in a form.
|
||||
*
|
||||
* $minutes = Date::minutes(); // 05, 10, 15, ..., 50, 55, 60
|
||||
*
|
||||
* @uses Date::seconds
|
||||
* @param integer amount to increment each step by, 1 to 30
|
||||
* @return array A mirrored (foo => foo) array from 1-60.
|
||||
*/
|
||||
public static function minutes($step = 5)
|
||||
{
|
||||
// Because there are the same number of minutes as seconds in this set,
|
||||
// we choose to re-use seconds(), rather than creating an entirely new
|
||||
// function. Shhhh, it's cheating! ;) There are several more of these
|
||||
// in the following methods.
|
||||
return Date::seconds($step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of hours in a day. Typically used as a shortcut for generating a
|
||||
* list that can be used in a form.
|
||||
*
|
||||
* $hours = Date::hours(); // 01, 02, 03, ..., 10, 11, 12
|
||||
*
|
||||
* @param integer amount to increment each step by
|
||||
* @param boolean use 24-hour time
|
||||
* @param integer the hour to start at
|
||||
* @return array A mirrored (foo => foo) array from start-12 or start-23.
|
||||
*/
|
||||
public static function hours($step = 1, $long = FALSE, $start = NULL)
|
||||
{
|
||||
// Default values
|
||||
$step = (int) $step;
|
||||
$long = (bool) $long;
|
||||
$hours = array();
|
||||
|
||||
// Set the default start if none was specified.
|
||||
if ($start === NULL)
|
||||
{
|
||||
$start = ($long === FALSE) ? 1 : 0;
|
||||
}
|
||||
|
||||
$hours = array();
|
||||
|
||||
// 24-hour time has 24 hours, instead of 12
|
||||
$size = ($long === TRUE) ? 23 : 12;
|
||||
|
||||
for ($i = $start; $i <= $size; $i += $step)
|
||||
{
|
||||
$hours[$i] = (string) $i;
|
||||
}
|
||||
|
||||
return $hours;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns AM or PM, based on a given hour (in 24 hour format).
|
||||
*
|
||||
* $type = Date::ampm(12); // PM
|
||||
* $type = Date::ampm(1); // AM
|
||||
*
|
||||
* @param integer number of the hour
|
||||
* @return string
|
||||
*/
|
||||
public static function ampm($hour)
|
||||
{
|
||||
// Always integer
|
||||
$hour = (int) $hour;
|
||||
|
||||
return ($hour > 11) ? 'PM' : 'AM';
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts a non-24-hour number into a 24-hour number.
|
||||
*
|
||||
* $hour = Date::adjust(3, 'pm'); // 15
|
||||
*
|
||||
* @param integer hour to adjust
|
||||
* @param string AM or PM
|
||||
* @return string
|
||||
*/
|
||||
public static function adjust($hour, $ampm)
|
||||
{
|
||||
$hour = (int) $hour;
|
||||
$ampm = strtolower($ampm);
|
||||
|
||||
switch ($ampm)
|
||||
{
|
||||
case 'am':
|
||||
if ($hour == 12)
|
||||
{
|
||||
$hour = 0;
|
||||
}
|
||||
break;
|
||||
case 'pm':
|
||||
if ($hour < 12)
|
||||
{
|
||||
$hour += 12;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return sprintf('%02d', $hour);
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of days in a given month and year. Typically used as a shortcut
|
||||
* for generating a list that can be used in a form.
|
||||
*
|
||||
* Date::days(4, 2010); // 1, 2, 3, ..., 28, 29, 30
|
||||
*
|
||||
* @param integer number of month
|
||||
* @param integer number of year to check month, defaults to the current year
|
||||
* @return array A mirrored (foo => foo) array of the days.
|
||||
*/
|
||||
public static function days($month, $year = FALSE)
|
||||
{
|
||||
static $months;
|
||||
|
||||
if ($year === FALSE)
|
||||
{
|
||||
// Use the current year by default
|
||||
$year = date('Y');
|
||||
}
|
||||
|
||||
// Always integers
|
||||
$month = (int) $month;
|
||||
$year = (int) $year;
|
||||
|
||||
// We use caching for months, because time functions are used
|
||||
if (empty($months[$year][$month]))
|
||||
{
|
||||
$months[$year][$month] = array();
|
||||
|
||||
// Use date to find the number of days in the given month
|
||||
$total = date('t', mktime(1, 0, 0, $month, 1, $year)) + 1;
|
||||
|
||||
for ($i = 1; $i < $total; $i++)
|
||||
{
|
||||
$months[$year][$month][$i] = (string) $i;
|
||||
}
|
||||
}
|
||||
|
||||
return $months[$year][$month];
|
||||
}
|
||||
|
||||
/**
|
||||
* Number of months in a year. Typically used as a shortcut for generating
|
||||
* a list that can be used in a form.
|
||||
*
|
||||
* 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
|
||||
* @param string The format to use for months
|
||||
* @return array An array of months based on the specified format
|
||||
*/
|
||||
public static function months($format = NULL)
|
||||
{
|
||||
$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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of years between a starting and ending year. By default,
|
||||
* the the current year - 5 and current year + 5 will be used. Typically used
|
||||
* as a shortcut for generating a list that can be used in a form.
|
||||
*
|
||||
* $years = Date::years(2000, 2010); // 2000, 2001, ..., 2009, 2010
|
||||
*
|
||||
* @param integer starting year (default is current year - 5)
|
||||
* @param integer ending year (default is current year + 5)
|
||||
* @return array
|
||||
*/
|
||||
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;
|
||||
|
||||
$years = array();
|
||||
|
||||
for ($i = $start; $i <= $end; $i++)
|
||||
{
|
||||
$years[$i] = (string) $i;
|
||||
}
|
||||
|
||||
return $years;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns time difference between two timestamps, in human readable format.
|
||||
* If the second timestamp is not given, the current time will be used.
|
||||
* Also consider using [Date::fuzzy_span] when displaying a span.
|
||||
*
|
||||
* $span = Date::span(60, 182, 'minutes,seconds'); // array('minutes' => 2, 'seconds' => 2)
|
||||
* $span = Date::span(60, 182, 'minutes'); // 2
|
||||
*
|
||||
* @param integer timestamp to find the span of
|
||||
* @param integer timestamp to use as the baseline
|
||||
* @param string formatting string
|
||||
* @return string when only a single output is requested
|
||||
* @return array associative list of all outputs requested
|
||||
*/
|
||||
public static function span($remote, $local = NULL, $output = 'years,months,weeks,days,hours,minutes,seconds')
|
||||
{
|
||||
// Normalize output
|
||||
$output = trim(strtolower( (string) $output));
|
||||
|
||||
if ( ! $output)
|
||||
{
|
||||
// Invalid output
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Array with the output formats
|
||||
$output = preg_split('/[^a-z]+/', $output);
|
||||
|
||||
// Convert the list of outputs to an associative array
|
||||
$output = array_combine($output, array_fill(0, count($output), 0));
|
||||
|
||||
// Make the output values into keys
|
||||
extract(array_flip($output), EXTR_SKIP);
|
||||
|
||||
if ($local === NULL)
|
||||
{
|
||||
// Calculate the span from the current time
|
||||
$local = time();
|
||||
}
|
||||
|
||||
// Calculate timespan (seconds)
|
||||
$timespan = abs($remote - $local);
|
||||
|
||||
if (isset($output['years']))
|
||||
{
|
||||
$timespan -= Date::YEAR * ($output['years'] = (int) floor($timespan / Date::YEAR));
|
||||
}
|
||||
|
||||
if (isset($output['months']))
|
||||
{
|
||||
$timespan -= Date::MONTH * ($output['months'] = (int) floor($timespan / Date::MONTH));
|
||||
}
|
||||
|
||||
if (isset($output['weeks']))
|
||||
{
|
||||
$timespan -= Date::WEEK * ($output['weeks'] = (int) floor($timespan / Date::WEEK));
|
||||
}
|
||||
|
||||
if (isset($output['days']))
|
||||
{
|
||||
$timespan -= Date::DAY * ($output['days'] = (int) floor($timespan / Date::DAY));
|
||||
}
|
||||
|
||||
if (isset($output['hours']))
|
||||
{
|
||||
$timespan -= Date::HOUR * ($output['hours'] = (int) floor($timespan / Date::HOUR));
|
||||
}
|
||||
|
||||
if (isset($output['minutes']))
|
||||
{
|
||||
$timespan -= Date::MINUTE * ($output['minutes'] = (int) floor($timespan / Date::MINUTE));
|
||||
}
|
||||
|
||||
// Seconds ago, 1
|
||||
if (isset($output['seconds']))
|
||||
{
|
||||
$output['seconds'] = $timespan;
|
||||
}
|
||||
|
||||
if (count($output) === 1)
|
||||
{
|
||||
// Only a single output was requested, return it
|
||||
return array_pop($output);
|
||||
}
|
||||
|
||||
// Return array
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the difference between a time and now in a "fuzzy" way.
|
||||
* 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, $local_timestamp = NULL)
|
||||
{
|
||||
$local_timestamp = ($local_timestamp === NULL) ? time() : (int) $local_timestamp;
|
||||
|
||||
// Determine the difference in seconds
|
||||
$offset = abs($local_timestamp - $timestamp);
|
||||
|
||||
if ($offset <= Date::MINUTE)
|
||||
{
|
||||
$span = 'moments';
|
||||
}
|
||||
elseif ($offset < (Date::MINUTE * 20))
|
||||
{
|
||||
$span = 'a few minutes';
|
||||
}
|
||||
elseif ($offset < Date::HOUR)
|
||||
{
|
||||
$span = 'less than an hour';
|
||||
}
|
||||
elseif ($offset < (Date::HOUR * 4))
|
||||
{
|
||||
$span = 'a couple of hours';
|
||||
}
|
||||
elseif ($offset < Date::DAY)
|
||||
{
|
||||
$span = 'less than a day';
|
||||
}
|
||||
elseif ($offset < (Date::DAY * 2))
|
||||
{
|
||||
$span = 'about a day';
|
||||
}
|
||||
elseif ($offset < (Date::DAY * 4))
|
||||
{
|
||||
$span = 'a couple of days';
|
||||
}
|
||||
elseif ($offset < Date::WEEK)
|
||||
{
|
||||
$span = 'less than a week';
|
||||
}
|
||||
elseif ($offset < (Date::WEEK * 2))
|
||||
{
|
||||
$span = 'about a week';
|
||||
}
|
||||
elseif ($offset < Date::MONTH)
|
||||
{
|
||||
$span = 'less than a month';
|
||||
}
|
||||
elseif ($offset < (Date::MONTH * 2))
|
||||
{
|
||||
$span = 'about a month';
|
||||
}
|
||||
elseif ($offset < (Date::MONTH * 4))
|
||||
{
|
||||
$span = 'a couple of months';
|
||||
}
|
||||
elseif ($offset < Date::YEAR)
|
||||
{
|
||||
$span = 'less than a year';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 2))
|
||||
{
|
||||
$span = 'about a year';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 4))
|
||||
{
|
||||
$span = 'a couple of years';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 8))
|
||||
{
|
||||
$span = 'a few years';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 12))
|
||||
{
|
||||
$span = 'about a decade';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 24))
|
||||
{
|
||||
$span = 'a couple of decades';
|
||||
}
|
||||
elseif ($offset < (Date::YEAR * 64))
|
||||
{
|
||||
$span = 'several decades';
|
||||
}
|
||||
else
|
||||
{
|
||||
$span = 'a long time';
|
||||
}
|
||||
|
||||
if ($timestamp <= $local_timestamp)
|
||||
{
|
||||
// This is in the past
|
||||
return $span.' ago';
|
||||
}
|
||||
else
|
||||
{
|
||||
// This in the future
|
||||
return 'in '.$span;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a UNIX timestamp to DOS format. There are very few cases where
|
||||
* this is needed, but some binary formats use it (eg: zip files.)
|
||||
* Converting the other direction is done using {@link Date::dos2unix}.
|
||||
*
|
||||
* $dos = Date::unix2dos($unix);
|
||||
*
|
||||
* @param integer UNIX timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function unix2dos($timestamp = FALSE)
|
||||
{
|
||||
$timestamp = ($timestamp === FALSE) ? getdate() : getdate($timestamp);
|
||||
|
||||
if ($timestamp['year'] < 1980)
|
||||
{
|
||||
return (1 << 21 | 1 << 16);
|
||||
}
|
||||
|
||||
$timestamp['year'] -= 1980;
|
||||
|
||||
// What voodoo is this? I have no idea... Geert can explain it though,
|
||||
// and that's good enough for me.
|
||||
return ($timestamp['year'] << 25 | $timestamp['mon'] << 21 |
|
||||
$timestamp['mday'] << 16 | $timestamp['hours'] << 11 |
|
||||
$timestamp['minutes'] << 5 | $timestamp['seconds'] >> 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts a DOS timestamp to UNIX format.There are very few cases where
|
||||
* this is needed, but some binary formats use it (eg: zip files.)
|
||||
* Converting the other direction is done using {@link Date::unix2dos}.
|
||||
*
|
||||
* $unix = Date::dos2unix($dos);
|
||||
*
|
||||
* @param integer DOS timestamp
|
||||
* @return integer
|
||||
*/
|
||||
public static function dos2unix($timestamp = FALSE)
|
||||
{
|
||||
$sec = 2 * ($timestamp & 0x1f);
|
||||
$min = ($timestamp >> 5) & 0x3f;
|
||||
$hrs = ($timestamp >> 11) & 0x1f;
|
||||
$day = ($timestamp >> 16) & 0x1f;
|
||||
$mon = ($timestamp >> 21) & 0x0f;
|
||||
$year = ($timestamp >> 25) & 0x7f;
|
||||
|
||||
return mktime($hrs, $min, $sec, $mon, $day, $year + 1980);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a date/time string with the specified timestamp format
|
||||
*
|
||||
* $time = Date::formatted_time('5 minutes ago');
|
||||
*
|
||||
* @see http://php.net/manual/en/datetime.construct.php
|
||||
* @param string datetime_str datetime string
|
||||
* @param string timestamp_format timestamp format
|
||||
* @return string
|
||||
*/
|
||||
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;
|
||||
|
||||
$time = new DateTime($datetime_str, new DateTimeZone(
|
||||
$timezone ? $timezone : date_default_timezone_get()
|
||||
));
|
||||
|
||||
return $time->format($timestamp_format);
|
||||
}
|
||||
|
||||
} // End date
|
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;
|
||||
}
|
||||
|
||||
}
|
213
includes/kohana/system/classes/kohana/encrypt.php
Normal file
213
includes/kohana/system/classes/kohana/encrypt.php
Normal file
@@ -0,0 +1,213 @@
|
||||
<?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
|
||||
* parts: the key, the cipher, and the mode.
|
||||
*
|
||||
* The Key
|
||||
* : A secret passphrase that is used for encoding and decoding
|
||||
*
|
||||
* The Cipher
|
||||
* : A [cipher](http://php.net/mcrypt.ciphers) determines how the encryption
|
||||
* is mathematically calculated. By default, the "rijndael-128" cipher
|
||||
* is used. This is commonly known as "AES-128" and is an industry standard.
|
||||
*
|
||||
* The Mode
|
||||
* : The [mode](http://php.net/mcrypt.constants) determines how the encrypted
|
||||
* data is written in binary form. By default, the "nofb" mode is used,
|
||||
* which produces short output with high entropy.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Security
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Encrypt {
|
||||
|
||||
/**
|
||||
* @var string default instance name
|
||||
*/
|
||||
public static $default = 'default';
|
||||
|
||||
/**
|
||||
* @var array Encrypt class instances
|
||||
*/
|
||||
public static $instances = array();
|
||||
|
||||
/**
|
||||
* @var string OS-dependent RAND type to use
|
||||
*/
|
||||
protected static $_rand;
|
||||
|
||||
/**
|
||||
* Returns a singleton instance of Encrypt. An encryption key must be
|
||||
* provided in your "encrypt" configuration file.
|
||||
*
|
||||
* $encrypt = Encrypt::instance();
|
||||
*
|
||||
* @param string configuration group name
|
||||
* @return Encrypt
|
||||
*/
|
||||
public static function instance($name = NULL)
|
||||
{
|
||||
if ($name === NULL)
|
||||
{
|
||||
// Use the default instance name
|
||||
$name = Encrypt::$default;
|
||||
}
|
||||
|
||||
if ( ! isset(Encrypt::$instances[$name]))
|
||||
{
|
||||
// Load the configuration data
|
||||
$config = Kohana::config('encrypt')->$name;
|
||||
|
||||
if ( ! isset($config['key']))
|
||||
{
|
||||
// No default encryption key is provided!
|
||||
throw new Kohana_Exception('No encryption key is defined in the encryption configuration group: :group',
|
||||
array(':group' => $name));
|
||||
}
|
||||
|
||||
if ( ! isset($config['mode']))
|
||||
{
|
||||
// Add the default mode
|
||||
$config['mode'] = MCRYPT_MODE_NOFB;
|
||||
}
|
||||
|
||||
if ( ! isset($config['cipher']))
|
||||
{
|
||||
// Add the default cipher
|
||||
$config['cipher'] = MCRYPT_RIJNDAEL_128;
|
||||
}
|
||||
|
||||
// Create a new instance
|
||||
Encrypt::$instances[$name] = new Encrypt($config['key'], $config['mode'], $config['cipher']);
|
||||
}
|
||||
|
||||
return Encrypt::$instances[$name];
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new mcrypt wrapper.
|
||||
*
|
||||
* @param string encryption key
|
||||
* @param string mcrypt mode
|
||||
* @param string mcrypt cipher
|
||||
*/
|
||||
public function __construct($key, $mode, $cipher)
|
||||
{
|
||||
// Find the max length of the key, based on cipher and mode
|
||||
$size = mcrypt_get_key_size($cipher, $mode);
|
||||
|
||||
if (isset($key[$size]))
|
||||
{
|
||||
// Shorten the key to the maximum size
|
||||
$key = substr($key, 0, $size);
|
||||
}
|
||||
|
||||
// Store the key, mode, and cipher
|
||||
$this->_key = $key;
|
||||
$this->_mode = $mode;
|
||||
$this->_cipher = $cipher;
|
||||
|
||||
// Store the IV size
|
||||
$this->_iv_size = mcrypt_get_iv_size($this->_cipher, $this->_mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Encrypts a string and returns an encrypted string that can be decoded.
|
||||
*
|
||||
* $data = $encrypt->encode($data);
|
||||
*
|
||||
* The encrypted binary data is encoded using [base64](http://php.net/base64_encode)
|
||||
* to convert it to a string. This string can be stored in a database,
|
||||
* displayed, and passed using most other means without corruption.
|
||||
*
|
||||
* @param string data to be encrypted
|
||||
* @return string
|
||||
*/
|
||||
public function encode($data)
|
||||
{
|
||||
// Set the rand type if it has not already been set
|
||||
if (Encrypt::$_rand === NULL)
|
||||
{
|
||||
if (Kohana::$is_windows)
|
||||
{
|
||||
// Windows only supports the system random number generator
|
||||
Encrypt::$_rand = MCRYPT_RAND;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (defined('MCRYPT_DEV_URANDOM'))
|
||||
{
|
||||
// Use /dev/urandom
|
||||
Encrypt::$_rand = MCRYPT_DEV_URANDOM;
|
||||
}
|
||||
elseif (defined('MCRYPT_DEV_RANDOM'))
|
||||
{
|
||||
// Use /dev/random
|
||||
Encrypt::$_rand = MCRYPT_DEV_RANDOM;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Use the system random number generator
|
||||
Encrypt::$_rand = MCRYPT_RAND;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (Encrypt::$_rand === MCRYPT_RAND)
|
||||
{
|
||||
// The system random number generator must always be seeded each
|
||||
// time it is used, or it will not produce true random results
|
||||
mt_srand();
|
||||
}
|
||||
|
||||
// Create a random initialization vector of the proper size for the current cipher
|
||||
$iv = mcrypt_create_iv($this->_iv_size, Encrypt::$_rand);
|
||||
|
||||
// Encrypt the data using the configured options and generated iv
|
||||
$data = mcrypt_encrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv);
|
||||
|
||||
// Use base64 encoding to convert to a string
|
||||
return base64_encode($iv.$data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrypts an encoded string back to its original value.
|
||||
*
|
||||
* $data = $encrypt->decode($data);
|
||||
*
|
||||
* @param string encoded string to be decrypted
|
||||
* @return FALSE if decryption fails
|
||||
* @return string
|
||||
*/
|
||||
public function decode($data)
|
||||
{
|
||||
// Convert the data back to binary
|
||||
$data = base64_decode($data, TRUE);
|
||||
|
||||
if ( ! $data)
|
||||
{
|
||||
// Invalid base64 data
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Extract the initialization vector from the data
|
||||
$iv = substr($data, 0, $this->_iv_size);
|
||||
|
||||
if ($this->_iv_size !== strlen($iv))
|
||||
{
|
||||
// The iv is not the expected size
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Remove the iv from the data
|
||||
$data = substr($data, $this->_iv_size);
|
||||
|
||||
// Return the decrypted data, trimming the \0 padding bytes from the end of the data
|
||||
return rtrim(mcrypt_decrypt($this->_cipher, $this->_key, $data, $this->_mode, $iv), "\0");
|
||||
}
|
||||
|
||||
} // End Encrypt
|
3
includes/kohana/system/classes/kohana/exception.php
Normal file
3
includes/kohana/system/classes/kohana/exception.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Kohana_Exception extends Kohana_Kohana_Exception {}
|
176
includes/kohana/system/classes/kohana/feed.php
Normal file
176
includes/kohana/system/classes/kohana/feed.php
Normal file
@@ -0,0 +1,176 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* RSS and Atom feed helper.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Feed {
|
||||
|
||||
/**
|
||||
* Parses a remote feed into an array.
|
||||
*
|
||||
* @param string remote feed URL
|
||||
* @param integer item limit to fetch
|
||||
* @return array
|
||||
*/
|
||||
public static function parse($feed, $limit = 0)
|
||||
{
|
||||
// Check if SimpleXML is installed
|
||||
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
|
||||
$error_level = error_reporting(0);
|
||||
|
||||
// Allow loading by filename or raw XML 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($error_level);
|
||||
|
||||
// Feed could not be loaded
|
||||
if ($feed === FALSE)
|
||||
return array();
|
||||
|
||||
$namespaces = $feed->getNamespaces(true);
|
||||
|
||||
// Detect the feed type. RSS 1.0/2.0 and Atom 1.0 are supported.
|
||||
$feed = isset($feed->channel) ? $feed->xpath('//item') : $feed->entry;
|
||||
|
||||
$i = 0;
|
||||
$items = array();
|
||||
|
||||
foreach ($feed as $item)
|
||||
{
|
||||
if ($limit > 0 AND $i++ === $limit)
|
||||
break;
|
||||
$item_fields = (array) $item;
|
||||
|
||||
// get namespaced tags
|
||||
foreach ($namespaces as $ns)
|
||||
{
|
||||
$item_fields += (array) $item->children($ns);
|
||||
}
|
||||
$items[] = $item_fields;
|
||||
}
|
||||
|
||||
return $items;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a feed from the given parameters.
|
||||
*
|
||||
* @param array feed information
|
||||
* @param array items to add to the feed
|
||||
* @param string define which format to use (only rss2 is supported)
|
||||
* @param string define which encoding to use
|
||||
* @return string
|
||||
*/
|
||||
public static function create($info, $items, $format = 'rss2', $encoding = 'UTF-8')
|
||||
{
|
||||
$info += array('title' => 'Generated Feed', 'link' => '', 'generator' => 'KohanaPHP');
|
||||
|
||||
$feed = '<?xml version="1.0" encoding="'.$encoding.'"?><rss version="2.0"><channel></channel></rss>';
|
||||
$feed = simplexml_load_string($feed);
|
||||
|
||||
foreach ($info as $name => $value)
|
||||
{
|
||||
if ($name === 'image')
|
||||
{
|
||||
// Create an image element
|
||||
$image = $feed->channel->addChild('image');
|
||||
|
||||
if ( ! isset($value['link'], $value['url'], $value['title']))
|
||||
{
|
||||
throw new Kohana_Exception('Feed images require a link, url, and title');
|
||||
}
|
||||
|
||||
if (strpos($value['link'], '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value['link'] = URL::site($value['link'], 'http');
|
||||
}
|
||||
|
||||
if (strpos($value['url'], '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value['url'] = URL::site($value['url'], 'http');
|
||||
}
|
||||
|
||||
// Create the image elements
|
||||
$image->addChild('link', $value['link']);
|
||||
$image->addChild('url', $value['url']);
|
||||
$image->addChild('title', $value['title']);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($name === 'pubDate' OR $name === 'lastBuildDate') AND (is_int($value) OR ctype_digit($value)))
|
||||
{
|
||||
// Convert timestamps to RFC 822 formatted dates
|
||||
$value = date('r', $value);
|
||||
}
|
||||
elseif (($name === 'link' OR $name === 'docs') AND strpos($value, '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value = URL::site($value, 'http');
|
||||
}
|
||||
|
||||
// Add the info to the channel
|
||||
$feed->channel->addChild($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($items as $item)
|
||||
{
|
||||
// Add the item to the channel
|
||||
$row = $feed->channel->addChild('item');
|
||||
|
||||
foreach ($item as $name => $value)
|
||||
{
|
||||
if ($name === 'pubDate' AND (is_int($value) OR ctype_digit($value)))
|
||||
{
|
||||
// Convert timestamps to RFC 822 formatted dates
|
||||
$value = date('r', $value);
|
||||
}
|
||||
elseif (($name === 'link' OR $name === 'guid') AND strpos($value, '://') === FALSE)
|
||||
{
|
||||
// Convert URIs to URLs
|
||||
$value = URL::site($value, 'http');
|
||||
}
|
||||
|
||||
// Add the info to the row
|
||||
$row->addChild($name, $value);
|
||||
}
|
||||
}
|
||||
|
||||
if (function_exists('dom_import_simplexml'))
|
||||
{
|
||||
// Convert the feed object to a DOM object
|
||||
$feed = dom_import_simplexml($feed)->ownerDocument;
|
||||
|
||||
// DOM generates more readable XML
|
||||
$feed->formatOutput = TRUE;
|
||||
|
||||
// Export the document as XML
|
||||
$feed = $feed->saveXML();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Export the document as XML
|
||||
$feed = $feed->asXML();
|
||||
}
|
||||
|
||||
return $feed;
|
||||
}
|
||||
|
||||
} // End Feed
|
243
includes/kohana/system/classes/kohana/file.php
Normal file
243
includes/kohana/system/classes/kohana/file.php
Normal file
@@ -0,0 +1,243 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* File helper class.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_File {
|
||||
|
||||
/**
|
||||
* Attempt to get the mime type from a file. This method is horribly
|
||||
* unreliable, due to PHP being horribly unreliable when it comes to
|
||||
* determining the mime type of a file.
|
||||
*
|
||||
* $mime = File::mime($file);
|
||||
*
|
||||
* @param string file name or path
|
||||
* @return string mime type on success
|
||||
* @return FALSE on failure
|
||||
*/
|
||||
public static function mime($filename)
|
||||
{
|
||||
// Get the complete path to the file
|
||||
$filename = realpath($filename);
|
||||
|
||||
// Get the extension from the filename
|
||||
$extension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
|
||||
|
||||
if (preg_match('/^(?:jpe?g|png|[gt]if|bmp|swf)$/', $extension))
|
||||
{
|
||||
// Use getimagesize() to find the mime type on images
|
||||
$file = getimagesize($filename);
|
||||
|
||||
if (isset($file['mime']))
|
||||
return $file['mime'];
|
||||
}
|
||||
|
||||
if (class_exists('finfo', FALSE))
|
||||
{
|
||||
if ($info = new finfo(defined('FILEINFO_MIME_TYPE') ? FILEINFO_MIME_TYPE : FILEINFO_MIME))
|
||||
{
|
||||
return $info->file($filename);
|
||||
}
|
||||
}
|
||||
|
||||
if (ini_get('mime_magic.magicfile') AND function_exists('mime_content_type'))
|
||||
{
|
||||
// The mime_content_type function is only useful with a magic file
|
||||
return mime_content_type($filename);
|
||||
}
|
||||
|
||||
if ( ! empty($extension))
|
||||
{
|
||||
return File::mime_by_ext($extension);
|
||||
}
|
||||
|
||||
// Unable to find the mime-type
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mime type of an extension.
|
||||
*
|
||||
* $mime = File::mime_by_ext('png'); // "image/png"
|
||||
*
|
||||
* @param string extension: php, pdf, txt, etc
|
||||
* @return string mime type on success
|
||||
* @return FALSE on failure
|
||||
*/
|
||||
public static function mime_by_ext($extension)
|
||||
{
|
||||
// Load all of the mime types
|
||||
$mimes = Kohana::config('mimes');
|
||||
|
||||
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.
|
||||
*
|
||||
* $count = File::split($file);
|
||||
*
|
||||
* @param string file to be split
|
||||
* @param string directory to output to, defaults to the same directory as the file
|
||||
* @param integer size, in MB, for each piece to be
|
||||
* @return integer The number of pieces that were created
|
||||
*/
|
||||
public static function split($filename, $piece_size = 10)
|
||||
{
|
||||
// Open the input file
|
||||
$file = fopen($filename, 'rb');
|
||||
|
||||
// Change the piece size to bytes
|
||||
$piece_size = floor($piece_size * 1024 * 1024);
|
||||
|
||||
// Write files in 8k blocks
|
||||
$block_size = 1024 * 8;
|
||||
|
||||
// Total number of peices
|
||||
$peices = 0;
|
||||
|
||||
while ( ! feof($file))
|
||||
{
|
||||
// Create another piece
|
||||
$peices += 1;
|
||||
|
||||
// Create a new file piece
|
||||
$piece = str_pad($peices, 3, '0', STR_PAD_LEFT);
|
||||
$piece = fopen($filename.'.'.$piece, 'wb+');
|
||||
|
||||
// Number of bytes read
|
||||
$read = 0;
|
||||
|
||||
do
|
||||
{
|
||||
// Transfer the data in blocks
|
||||
fwrite($piece, fread($file, $block_size));
|
||||
|
||||
// Another block has been read
|
||||
$read += $block_size;
|
||||
}
|
||||
while ($read < $piece_size);
|
||||
|
||||
// Close the piece
|
||||
fclose($piece);
|
||||
}
|
||||
|
||||
// Close the file
|
||||
fclose($file);
|
||||
|
||||
return $peices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Join a split file into a whole file. Does the reverse of [File::split].
|
||||
*
|
||||
* $count = File::join($file);
|
||||
*
|
||||
* @param string split filename, without .000 extension
|
||||
* @param string output filename, if different then an the filename
|
||||
* @return integer The number of pieces that were joined.
|
||||
*/
|
||||
public static function join($filename)
|
||||
{
|
||||
// Open the file
|
||||
$file = fopen($filename, 'wb+');
|
||||
|
||||
// Read files in 8k blocks
|
||||
$block_size = 1024 * 8;
|
||||
|
||||
// Total number of peices
|
||||
$pieces = 0;
|
||||
|
||||
while (is_file($piece = $filename.'.'.str_pad($pieces + 1, 3, '0', STR_PAD_LEFT)))
|
||||
{
|
||||
// Read another piece
|
||||
$pieces += 1;
|
||||
|
||||
// Open the piece for reading
|
||||
$piece = fopen($piece, 'rb');
|
||||
|
||||
while ( ! feof($piece))
|
||||
{
|
||||
// Transfer the data in blocks
|
||||
fwrite($file, fread($piece, $block_size));
|
||||
}
|
||||
|
||||
// Close the peice
|
||||
fclose($piece);
|
||||
}
|
||||
|
||||
return $pieces;
|
||||
}
|
||||
|
||||
} // End file
|
434
includes/kohana/system/classes/kohana/form.php
Normal file
434
includes/kohana/system/classes/kohana/form.php
Normal file
@@ -0,0 +1,434 @@
|
||||
<?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
|
||||
* attacks that could otherwise be trigged by inserting HTML characters into
|
||||
* form fields.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Form {
|
||||
|
||||
/**
|
||||
* Generates an opening HTML form tag.
|
||||
*
|
||||
* // Form will submit back to the current page using POST
|
||||
* echo Form::open();
|
||||
*
|
||||
* // Form will submit to 'search' using GET
|
||||
* echo Form::open('search', array('method' => 'get'));
|
||||
*
|
||||
* // When "file" inputs are present, you must include the "enctype"
|
||||
* echo Form::open(NULL, array('enctype' => 'multipart/form-data'));
|
||||
*
|
||||
* @param mixed form action, defaults to the current request URI, or [Request] class to use
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Request::instance
|
||||
* @uses URL::site
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function open($action = NULL, array $attributes = NULL)
|
||||
{
|
||||
if ($action instanceof Request)
|
||||
{
|
||||
// Use the current URI
|
||||
$action = $action->uri();
|
||||
}
|
||||
|
||||
if ($action === '')
|
||||
{
|
||||
// Use only the base URI
|
||||
$action = Kohana::$base_url;
|
||||
}
|
||||
elseif (strpos($action, '://') === FALSE)
|
||||
{
|
||||
// Make the URI absolute
|
||||
$action = URL::site($action);
|
||||
}
|
||||
|
||||
// Add the form action to the attributes
|
||||
$attributes['action'] = $action;
|
||||
|
||||
// Only accept the default character set
|
||||
$attributes['accept-charset'] = Kohana::$charset;
|
||||
|
||||
if ( ! isset($attributes['method']))
|
||||
{
|
||||
// Use POST method
|
||||
$attributes['method'] = 'post';
|
||||
}
|
||||
|
||||
return '<form'.HTML::attributes($attributes).'>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the closing form tag.
|
||||
*
|
||||
* echo Form::close();
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function close()
|
||||
{
|
||||
return '</form>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form input. If no type is specified, a "text" type input will
|
||||
* be returned.
|
||||
*
|
||||
* echo Form::input('username', $username);
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function input($name, $value = NULL, array $attributes = NULL)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// Set the input value
|
||||
$attributes['value'] = $value;
|
||||
|
||||
if ( ! isset($attributes['type']))
|
||||
{
|
||||
// Default type is text
|
||||
$attributes['type'] = 'text';
|
||||
}
|
||||
|
||||
return '<input'.HTML::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a hidden form input.
|
||||
*
|
||||
* echo Form::hidden('csrf', $token);
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function hidden($name, $value = NULL, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'hidden';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a password form input.
|
||||
*
|
||||
* echo Form::password('password');
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function password($name, $value = NULL, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'password';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a file upload form input. No input value can be specified.
|
||||
*
|
||||
* echo Form::file('image');
|
||||
*
|
||||
* @param string input name
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function file($name, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'file';
|
||||
|
||||
return Form::input($name, NULL, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a checkbox form input.
|
||||
*
|
||||
* echo Form::checkbox('remember_me', 1, (bool) $remember);
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param boolean checked status
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function checkbox($name, $value = NULL, $checked = FALSE, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'checkbox';
|
||||
|
||||
if ($checked === TRUE)
|
||||
{
|
||||
// Make the checkbox active
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a radio form input.
|
||||
*
|
||||
* echo Form::radio('like_cats', 1, $cats);
|
||||
* echo Form::radio('like_cats', 0, ! $cats);
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param boolean checked status
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function radio($name, $value = NULL, $checked = FALSE, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'radio';
|
||||
|
||||
if ($checked === TRUE)
|
||||
{
|
||||
// Make the radio active
|
||||
$attributes['checked'] = 'checked';
|
||||
}
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a textarea form input.
|
||||
*
|
||||
* echo Form::textarea('about', $about);
|
||||
*
|
||||
* @param string textarea name
|
||||
* @param string textarea body
|
||||
* @param array html attributes
|
||||
* @param boolean encode existing HTML characters
|
||||
* @return string
|
||||
* @uses HTML::attributes
|
||||
* @uses HTML::chars
|
||||
*/
|
||||
public static function textarea($name, $body = '', array $attributes = NULL, $double_encode = TRUE)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
// Add default rows and cols attributes (required)
|
||||
$attributes += array('rows' => 10, 'cols' => 50);
|
||||
|
||||
return '<textarea'.HTML::attributes($attributes).'>'.HTML::chars($body, $double_encode).'</textarea>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a select form input.
|
||||
*
|
||||
* 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
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function select($name, array $options = NULL, $selected = NULL, array $attributes = NULL)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
if (is_array($selected))
|
||||
{
|
||||
// This is a multi-select, god save us!
|
||||
$attributes['multiple'] = 'multiple';
|
||||
}
|
||||
|
||||
if ( ! is_array($selected))
|
||||
{
|
||||
if ($selected === NULL)
|
||||
{
|
||||
// Use an empty array
|
||||
$selected = array();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Convert the selected options to an array
|
||||
$selected = array( (string) $selected);
|
||||
}
|
||||
}
|
||||
|
||||
if (empty($options))
|
||||
{
|
||||
// There are no options
|
||||
$options = '';
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach ($options as $value => $name)
|
||||
{
|
||||
if (is_array($name))
|
||||
{
|
||||
// Create a new optgroup
|
||||
$group = array('label' => $value);
|
||||
|
||||
// Create a new list of options
|
||||
$_options = array();
|
||||
|
||||
foreach ($name as $_value => $_name)
|
||||
{
|
||||
// Force value to be string
|
||||
$_value = (string) $_value;
|
||||
|
||||
// Create a new attribute set for this option
|
||||
$option = array('value' => $_value);
|
||||
|
||||
if (in_array($_value, $selected))
|
||||
{
|
||||
// This option is selected
|
||||
$option['selected'] = 'selected';
|
||||
}
|
||||
|
||||
// Change the option to the HTML string
|
||||
$_options[] = '<option'.HTML::attributes($option).'>'.HTML::chars($_name, FALSE).'</option>';
|
||||
}
|
||||
|
||||
// Compile the options into a string
|
||||
$_options = "\n".implode("\n", $_options)."\n";
|
||||
|
||||
$options[$value] = '<optgroup'.HTML::attributes($group).'>'.$_options.'</optgroup>';
|
||||
}
|
||||
else
|
||||
{
|
||||
// Force value to be string
|
||||
$value = (string) $value;
|
||||
|
||||
// Create a new attribute set for this option
|
||||
$option = array('value' => $value);
|
||||
|
||||
if (in_array($value, $selected))
|
||||
{
|
||||
// This option is selected
|
||||
$option['selected'] = 'selected';
|
||||
}
|
||||
|
||||
// Change the option to the HTML string
|
||||
$options[$value] = '<option'.HTML::attributes($option).'>'.HTML::chars($name, FALSE).'</option>';
|
||||
}
|
||||
}
|
||||
|
||||
// Compile the options into a single string
|
||||
$options = "\n".implode("\n", $options)."\n";
|
||||
}
|
||||
|
||||
return '<select'.HTML::attributes($attributes).'>'.$options.'</select>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a submit form input.
|
||||
*
|
||||
* echo Form::submit(NULL, 'Login');
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function submit($name, $value, array $attributes = NULL)
|
||||
{
|
||||
$attributes['type'] = 'submit';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a image form input.
|
||||
*
|
||||
* echo Form::image(NULL, NULL, array('src' => 'media/img/login.png'));
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @param boolean add index file to URL?
|
||||
* @return string
|
||||
* @uses Form::input
|
||||
*/
|
||||
public static function image($name, $value, array $attributes = NULL, $index = FALSE)
|
||||
{
|
||||
if ( ! empty($attributes['src']))
|
||||
{
|
||||
if (strpos($attributes['src'], '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$attributes['src'] = URL::base($index).$attributes['src'];
|
||||
}
|
||||
}
|
||||
|
||||
$attributes['type'] = 'image';
|
||||
|
||||
return Form::input($name, $value, $attributes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a button form input. Note that the body of a button is NOT escaped,
|
||||
* to allow images and other HTML to be used.
|
||||
*
|
||||
* echo Form::button('save', 'Save Profile', array('type' => 'submit'));
|
||||
*
|
||||
* @param string input name
|
||||
* @param string input value
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function button($name, $body, array $attributes = NULL)
|
||||
{
|
||||
// Set the input name
|
||||
$attributes['name'] = $name;
|
||||
|
||||
return '<button'.HTML::attributes($attributes).'>'.$body.'</button>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a form label. Label text is not automatically translated.
|
||||
*
|
||||
* echo Form::label('username', 'Username');
|
||||
*
|
||||
* @param string target input
|
||||
* @param string label text
|
||||
* @param array html attributes
|
||||
* @return string
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function label($input, $text = NULL, array $attributes = NULL)
|
||||
{
|
||||
if ($text === NULL)
|
||||
{
|
||||
// Use the input name as the text
|
||||
$text = ucwords(preg_replace('/[\W_]+/', ' ', $input));
|
||||
}
|
||||
|
||||
// Set the label target
|
||||
$attributes['for'] = $input;
|
||||
|
||||
return '<label'.HTML::attributes($attributes).'>'.$text.'</label>';
|
||||
}
|
||||
|
||||
} // End form
|
147
includes/kohana/system/classes/kohana/fragment.php
Normal file
147
includes/kohana/system/classes/kohana/fragment.php
Normal file
@@ -0,0 +1,147 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* View fragment caching. This is primarily used to cache small parts of a view
|
||||
* that rarely change. For instance, you may want to cache the footer of your
|
||||
* template because it has very little dynamic content. Or you could cache a
|
||||
* user profile page and delete the fragment when the user updates.
|
||||
*
|
||||
* For obvious reasons, fragment caching should not be applied to any
|
||||
* content that contains forms.
|
||||
*
|
||||
* [!!] Multiple language (I18n) support was added in v3.0.4.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
* @uses Kohana::cache
|
||||
*/
|
||||
class Kohana_Fragment {
|
||||
|
||||
/**
|
||||
* @var integer default number of seconds to cache for
|
||||
*/
|
||||
public static $lifetime = 30;
|
||||
|
||||
/**
|
||||
* @var boolean use multilingual fragment support?
|
||||
*/
|
||||
public static $i18n = FALSE;
|
||||
|
||||
/**
|
||||
* @var array list of buffer => cache key
|
||||
*/
|
||||
protected static $_caches = array();
|
||||
|
||||
/**
|
||||
* Generate the cache key name for a fragment.
|
||||
*
|
||||
* $key = Fragment::_cache_key('footer', TRUE);
|
||||
*
|
||||
* @param string fragment name
|
||||
* @param boolean multilingual fragment support
|
||||
* @return string
|
||||
* @uses I18n::lang
|
||||
* @since 3.0.4
|
||||
*/
|
||||
protected static function _cache_key($name, $i18n = NULL)
|
||||
{
|
||||
if ($i18n === NULL)
|
||||
{
|
||||
// Use the default setting
|
||||
$i18n = Fragment::$i18n;
|
||||
}
|
||||
|
||||
// Language prefix for cache key
|
||||
$i18n = ($i18n === TRUE) ? I18n::lang() : '';
|
||||
|
||||
// Note: $i18n and $name need to be delimited to prevent naming collisions
|
||||
return 'Fragment::cache('.$i18n.'+'.$name.')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a fragment from cache and display it. Multiple fragments can
|
||||
* be nested with different life times.
|
||||
*
|
||||
* if ( ! Fragment::load('footer')) {
|
||||
* // Anything that is echo'ed here will be saved
|
||||
* Fragment::save();
|
||||
* }
|
||||
*
|
||||
* @param string fragment name
|
||||
* @param integer fragment cache lifetime
|
||||
* @param boolean multilingual fragment support
|
||||
* @return boolean
|
||||
*/
|
||||
public static function load($name, $lifetime = NULL, $i18n = NULL)
|
||||
{
|
||||
// Set the cache lifetime
|
||||
$lifetime = ($lifetime === NULL) ? Fragment::$lifetime : (int) $lifetime;
|
||||
|
||||
// Get the cache key name
|
||||
$cache_key = Fragment::_cache_key($name, $i18n);
|
||||
|
||||
if ($fragment = Kohana::cache($cache_key, NULL, $lifetime))
|
||||
{
|
||||
// Display the cached fragment now
|
||||
echo $fragment;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Start the output buffer
|
||||
ob_start();
|
||||
|
||||
// Store the cache key by the buffer level
|
||||
Fragment::$_caches[ob_get_level()] = $cache_key;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the currently open fragment in the cache.
|
||||
*
|
||||
* Fragment::save();
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function save()
|
||||
{
|
||||
// Get the buffer level
|
||||
$level = ob_get_level();
|
||||
|
||||
if (isset(Fragment::$_caches[$level]))
|
||||
{
|
||||
// Get the cache key based on the level
|
||||
$cache_key = Fragment::$_caches[$level];
|
||||
|
||||
// Delete the cache key, we don't need it anymore
|
||||
unset(Fragment::$_caches[$level]);
|
||||
|
||||
// Get the output buffer and display it at the same time
|
||||
$fragment = ob_get_flush();
|
||||
|
||||
// Cache the fragment
|
||||
Kohana::cache($cache_key, $fragment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cached fragment.
|
||||
*
|
||||
* Fragment::delete($key);
|
||||
*
|
||||
* @param string fragment name
|
||||
* @param boolean multilingual fragment support
|
||||
* @return void
|
||||
*/
|
||||
public static function delete($name, $i18n = NULL)
|
||||
{
|
||||
// Invalid the cache
|
||||
Kohana::cache(Fragment::_cache_key($name, $i18n), NULL, -3600);
|
||||
}
|
||||
|
||||
} // End Fragment
|
386
includes/kohana/system/classes/kohana/html.php
Normal file
386
includes/kohana/system/classes/kohana/html.php
Normal file
@@ -0,0 +1,386 @@
|
||||
<?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.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Helpers
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2011 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_HTML {
|
||||
|
||||
/**
|
||||
* @var array preferred order of attributes
|
||||
*/
|
||||
public static $attribute_order = array
|
||||
(
|
||||
'action',
|
||||
'method',
|
||||
'type',
|
||||
'id',
|
||||
'name',
|
||||
'value',
|
||||
'href',
|
||||
'src',
|
||||
'width',
|
||||
'height',
|
||||
'cols',
|
||||
'rows',
|
||||
'size',
|
||||
'maxlength',
|
||||
'rel',
|
||||
'media',
|
||||
'accept-charset',
|
||||
'accept',
|
||||
'tabindex',
|
||||
'accesskey',
|
||||
'alt',
|
||||
'title',
|
||||
'class',
|
||||
'style',
|
||||
'selected',
|
||||
'checked',
|
||||
'readonly',
|
||||
'disabled',
|
||||
);
|
||||
|
||||
/**
|
||||
* @var boolean automatically target external URLs to a new window?
|
||||
*/
|
||||
public static $windowed_urls = FALSE;
|
||||
|
||||
/**
|
||||
* Convert special characters to HTML entities. All untrusted content
|
||||
* should be passed through this method to prevent XSS injections.
|
||||
*
|
||||
* echo HTML::chars($username);
|
||||
*
|
||||
* @param string string to convert
|
||||
* @param boolean encode existing entities
|
||||
* @return string
|
||||
*/
|
||||
public static function chars($value, $double_encode = TRUE)
|
||||
{
|
||||
return htmlspecialchars( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert all applicable characters to HTML entities. All characters
|
||||
* that cannot be represented in HTML with the current character set
|
||||
* will be converted to entities.
|
||||
*
|
||||
* echo HTML::entities($username);
|
||||
*
|
||||
* @param string string to convert
|
||||
* @param boolean encode existing entities
|
||||
* @return string
|
||||
*/
|
||||
public static function entities($value, $double_encode = TRUE)
|
||||
{
|
||||
return htmlentities( (string) $value, ENT_QUOTES, Kohana::$charset, $double_encode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create HTML link anchors. Note that the title is not escaped, to allow
|
||||
* HTML elements within links (images, etc).
|
||||
*
|
||||
* echo HTML::anchor('/user/profile', 'My Profile');
|
||||
*
|
||||
* @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, $index = FALSE)
|
||||
{
|
||||
if ($title === NULL)
|
||||
{
|
||||
// Use the URI as the title
|
||||
$title = $uri;
|
||||
}
|
||||
|
||||
if ($uri === '')
|
||||
{
|
||||
// Only use the base URL
|
||||
$uri = URL::base($protocol, $index);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (strpos($uri, '://') !== FALSE)
|
||||
{
|
||||
if (HTML::$windowed_urls === TRUE AND empty($attributes['target']))
|
||||
{
|
||||
// Make the link open in a new window
|
||||
$attributes['target'] = '_blank';
|
||||
}
|
||||
}
|
||||
elseif ($uri[0] !== '#')
|
||||
{
|
||||
// Make the URI absolute for non-id anchors
|
||||
$uri = URL::site($uri, $protocol, $index);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the sanitized link to the attributes
|
||||
$attributes['href'] = $uri;
|
||||
|
||||
return '<a'.HTML::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an HTML anchor to a file. Note that the title is not escaped,
|
||||
* to allow HTML elements within links (images, etc).
|
||||
*
|
||||
* echo HTML::file_anchor('media/doc/user_guide.pdf', 'User Guide');
|
||||
*
|
||||
* @param string name of file to link to
|
||||
* @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 HTML::attributes
|
||||
*/
|
||||
public static function file_anchor($file, $title = NULL, array $attributes = NULL, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if ($title === NULL)
|
||||
{
|
||||
// Use the file name as the title
|
||||
$title = basename($file);
|
||||
}
|
||||
|
||||
// Add the file link to the attributes
|
||||
$attributes['href'] = URL::base($protocol, $index).$file;
|
||||
|
||||
return '<a'.HTML::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an obfuscated version of a string. Text passed through this
|
||||
* method is less likely to be read by web crawlers and robots, which can
|
||||
* be helpful for spam prevention, but can prevent legitimate robots from
|
||||
* reading your content.
|
||||
*
|
||||
* echo HTML::obfuscate($text);
|
||||
*
|
||||
* @param string string to obfuscate
|
||||
* @return string
|
||||
* @since 3.0.3
|
||||
*/
|
||||
public static function obfuscate($string)
|
||||
{
|
||||
$safe = '';
|
||||
foreach (str_split($string) as $letter)
|
||||
{
|
||||
switch (rand(1, 3))
|
||||
{
|
||||
// HTML entity code
|
||||
case 1:
|
||||
$safe .= '&#'.ord($letter).';';
|
||||
break;
|
||||
|
||||
// Hex character code
|
||||
case 2:
|
||||
$safe .= '&#x'.dechex(ord($letter)).';';
|
||||
break;
|
||||
|
||||
// Raw (no) encoding
|
||||
case 3:
|
||||
$safe .= $letter;
|
||||
}
|
||||
}
|
||||
|
||||
return $safe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an obfuscated version of an email address. Helps prevent spam
|
||||
* robots from finding email addresses.
|
||||
*
|
||||
* echo HTML::email($address);
|
||||
*
|
||||
* @param string email address
|
||||
* @return string
|
||||
* @uses HTML::obfuscate
|
||||
*/
|
||||
public static function email($email)
|
||||
{
|
||||
// Make sure the at sign is always obfuscated
|
||||
return str_replace('@', '@', HTML::obfuscate($email));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an email (mailto:) anchor. Note that the title is not escaped,
|
||||
* to allow HTML elements within links (images, etc).
|
||||
*
|
||||
* echo HTML::mailto($address);
|
||||
*
|
||||
* @param string email address to send to
|
||||
* @param string link text
|
||||
* @param array HTML anchor attributes
|
||||
* @return string
|
||||
* @uses HTML::email
|
||||
* @uses HTML::attributes
|
||||
*/
|
||||
public static function mailto($email, $title = NULL, array $attributes = NULL)
|
||||
{
|
||||
// Obfuscate email address
|
||||
$email = HTML::email($email);
|
||||
|
||||
if ($title === NULL)
|
||||
{
|
||||
// Use the email address as the title
|
||||
$title = $email;
|
||||
}
|
||||
|
||||
return '<a href="mailto:'.$email.'"'.HTML::attributes($attributes).'>'.$title.'</a>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a style sheet link element.
|
||||
*
|
||||
* echo HTML::style('media/css/screen.css');
|
||||
*
|
||||
* @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, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Set the stylesheet link
|
||||
$attributes['href'] = $file;
|
||||
|
||||
// Set the stylesheet rel
|
||||
$attributes['rel'] = 'stylesheet';
|
||||
|
||||
// Set the stylesheet type
|
||||
$attributes['type'] = 'text/css';
|
||||
|
||||
return '<link'.HTML::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a script link.
|
||||
*
|
||||
* echo HTML::script('media/js/jquery.min.js');
|
||||
*
|
||||
* @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, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Set the script link
|
||||
$attributes['src'] = $file;
|
||||
|
||||
// Set the script type
|
||||
$attributes['type'] = 'text/javascript';
|
||||
|
||||
return '<script'.HTML::attributes($attributes).'></script>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a image link.
|
||||
*
|
||||
* echo HTML::image('media/img/logo.png', array('alt' => 'My Company'));
|
||||
*
|
||||
* @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, $protocol = NULL, $index = FALSE)
|
||||
{
|
||||
if (strpos($file, '://') === FALSE)
|
||||
{
|
||||
// Add the base URL
|
||||
$file = URL::base($protocol, $index).$file;
|
||||
}
|
||||
|
||||
// Add the image link
|
||||
$attributes['src'] = $file;
|
||||
|
||||
return '<img'.HTML::attributes($attributes).' />';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles an array of HTML attributes into an attribute string.
|
||||
* Attributes will be sorted using HTML::$attribute_order for consistency.
|
||||
*
|
||||
* echo '<div'.HTML::attributes($attrs).'>'.$content.'</div>';
|
||||
*
|
||||
* @param array attribute list
|
||||
* @return string
|
||||
*/
|
||||
public static function attributes(array $attributes = NULL)
|
||||
{
|
||||
if (empty($attributes))
|
||||
return '';
|
||||
|
||||
$sorted = array();
|
||||
foreach (HTML::$attribute_order as $key)
|
||||
{
|
||||
if (isset($attributes[$key]))
|
||||
{
|
||||
// Add the attribute to the sorted list
|
||||
$sorted[$key] = $attributes[$key];
|
||||
}
|
||||
}
|
||||
|
||||
// Combine the sorted attributes
|
||||
$attributes = $sorted + $attributes;
|
||||
|
||||
$compiled = '';
|
||||
foreach ($attributes as $key => $value)
|
||||
{
|
||||
if ($value === NULL)
|
||||
{
|
||||
// Skip attributes that have NULL values
|
||||
continue;
|
||||
}
|
||||
|
||||
if (is_int($key))
|
||||
{
|
||||
// Assume non-associative keys are mirrored attributes
|
||||
$key = $value;
|
||||
}
|
||||
|
||||
// Add the attribute value
|
||||
$compiled .= ' '.$key.'="'.HTML::chars($value).'"';
|
||||
}
|
||||
|
||||
return $compiled;
|
||||
}
|
||||
|
||||
} // End html
|
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);
|
||||
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user