diff options
Diffstat (limited to 'kohana/libraries')
50 files changed, 0 insertions, 13639 deletions
diff --git a/kohana/libraries/Cache.php b/kohana/libraries/Cache.php deleted file mode 100644 index 8a02a905..00000000 --- a/kohana/libraries/Cache.php +++ /dev/null @@ -1,208 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Provides a driver-based interface for finding, creating, and deleting cached - * resources. Caches are identified by a unique string. Tagging of caches is - * also supported, and caches can be found and deleted by id or tag. - * - * $Id: Cache.php 4321 2009-05-04 01:39:44Z kiall $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Core { - - protected static $instances = array(); - - // For garbage collection - protected static $loaded; - - // Configuration - protected $config; - - // Driver object - protected $driver; - - /** - * Returns a singleton instance of Cache. - * - * @param string configuration - * @return Cache_Core - */ - public static function & instance($config = FALSE) - { - if ( ! isset(Cache::$instances[$config])) - { - // Create a new instance - Cache::$instances[$config] = new Cache($config); - } - - return Cache::$instances[$config]; - } - - /** - * Loads the configured driver and validates it. - * - * @param array|string custom configuration or config group name - * @return void - */ - public function __construct($config = FALSE) - { - if (is_string($config)) - { - $name = $config; - - // Test the config group name - if (($config = Kohana::config('cache.'.$config)) === NULL) - throw new Kohana_Exception('cache.undefined_group', $name); - } - - if (is_array($config)) - { - // Append the default configuration options - $config += Kohana::config('cache.default'); - } - else - { - // Load the default group - $config = Kohana::config('cache.default'); - } - - // Cache the config in the object - $this->config = $config; - - // Set driver name - $driver = 'Cache_'.ucfirst($this->config['driver']).'_Driver'; - - // Load the driver - if ( ! Kohana::auto_load($driver)) - throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); - - // Initialize the driver - $this->driver = new $driver($this->config['params']); - - // Validate the driver - if ( ! ($this->driver instanceof Cache_Driver)) - throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Cache_Driver'); - - Kohana::log('debug', 'Cache Library initialized'); - - if (Cache::$loaded !== TRUE) - { - $this->config['requests'] = (int) $this->config['requests']; - - if ($this->config['requests'] > 0 AND mt_rand(1, $this->config['requests']) === 1) - { - // Do garbage collection - $this->driver->delete_expired(); - - Kohana::log('debug', 'Cache: Expired caches deleted.'); - } - - // Cache has been loaded once - Cache::$loaded = TRUE; - } - } - - /** - * Fetches a cache by id. NULL is returned when a cache item is not found. - * - * @param string cache id - * @return mixed cached data or NULL - */ - public function get($id) - { - // Sanitize the ID - $id = $this->sanitize_id($id); - - return $this->driver->get($id); - } - - /** - * Fetches all of the caches for a given tag. An empty array will be - * returned when no matching caches are found. - * - * @param string cache tag - * @return array all cache items matching the tag - */ - public function find($tag) - { - return $this->driver->find($tag); - } - - /** - * Set a cache item by id. Tags may also be added and a custom lifetime - * can be set. Non-string data is automatically serialized. - * - * @param string unique cache id - * @param mixed data to cache - * @param array|string tags for this item - * @param integer number of seconds until the cache expires - * @return boolean - */ - function set($id, $data, $tags = NULL, $lifetime = NULL) - { - if (is_resource($data)) - throw new Kohana_Exception('cache.resources'); - - // Sanitize the ID - $id = $this->sanitize_id($id); - - if ($lifetime === NULL) - { - // Get the default lifetime - $lifetime = $this->config['lifetime']; - } - - return $this->driver->set($id, $data, (array) $tags, $lifetime); - } - - /** - * Delete a cache item by id. - * - * @param string cache id - * @return boolean - */ - public function delete($id) - { - // Sanitize the ID - $id = $this->sanitize_id($id); - - return $this->driver->delete($id); - } - - /** - * Delete all cache items with a given tag. - * - * @param string cache tag name - * @return boolean - */ - public function delete_tag($tag) - { - return $this->driver->delete($tag, TRUE); - } - - /** - * Delete ALL cache items items. - * - * @return boolean - */ - public function delete_all() - { - return $this->driver->delete(TRUE); - } - - /** - * Replaces troublesome characters with underscores. - * - * @param string cache id - * @return string - */ - protected function sanitize_id($id) - { - // Change slashes and spaces to underscores - return str_replace(array('/', '\\', ' '), '_', $id); - } - -} // End Cache diff --git a/kohana/libraries/Controller.php b/kohana/libraries/Controller.php deleted file mode 100644 index d111f25e..00000000 --- a/kohana/libraries/Controller.php +++ /dev/null @@ -1,78 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Kohana Controller class. The controller class must be extended to work - * properly, so this class is defined as abstract. - * - * $Id: Controller.php 3979 2009-02-13 16:46:12Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Controller_Core { - - // Allow all controllers to run in production by default - const ALLOW_PRODUCTION = TRUE; - - /** - * Loads URI, and Input into this controller. - * - * @return void - */ - public function __construct() - { - if (Kohana::$instance == NULL) - { - // Set the instance to the first controller loaded - Kohana::$instance = $this; - } - - // URI should always be available - $this->uri = URI::instance(); - - // Input should always be available - $this->input = Input::instance(); - } - - /** - * Handles methods that do not exist. - * - * @param string method name - * @param array arguments - * @return void - */ - public function __call($method, $args) - { - // Default to showing a 404 page - Event::run('system.404'); - } - - /** - * Includes a View within the controller scope. - * - * @param string view filename - * @param array array of view variables - * @return string - */ - public function _kohana_load_view($kohana_view_filename, $kohana_input_data) - { - if ($kohana_view_filename == '') - return; - - // Buffering on - ob_start(); - - // Import the view variables to local namespace - extract($kohana_input_data, EXTR_SKIP); - - // Views are straight HTML pages with embedded PHP, so importing them - // this way insures that $this can be accessed as if the user was in - // the controller, which gives the easiest access to libraries in views - include $kohana_view_filename; - - // Fetch the output and close the buffer - return ob_get_clean(); - } - -} // End Controller Class
\ No newline at end of file diff --git a/kohana/libraries/Database.php b/kohana/libraries/Database.php deleted file mode 100644 index 6267f63a..00000000 --- a/kohana/libraries/Database.php +++ /dev/null @@ -1,1444 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Provides database access in a platform agnostic way, using simple query building blocks. - * - * $Id: Database.php 4342 2009-05-08 16:56:01Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Core { - - // Database instances - public static $instances = array(); - - // Global benchmark - public static $benchmarks = array(); - - // Configuration - protected $config = array - ( - 'benchmark' => TRUE, - 'persistent' => FALSE, - 'connection' => '', - 'character_set' => 'utf8', - 'table_prefix' => '', - 'object' => TRUE, - 'cache' => FALSE, - 'escape' => TRUE, - ); - - // Database driver object - protected $driver; - protected $link; - - // Un-compiled parts of the SQL query - protected $select = array(); - protected $set = array(); - protected $from = array(); - protected $join = array(); - protected $where = array(); - protected $orderby = array(); - protected $order = array(); - protected $groupby = array(); - protected $having = array(); - protected $distinct = FALSE; - protected $limit = FALSE; - protected $offset = FALSE; - protected $last_query = ''; - - // Stack of queries for push/pop - protected $query_history = array(); - - /** - * Returns a singleton instance of Database. - * - * @param mixed configuration array or DSN - * @return Database_Core - */ - public static function & instance($name = 'default', $config = NULL) - { - if ( ! isset(Database::$instances[$name])) - { - // Create a new instance - Database::$instances[$name] = new Database($config === NULL ? $name : $config); - } - - return Database::$instances[$name]; - } - - /** - * Returns the name of a given database instance. - * - * @param Database instance of Database - * @return string - */ - public static function instance_name(Database $db) - { - return array_search($db, Database::$instances, TRUE); - } - - /** - * Sets up the database configuration, loads the Database_Driver. - * - * @throws Kohana_Database_Exception - */ - public function __construct($config = array()) - { - if (empty($config)) - { - // Load the default group - $config = Kohana::config('database.default'); - } - elseif (is_array($config) AND count($config) > 0) - { - if ( ! array_key_exists('connection', $config)) - { - $config = array('connection' => $config); - } - } - elseif (is_string($config)) - { - // The config is a DSN string - if (strpos($config, '://') !== FALSE) - { - $config = array('connection' => $config); - } - // The config is a group name - else - { - $name = $config; - - // Test the config group name - if (($config = Kohana::config('database.'.$config)) === NULL) - throw new Kohana_Database_Exception('database.undefined_group', $name); - } - } - - // Merge the default config with the passed config - $this->config = array_merge($this->config, $config); - - if (is_string($this->config['connection'])) - { - // Make sure the connection is valid - if (strpos($this->config['connection'], '://') === FALSE) - throw new Kohana_Database_Exception('database.invalid_dsn', $this->config['connection']); - - // Parse the DSN, creating an array to hold the connection parameters - $db = array - ( - 'type' => FALSE, - 'user' => FALSE, - 'pass' => FALSE, - 'host' => FALSE, - 'port' => FALSE, - 'socket' => FALSE, - 'database' => FALSE - ); - - // Get the protocol and arguments - list ($db['type'], $connection) = explode('://', $this->config['connection'], 2); - - if (strpos($connection, '@') !== FALSE) - { - // Get the username and password - list ($db['pass'], $connection) = explode('@', $connection, 2); - // Check if a password is supplied - $logindata = explode(':', $db['pass'], 2); - $db['pass'] = (count($logindata) > 1) ? $logindata[1] : ''; - $db['user'] = $logindata[0]; - - // Prepare for finding the database - $connection = explode('/', $connection); - - // Find the database name - $db['database'] = array_pop($connection); - - // Reset connection string - $connection = implode('/', $connection); - - // Find the socket - if (preg_match('/^unix\([^)]++\)/', $connection)) - { - // This one is a little hairy: we explode based on the end of - // the socket, removing the 'unix(' from the connection string - list ($db['socket'], $connection) = explode(')', substr($connection, 5), 2); - } - elseif (strpos($connection, ':') !== FALSE) - { - // Fetch the host and port name - list ($db['host'], $db['port']) = explode(':', $connection, 2); - } - else - { - $db['host'] = $connection; - } - } - else - { - // File connection - $connection = explode('/', $connection); - - // Find database file name - $db['database'] = array_pop($connection); - - // Find database directory name - $db['socket'] = implode('/', $connection).'/'; - } - - // Reset the connection array to the database config - $this->config['connection'] = $db; - } - // Set driver name - $driver = 'Database_'.ucfirst($this->config['connection']['type']).'_Driver'; - - // Load the driver - if ( ! Kohana::auto_load($driver)) - throw new Kohana_Database_Exception('core.driver_not_found', $this->config['connection']['type'], get_class($this)); - - // Initialize the driver - $this->driver = new $driver($this->config); - - // Validate the driver - if ( ! ($this->driver instanceof Database_Driver)) - throw new Kohana_Database_Exception('core.driver_implements', $this->config['connection']['type'], get_class($this), 'Database_Driver'); - - Kohana::log('debug', 'Database Library initialized'); - } - - /** - * Simple connect method to get the database queries up and running. - * - * @return void - */ - public function connect() - { - // A link can be a resource or an object - if ( ! is_resource($this->link) AND ! is_object($this->link)) - { - $this->link = $this->driver->connect(); - if ( ! is_resource($this->link) AND ! is_object($this->link)) - throw new Kohana_Database_Exception('database.connection', $this->driver->show_error()); - - // Clear password after successful connect - $this->config['connection']['pass'] = NULL; - } - } - - /** - * Runs a query into the driver and returns the result. - * - * @param string SQL query to execute - * @return Database_Result - */ - public function query($sql = '') - { - if ($sql == '') return FALSE; - - // No link? Connect! - $this->link or $this->connect(); - - // Start the benchmark - $start = microtime(TRUE); - - if (func_num_args() > 1) //if we have more than one argument ($sql) - { - $argv = func_get_args(); - $binds = (is_array(next($argv))) ? current($argv) : array_slice($argv, 1); - } - - // Compile binds if needed - if (isset($binds)) - { - $sql = $this->compile_binds($sql, $binds); - } - - // Fetch the result - $result = $this->driver->query($this->last_query = $sql); - - // Stop the benchmark - $stop = microtime(TRUE); - - if ($this->config['benchmark'] == TRUE) - { - // Benchmark the query - Database::$benchmarks[] = array('query' => $sql, 'time' => $stop - $start, 'rows' => count($result)); - } - - return $result; - } - - /** - * Selects the column names for a database query. - * - * @param string string or array of column names to select - * @return Database_Core This Database object. - */ - public function select($sql = '*') - { - if (func_num_args() > 1) - { - $sql = func_get_args(); - } - elseif (is_string($sql)) - { - $sql = explode(',', $sql); - } - else - { - $sql = (array) $sql; - } - - foreach ($sql as $val) - { - if (($val = trim($val)) === '') continue; - - if (strpos($val, '(') === FALSE AND $val !== '*') - { - if (preg_match('/^DISTINCT\s++(.+)$/i', $val, $matches)) - { - // Only prepend with table prefix if table name is specified - $val = (strpos($matches[1], '.') !== FALSE) ? $this->config['table_prefix'].$matches[1] : $matches[1]; - - $this->distinct = TRUE; - } - else - { - $val = (strpos($val, '.') !== FALSE) ? $this->config['table_prefix'].$val : $val; - } - - $val = $this->driver->escape_column($val); - } - - $this->select[] = $val; - } - - return $this; - } - - /** - * Selects the from table(s) for a database query. - * - * @param string string or array of tables to select - * @return Database_Core This Database object. - */ - public function from($sql) - { - if (func_num_args() > 1) - { - $sql = func_get_args(); - } - elseif (is_string($sql)) - { - $sql = explode(',', $sql); - } - else - { - $sql = array($sql); - } - - foreach ($sql as $val) - { - if (is_string($val)) - { - if (($val = trim($val)) === '') continue; - - // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) - if (stripos($val, ' AS ') !== FALSE) - { - $val = str_ireplace(' AS ', ' AS ', $val); - - list($table, $alias) = explode(' AS ', $val); - - // Attach prefix to both sides of the AS - $val = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; - } - else - { - $val = $this->config['table_prefix'].$val; - } - } - - $this->from[] = $val; - } - - return $this; - } - - /** - * Generates the JOIN portion of the query. - * - * @param string table name - * @param string|array where key or array of key => value pairs - * @param string where value - * @param string type of join - * @return Database_Core This Database object. - */ - public function join($table, $key, $value = NULL, $type = '') - { - $join = array(); - - if ( ! empty($type)) - { - $type = strtoupper(trim($type)); - - if ( ! in_array($type, array('LEFT', 'RIGHT', 'OUTER', 'INNER', 'LEFT OUTER', 'RIGHT OUTER'), TRUE)) - { - $type = ''; - } - else - { - $type .= ' '; - } - } - - $cond = array(); - $keys = is_array($key) ? $key : array($key => $value); - foreach ($keys as $key => $value) - { - $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; - - if (is_string($value)) - { - // Only escape if it's a string - $value = $this->driver->escape_column($this->config['table_prefix'].$value); - } - - $cond[] = $this->driver->where($key, $value, 'AND ', count($cond), FALSE); - } - - if ( ! is_array($this->join)) - { - $this->join = array(); - } - - if ( ! is_array($table)) - { - $table = array($table); - } - - foreach ($table as $t) - { - if (is_string($t)) - { - // TODO: Temporary solution, this should be moved to database driver (AS is checked for twice) - if (stripos($t, ' AS ') !== FALSE) - { - $t = str_ireplace(' AS ', ' AS ', $t); - - list($table, $alias) = explode(' AS ', $t); - - // Attach prefix to both sides of the AS - $t = $this->config['table_prefix'].$table.' AS '.$this->config['table_prefix'].$alias; - } - else - { - $t = $this->config['table_prefix'].$t; - } - } - - $join['tables'][] = $this->driver->escape_column($t); - } - - $join['conditions'] = '('.trim(implode(' ', $cond)).')'; - $join['type'] = $type; - - $this->join[] = $join; - - return $this; - } - - - /** - * Selects the where(s) for a database query. - * - * @param string|array key name or array of key => value pairs - * @param string value to match with key - * @param boolean disable quoting of WHERE clause - * @return Database_Core This Database object. - */ - public function where($key, $value = NULL, $quote = TRUE) - { - $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; - if (is_object($key)) - { - $keys = array((string) $key => ''); - } - elseif ( ! is_array($key)) - { - $keys = array($key => $value); - } - else - { - $keys = $key; - } - - foreach ($keys as $key => $value) - { - $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; - $this->where[] = $this->driver->where($key, $value, 'AND ', count($this->where), $quote); - } - - return $this; - } - - /** - * Selects the or where(s) for a database query. - * - * @param string|array key name or array of key => value pairs - * @param string value to match with key - * @param boolean disable quoting of WHERE clause - * @return Database_Core This Database object. - */ - public function orwhere($key, $value = NULL, $quote = TRUE) - { - $quote = (func_num_args() < 2 AND ! is_array($key)) ? -1 : $quote; - if (is_object($key)) - { - $keys = array((string) $key => ''); - } - elseif ( ! is_array($key)) - { - $keys = array($key => $value); - } - else - { - $keys = $key; - } - - foreach ($keys as $key => $value) - { - $key = (strpos($key, '.') !== FALSE) ? $this->config['table_prefix'].$key : $key; - $this->where[] = $this->driver->where($key, $value, 'OR ', count($this->where), $quote); - } - - return $this; - } - - /** - * Selects the like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @param boolean automatically add starting and ending wildcards - * @return Database_Core This Database object. - */ - public function like($field, $match = '', $auto = TRUE) - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->like($field, $match, $auto, 'AND ', count($this->where)); - } - - return $this; - } - - /** - * Selects the or like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @param boolean automatically add starting and ending wildcards - * @return Database_Core This Database object. - */ - public function orlike($field, $match = '', $auto = TRUE) - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->like($field, $match, $auto, 'OR ', count($this->where)); - } - - return $this; - } - - /** - * Selects the not like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @param boolean automatically add starting and ending wildcards - * @return Database_Core This Database object. - */ - public function notlike($field, $match = '', $auto = TRUE) - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->notlike($field, $match, $auto, 'AND ', count($this->where)); - } - - return $this; - } - - /** - * Selects the or not like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @return Database_Core This Database object. - */ - public function ornotlike($field, $match = '', $auto = TRUE) - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->notlike($field, $match, $auto, 'OR ', count($this->where)); - } - - return $this; - } - - /** - * Selects the like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @return Database_Core This Database object. - */ - public function regex($field, $match = '') - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->regex($field, $match, 'AND ', count($this->where)); - } - - return $this; - } - - /** - * Selects the or like(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string like value to match with field - * @return Database_Core This Database object. - */ - public function orregex($field, $match = '') - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->regex($field, $match, 'OR ', count($this->where)); - } - - return $this; - } - - /** - * Selects the not regex(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string regex value to match with field - * @return Database_Core This Database object. - */ - public function notregex($field, $match = '') - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->notregex($field, $match, 'AND ', count($this->where)); - } - - return $this; - } - - /** - * Selects the or not regex(s) for a database query. - * - * @param string|array field name or array of field => match pairs - * @param string regex value to match with field - * @return Database_Core This Database object. - */ - public function ornotregex($field, $match = '') - { - $fields = is_array($field) ? $field : array($field => $match); - - foreach ($fields as $field => $match) - { - $field = (strpos($field, '.') !== FALSE) ? $this->config['table_prefix'].$field : $field; - $this->where[] = $this->driver->notregex($field, $match, 'OR ', count($this->where)); - } - - return $this; - } - - /** - * Chooses the column to group by in a select query. - * - * @param string column name to group by - * @return Database_Core This Database object. - */ - public function groupby($by) - { - if ( ! is_array($by)) - { - $by = explode(',', (string) $by); - } - - foreach ($by as $val) - { - $val = trim($val); - - if ($val != '') - { - // Add the table prefix if we are using table.column names - if(strpos($val, '.')) - { - $val = $this->config['table_prefix'].$val; - } - - $this->groupby[] = $this->driver->escape_column($val); - } - } - - return $this; - } - - /** - * Selects the having(s) for a database query. - * - * @param string|array key name or array of key => value pairs - * @param string value to match with key - * @param boolean disable quoting of WHERE clause - * @return Database_Core This Database object. - */ - public function having($key, $value = '', $quote = TRUE) - { - $this->having[] = $this->driver->where($key, $value, 'AND', count($this->having), TRUE); - return $this; - } - - /** - * Selects the or having(s) for a database query. - * - * @param string|array key name or array of key => value pairs - * @param string value to match with key - * @param boolean disable quoting of WHERE clause - * @return Database_Core This Database object. - */ - public function orhaving($key, $value = '', $quote = TRUE) - { - $this->having[] = $this->driver->where($key, $value, 'OR', count($this->having), TRUE); - return $this; - } - - /** - * Chooses which column(s) to order the select query by. - * - * @param string|array column(s) to order on, can be an array, single column, or comma seperated list of columns - * @param string direction of the order - * @return Database_Core This Database object. - */ - public function orderby($orderby, $direction = NULL) - { - if ( ! is_array($orderby)) - { - $orderby = array($orderby => $direction); - } - - foreach ($orderby as $column => $direction) - { - $direction = strtoupper(trim($direction)); - - // Add a direction if the provided one isn't valid - if ( ! in_array($direction, array('ASC', 'DESC', 'RAND()', 'RANDOM()', 'NULL'))) - { - $direction = 'ASC'; - } - - // Add the table prefix if a table.column was passed - if (strpos($column, '.')) - { - $column = $this->config['table_prefix'].$column; - } - - $this->orderby[] = $this->driver->escape_column($column).' '.$direction; - } - - return $this; - } - - /** - * Selects the limit section of a query. - * - * @param integer number of rows to limit result to - * @param integer offset in result to start returning rows from - * @return Database_Core This Database object. - */ - public function limit($limit, $offset = NULL) - { - $this->limit = (int) $limit; - - if ($offset !== NULL OR ! is_int($this->offset)) - { - $this->offset($offset); - } - - return $this; - } - - /** - * Sets the offset portion of a query. - * - * @param integer offset value - * @return Database_Core This Database object. - */ - public function offset($value) - { - $this->offset = (int) $value; - - return $this; - } - - /** - * Allows key/value pairs to be set for inserting or updating. - * - * @param string|array key name or array of key => value pairs - * @param string value to match with key - * @return Database_Core This Database object. - */ - public function set($key, $value = '') - { - if ( ! is_array($key)) - { - $key = array($key => $value); - } - - foreach ($key as $k => $v) - { - // Add a table prefix if the column includes the table. - if (strpos($k, '.')) - $k = $this->config['table_prefix'].$k; - - $this->set[$k] = $this->driver->escape($v); - } - - return $this; - } - - /** - * Compiles the select statement based on the other functions called and runs the query. - * - * @param string table name - * @param string limit clause - * @param string offset clause - * @return Database_Result - */ - public function get($table = '', $limit = NULL, $offset = NULL) - { - if ($table != '') - { - $this->from($table); - } - - if ( ! is_null($limit)) - { - $this->limit($limit, $offset); - } - - $sql = $this->driver->compile_select(get_object_vars($this)); - - $this->reset_select(); - - $result = $this->query($sql); - - $this->last_query = $sql; - - return $result; - } - - /** - * Compiles the select statement based on the other functions called and runs the query. - * - * @param string table name - * @param array where clause - * @param string limit clause - * @param string offset clause - * @return Database_Core This Database object. - */ - public function getwhere($table = '', $where = NULL, $limit = NULL, $offset = NULL) - { - if ($table != '') - { - $this->from($table); - } - - if ( ! is_null($where)) - { - $this->where($where); - } - - if ( ! is_null($limit)) - { - $this->limit($limit, $offset); - } - - $sql = $this->driver->compile_select(get_object_vars($this)); - - $this->reset_select(); - - $result = $this->query($sql); - - return $result; - } - - /** - * Compiles the select statement based on the other functions called and returns the query string. - * - * @param string table name - * @param string limit clause - * @param string offset clause - * @return string sql string - */ - public function compile($table = '', $limit = NULL, $offset = NULL) - { - if ($table != '') - { - $this->from($table); - } - - if ( ! is_null($limit)) - { - $this->limit($limit, $offset); - } - - $sql = $this->driver->compile_select(get_object_vars($this)); - - $this->reset_select(); - - return $sql; - } - - /** - * Compiles an insert string and runs the query. - * - * @param string table name - * @param array array of key/value pairs to insert - * @return Database_Result Query result - */ - public function insert($table = '', $set = NULL) - { - if ( ! is_null($set)) - { - $this->set($set); - } - - if ($this->set == NULL) - throw new Kohana_Database_Exception('database.must_use_set'); - - if ($table == '') - { - if ( ! isset($this->from[0])) - throw new Kohana_Database_Exception('database.must_use_table'); - - $table = $this->from[0]; - } - - // If caching is enabled, clear the cache before inserting - ($this->config['cache'] === TRUE) and $this->clear_cache(); - - $sql = $this->driver->insert($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); - - $this->reset_write(); - - return $this->query($sql); - } - - /** - * Adds an "IN" condition to the where clause - * - * @param string Name of the column being examined - * @param mixed An array or string to match against - * @param bool Generate a NOT IN clause instead - * @return Database_Core This Database object. - */ - public function in($field, $values, $not = FALSE) - { - if (is_array($values)) - { - $escaped_values = array(); - foreach ($values as $v) - { - if (is_numeric($v)) - { - $escaped_values[] = $v; - } - else - { - $escaped_values[] = "'".$this->driver->escape_str($v)."'"; - } - } - $values = implode(",", $escaped_values); - } - - $where = $this->driver->escape_column(((strpos($field,'.') !== FALSE) ? $this->config['table_prefix'] : ''). $field).' '.($not === TRUE ? 'NOT ' : '').'IN ('.$values.')'; - $this->where[] = $this->driver->where($where, '', 'AND ', count($this->where), -1); - - return $this; - } - - /** - * Adds a "NOT IN" condition to the where clause - * - * @param string Name of the column being examined - * @param mixed An array or string to match against - * @return Database_Core This Database object. - */ - public function notin($field, $values) - { - return $this->in($field, $values, TRUE); - } - - /** - * Compiles a merge string and runs the query. - * - * @param string table name - * @param array array of key/value pairs to merge - * @return Database_Result Query result - */ - public function merge($table = '', $set = NULL) - { - if ( ! is_null($set)) - { - $this->set($set); - } - - if ($this->set == NULL) - throw new Kohana_Database_Exception('database.must_use_set'); - - if ($table == '') - { - if ( ! isset($this->from[0])) - throw new Kohana_Database_Exception('database.must_use_table'); - - $table = $this->from[0]; - } - - $sql = $this->driver->merge($this->config['table_prefix'].$table, array_keys($this->set), array_values($this->set)); - - $this->reset_write(); - return $this->query($sql); - } - - /** - * Compiles an update string and runs the query. - * - * @param string table name - * @param array associative array of update values - * @param array where clause - * @return Database_Result Query result - */ - public function update($table = '', $set = NULL, $where = NULL) - { - if ( is_array($set)) - { - $this->set($set); - } - - if ( ! is_null($where)) - { - $this->where($where); - } - - if ($this->set == FALSE) - throw new Kohana_Database_Exception('database.must_use_set'); - - if ($table == '') - { - if ( ! isset($this->from[0])) - throw new Kohana_Database_Exception('database.must_use_table'); - - $table = $this->from[0]; - } - - $sql = $this->driver->update($this->config['table_prefix'].$table, $this->set, $this->where); - - $this->reset_write(); - return $this->query($sql); - } - - /** - * Compiles a delete string and runs the query. - * - * @param string table name - * @param array where clause - * @return Database_Result Query result - */ - public function delete($table = '', $where = NULL) - { - if ($table == '') - { - if ( ! isset($this->from[0])) - throw new Kohana_Database_Exception('database.must_use_table'); - - $table = $this->from[0]; - } - else - { - $table = $this->config['table_prefix'].$table; - } - - if (! is_null($where)) - { - $this->where($where); - } - - if (count($this->where) < 1) - throw new Kohana_Database_Exception('database.must_use_where'); - - $sql = $this->driver->delete($table, $this->where); - - $this->reset_write(); - return $this->query($sql); - } - - /** - * Returns the last query run. - * - * @return string SQL - */ - public function last_query() - { - return $this->last_query; - } - - /** - * Count query records. - * - * @param string table name - * @param array where clause - * @return integer - */ - public function count_records($table = FALSE, $where = NULL) - { - if (count($this->from) < 1) - { - if ($table == FALSE) - throw new Kohana_Database_Exception('database.must_use_table'); - - $this->from($table); - } - - if ($where !== NULL) - { - $this->where($where); - } - - $query = $this->select('COUNT(*) AS '.$this->escape_column('records_found'))->get()->result(TRUE); - - return (int) $query->current()->records_found; - } - - /** - * Resets all private select variables. - * - * @return void - */ - protected function reset_select() - { - $this->select = array(); - $this->from = array(); - $this->join = array(); - $this->where = array(); - $this->orderby = array(); - $this->groupby = array(); - $this->having = array(); - $this->distinct = FALSE; - $this->limit = FALSE; - $this->offset = FALSE; - } - - /** - * Resets all private insert and update variables. - * - * @return void - */ - protected function reset_write() - { - $this->set = array(); - $this->from = array(); - $this->where = array(); - } - - /** - * Lists all the tables in the current database. - * - * @return array - */ - public function list_tables() - { - $this->link or $this->connect(); - - return $this->driver->list_tables(); - } - - /** - * See if a table exists in the database. - * - * @param string table name - * @param boolean True to attach table prefix - * @return boolean - */ - public function table_exists($table_name, $prefix = TRUE) - { - if ($prefix) - return in_array($this->config['table_prefix'].$table_name, $this->list_tables()); - else - return in_array($table_name, $this->list_tables()); - } - - /** - * Combine a SQL statement with the bind values. Used for safe queries. - * - * @param string query to bind to the values - * @param array array of values to bind to the query - * @return string - */ - public function compile_binds($sql, $binds) - { - foreach ((array) $binds as $val) - { - // If the SQL contains no more bind marks ("?"), we're done. - if (($next_bind_pos = strpos($sql, '?')) === FALSE) - break; - - // Properly escape the bind value. - $val = $this->driver->escape($val); - - // Temporarily replace possible bind marks ("?"), in the bind value itself, with a placeholder. - $val = str_replace('?', '{%B%}', $val); - - // Replace the first bind mark ("?") with its corresponding value. - $sql = substr($sql, 0, $next_bind_pos).$val.substr($sql, $next_bind_pos + 1); - } - - // Restore placeholders. - return str_replace('{%B%}', '?', $sql); - } - - /** - * Get the field data for a database table, along with the field's attributes. - * - * @param string table name - * @return array - */ - public function field_data($table = '') - { - $this->link or $this->connect(); - - return $this->driver->field_data($this->config['table_prefix'].$table); - } - - /** - * Get the field data for a database table, along with the field's attributes. - * - * @param string table name - * @return array - */ - public function list_fields($table = '') - { - $this->link or $this->connect(); - - return $this->driver->list_fields($this->config['table_prefix'].$table); - } - - /** - * Escapes a value for a query. - * - * @param mixed value to escape - * @return string - */ - public function escape($value) - { - return $this->driver->escape($value); - } - - /** - * Escapes a string for a query. - * - * @param string string to escape - * @return string - */ - public function escape_str($str) - { - return $this->driver->escape_str($str); - } - - /** - * Escapes a table name for a query. - * - * @param string string to escape - * @return string - */ - public function escape_table($table) - { - return $this->driver->escape_table($table); - } - - /** - * Escapes a column name for a query. - * - * @param string string to escape - * @return string - */ - public function escape_column($table) - { - return $this->driver->escape_column($table); - } - - /** - * Returns table prefix of current configuration. - * - * @return string - */ - public function table_prefix() - { - return $this->config['table_prefix']; - } - - /** - * Clears the query cache. - * - * @param string|TRUE clear cache by SQL statement or TRUE for last query - * @return Database_Core This Database object. - */ - public function clear_cache($sql = NULL) - { - if ($sql === TRUE) - { - $this->driver->clear_cache($this->last_query); - } - elseif (is_string($sql)) - { - $this->driver->clear_cache($sql); - } - else - { - $this->driver->clear_cache(); - } - - return $this; - } - - /** - * Pushes existing query space onto the query stack. Use push - * and pop to prevent queries from clashing before they are - * executed - * - * @return Database_Core This Databaes object - */ - public function push() - { - array_push($this->query_history, array( - $this->select, - $this->from, - $this->join, - $this->where, - $this->orderby, - $this->order, - $this->groupby, - $this->having, - $this->distinct, - $this->limit, - $this->offset - )); - - $this->reset_select(); - - return $this; - } - - /** - * Pops from query stack into the current query space. - * - * @return Database_Core This Databaes object - */ - public function pop() - { - if (count($this->query_history) == 0) - { - // No history - return $this; - } - - list( - $this->select, - $this->from, - $this->join, - $this->where, - $this->orderby, - $this->order, - $this->groupby, - $this->having, - $this->distinct, - $this->limit, - $this->offset - ) = array_pop($this->query_history); - - return $this; - } - - /** - * Count the number of records in the last query, without LIMIT or OFFSET applied. - * - * @return integer - */ - public function count_last_query() - { - if ($sql = $this->last_query()) - { - if (stripos($sql, 'LIMIT') !== FALSE) - { - // Remove LIMIT from the SQL - $sql = preg_replace('/\sLIMIT\s+[^a-z]+/i', ' ', $sql); - } - - if (stripos($sql, 'OFFSET') !== FALSE) - { - // Remove OFFSET from the SQL - $sql = preg_replace('/\sOFFSET\s+\d+/i', '', $sql); - } - - // Get the total rows from the last query executed - $result = $this->query - ( - 'SELECT COUNT(*) AS '.$this->escape_column('total_rows').' '. - 'FROM ('.trim($sql).') AS '.$this->escape_table('counted_results') - ); - - // Return the total number of rows from the query - return (int) $result->current()->total_rows; - } - - return FALSE; - } - -} // End Database Class - - -/** - * Sets the code for a Database exception. - */ -class Kohana_Database_Exception extends Kohana_Exception { - - protected $code = E_DATABASE_ERROR; - -} // End Kohana Database Exception diff --git a/kohana/libraries/Database_Expression.php b/kohana/libraries/Database_Expression.php deleted file mode 100644 index 940a6363..00000000 --- a/kohana/libraries/Database_Expression.php +++ /dev/null @@ -1,26 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Database expression class to allow for explicit joins and where expressions. - * - * $Id: Database_Expression.php 4037 2009-03-04 23:35:53Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2009 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Expression_Core { - - protected $expression; - - public function __construct($expression) - { - $this->expression = $expression; - } - - public function __toString() - { - return (string) $this->expression; - } - -} // End Database Expr Class
\ No newline at end of file diff --git a/kohana/libraries/Encrypt.php b/kohana/libraries/Encrypt.php deleted file mode 100644 index 3d564f99..00000000 --- a/kohana/libraries/Encrypt.php +++ /dev/null @@ -1,164 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * The Encrypt library provides two-way encryption of text and binary strings - * using the MCrypt extension. - * @see http://php.net/mcrypt - * - * $Id: Encrypt.php 4072 2009-03-13 17:20:38Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Encrypt_Core { - - // OS-dependant RAND type to use - protected static $rand; - - // Configuration - protected $config; - - /** - * Returns a singleton instance of Encrypt. - * - * @param array configuration options - * @return Encrypt_Core - */ - public static function instance($config = NULL) - { - static $instance; - - // Create the singleton - empty($instance) and $instance = new Encrypt((array) $config); - - return $instance; - } - - /** - * Loads encryption configuration and validates the data. - * - * @param array|string custom configuration or config group name - * @throws Kohana_Exception - */ - public function __construct($config = FALSE) - { - if ( ! defined('MCRYPT_ENCRYPT')) - throw new Kohana_Exception('encrypt.requires_mcrypt'); - - if (is_string($config)) - { - $name = $config; - - // Test the config group name - if (($config = Kohana::config('encryption.'.$config)) === NULL) - throw new Kohana_Exception('encrypt.undefined_group', $name); - } - - if (is_array($config)) - { - // Append the default configuration options - $config += Kohana::config('encryption.default'); - } - else - { - // Load the default group - $config = Kohana::config('encryption.default'); - } - - if (empty($config['key'])) - throw new Kohana_Exception('encrypt.no_encryption_key'); - - // Find the max length of the key, based on cipher and mode - $size = mcrypt_get_key_size($config['cipher'], $config['mode']); - - if (strlen($config['key']) > $size) - { - // Shorten the key to the maximum size - $config['key'] = substr($config['key'], 0, $size); - } - - // Find the initialization vector size - $config['iv_size'] = mcrypt_get_iv_size($config['cipher'], $config['mode']); - - // Cache the config in the object - $this->config = $config; - - Kohana::log('debug', 'Encrypt Library initialized'); - } - - /** - * Encrypts a string and returns an encrypted string that can be decoded. - * - * @param string data to be encrypted - * @return string encrypted data - */ - public function encode($data) - { - // Set the rand type if it has not already been set - if (Encrypt::$rand === NULL) - { - if (KOHANA_IS_WIN) - { - // 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->config['iv_size'], Encrypt::$rand); - - // Encrypt the data using the configured options and generated iv - $data = mcrypt_encrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv); - - // Use base64 encoding to convert to a string - return base64_encode($iv.$data); - } - - /** - * Decrypts an encoded string back to its original value. - * - * @param string encoded string to be decrypted - * @return string decrypted data - */ - public function decode($data) - { - // Convert the data back to binary - $data = base64_decode($data); - - // Extract the initialization vector from the data - $iv = substr($data, 0, $this->config['iv_size']); - - // Remove the iv from the data - $data = substr($data, $this->config['iv_size']); - - // Return the decrypted data, trimming the \0 padding bytes from the end of the data - return rtrim(mcrypt_decrypt($this->config['cipher'], $this->config['key'], $data, $this->config['mode'], $iv), "\0"); - } - -} // End Encrypt diff --git a/kohana/libraries/Event_Observer.php b/kohana/libraries/Event_Observer.php deleted file mode 100644 index 086c8a23..00000000 --- a/kohana/libraries/Event_Observer.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Kohana event observer. Uses the SPL observer pattern. - * - * $Id: Event_Observer.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Event_Observer implements SplObserver { - - // Calling object - protected $caller; - - /** - * Initializes a new observer and attaches the subject as the caller. - * - * @param object Event_Subject - * @return void - */ - public function __construct(SplSubject $caller) - { - // Update the caller - $this->update($caller); - } - - /** - * Updates the observer subject with a new caller. - * - * @chainable - * @param object Event_Subject - * @return object - */ - public function update(SplSubject $caller) - { - if ( ! ($caller instanceof Event_Subject)) - throw new Kohana_Exception('event.invalid_subject', get_class($caller), get_class($this)); - - // Update the caller - $this->caller = $caller; - - return $this; - } - - /** - * Detaches this observer from the subject. - * - * @chainable - * @return object - */ - public function remove() - { - // Detach this observer from the caller - $this->caller->detach($this); - - return $this; - } - - /** - * Notify the observer of a new message. This function must be defined in - * all observers and must take exactly one parameter of any type. - * - * @param mixed message string, object, or array - * @return void - */ - abstract public function notify($message); - -} // End Event Observer
\ No newline at end of file diff --git a/kohana/libraries/Event_Subject.php b/kohana/libraries/Event_Subject.php deleted file mode 100644 index d1ccc544..00000000 --- a/kohana/libraries/Event_Subject.php +++ /dev/null @@ -1,67 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Kohana event subject. Uses the SPL observer pattern. - * - * $Id: Event_Subject.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Event_Subject implements SplSubject { - - // Attached subject listeners - protected $listeners = array(); - - /** - * Attach an observer to the object. - * - * @chainable - * @param object Event_Observer - * @return object - */ - public function attach(SplObserver $obj) - { - if ( ! ($obj instanceof Event_Observer)) - throw new Kohana_Exception('eventable.invalid_observer', get_class($obj), get_class($this)); - - // Add a new listener - $this->listeners[spl_object_hash($obj)] = $obj; - - return $this; - } - - /** - * Detach an observer from the object. - * - * @chainable - * @param object Event_Observer - * @return object - */ - public function detach(SplObserver $obj) - { - // Remove the listener - unset($this->listeners[spl_object_hash($obj)]); - - return $this; - } - - /** - * Notify all attached observers of a new message. - * - * @chainable - * @param mixed message string, object, or array - * @return object - */ - public function notify($message) - { - foreach ($this->listeners as $obj) - { - $obj->notify($message); - } - - return $this; - } - -} // End Event Subject
\ No newline at end of file diff --git a/kohana/libraries/Image.php b/kohana/libraries/Image.php deleted file mode 100644 index 08c2957c..00000000 --- a/kohana/libraries/Image.php +++ /dev/null @@ -1,460 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Manipulate images using standard methods such as resize, crop, rotate, etc. - * This class must be re-initialized for every image you wish to manipulate. - * - * $Id: Image.php 4072 2009-03-13 17:20:38Z jheathco $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_Core { - - // Master Dimension - const NONE = 1; - const AUTO = 2; - const HEIGHT = 3; - const WIDTH = 4; - // Flip Directions - const HORIZONTAL = 5; - const VERTICAL = 6; - - // Allowed image types - public static $allowed_types = array - ( - IMAGETYPE_GIF => 'gif', - IMAGETYPE_JPEG => 'jpg', - IMAGETYPE_PNG => 'png', - IMAGETYPE_TIFF_II => 'tiff', - IMAGETYPE_TIFF_MM => 'tiff', - ); - - // Driver instance - protected $driver; - - // Driver actions - protected $actions = array(); - - // Reference to the current image filename - protected $image = ''; - - /** - * Creates a new Image instance and returns it. - * - * @param string filename of image - * @param array non-default configurations - * @return object - */ - public static function factory($image, $config = NULL) - { - return new Image($image, $config); - } - - /** - * Creates a new image editor instance. - * - * @throws Kohana_Exception - * @param string filename of image - * @param array non-default configurations - * @return void - */ - public function __construct($image, $config = NULL) - { - static $check; - - // Make the check exactly once - ($check === NULL) and $check = function_exists('getimagesize'); - - if ($check === FALSE) - throw new Kohana_Exception('image.getimagesize_missing'); - - // Check to make sure the image exists - if ( ! is_file($image)) - throw new Kohana_Exception('image.file_not_found', $image); - - // Disable error reporting, to prevent PHP warnings - $ER = error_reporting(0); - - // Fetch the image size and mime type - $image_info = getimagesize($image); - - // Turn on error reporting again - error_reporting($ER); - - // Make sure that the image is readable and valid - if ( ! is_array($image_info) OR count($image_info) < 3) - throw new Kohana_Exception('image.file_unreadable', $image); - - // Check to make sure the image type is allowed - if ( ! isset(Image::$allowed_types[$image_info[2]])) - throw new Kohana_Exception('image.type_not_allowed', $image); - - // Image has been validated, load it - $this->image = array - ( - 'file' => str_replace('\\', '/', realpath($image)), - 'width' => $image_info[0], - 'height' => $image_info[1], - 'type' => $image_info[2], - 'ext' => Image::$allowed_types[$image_info[2]], - 'mime' => $image_info['mime'] - ); - - // Load configuration - $this->config = (array) $config + Kohana::config('image'); - - // Set driver class name - $driver = 'Image_'.ucfirst($this->config['driver']).'_Driver'; - - // Load the driver - if ( ! Kohana::auto_load($driver)) - throw new Kohana_Exception('core.driver_not_found', $this->config['driver'], get_class($this)); - - // Initialize the driver - $this->driver = new $driver($this->config['params']); - - // Validate the driver - if ( ! ($this->driver instanceof Image_Driver)) - throw new Kohana_Exception('core.driver_implements', $this->config['driver'], get_class($this), 'Image_Driver'); - } - - /** - * Handles retrieval of pre-save image properties - * - * @param string property name - * @return mixed - */ - public function __get($property) - { - if (isset($this->image[$property])) - { - return $this->image[$property]; - } - else - { - throw new Kohana_Exception('core.invalid_property', $property, get_class($this)); - } - } - - /** - * Resize an image to a specific width and height. By default, Kohana will - * maintain the aspect ratio using the width as the master dimension. If you - * wish to use height as master dim, set $image->master_dim = Image::HEIGHT - * This method is chainable. - * - * @throws Kohana_Exception - * @param integer width - * @param integer height - * @param integer one of: Image::NONE, Image::AUTO, Image::WIDTH, Image::HEIGHT - * @return object - */ - public function resize($width, $height, $master = NULL) - { - if ( ! $this->valid_size('width', $width)) - throw new Kohana_Exception('image.invalid_width', $width); - - if ( ! $this->valid_size('height', $height)) - throw new Kohana_Exception('image.invalid_height', $height); - - if (empty($width) AND empty($height)) - throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); - - if ($master === NULL) - { - // Maintain the aspect ratio by default - $master = Image::AUTO; - } - elseif ( ! $this->valid_size('master', $master)) - throw new Kohana_Exception('image.invalid_master'); - - $this->actions['resize'] = array - ( - 'width' => $width, - 'height' => $height, - 'master' => $master, - ); - - return $this; - } - - /** - * Crop an image to a specific width and height. You may also set the top - * and left offset. - * This method is chainable. - * - * @throws Kohana_Exception - * @param integer width - * @param integer height - * @param integer top offset, pixel value or one of: top, center, bottom - * @param integer left offset, pixel value or one of: left, center, right - * @return object - */ - public function crop($width, $height, $top = 'center', $left = 'center') - { - if ( ! $this->valid_size('width', $width)) - throw new Kohana_Exception('image.invalid_width', $width); - - if ( ! $this->valid_size('height', $height)) - throw new Kohana_Exception('image.invalid_height', $height); - - if ( ! $this->valid_size('top', $top)) - throw new Kohana_Exception('image.invalid_top', $top); - - if ( ! $this->valid_size('left', $left)) - throw new Kohana_Exception('image.invalid_left', $left); - - if (empty($width) AND empty($height)) - throw new Kohana_Exception('image.invalid_dimensions', __FUNCTION__); - - $this->actions['crop'] = array - ( - 'width' => $width, - 'height' => $height, - 'top' => $top, - 'left' => $left, - ); - - return $this; - } - - /** - * Allows rotation of an image by 180 degrees clockwise or counter clockwise. - * - * @param integer degrees - * @return object - */ - public function rotate($degrees) - { - $degrees = (int) $degrees; - - if ($degrees > 180) - { - do - { - // Keep subtracting full circles until the degrees have normalized - $degrees -= 360; - } - while($degrees > 180); - } - - if ($degrees < -180) - { - do - { - // Keep adding full circles until the degrees have normalized - $degrees += 360; - } - while($degrees < -180); - } - - $this->actions['rotate'] = $degrees; - - return $this; - } - - /** - * Overlay a second image on top of this one. - * - * @throws Kohana_Exception - * @param string $overlay_file path to an image file - * @param integer $x x offset for the overlay - * @param integer $y y offset for the overlay - * @param integer $transparency transparency percent - */ - public function composite($overlay_file, $x, $y, $transparency) - { - $image_info = getimagesize($overlay_file); - - // Check to make sure the image type is allowed - if ( ! isset(Image::$allowed_types[$image_info[2]])) - throw new Kohana_Exception('image.type_not_allowed', $overlay_file); - - $this->actions['composite'] = array - ( - 'overlay_file' => $overlay_file, - 'mime' => $image_info['mime'], - 'x' => $x, - 'y' => $y, - 'transparency' => $transparency - ); - - return $this; - } - - /** - * Flip an image horizontally or vertically. - * - * @throws Kohana_Exception - * @param integer direction - * @return object - */ - public function flip($direction) - { - if ($direction !== Image::HORIZONTAL AND $direction !== Image::VERTICAL) - throw new Kohana_Exception('image.invalid_flip'); - - $this->actions['flip'] = $direction; - - return $this; - } - - /** - * Change the quality of an image. - * - * @param integer quality as a percentage - * @return object - */ - public function quality($amount) - { - $this->actions['quality'] = max(1, min($amount, 100)); - - return $this; - } - - /** - * Sharpen an image. - * - * @param integer amount to sharpen, usually ~20 is ideal - * @return object - */ - public function sharpen($amount) - { - $this->actions['sharpen'] = max(1, min($amount, 100)); - - return $this; - } - - /** - * Save the image to a new image or overwrite this image. - * - * @throws Kohana_Exception - * @param string new image filename - * @param integer permissions for new image - * @param boolean keep or discard image process actions - * @return object - */ - public function save($new_image = FALSE, $chmod = 0644, $keep_actions = FALSE) - { - // If no new image is defined, use the current image - empty($new_image) and $new_image = $this->image['file']; - - // Separate the directory and filename - $dir = pathinfo($new_image, PATHINFO_DIRNAME); - $file = pathinfo($new_image, PATHINFO_BASENAME); - - // Normalize the path - $dir = str_replace('\\', '/', realpath($dir)).'/'; - - if ( ! is_writable($dir)) - throw new Kohana_Exception('image.directory_unwritable', $dir); - - if ($status = $this->driver->process($this->image, $this->actions, $dir, $file)) - { - if ($chmod !== FALSE) - { - // Set permissions - chmod($new_image, $chmod); - } - } - - // Reset actions. Subsequent save() or render() will not apply previous actions. - if ($keep_actions === FALSE) - $this->actions = array(); - - return $status; - } - - /** - * Output the image to the browser. - * - * @param boolean keep or discard image process actions - * @return object - */ - public function render($keep_actions = FALSE) - { - $new_image = $this->image['file']; - - // Separate the directory and filename - $dir = pathinfo($new_image, PATHINFO_DIRNAME); - $file = pathinfo($new_image, PATHINFO_BASENAME); - - // Normalize the path - $dir = str_replace('\\', '/', realpath($dir)).'/'; - - // Process the image with the driver - $status = $this->driver->process($this->image, $this->actions, $dir, $file, $render = TRUE); - - // Reset actions. Subsequent save() or render() will not apply previous actions. - if ($keep_actions === FALSE) - $this->actions = array(); - - return $status; - } - - /** - * Sanitize a given value type. - * - * @param string type of property - * @param mixed property value - * @return boolean - */ - protected function valid_size($type, & $value) - { - if (is_null($value)) - return TRUE; - - if ( ! is_scalar($value)) - return FALSE; - - switch ($type) - { - case 'width': - case 'height': - if (is_string($value) AND ! ctype_digit($value)) - { - // Only numbers and percent signs - if ( ! preg_match('/^[0-9]++%$/D', $value)) - return FALSE; - } - else - { - $value = (int) $value; - } - break; - case 'top': - if (is_string($value) AND ! ctype_digit($value)) - { - if ( ! in_array($value, array('top', 'bottom', 'center'))) - return FALSE; - } - else - { - $value = (int) $value; - } - break; - case 'left': - if (is_string($value) AND ! ctype_digit($value)) - { - if ( ! in_array($value, array('left', 'right', 'center'))) - return FALSE; - } - else - { - $value = (int) $value; - } - break; - case 'master': - if ($value !== Image::NONE AND - $value !== Image::AUTO AND - $value !== Image::WIDTH AND - $value !== Image::HEIGHT) - return FALSE; - break; - } - - return TRUE; - } - -} // End Image
\ No newline at end of file diff --git a/kohana/libraries/Input.php b/kohana/libraries/Input.php deleted file mode 100644 index 0e23c800..00000000 --- a/kohana/libraries/Input.php +++ /dev/null @@ -1,452 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Input library. - * - * $Id: Input.php 4346 2009-05-11 17:08:15Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Input_Core { - - // Enable or disable automatic XSS cleaning - protected $use_xss_clean = FALSE; - - // Are magic quotes enabled? - protected $magic_quotes_gpc = FALSE; - - // IP address of current user - public $ip_address; - - // Input singleton - protected static $instance; - - /** - * Retrieve a singleton instance of Input. This will always be the first - * created instance of this class. - * - * @return object - */ - public static function instance() - { - if (Input::$instance === NULL) - { - // Create a new instance - return new Input; - } - - return Input::$instance; - } - - /** - * Sanitizes global GET, POST and COOKIE data. Also takes care of - * magic_quotes and register_globals, if they have been enabled. - * - * @return void - */ - public function __construct() - { - // Use XSS clean? - $this->use_xss_clean = (bool) Kohana::config('core.global_xss_filtering'); - - if (Input::$instance === NULL) - { - // magic_quotes_runtime is enabled - if (get_magic_quotes_runtime()) - { - set_magic_quotes_runtime(0); - Kohana::log('debug', 'Disable magic_quotes_runtime! It is evil and deprecated: http://php.net/magic_quotes'); - } - - // magic_quotes_gpc is enabled - if (get_magic_quotes_gpc()) - { - $this->magic_quotes_gpc = TRUE; - Kohana::log('debug', 'Disable magic_quotes_gpc! It is evil and deprecated: http://php.net/magic_quotes'); - } - - // register_globals is enabled - if (ini_get('register_globals')) - { - if (isset($_REQUEST['GLOBALS'])) - { - // Prevent GLOBALS override attacks - exit('Global variable overload attack.'); - } - - // Destroy the REQUEST global - $_REQUEST = array(); - - // These globals are standard and should not be removed - $preserve = array('GLOBALS', '_REQUEST', '_GET', '_POST', '_FILES', '_COOKIE', '_SERVER', '_ENV', '_SESSION'); - - // This loop has the same effect as disabling register_globals - foreach (array_diff(array_keys($GLOBALS), $preserve) as $key) - { - global $$key; - $$key = NULL; - - // Unset the global variable - unset($GLOBALS[$key], $$key); - } - - // Warn the developer about register globals - Kohana::log('debug', 'Disable register_globals! It is evil and deprecated: http://php.net/register_globals'); - } - - if (is_array($_GET)) - { - foreach ($_GET as $key => $val) - { - // Sanitize $_GET - $_GET[$this->clean_input_keys($key)] = $this->clean_input_data($val); - } - } - else - { - $_GET = array(); - } - - if (is_array($_POST)) - { - foreach ($_POST as $key => $val) - { - // Sanitize $_POST - $_POST[$this->clean_input_keys($key)] = $this->clean_input_data($val); - } - } - else - { - $_POST = array(); - } - - if (is_array($_COOKIE)) - { - foreach ($_COOKIE as $key => $val) - { - // Ignore special attributes in RFC2109 compliant cookies - if ($key == '$Version' OR $key == '$Path' OR $key == '$Domain') - continue; - - // Sanitize $_COOKIE - $_COOKIE[$this->clean_input_keys($key)] = $this->clean_input_data($val); - } - } - else - { - $_COOKIE = array(); - } - - // Create a singleton - Input::$instance = $this; - - Kohana::log('debug', 'Global GET, POST and COOKIE data sanitized'); - } - } - - /** - * Fetch an item from the $_GET array. - * - * @param string key to find - * @param mixed default value - * @param boolean XSS clean the value - * @return mixed - */ - public function get($key = array(), $default = NULL, $xss_clean = FALSE) - { - return $this->search_array($_GET, $key, $default, $xss_clean); - } - - /** - * Fetch an item from the $_POST array. - * - * @param string key to find - * @param mixed default value - * @param boolean XSS clean the value - * @return mixed - */ - public function post($key = array(), $default = NULL, $xss_clean = FALSE) - { - return $this->search_array($_POST, $key, $default, $xss_clean); - } - - /** - * Fetch an item from the $_COOKIE array. - * - * @param string key to find - * @param mixed default value - * @param boolean XSS clean the value - * @return mixed - */ - public function cookie($key = array(), $default = NULL, $xss_clean = FALSE) - { - return $this->search_array($_COOKIE, $key, $default, $xss_clean); - } - - /** - * Fetch an item from the $_SERVER array. - * - * @param string key to find - * @param mixed default value - * @param boolean XSS clean the value - * @return mixed - */ - public function server($key = array(), $default = NULL, $xss_clean = FALSE) - { - return $this->search_array($_SERVER, $key, $default, $xss_clean); - } - - /** - * Fetch an item from a global array. - * - * @param array array to search - * @param string key to find - * @param mixed default value - * @param boolean XSS clean the value - * @return mixed - */ - protected function search_array($array, $key, $default = NULL, $xss_clean = FALSE) - { - if ($key === array()) - return $array; - - if ( ! isset($array[$key])) - return $default; - - // Get the value - $value = $array[$key]; - - if ($this->use_xss_clean === FALSE AND $xss_clean === TRUE) - { - // XSS clean the value - $value = $this->xss_clean($value); - } - - return $value; - } - - /** - * Fetch the IP Address. - * - * @return string - */ - public function ip_address() - { - if ($this->ip_address !== NULL) - return $this->ip_address; - - // Server keys that could contain the client IP address - $keys = array('HTTP_X_FORWARDED_FOR', 'HTTP_CLIENT_IP', 'REMOTE_ADDR'); - - foreach ($keys as $key) - { - if ($ip = $this->server($key)) - { - $this->ip_address = $ip; - - // An IP address has been found - break; - } - } - - if ($comma = strrpos($this->ip_address, ',') !== FALSE) - { - $this->ip_address = substr($this->ip_address, $comma + 1); - } - - if ( ! valid::ip($this->ip_address)) - { - // Use an empty IP - $this->ip_address = '0.0.0.0'; - } - - return $this->ip_address; - } - - /** - * Clean cross site scripting exploits from string. - * HTMLPurifier may be used if installed, otherwise defaults to built in method. - * Note - This function should only be used to deal with data upon submission. - * It's not something that should be used for general runtime processing - * since it requires a fair amount of processing overhead. - * - * @param string data to clean - * @param string xss_clean method to use ('htmlpurifier' or defaults to built-in method) - * @return string - */ - public function xss_clean($data, $tool = NULL) - { - if ($tool === NULL) - { - // Use the default tool - $tool = Kohana::config('core.global_xss_filtering'); - } - - if (is_array($data)) - { - foreach ($data as $key => $val) - { - $data[$key] = $this->xss_clean($val, $tool); - } - - return $data; - } - - // Do not clean empty strings - if (trim($data) === '') - return $data; - - if ($tool === TRUE) - { - // NOTE: This is necessary because switch is NOT type-sensative! - $tool = 'default'; - } - - switch ($tool) - { - case 'htmlpurifier': - /** - * @todo License should go here, http://htmlpurifier.org/ - */ - if ( ! class_exists('HTMLPurifier_Config', FALSE)) - { - // Load HTMLPurifier - require Kohana::find_file('vendor', 'htmlpurifier/HTMLPurifier.auto', TRUE); - require 'HTMLPurifier.func.php'; - } - - // Set configuration - $config = HTMLPurifier_Config::createDefault(); - $config->set('HTML', 'TidyLevel', 'none'); // Only XSS cleaning now - - // Run HTMLPurifier - $data = HTMLPurifier($data, $config); - break; - default: - // http://svn.bitflux.ch/repos/public/popoon/trunk/classes/externalinput.php - // +----------------------------------------------------------------------+ - // | Copyright (c) 2001-2006 Bitflux GmbH | - // +----------------------------------------------------------------------+ - // | Licensed under the Apache License, Version 2.0 (the "License"); | - // | you may not use this file except in compliance with the License. | - // | You may obtain a copy of the License at | - // | http://www.apache.org/licenses/LICENSE-2.0 | - // | Unless required by applicable law or agreed to in writing, software | - // | distributed under the License is distributed on an "AS IS" BASIS, | - // | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | - // | implied. See the License for the specific language governing | - // | permissions and limitations under the License. | - // +----------------------------------------------------------------------+ - // | Author: Christian Stocker <chregu@bitflux.ch> | - // +----------------------------------------------------------------------+ - // - // Kohana Modifications: - // * Changed double quotes to single quotes, changed indenting and spacing - // * Removed magic_quotes stuff - // * Increased regex readability: - // * Used delimeters that aren't found in the pattern - // * Removed all unneeded escapes - // * Deleted U modifiers and swapped greediness where needed - // * Increased regex speed: - // * Made capturing parentheses non-capturing where possible - // * Removed parentheses where possible - // * Split up alternation alternatives - // * Made some quantifiers possessive - - // Fix &entity\n; - $data = str_replace(array('&','<','>'), array('&amp;','&lt;','&gt;'), $data); - $data = preg_replace('/(&#*\w+)[\x00-\x20]+;/u', '$1;', $data); - $data = preg_replace('/(&#x*[0-9A-F]+);*/iu', '$1;', $data); - $data = html_entity_decode($data, ENT_COMPAT, 'UTF-8'); - - // Remove any attribute starting with "on" or xmlns - $data = preg_replace('#(<[^>]+?[\x00-\x20"\'])(?:on|xmlns)[^>]*+>#iu', '$1>', $data); - - // Remove javascript: and vbscript: protocols - $data = preg_replace('#([a-z]*)[\x00-\x20]*=[\x00-\x20]*([`\'"]*)[\x00-\x20]*j[\x00-\x20]*a[\x00-\x20]*v[\x00-\x20]*a[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2nojavascript...', $data); - $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*v[\x00-\x20]*b[\x00-\x20]*s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:#iu', '$1=$2novbscript...', $data); - $data = preg_replace('#([a-z]*)[\x00-\x20]*=([\'"]*)[\x00-\x20]*-moz-binding[\x00-\x20]*:#u', '$1=$2nomozbinding...', $data); - - // Only works in IE: <span style="width: expression(alert('Ping!'));"></span> - $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?expression[\x00-\x20]*\([^>]*+>#i', '$1>', $data); - $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?behaviour[\x00-\x20]*\([^>]*+>#i', '$1>', $data); - $data = preg_replace('#(<[^>]+?)style[\x00-\x20]*=[\x00-\x20]*[`\'"]*.*?s[\x00-\x20]*c[\x00-\x20]*r[\x00-\x20]*i[\x00-\x20]*p[\x00-\x20]*t[\x00-\x20]*:*[^>]*+>#iu', '$1>', $data); - - // Remove namespaced elements (we do not need them) - $data = preg_replace('#</*\w+:\w[^>]*+>#i', '', $data); - - do - { - // Remove really unwanted tags - $old_data = $data; - $data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data); - } - while ($old_data !== $data); - break; - } - - return $data; - } - - /** - * This is a helper method. It enforces W3C specifications for allowed - * key name strings, to prevent malicious exploitation. - * - * @param string string to clean - * @return string - */ - public function clean_input_keys($str) - { - $chars = PCRE_UNICODE_PROPERTIES ? '\pL' : 'a-zA-Z'; - - if ( ! preg_match('#^['.$chars.'0-9:_.-]++$#uD', $str)) - { - exit('Disallowed key characters in global data.'); - } - - return $str; - } - - /** - * This is a helper method. It escapes data and forces all newline - * characters to "\n". - * - * @param unknown_type string to clean - * @return string - */ - public function clean_input_data($str) - { - if (is_array($str)) - { - $new_array = array(); - foreach ($str as $key => $val) - { - // Recursion! - $new_array[$this->clean_input_keys($key)] = $this->clean_input_data($val); - } - return $new_array; - } - - if ($this->magic_quotes_gpc === TRUE) - { - // Remove annoying magic quotes - $str = stripslashes($str); - } - - if ($this->use_xss_clean === TRUE) - { - $str = $this->xss_clean($str); - } - - if (strpos($str, "\r") !== FALSE) - { - // Standardize newlines - $str = str_replace(array("\r\n", "\r"), "\n", $str); - } - - return $str; - } - -} // End Input Class diff --git a/kohana/libraries/Model.php b/kohana/libraries/Model.php deleted file mode 100644 index 0c9fd8d6..00000000 --- a/kohana/libraries/Model.php +++ /dev/null @@ -1,31 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Model base class. - * - * $Id: Model.php 4007 2009-02-20 01:54:00Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2009 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Model_Core { - - // Database object - protected $db = 'default'; - - /** - * Loads the database instance, if the database is not already loaded. - * - * @return void - */ - public function __construct() - { - if ( ! is_object($this->db)) - { - // Load the default database - $this->db = Database::instance($this->db); - } - } - -} // End Model
\ No newline at end of file diff --git a/kohana/libraries/ORM.php b/kohana/libraries/ORM.php deleted file mode 100644 index c1048604..00000000 --- a/kohana/libraries/ORM.php +++ /dev/null @@ -1,1431 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * [Object Relational Mapping][ref-orm] (ORM) is a method of abstracting database - * access to standard PHP calls. All table rows are represented as model objects, - * with object properties representing row data. ORM in Kohana generally follows - * the [Active Record][ref-act] pattern. - * - * [ref-orm]: http://wikipedia.org/wiki/Object-relational_mapping - * [ref-act]: http://wikipedia.org/wiki/Active_record - * - * $Id: ORM.php 4354 2009-05-15 16:51:37Z kiall $ - * - * @package ORM - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class ORM_Core { - - // Current relationships - protected $has_one = array(); - protected $belongs_to = array(); - protected $has_many = array(); - protected $has_and_belongs_to_many = array(); - - // Relationships that should always be joined - protected $load_with = array(); - - // Current object - protected $object = array(); - protected $changed = array(); - protected $related = array(); - protected $loaded = FALSE; - protected $saved = FALSE; - protected $sorting; - - // Related objects - protected $object_relations = array(); - protected $changed_relations = array(); - - // Model table information - protected $object_name; - protected $object_plural; - protected $table_name; - protected $table_columns; - protected $ignored_columns; - - // Table primary key and value - protected $primary_key = 'id'; - protected $primary_val = 'name'; - - // Array of foreign key name overloads - protected $foreign_key = array(); - - // Model configuration - protected $table_names_plural = TRUE; - protected $reload_on_wakeup = TRUE; - - // Database configuration - protected $db = 'default'; - protected $db_applied = array(); - - // With calls already applied - protected $with_applied = array(); - - // Stores column information for ORM models - protected static $column_cache = array(); - - /** - * Creates and returns a new model. - * - * @chainable - * @param string model name - * @param mixed parameter for find() - * @return ORM - */ - public static function factory($model, $id = NULL) - { - // Set class name - $model = ucfirst($model).'_Model'; - - return new $model($id); - } - - /** - * Prepares the model database connection and loads the object. - * - * @param mixed parameter for find or object to load - * @return void - */ - public function __construct($id = NULL) - { - // Set the object name and plural name - $this->object_name = strtolower(substr(get_class($this), 0, -6)); - $this->object_plural = inflector::plural($this->object_name); - - if (!isset($this->sorting)) - { - // Default sorting - $this->sorting = array($this->primary_key => 'asc'); - } - - // Initialize database - $this->__initialize(); - - // Clear the object - $this->clear(); - - if (is_object($id)) - { - // Load an object - $this->load_values((array) $id); - } - elseif (!empty($id)) - { - // Find an object - $this->find($id); - } - } - - /** - * Prepares the model database connection, determines the table name, - * and loads column information. - * - * @return void - */ - public function __initialize() - { - if ( ! is_object($this->db)) - { - // Get database instance - $this->db = Database::instance($this->db); - } - - if (empty($this->table_name)) - { - // Table name is the same as the object name - $this->table_name = $this->object_name; - - if ($this->table_names_plural === TRUE) - { - // Make the table name plural - $this->table_name = inflector::plural($this->table_name); - } - } - - if (is_array($this->ignored_columns)) - { - // Make the ignored columns mirrored = mirrored - $this->ignored_columns = array_combine($this->ignored_columns, $this->ignored_columns); - } - - // Load column information - $this->reload_columns(); - } - - /** - * Allows serialization of only the object data and state, to prevent - * "stale" objects being unserialized, which also requires less memory. - * - * @return array - */ - public function __sleep() - { - // Store only information about the object - return array('object_name', 'object', 'changed', 'loaded', 'saved', 'sorting'); - } - - /** - * Prepares the database connection and reloads the object. - * - * @return void - */ - public function __wakeup() - { - // Initialize database - $this->__initialize(); - - if ($this->reload_on_wakeup === TRUE) - { - // Reload the object - $this->reload(); - } - } - - /** - * Handles pass-through to database methods. Calls to query methods - * (query, get, insert, update) are not allowed. Query builder methods - * are chainable. - * - * @param string method name - * @param array method arguments - * @return mixed - */ - public function __call($method, array $args) - { - if (method_exists($this->db, $method)) - { - if (in_array($method, array('query', 'get', 'insert', 'update', 'delete'))) - throw new Kohana_Exception('orm.query_methods_not_allowed'); - - // Method has been applied to the database - $this->db_applied[$method] = $method; - - // Number of arguments passed - $num_args = count($args); - - if ($method === 'select' AND $num_args > 3) - { - // Call select() manually to avoid call_user_func_array - $this->db->select($args); - } - else - { - // We use switch here to manually call the database methods. This is - // done for speed: call_user_func_array can take over 300% longer to - // make calls. Most database methods are 4 arguments or less, so this - // avoids almost any calls to call_user_func_array. - - switch ($num_args) - { - case 0: - if (in_array($method, array('open_paren', 'close_paren', 'enable_cache', 'disable_cache'))) - { - // Should return ORM, not Database - $this->db->$method(); - } - else - { - // Support for things like reset_select, reset_write, list_tables - return $this->db->$method(); - } - break; - case 1: - $this->db->$method($args[0]); - break; - case 2: - $this->db->$method($args[0], $args[1]); - break; - case 3: - $this->db->$method($args[0], $args[1], $args[2]); - break; - case 4: - $this->db->$method($args[0], $args[1], $args[2], $args[3]); - break; - default: - // Here comes the snail... - call_user_func_array(array($this->db, $method), $args); - break; - } - } - - return $this; - } - else - { - throw new Kohana_Exception('core.invalid_method', $method, get_class($this)); - } - } - - /** - * Handles retrieval of all model values, relationships, and metadata. - * - * @param string column name - * @return mixed - */ - public function __get($column) - { - if (array_key_exists($column, $this->object)) - { - return $this->object[$column]; - } - elseif (isset($this->related[$column])) - { - return $this->related[$column]; - } - elseif ($column === 'primary_key_value') - { - return $this->object[$this->primary_key]; - } - elseif ($model = $this->related_object($column)) - { - // This handles the has_one and belongs_to relationships - - if (in_array($model->object_name, $this->belongs_to) OR ! array_key_exists($this->foreign_key($column), $model->object)) - { - // Foreign key lies in this table (this model belongs_to target model) OR an invalid has_one relationship - $where = array($model->table_name.'.'.$model->primary_key => $this->object[$this->foreign_key($column)]); - } - else - { - // Foreign key lies in the target table (this model has_one target model) - $where = array($this->foreign_key($column, $model->table_name) => $this->primary_key_value); - } - - // one<>alias:one relationship - return $this->related[$column] = $model->find($where); - } - elseif (isset($this->has_many[$column])) - { - // Load the "middle" model - $through = ORM::factory(inflector::singular($this->has_many[$column])); - - // Load the "end" model - $model = ORM::factory(inflector::singular($column)); - - // Join ON target model's primary key set to 'through' model's foreign key - // User-defined foreign keys must be defined in the 'through' model - $join_table = $through->table_name; - $join_col1 = $through->foreign_key($model->object_name, $join_table); - $join_col2 = $model->table_name.'.'.$model->primary_key; - - // one<>alias:many relationship - return $this->related[$column] = $model - ->join($join_table, $join_col1, $join_col2) - ->where($through->foreign_key($this->object_name, $join_table), $this->object[$this->primary_key]) - ->find_all(); - } - elseif (in_array($column, $this->has_many)) - { - // one<>many relationship - $model = ORM::factory(inflector::singular($column)); - return $this->related[$column] = $model - ->where($this->foreign_key($column, $model->table_name), $this->object[$this->primary_key]) - ->find_all(); - } - elseif (in_array($column, $this->has_and_belongs_to_many)) - { - // Load the remote model, always singular - $model = ORM::factory(inflector::singular($column)); - - if ($this->has($model, TRUE)) - { - // many<>many relationship - return $this->related[$column] = $model - ->in($model->table_name.'.'.$model->primary_key, $this->changed_relations[$column]) - ->find_all(); - } - else - { - // empty many<>many relationship - return $this->related[$column] = $model - ->where($model->table_name.'.'.$model->primary_key, NULL) - ->find_all(); - } - } - elseif (isset($this->ignored_columns[$column])) - { - return NULL; - } - elseif (in_array($column, array - ( - 'object_name', 'object_plural', // Object - 'primary_key', 'primary_val', 'table_name', 'table_columns', // Table - 'loaded', 'saved', // Status - 'has_one', 'belongs_to', 'has_many', 'has_and_belongs_to_many', 'load_with' // Relationships - ))) - { - // Model meta information - return $this->$column; - } - else - { - throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); - } - } - - /** - * Handles setting of all model values, and tracks changes between values. - * - * @param string column name - * @param mixed column value - * @return void - */ - public function __set($column, $value) - { - if (isset($this->ignored_columns[$column])) - { - return NULL; - } - elseif (isset($this->object[$column]) OR array_key_exists($column, $this->object)) - { - if (isset($this->table_columns[$column])) - { - // Data has changed - $this->changed[$column] = $column; - - // Object is no longer saved - $this->saved = FALSE; - } - - $this->object[$column] = $this->load_type($column, $value); - } - elseif (in_array($column, $this->has_and_belongs_to_many) AND is_array($value)) - { - // Load relations - $model = ORM::factory(inflector::singular($column)); - - if ( ! isset($this->object_relations[$column])) - { - // Load relations - $this->has($model); - } - - // Change the relationships - $this->changed_relations[$column] = $value; - - if (isset($this->related[$column])) - { - // Force a reload of the relationships - unset($this->related[$column]); - } - } - else - { - throw new Kohana_Exception('core.invalid_property', $column, get_class($this)); - } - } - - /** - * Checks if object data is set. - * - * @param string column name - * @return boolean - */ - public function __isset($column) - { - return (isset($this->object[$column]) OR isset($this->related[$column])); - } - - /** - * Unsets object data. - * - * @param string column name - * @return void - */ - public function __unset($column) - { - unset($this->object[$column], $this->changed[$column], $this->related[$column]); - } - - /** - * Displays the primary key of a model when it is converted to a string. - * - * @return string - */ - public function __toString() - { - return (string) $this->object[$this->primary_key]; - } - - /** - * Returns the values of this object as an array. - * - * @return array - */ - public function as_array() - { - $object = array(); - - foreach ($this->object as $key => $val) - { - // Reconstruct the array (calls __get) - $object[$key] = $this->$key; - } - - return $object; - } - - /** - * Binds another one-to-one object to this model. One-to-one objects - * can be nested using 'object1:object2' syntax - * - * @param string $target_path - * @return void - */ - public function with($target_path) - { - if (isset($this->with_applied[$target_path])) - { - // Don't join anything already joined - return $this; - } - - // Split object parts - $objects = explode(':', $target_path); - $target = $this; - foreach ($objects as $object) - { - // Go down the line of objects to find the given target - $parent = $target; - $target = $parent->related_object($object); - - if ( ! $target) - { - // Can't find related object - return $this; - } - } - - $target_name = $object; - - // Pop-off top object to get the parent object (user:photo:tag becomes user:photo - the parent table prefix) - array_pop($objects); - $parent_path = implode(':', $objects); - - if (empty($parent_path)) - { - // Use this table name itself for the parent object - $parent_path = $this->table_name; - } - else - { - if( ! isset($this->with_applied[$parent_path])) - { - // If the parent object hasn't been joined yet, do it first (otherwise LEFT JOINs fail) - $this->with($parent_path); - } - } - - // Add to with_applied to prevent duplicate joins - $this->with_applied[$target_path] = TRUE; - - // Use the keys of the empty object to determine the columns - $select = array_keys($target->object); - foreach ($select as $i => $column) - { - // Add the prefix so that load_result can determine the relationship - $select[$i] = $target_path.'.'.$column.' AS '.$target_path.':'.$column; - } - - - // Select all of the prefixed keys in the object - $this->db->select($select); - - if (in_array($target->object_name, $parent->belongs_to) OR ! isset($target->object[$parent->foreign_key($target_name)])) - { - // Parent belongs_to target, use target's primary key as join column - $join_col1 = $target->foreign_key(TRUE, $target_path); - $join_col2 = $parent->foreign_key($target_name, $parent_path); - } - else - { - // Parent has_one target, use parent's primary key as join column - $join_col2 = $parent->foreign_key(TRUE, $parent_path); - $join_col1 = $parent->foreign_key($target_name, $target_path); - } - - // This allows for models to use different table prefixes (sharing the same database) - $join_table = new Database_Expression($target->db->table_prefix().$target->table_name.' AS '.$this->db->table_prefix().$target_path); - - // Join the related object into the result - $this->db->join($join_table, $join_col1, $join_col2, 'LEFT'); - - return $this; - } - - /** - * Finds and loads a single database row into the object. - * - * @chainable - * @param mixed primary key or an array of clauses - * @return ORM - */ - public function find($id = NULL) - { - if ($id !== NULL) - { - if (is_array($id)) - { - // Search for all clauses - $this->db->where($id); - } - else - { - // Search for a specific column - $this->db->where($this->table_name.'.'.$this->unique_key($id), $id); - } - } - - return $this->load_result(); - } - - /** - * Finds multiple database rows and returns an iterator of the rows found. - * - * @chainable - * @param integer SQL limit - * @param integer SQL offset - * @return ORM_Iterator - */ - public function find_all($limit = NULL, $offset = NULL) - { - if ($limit !== NULL AND ! isset($this->db_applied['limit'])) - { - // Set limit - $this->limit($limit); - } - - if ($offset !== NULL AND ! isset($this->db_applied['offset'])) - { - // Set offset - $this->offset($offset); - } - - return $this->load_result(TRUE); - } - - /** - * Creates a key/value array from all of the objects available. Uses find_all - * to find the objects. - * - * @param string key column - * @param string value column - * @return array - */ - public function select_list($key = NULL, $val = NULL) - { - if ($key === NULL) - { - $key = $this->primary_key; - } - - if ($val === NULL) - { - $val = $this->primary_val; - } - - // Return a select list from the results - return $this->select($key, $val)->find_all()->select_list($key, $val); - } - - /** - * Validates the current object. This method should generally be called - * via the model, after the $_POST Validation object has been created. - * - * @param object Validation array - * @return boolean - */ - public function validate(Validation $array, $save = FALSE) - { - $safe_array = $array->safe_array(); - - if ( ! $array->submitted()) - { - foreach ($safe_array as $key => $value) - { - // Get the value from this object - $value = $this->$key; - - if (is_object($value) AND $value instanceof ORM_Iterator) - { - // Convert the value to an array of primary keys - $value = $value->primary_key_array(); - } - - // Pre-fill data - $array[$key] = $value; - } - } - - // Validate the array - if ($status = $array->validate()) - { - // Grab only set fields (excludes missing data, unlike safe_array) - $fields = $array->as_array(); - - foreach ($fields as $key => $value) - { - if (isset($safe_array[$key])) - { - // Set new data, ignoring any missing fields or fields without rules - $this->$key = $value; - } - } - - if ($save === TRUE OR is_string($save)) - { - // Save this object - $this->save(); - - if (is_string($save)) - { - // Redirect to the saved page - url::redirect($save); - } - } - } - - // Return validation status - return $status; - } - - /** - * Saves the current object. - * - * @chainable - * @return ORM - */ - public function save() - { - if ( ! empty($this->changed)) - { - $data = array(); - foreach ($this->changed as $column) - { - // Compile changed data - $data[$column] = $this->object[$column]; - } - - if ($this->loaded === TRUE) - { - $query = $this->db - ->where($this->primary_key, $this->object[$this->primary_key]) - ->update($this->table_name, $data); - - // Object has been saved - $this->saved = TRUE; - } - else - { - $query = $this->db - ->insert($this->table_name, $data); - - if ($query->count() > 0) - { - if (empty($this->object[$this->primary_key])) - { - // Load the insert id as the primary key - $this->object[$this->primary_key] = $query->insert_id(); - } - - // Object is now loaded and saved - $this->loaded = $this->saved = TRUE; - } - } - - if ($this->saved === TRUE) - { - // All changes have been saved - $this->changed = array(); - } - } - - if ($this->saved === TRUE AND ! empty($this->changed_relations)) - { - foreach ($this->changed_relations as $column => $values) - { - // All values that were added - $added = array_diff($values, $this->object_relations[$column]); - - // All values that were saved - $removed = array_diff($this->object_relations[$column], $values); - - if (empty($added) AND empty($removed)) - { - // No need to bother - continue; - } - - // Clear related columns - unset($this->related[$column]); - - // Load the model - $model = ORM::factory(inflector::singular($column)); - - if (($join_table = array_search($column, $this->has_and_belongs_to_many)) === FALSE) - continue; - - if (is_int($join_table)) - { - // No "through" table, load the default JOIN table - $join_table = $model->join_table($this->table_name); - } - - // Foreign keys for the join table - $object_fk = $this->foreign_key(NULL); - $related_fk = $model->foreign_key(NULL); - - if ( ! empty($added)) - { - foreach ($added as $id) - { - // Insert the new relationship - $this->db->insert($join_table, array - ( - $object_fk => $this->object[$this->primary_key], - $related_fk => $id, - )); - } - } - - if ( ! empty($removed)) - { - $this->db - ->where($object_fk, $this->object[$this->primary_key]) - ->in($related_fk, $removed) - ->delete($join_table); - } - - // Clear all relations for this column - unset($this->object_relations[$column], $this->changed_relations[$column]); - } - } - - return $this; - } - - /** - * Deletes the current object from the database. This does NOT destroy - * relationships that have been created with other objects. - * - * @chainable - * @return ORM - */ - public function delete($id = NULL) - { - if ($id === NULL AND $this->loaded) - { - // Use the the primary key value - $id = $this->object[$this->primary_key]; - } - - // Delete this object - $this->db->where($this->primary_key, $id)->delete($this->table_name); - - return $this->clear(); - } - - /** - * Delete all objects in the associated table. This does NOT destroy - * relationships that have been created with other objects. - * - * @chainable - * @param array ids to delete - * @return ORM - */ - public function delete_all($ids = NULL) - { - if (is_array($ids)) - { - // Delete only given ids - $this->db->in($this->primary_key, $ids); - } - elseif (is_null($ids)) - { - // Delete all records - $this->db->where('1=1'); - } - else - { - // Do nothing - safeguard - return $this; - } - - // Delete all objects - $this->db->delete($this->table_name); - - return $this->clear(); - } - - /** - * Unloads the current object and clears the status. - * - * @chainable - * @return ORM - */ - public function clear() - { - // Create an array with all the columns set to NULL - $columns = array_keys($this->table_columns); - $values = array_combine($columns, array_fill(0, count($columns), NULL)); - - // Replace the current object with an empty one - $this->load_values($values); - - return $this; - } - - /** - * Reloads the current object from the database. - * - * @chainable - * @return ORM - */ - public function reload() - { - return $this->find($this->object[$this->primary_key]); - } - - /** - * Reload column definitions. - * - * @chainable - * @param boolean force reloading - * @return ORM - */ - public function reload_columns($force = FALSE) - { - if ($force === TRUE OR empty($this->table_columns)) - { - if (isset(ORM::$column_cache[$this->object_name])) - { - // Use cached column information - $this->table_columns = ORM::$column_cache[$this->object_name]; - } - else - { - // Load table columns - ORM::$column_cache[$this->object_name] = $this->table_columns = $this->list_fields(); - } - } - - return $this; - } - - /** - * Tests if this object has a relationship to a different model. - * - * @param object related ORM model - * @param boolean check for any relations to given model - * @return boolean - */ - public function has(ORM $model, $any = FALSE) - { - // Determine plural or singular relation name - $related = ($model->table_names_plural === TRUE) ? $model->object_plural : $model->object_name; - - if (($join_table = array_search($related, $this->has_and_belongs_to_many)) === FALSE) - return FALSE; - - if (is_int($join_table)) - { - // No "through" table, load the default JOIN table - $join_table = $model->join_table($this->table_name); - } - - if ( ! isset($this->object_relations[$related])) - { - // Load the object relationships - $this->changed_relations[$related] = $this->object_relations[$related] = $this->load_relations($join_table, $model); - } - - if ( ! $model->empty_primary_key()) - { - // Check if a specific object exists - return in_array($model->primary_key_value, $this->changed_relations[$related]); - } - elseif ($any) - { - // Check if any relations to given model exist - return ! empty($this->changed_relations[$related]); - } - else - { - return FALSE; - } - } - - /** - * Adds a new relationship to between this model and another. - * - * @param object related ORM model - * @return boolean - */ - public function add(ORM $model) - { - if ($this->has($model)) - return TRUE; - - // Get the faked column name - $column = $model->object_plural; - - // Add the new relation to the update - $this->changed_relations[$column][] = $model->primary_key_value; - - if (isset($this->related[$column])) - { - // Force a reload of the relationships - unset($this->related[$column]); - } - - return TRUE; - } - - /** - * Adds a new relationship to between this model and another. - * - * @param object related ORM model - * @return boolean - */ - public function remove(ORM $model) - { - if ( ! $this->has($model)) - return FALSE; - - // Get the faked column name - $column = $model->object_plural; - - if (($key = array_search($model->primary_key_value, $this->changed_relations[$column])) === FALSE) - return FALSE; - - // Remove the relationship - unset($this->changed_relations[$column][$key]); - - if (isset($this->related[$column])) - { - // Force a reload of the relationships - unset($this->related[$column]); - } - - return TRUE; - } - - /** - * Count the number of records in the table. - * - * @return integer - */ - public function count_all() - { - // Return the total number of records in a table - return $this->db->count_records($this->table_name); - } - - /** - * Proxy method to Database list_fields. - * - * @param string table name or NULL to use this table - * @return array - */ - public function list_fields($table = NULL) - { - if ($table === NULL) - { - $table = $this->table_name; - } - - // Proxy to database - return $this->db->list_fields($table); - } - - /** - * Proxy method to Database field_data. - * - * @param string table name - * @return array - */ - public function field_data($table) - { - // Proxy to database - return $this->db->field_data($table); - } - - /** - * Proxy method to Database field_data. - * - * @chainable - * @param string SQL query to clear - * @return ORM - */ - public function clear_cache($sql = NULL) - { - // Proxy to database - $this->db->clear_cache($sql); - - ORM::$column_cache = array(); - - return $this; - } - - /** - * Returns the unique key for a specific value. This method is expected - * to be overloaded in models if the model has other unique columns. - * - * @param mixed unique value - * @return string - */ - public function unique_key($id) - { - return $this->primary_key; - } - - /** - * Determines the name of a foreign key for a specific table. - * - * @param string related table name - * @param string prefix table name (used for JOINs) - * @return string - */ - public function foreign_key($table = NULL, $prefix_table = NULL) - { - if ($table === TRUE) - { - if (is_string($prefix_table)) - { - // Use prefix table name and this table's PK - return $prefix_table.'.'.$this->primary_key; - } - else - { - // Return the name of this table's PK - return $this->table_name.'.'.$this->primary_key; - } - } - - if (is_string($prefix_table)) - { - // Add a period for prefix_table.column support - $prefix_table .= '.'; - } - - if (isset($this->foreign_key[$table])) - { - // Use the defined foreign key name, no magic here! - $foreign_key = $this->foreign_key[$table]; - } - else - { - if ( ! is_string($table) OR ! array_key_exists($table.'_'.$this->primary_key, $this->object)) - { - // Use this table - $table = $this->table_name; - - if (strpos($table, '.') !== FALSE) - { - // Hack around support for PostgreSQL schemas - list ($schema, $table) = explode('.', $table, 2); - } - - if ($this->table_names_plural === TRUE) - { - // Make the key name singular - $table = inflector::singular($table); - } - } - - $foreign_key = $table.'_'.$this->primary_key; - } - - return $prefix_table.$foreign_key; - } - - /** - * This uses alphabetical comparison to choose the name of the table. - * - * Example: The joining table of users and roles would be roles_users, - * because "r" comes before "u". Joining products and categories would - * result in categories_products, because "c" comes before "p". - * - * Example: zoo > zebra > robber > ocean > angel > aardvark - * - * @param string table name - * @return string - */ - public function join_table($table) - { - if ($this->table_name > $table) - { - $table = $table.'_'.$this->table_name; - } - else - { - $table = $this->table_name.'_'.$table; - } - - return $table; - } - - /** - * Returns an ORM model for the given object name; - * - * @param string object name - * @return ORM - */ - protected function related_object($object) - { - if (isset($this->has_one[$object])) - { - $object = ORM::factory($this->has_one[$object]); - } - elseif (isset($this->belongs_to[$object])) - { - $object = ORM::factory($this->belongs_to[$object]); - } - elseif (in_array($object, $this->has_one) OR in_array($object, $this->belongs_to)) - { - $object = ORM::factory($object); - } - else - { - return FALSE; - } - - return $object; - } - - /** - * Loads an array of values into into the current object. - * - * @chainable - * @param array values to load - * @return ORM - */ - public function load_values(array $values) - { - if (array_key_exists($this->primary_key, $values)) - { - // Replace the object and reset the object status - $this->object = $this->changed = $this->related = array(); - - // Set the loaded and saved object status based on the primary key - $this->loaded = $this->saved = ($values[$this->primary_key] !== NULL); - } - - // Related objects - $related = array(); - - foreach ($values as $column => $value) - { - if (strpos($column, ':') === FALSE) - { - if (isset($this->table_columns[$column])) - { - // The type of the value can be determined, convert the value - $value = $this->load_type($column, $value); - } - - $this->object[$column] = $value; - } - else - { - list ($prefix, $column) = explode(':', $column, 2); - - $related[$prefix][$column] = $value; - } - } - - if ( ! empty($related)) - { - foreach ($related as $object => $values) - { - // Load the related objects with the values in the result - $this->related[$object] = $this->related_object($object)->load_values($values); - } - } - - return $this; - } - - /** - * Loads a value according to the types defined by the column metadata. - * - * @param string column name - * @param mixed value to load - * @return mixed - */ - protected function load_type($column, $value) - { - $type = gettype($value); - if ($type == 'object' OR $type == 'array' OR ! isset($this->table_columns[$column])) - return $value; - - // Load column data - $column = $this->table_columns[$column]; - - if ($value === NULL AND ! empty($column['null'])) - return $value; - - if ( ! empty($column['binary']) AND ! empty($column['exact']) AND (int) $column['length'] === 1) - { - // Use boolean for BINARY(1) fields - $column['type'] = 'boolean'; - } - - switch ($column['type']) - { - case 'int': - if ($value === '' AND ! empty($column['null'])) - { - // Forms will only submit strings, so empty integer values must be null - $value = NULL; - } - elseif ((float) $value > PHP_INT_MAX) - { - // This number cannot be represented by a PHP integer, so we convert it to a string - $value = (string) $value; - } - else - { - $value = (int) $value; - } - break; - case 'float': - $value = (float) $value; - break; - case 'boolean': - $value = (bool) $value; - break; - case 'string': - $value = (string) $value; - break; - } - - return $value; - } - - /** - * Loads a database result, either as a new object for this model, or as - * an iterator for multiple rows. - * - * @chainable - * @param boolean return an iterator or load a single row - * @return ORM for single rows - * @return ORM_Iterator for multiple rows - */ - protected function load_result($array = FALSE) - { - if ($array === FALSE) - { - // Only fetch 1 record - $this->db->limit(1); - } - - if ( ! isset($this->db_applied['select'])) - { - // Select all columns by default - $this->db->select($this->table_name.'.*'); - } - - if ( ! empty($this->load_with)) - { - foreach ($this->load_with as $alias => $object) - { - // Join each object into the results - if (is_string($alias)) - { - // Use alias - $this->with($alias); - } - else - { - // Use object - $this->with($object); - } - } - } - - if ( ! isset($this->db_applied['orderby']) AND ! empty($this->sorting)) - { - $sorting = array(); - foreach ($this->sorting as $column => $direction) - { - if (strpos($column, '.') === FALSE) - { - // Keeps sorting working properly when using JOINs on - // tables with columns of the same name - $column = $this->table_name.'.'.$column; - } - - $sorting[$column] = $direction; - } - - // Apply the user-defined sorting - $this->db->orderby($sorting); - } - - // Load the result - $result = $this->db->get($this->table_name); - - if ($array === TRUE) - { - // Return an iterated result - return new ORM_Iterator($this, $result); - } - - if ($result->count() === 1) - { - // Load object values - $this->load_values($result->result(FALSE)->current()); - } - else - { - // Clear the object, nothing was found - $this->clear(); - } - - return $this; - } - - /** - * Return an array of all the primary keys of the related table. - * - * @param string table name - * @param object ORM model to find relations of - * @return array - */ - protected function load_relations($table, ORM $model) - { - // Save the current query chain (otherwise the next call will clash) - $this->db->push(); - - $query = $this->db - ->select($model->foreign_key(NULL).' AS id') - ->from($table) - ->where($this->foreign_key(NULL, $table), $this->object[$this->primary_key]) - ->get() - ->result(TRUE); - - $this->db->pop(); - - $relations = array(); - foreach ($query as $row) - { - $relations[] = $row->id; - } - - return $relations; - } - - /** - * Returns whether or not primary key is empty - * - * @return bool - */ - protected function empty_primary_key() - { - return (empty($this->object[$this->primary_key]) AND $this->object[$this->primary_key] !== '0'); - } - -} // End ORM diff --git a/kohana/libraries/ORM_Iterator.php b/kohana/libraries/ORM_Iterator.php deleted file mode 100644 index 41aa8065..00000000 --- a/kohana/libraries/ORM_Iterator.php +++ /dev/null @@ -1,228 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** -* Object Relational Mapping (ORM) result iterator. -* -* $Id: ORM_Iterator.php 3769 2008-12-15 00:48:56Z zombor $ -* -* @package ORM -* @author Kohana Team -* @copyright (c) 2007-2008 Kohana Team -* @license http://kohanaphp.com/license.html -*/ -class ORM_Iterator_Core implements Iterator, ArrayAccess, Countable { - - // Class attributes - protected $class_name; - protected $primary_key; - protected $primary_val; - - // Database result object - protected $result; - - public function __construct(ORM $model, Database_Result $result) - { - // Class attributes - $this->class_name = get_class($model); - $this->primary_key = $model->primary_key; - $this->primary_val = $model->primary_val; - - // Database result - $this->result = $result->result(TRUE); - } - - /** - * Returns an array of the results as ORM objects. - * - * @return array - */ - public function as_array() - { - $array = array(); - - if ($results = $this->result->result_array()) - { - // Import class name - $class = $this->class_name; - - foreach ($results as $obj) - { - $array[] = new $class($obj); - } - } - - return $array; - } - - /** - * Return an array of all of the primary keys for this object. - * - * @return array - */ - public function primary_key_array() - { - $ids = array(); - foreach ($this->result as $row) - { - $ids[] = $row->{$this->primary_key}; - } - return $ids; - } - - /** - * Create a key/value array from the results. - * - * @param string key column - * @param string value column - * @return array - */ - public function select_list($key = NULL, $val = NULL) - { - if ($key === NULL) - { - // Use the default key - $key = $this->primary_key; - } - - if ($val === NULL) - { - // Use the default value - $val = $this->primary_val; - } - - $array = array(); - foreach ($this->result->result_array() as $row) - { - $array[$row->$key] = $row->$val; - } - return $array; - } - - /** - * Return a range of offsets. - * - * @param integer start - * @param integer end - * @return array - */ - public function range($start, $end) - { - // Array of objects - $array = array(); - - if ($this->result->offsetExists($start)) - { - // Import the class name - $class = $this->class_name; - - // Set the end offset - $end = $this->result->offsetExists($end) ? $end : $this->count(); - - for ($i = $start; $i < $end; $i++) - { - // Insert each object in the range - $array[] = new $class($this->result->offsetGet($i)); - } - } - - return $array; - } - - /** - * Countable: count - */ - public function count() - { - return $this->result->count(); - } - - /** - * Iterator: current - */ - public function current() - { - if ($row = $this->result->current()) - { - // Import class name - $class = $this->class_name; - - $row = new $class($row); - } - - return $row; - } - - /** - * Iterator: key - */ - public function key() - { - return $this->result->key(); - } - - /** - * Iterator: next - */ - public function next() - { - return $this->result->next(); - } - - /** - * Iterator: rewind - */ - public function rewind() - { - $this->result->rewind(); - } - - /** - * Iterator: valid - */ - public function valid() - { - return $this->result->valid(); - } - - /** - * ArrayAccess: offsetExists - */ - public function offsetExists($offset) - { - return $this->result->offsetExists($offset); - } - - /** - * ArrayAccess: offsetGet - */ - public function offsetGet($offset) - { - if ($this->result->offsetExists($offset)) - { - // Import class name - $class = $this->class_name; - - return new $class($this->result->offsetGet($offset)); - } - } - - /** - * ArrayAccess: offsetSet - * - * @throws Kohana_Database_Exception - */ - public function offsetSet($offset, $value) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - - /** - * ArrayAccess: offsetUnset - * - * @throws Kohana_Database_Exception - */ - public function offsetUnset($offset) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - -} // End ORM Iterator
\ No newline at end of file diff --git a/kohana/libraries/ORM_Tree.php b/kohana/libraries/ORM_Tree.php deleted file mode 100644 index cdb09fd0..00000000 --- a/kohana/libraries/ORM_Tree.php +++ /dev/null @@ -1,76 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Object Relational Mapping (ORM) "tree" extension. Allows ORM objects to act - * as trees, with parents and children. - * - * $Id: ORM_Tree.php 3923 2009-01-22 15:37:04Z samsoir $ - * - * @package ORM - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class ORM_Tree_Core extends ORM { - - // Name of the child - protected $ORM_Tree_children; - - // Parent keyword name - protected $ORM_Tree_parent_key = 'parent_id'; - - /** - * Overload ORM::__get to support "parent" and "children" properties. - * - * @param string column name - * @return mixed - */ - public function __get($column) - { - if ($column === 'parent') - { - if (empty($this->related[$column])) - { - // Load child model - $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); - - if (array_key_exists($this->ORM_Tree_parent_key, $this->object)) - { - // Find children of this parent - $model->where($model->primary_key, $this->object[$this->ORM_Tree_parent_key])->find(); - } - - $this->related[$column] = $model; - } - - return $this->related[$column]; - } - elseif ($column === 'children') - { - if (empty($this->related[$column])) - { - $model = ORM::factory(inflector::singular($this->ORM_Tree_children)); - - if ($this->ORM_Tree_children === $this->table_name) - { - // Load children within this table - $this->related[$column] = $model - ->where($this->ORM_Tree_parent_key, $this->object[$this->primary_key]) - ->find_all(); - } - else - { - // Find first selection of children - $this->related[$column] = $model - ->where($this->foreign_key(), $this->object[$this->primary_key]) - ->where($this->ORM_Tree_parent_key, NULL) - ->find_all(); - } - } - - return $this->related[$column]; - } - - return parent::__get($column); - } - -} // End ORM Tree
\ No newline at end of file diff --git a/kohana/libraries/ORM_Versioned.php b/kohana/libraries/ORM_Versioned.php deleted file mode 100644 index 078fe16a..00000000 --- a/kohana/libraries/ORM_Versioned.php +++ /dev/null @@ -1,143 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Object Relational Mapping (ORM) "versioned" extension. Allows ORM objects to - * be revisioned instead of updated. - * - * $Id$ - * - * @package ORM - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class ORM_Versioned_Core extends ORM { - - protected $last_version = NULL; - - /** - * Overload ORM::save() to support versioned data - * - * @chainable - * @return ORM - */ - public function save() - { - $this->last_version = 1 + ($this->last_version === NULL ? $this->object['version'] : $this->last_version); - $this->__set('version', $this->last_version); - - parent::save(); - - if ($this->saved) - { - $data = array(); - foreach ($this->object as $key => $value) - { - if ($key === 'id') - continue; - - $data[$key] = $value; - } - $data[$this->foreign_key()] = $this->id; - - $this->db->insert($this->table_name.'_versions', $data); - } - - return $this; - } - - /** - * Loads previous version from current object - * - * @chainable - * @return ORM - */ - public function previous() - { - if ( ! $this->loaded) - return $this; - - $this->last_version = ($this->last_version === NULL) ? $this->object['version'] : $this->last_version; - $version = $this->last_version - 1; - - $query = $this->db - ->where($this->foreign_key(), $this->object[$this->primary_key]) - ->where('version', $version) - ->limit(1) - ->get($this->table_name.'_versions'); - - if ($query->count()) - { - $this->load_values($query->result(FALSE)->current()); - } - - return $this; - } - - /** - * Restores the object with data from stored version - * - * @param integer version number you want to restore - * @return ORM - */ - public function restore($version) - { - if ( ! $this->loaded) - return $this; - - $query = $this->db - ->where($this->foreign_key(), $this->object[$this->primary_key]) - ->where('version', $version) - ->limit(1) - ->get($this->table_name.'_versions'); - - if ($query->count()) - { - $row = $query->result(FALSE)->current(); - - foreach ($row as $key => $value) - { - if ($key === $this->primary_key OR $key === $this->foreign_key()) - { - // Do not overwrite the primary key - continue; - } - - if ($key === 'version') - { - // Always use the current version - $value = $this->version; - } - - $this->__set($key, $value); - } - - $this->save(); - } - - return $this; - } - - /** - * Overloads ORM::delete() to delete all versioned entries of current object - * and the object itself - * - * @param integer id of the object you want to delete - * @return ORM - */ - public function delete($id = NULL) - { - if ($id === NULL) - { - // Use the current object id - $id = $this->object[$this->primary_key]; - } - - if ($status = parent::delete($id)) - { - $this->db->where($this->foreign_key(), $id)->delete($this->table_name.'_versions'); - } - - return $status; - } - -}
\ No newline at end of file diff --git a/kohana/libraries/Pagination.php b/kohana/libraries/Pagination.php deleted file mode 100644 index a8f7bb19..00000000 --- a/kohana/libraries/Pagination.php +++ /dev/null @@ -1,236 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Pagination library. - * - * $Id: Pagination.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Pagination_Core { - - // Config values - protected $base_url = ''; - protected $directory = 'pagination'; - protected $style = 'classic'; - protected $uri_segment = 3; - protected $query_string = ''; - protected $items_per_page = 20; - protected $total_items = 0; - protected $auto_hide = FALSE; - - // Autogenerated values - protected $url; - protected $current_page; - protected $total_pages; - protected $current_first_item; - protected $current_last_item; - protected $first_page; - protected $last_page; - protected $previous_page; - protected $next_page; - protected $sql_offset; - protected $sql_limit; - - /** - * Constructs and returns a new Pagination object. - * - * @param array configuration settings - * @return object - */ - public function factory($config = array()) - { - return new Pagination($config); - } - - /** - * Constructs a new Pagination object. - * - * @param array configuration settings - * @return void - */ - public function __construct($config = array()) - { - // No custom group name given - if ( ! isset($config['group'])) - { - $config['group'] = 'default'; - } - - // Pagination setup - $this->initialize($config); - - Kohana::log('debug', 'Pagination Library initialized'); - } - - /** - * Sets config values. - * - * @throws Kohana_Exception - * @param array configuration settings - * @return void - */ - public function initialize($config = array()) - { - // Load config group - if (isset($config['group'])) - { - // Load and validate config group - if ( ! is_array($group_config = Kohana::config('pagination.'.$config['group']))) - throw new Kohana_Exception('pagination.undefined_group', $config['group']); - - // All pagination config groups inherit default config group - if ($config['group'] !== 'default') - { - // Load and validate default config group - if ( ! is_array($default_config = Kohana::config('pagination.default'))) - throw new Kohana_Exception('pagination.undefined_group', 'default'); - - // Merge config group with default config group - $group_config += $default_config; - } - - // Merge custom config items with config group - $config += $group_config; - } - - // Assign config values to the object - foreach ($config as $key => $value) - { - if (property_exists($this, $key)) - { - $this->$key = $value; - } - } - - // Clean view directory - $this->directory = trim($this->directory, '/').'/'; - - // Build generic URL with page in query string - if ($this->query_string !== '') - { - // Extract current page - $this->current_page = isset($_GET[$this->query_string]) ? (int) $_GET[$this->query_string] : 1; - - // Insert {page} placeholder - $_GET[$this->query_string] = '{page}'; - - // Create full URL - $base_url = ($this->base_url === '') ? Router::$current_uri : $this->base_url; - $this->url = url::site($base_url).'?'.str_replace('%7Bpage%7D', '{page}', http_build_query($_GET)); - - // Reset page number - $_GET[$this->query_string] = $this->current_page; - } - - // Build generic URL with page as URI segment - else - { - // Use current URI if no base_url set - $this->url = ($this->base_url === '') ? Router::$segments : explode('/', trim($this->base_url, '/')); - - // Convert uri 'label' to corresponding integer if needed - if (is_string($this->uri_segment)) - { - if (($key = array_search($this->uri_segment, $this->url)) === FALSE) - { - // If uri 'label' is not found, auto add it to base_url - $this->url[] = $this->uri_segment; - $this->uri_segment = count($this->url) + 1; - } - else - { - $this->uri_segment = $key + 2; - } - } - - // Insert {page} placeholder - $this->url[$this->uri_segment - 1] = '{page}'; - - // Create full URL - $this->url = url::site(implode('/', $this->url)).Router::$query_string; - - // Extract current page - $this->current_page = URI::instance()->segment($this->uri_segment); - } - - // Core pagination values - $this->total_items = (int) max(0, $this->total_items); - $this->items_per_page = (int) max(1, $this->items_per_page); - $this->total_pages = (int) ceil($this->total_items / $this->items_per_page); - $this->current_page = (int) min(max(1, $this->current_page), max(1, $this->total_pages)); - $this->current_first_item = (int) min((($this->current_page - 1) * $this->items_per_page) + 1, $this->total_items); - $this->current_last_item = (int) min($this->current_first_item + $this->items_per_page - 1, $this->total_items); - - // If there is no first/last/previous/next page, relative to the - // current page, value is set to FALSE. Valid page number otherwise. - $this->first_page = ($this->current_page === 1) ? FALSE : 1; - $this->last_page = ($this->current_page >= $this->total_pages) ? FALSE : $this->total_pages; - $this->previous_page = ($this->current_page > 1) ? $this->current_page - 1 : FALSE; - $this->next_page = ($this->current_page < $this->total_pages) ? $this->current_page + 1 : FALSE; - - // SQL values - $this->sql_offset = (int) ($this->current_page - 1) * $this->items_per_page; - $this->sql_limit = sprintf(' LIMIT %d OFFSET %d ', $this->items_per_page, $this->sql_offset); - } - - /** - * Generates the HTML for the chosen pagination style. - * - * @param string pagination style - * @return string pagination html - */ - public function render($style = NULL) - { - // Hide single page pagination - if ($this->auto_hide === TRUE AND $this->total_pages <= 1) - return ''; - - if ($style === NULL) - { - // Use default style - $style = $this->style; - } - - // Return rendered pagination view - return View::factory($this->directory.$style, get_object_vars($this))->render(); - } - - /** - * Magically converts Pagination object to string. - * - * @return string pagination html - */ - public function __toString() - { - return $this->render(); - } - - /** - * Magically gets a pagination variable. - * - * @param string variable key - * @return mixed variable value if the key is found - * @return void if the key is not found - */ - public function __get($key) - { - if (isset($this->$key)) - return $this->$key; - } - - /** - * Adds a secondary interface for accessing properties, e.g. $pagination->total_pages(). - * Note that $pagination->total_pages is the recommended way to access properties. - * - * @param string function name - * @return string - */ - public function __call($func, $args = NULL) - { - return $this->__get($func); - } - -} // End Pagination Class
\ No newline at end of file diff --git a/kohana/libraries/Profiler.php b/kohana/libraries/Profiler.php deleted file mode 100644 index 47d82ace..00000000 --- a/kohana/libraries/Profiler.php +++ /dev/null @@ -1,271 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Adds useful information to the bottom of the current page for debugging and optimization purposes. - * - * Benchmarks - The times and memory usage of benchmarks run by the Benchmark library. - * Database - The raw SQL and number of affected rows of Database queries. - * Session Data - Data stored in the current session if using the Session library. - * POST Data - The name and values of any POST data submitted to the current page. - * Cookie Data - All cookies sent for the current request. - * - * $Id: Profiler.php 4090 2009-03-19 01:27:45Z bharat $ - * - * @package Profiler - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Profiler_Core { - - protected $profiles = array(); - protected $show; - - public function __construct() - { - // Add all built in profiles to event - Event::add('profiler.run', array($this, 'benchmarks')); - Event::add('profiler.run', array($this, 'database')); - Event::add('profiler.run', array($this, 'session')); - Event::add('profiler.run', array($this, 'post')); - Event::add('profiler.run', array($this, 'cookies')); - - // Add profiler to page output automatically - Event::add('system.display', array($this, 'render')); - - Kohana::log('debug', 'Profiler Library initialized'); - } - - /** - * Magic __call method. Creates a new profiler section object. - * - * @param string input type - * @param string input name - * @return object - */ - public function __call($method, $args) - { - if ( ! $this->show OR (is_array($this->show) AND ! in_array($args[0], $this->show))) - return FALSE; - - // Class name - $class = 'Profiler_'.ucfirst($method); - - $class = new $class(); - - $this->profiles[$args[0]] = $class; - - return $class; - } - - /** - * Disables the profiler for this page only. - * Best used when profiler is autoloaded. - * - * @return void - */ - public function disable() - { - // Removes itself from the event queue - Event::clear('system.display', array($this, 'render')); - } - - /** - * Render the profiler. Output is added to the bottom of the page by default. - * - * @param boolean return the output if TRUE - * @return void|string - */ - public function render($return = FALSE) - { - $start = microtime(TRUE); - - $get = isset($_GET['profiler']) ? explode(',', $_GET['profiler']) : array(); - $this->show = empty($get) ? Kohana::config('profiler.show') : $get; - - Event::run('profiler.run', $this); - - $styles = ''; - foreach ($this->profiles as $profile) - { - $styles .= $profile->styles(); - } - - // Don't display if there's no profiles - if (empty($this->profiles)) - return; - - // Load the profiler view - $data = array - ( - 'profiles' => $this->profiles, - 'styles' => $styles, - 'execution_time' => microtime(TRUE) - $start - ); - $view = new View('kohana_profiler', $data); - - // Return rendered view if $return is TRUE - if ($return == TRUE) - return $view->render(); - - // Add profiler data to the output - if (stripos(Kohana::$output, '</body>') !== FALSE) - { - // Closing body tag was found, insert the profiler data before it - Kohana::$output = str_ireplace('</body>', $view->render().'</body>', Kohana::$output); - } - else - { - // Append the profiler data to the output - Kohana::$output .= $view->render(); - } - } - - /** - * Benchmark times and memory usage from the Benchmark library. - * - * @return void - */ - public function benchmarks() - { - if ( ! $table = $this->table('benchmarks')) - return; - - $table->add_column(); - $table->add_column('kp-column kp-data'); - $table->add_column('kp-column kp-data'); - $table->add_column('kp-column kp-data'); - $table->add_row(array('Benchmarks', 'Time', 'Count', 'Memory'), 'kp-title', 'background-color: #FFE0E0'); - - $benchmarks = Benchmark::get(TRUE); - - // Moves the first benchmark (total execution time) to the end of the array - $benchmarks = array_slice($benchmarks, 1) + array_slice($benchmarks, 0, 1); - - text::alternate(); - foreach ($benchmarks as $name => $benchmark) - { - // Clean unique id from system benchmark names - $name = ucwords(str_replace(array('_', '-'), ' ', str_replace(SYSTEM_BENCHMARK.'_', '', $name))); - - $data = array($name, number_format($benchmark['time'], 3), $benchmark['count'], number_format($benchmark['memory'] / 1024 / 1024, 2).'MB'); - $class = text::alternate('', 'kp-altrow'); - - if ($name == 'Total Execution') - $class = 'kp-totalrow'; - - $table->add_row($data, $class); - } - } - - /** - * Database query benchmarks. - * - * @return void - */ - public function database() - { - if ( ! $table = $this->table('database')) - return; - - $table->add_column(); - $table->add_column('kp-column kp-data'); - $table->add_column('kp-column kp-data'); - $table->add_row(array('Queries', 'Time', 'Rows'), 'kp-title', 'background-color: #E0FFE0'); - - $queries = Database::$benchmarks; - - text::alternate(); - $total_time = $total_rows = 0; - foreach ($queries as $query) - { - $data = array($query['query'], number_format($query['time'], 3), $query['rows']); - $class = text::alternate('', 'kp-altrow'); - $table->add_row($data, $class); - $total_time += $query['time']; - $total_rows += $query['rows']; - } - - $data = array('Total: ' . count($queries), number_format($total_time, 3), $total_rows); - $table->add_row($data, 'kp-totalrow'); - } - - /** - * Session data. - * - * @return void - */ - public function session() - { - if (empty($_SESSION)) return; - - if ( ! $table = $this->table('session')) - return; - - $table->add_column('kp-name'); - $table->add_column(); - $table->add_row(array('Session', 'Value'), 'kp-title', 'background-color: #CCE8FB'); - - text::alternate(); - foreach($_SESSION as $name => $value) - { - if (is_object($value)) - { - $value = get_class($value).' [object]'; - } - - $data = array($name, $value); - $class = text::alternate('', 'kp-altrow'); - $table->add_row($data, $class); - } - } - - /** - * POST data. - * - * @return void - */ - public function post() - { - if (empty($_POST)) return; - - if ( ! $table = $this->table('post')) - return; - - $table->add_column('kp-name'); - $table->add_column(); - $table->add_row(array('POST', 'Value'), 'kp-title', 'background-color: #E0E0FF'); - - text::alternate(); - foreach($_POST as $name => $value) - { - $data = array($name, $value); - $class = text::alternate('', 'kp-altrow'); - $table->add_row($data, $class); - } - } - - /** - * Cookie data. - * - * @return void - */ - public function cookies() - { - if (empty($_COOKIE)) return; - - if ( ! $table = $this->table('cookies')) - return; - - $table->add_column('kp-name'); - $table->add_column(); - $table->add_row(array('Cookies', 'Value'), 'kp-title', 'background-color: #FFF4D7'); - - text::alternate(); - foreach($_COOKIE as $name => $value) - { - $data = array($name, $value); - $class = text::alternate('', 'kp-altrow'); - $table->add_row($data, $class); - } - } -}
\ No newline at end of file diff --git a/kohana/libraries/Profiler_Table.php b/kohana/libraries/Profiler_Table.php deleted file mode 100644 index a0058a58..00000000 --- a/kohana/libraries/Profiler_Table.php +++ /dev/null @@ -1,69 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Provides a table layout for sections in the Profiler library. - * - * $Id$ - * - * @package Profiler - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Profiler_Table_Core { - - protected $columns = array(); - protected $rows = array(); - - /** - * Get styles for table. - * - * @return string - */ - public function styles() - { - static $styles_output; - - if ( ! $styles_output) - { - $styles_output = TRUE; - return file_get_contents(Kohana::find_file('views', 'kohana_profiler_table', FALSE, 'css')); - } - - return ''; - } - - /** - * Add column to table. - * - * @param string CSS class - * @param string CSS style - */ - public function add_column($class = '', $style = '') - { - $this->columns[] = array('class' => $class, 'style' => $style); - } - - /** - * Add row to table. - * - * @param array data to go in table cells - * @param string CSS class - * @param string CSS style - */ - public function add_row($data, $class = '', $style = '') - { - $this->rows[] = array('data' => $data, 'class' => $class, 'style' => $style); - } - - /** - * Render table. - * - * @return string - */ - public function render() - { - $data['rows'] = $this->rows; - $data['columns'] = $this->columns; - return View::factory('kohana_profiler_table', $data)->render(); - } -}
\ No newline at end of file diff --git a/kohana/libraries/Router.php b/kohana/libraries/Router.php deleted file mode 100644 index 6dc9b10c..00000000 --- a/kohana/libraries/Router.php +++ /dev/null @@ -1,304 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Router - * - * $Id: Router.php 4350 2009-05-14 18:58:18Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Router_Core { - - protected static $routes; - - public static $current_uri = ''; - public static $query_string = ''; - public static $complete_uri = ''; - public static $routed_uri = ''; - public static $url_suffix = ''; - - public static $segments; - public static $rsegments; - - public static $controller; - public static $controller_path; - - public static $method = 'index'; - public static $arguments = array(); - - /** - * Router setup routine. Automatically called during Kohana setup process. - * - * @return void - */ - public static function setup() - { - if ( ! empty($_SERVER['QUERY_STRING'])) - { - // Set the query string to the current query string - Router::$query_string = '?'.trim($_SERVER['QUERY_STRING'], '&/'); - } - - if (Router::$routes === NULL) - { - // Load routes - Router::$routes = Kohana::config('routes'); - } - - // Default route status - $default_route = FALSE; - - if (Router::$current_uri === '') - { - // Make sure the default route is set - if ( ! isset(Router::$routes['_default'])) - throw new Kohana_Exception('core.no_default_route'); - - // Use the default route when no segments exist - Router::$current_uri = Router::$routes['_default']; - - // Default route is in use - $default_route = TRUE; - } - - // Make sure the URL is not tainted with HTML characters - Router::$current_uri = html::specialchars(Router::$current_uri, FALSE); - - // Remove all dot-paths from the URI, they are not valid - Router::$current_uri = preg_replace('#\.[\s./]*/#', '', Router::$current_uri); - - // At this point segments, rsegments, and current URI are all the same - Router::$segments = Router::$rsegments = Router::$current_uri = trim(Router::$current_uri, '/'); - - // Set the complete URI - Router::$complete_uri = Router::$current_uri.Router::$query_string; - - // Explode the segments by slashes - Router::$segments = ($default_route === TRUE OR Router::$segments === '') ? array() : explode('/', Router::$segments); - - if ($default_route === FALSE AND count(Router::$routes) > 1) - { - // Custom routing - Router::$rsegments = Router::routed_uri(Router::$current_uri); - } - - // The routed URI is now complete - Router::$routed_uri = Router::$rsegments; - - // Routed segments will never be empty - Router::$rsegments = explode('/', Router::$rsegments); - - // Prepare to find the controller - $controller_path = ''; - $method_segment = NULL; - - // Paths to search - $paths = Kohana::include_paths(); - - foreach (Router::$rsegments as $key => $segment) - { - // Add the segment to the search path - $controller_path .= $segment; - - $found = FALSE; - foreach ($paths as $dir) - { - // Search within controllers only - $dir .= 'controllers/'; - - if (is_dir($dir.$controller_path) OR is_file($dir.$controller_path.EXT)) - { - // Valid path - $found = TRUE; - - // The controller must be a file that exists with the search path - if ($c = str_replace('\\', '/', realpath($dir.$controller_path.EXT)) - AND is_file($c) AND strpos($c, $dir) === 0) - { - // Set controller name - Router::$controller = $segment; - - // Change controller path - Router::$controller_path = $c; - - // Set the method segment - $method_segment = $key + 1; - - // Stop searching - break; - } - } - } - - if ($found === FALSE) - { - // Maximum depth has been reached, stop searching - break; - } - - // Add another slash - $controller_path .= '/'; - } - - if ($method_segment !== NULL AND isset(Router::$rsegments[$method_segment])) - { - // Set method - Router::$method = Router::$rsegments[$method_segment]; - - if (isset(Router::$rsegments[$method_segment + 1])) - { - // Set arguments - Router::$arguments = array_slice(Router::$rsegments, $method_segment + 1); - } - } - - // Last chance to set routing before a 404 is triggered - Event::run('system.post_routing'); - - if (Router::$controller === NULL) - { - // No controller was found, so no page can be rendered - Event::run('system.404'); - } - } - - /** - * Attempts to determine the current URI using CLI, GET, PATH_INFO, ORIG_PATH_INFO, or PHP_SELF. - * - * @return void - */ - public static function find_uri() - { - if (PHP_SAPI === 'cli') - { - // Command line requires a bit of hacking - if (isset($_SERVER['argv'][1])) - { - Router::$current_uri = $_SERVER['argv'][1]; - - // Remove GET string from segments - if (($query = strpos(Router::$current_uri, '?')) !== FALSE) - { - list (Router::$current_uri, $query) = explode('?', Router::$current_uri, 2); - - // Parse the query string into $_GET - parse_str($query, $_GET); - - // Convert $_GET to UTF-8 - $_GET = utf8::clean($_GET); - } - } - } - elseif (isset($_GET['kohana_uri'])) - { - // Use the URI defined in the query string - Router::$current_uri = $_GET['kohana_uri']; - - // Remove the URI from $_GET - unset($_GET['kohana_uri']); - - // Remove the URI from $_SERVER['QUERY_STRING'] - $_SERVER['QUERY_STRING'] = preg_replace('~\bkohana_uri\b[^&]*+&?~', '', $_SERVER['QUERY_STRING']); - } - elseif (isset($_SERVER['PATH_INFO']) AND $_SERVER['PATH_INFO']) - { - Router::$current_uri = $_SERVER['PATH_INFO']; - } - elseif (isset($_SERVER['ORIG_PATH_INFO']) AND $_SERVER['ORIG_PATH_INFO']) - { - Router::$current_uri = $_SERVER['ORIG_PATH_INFO']; - } - elseif (isset($_SERVER['PHP_SELF']) AND $_SERVER['PHP_SELF']) - { - Router::$current_uri = $_SERVER['PHP_SELF']; - - if (($strpos_fc = strpos(Router::$current_uri, KOHANA)) !== FALSE) - { - // Remove the front controller from the current uri - Router::$current_uri = substr(Router::$current_uri, $strpos_fc + strlen(KOHANA)); - } - } - - // Remove slashes from the start and end of the URI - Router::$current_uri = trim(Router::$current_uri, '/'); - - if (Router::$current_uri !== '') - { - if ($suffix = Kohana::config('core.url_suffix') AND strpos(Router::$current_uri, $suffix) !== FALSE) - { - // Remove the URL suffix - Router::$current_uri = preg_replace('#'.preg_quote($suffix).'$#u', '', Router::$current_uri); - - // Set the URL suffix - Router::$url_suffix = $suffix; - } - - // Reduce multiple slashes into single slashes - Router::$current_uri = preg_replace('#//+#', '/', Router::$current_uri); - } - } - - /** - * Generates routed URI from given URI. - * - * @param string URI to convert - * @return string Routed uri - */ - public static function routed_uri($uri) - { - if (Router::$routes === NULL) - { - // Load routes - Router::$routes = Kohana::config('routes'); - } - - // Prepare variables - $routed_uri = $uri = trim($uri, '/'); - - if (isset(Router::$routes[$uri])) - { - // Literal match, no need for regex - $routed_uri = Router::$routes[$uri]; - } - else - { - // Loop through the routes and see if anything matches - foreach (Router::$routes as $key => $val) - { - if ($key === '_default') continue; - - // Trim slashes - $key = trim($key, '/'); - $val = trim($val, '/'); - - if (preg_match('#^'.$key.'$#u', $uri)) - { - if (strpos($val, '$') !== FALSE) - { - // Use regex routing - $routed_uri = preg_replace('#^'.$key.'$#u', $val, $uri); - } - else - { - // Standard routing - $routed_uri = $val; - } - - // A valid route has been found - break; - } - } - } - - if (isset(Router::$routes[$routed_uri])) - { - // Check for double routing (without regex) - $routed_uri = Router::$routes[$routed_uri]; - } - - return trim($routed_uri, '/'); - } - -} // End Router
\ No newline at end of file diff --git a/kohana/libraries/Session.php b/kohana/libraries/Session.php deleted file mode 100644 index e03f5dff..00000000 --- a/kohana/libraries/Session.php +++ /dev/null @@ -1,458 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session library. - * - * $Id: Session.php 4073 2009-03-13 17:53:58Z Shadowhand $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Core { - - // Session singleton - protected static $instance; - - // Protected key names (cannot be set by the user) - protected static $protect = array('session_id', 'user_agent', 'last_activity', 'ip_address', 'total_hits', '_kf_flash_'); - - // Configuration and driver - protected static $config; - protected static $driver; - - // Flash variables - protected static $flash; - - // Input library - protected $input; - - /** - * Singleton instance of Session. - */ - public static function instance() - { - if (Session::$instance == NULL) - { - // Create a new instance - new Session; - } - - return Session::$instance; - } - - /** - * On first session instance creation, sets up the driver and creates session. - */ - public function __construct() - { - $this->input = Input::instance(); - - // This part only needs to be run once - if (Session::$instance === NULL) - { - // Load config - Session::$config = Kohana::config('session'); - - // Makes a mirrored array, eg: foo=foo - Session::$protect = array_combine(Session::$protect, Session::$protect); - - // Configure garbage collection - ini_set('session.gc_probability', (int) Session::$config['gc_probability']); - ini_set('session.gc_divisor', 100); - ini_set('session.gc_maxlifetime', (Session::$config['expiration'] == 0) ? 86400 : Session::$config['expiration']); - - // Create a new session - $this->create(); - - if (Session::$config['regenerate'] > 0 AND ($_SESSION['total_hits'] % Session::$config['regenerate']) === 0) - { - // Regenerate session id and update session cookie - $this->regenerate(); - } - else - { - // Always update session cookie to keep the session alive - cookie::set(Session::$config['name'], $_SESSION['session_id'], Session::$config['expiration']); - } - - // Close the session just before sending the headers, so that - // the session cookie(s) can be written. - Event::add('system.send_headers', array($this, 'write_close')); - - // Make sure that sessions are closed before exiting - register_shutdown_function(array($this, 'write_close')); - - // Singleton instance - Session::$instance = $this; - } - - Kohana::log('debug', 'Session Library initialized'); - } - - /** - * Get the session id. - * - * @return string - */ - public function id() - { - return $_SESSION['session_id']; - } - - /** - * Create a new session. - * - * @param array variables to set after creation - * @return void - */ - public function create($vars = NULL) - { - // Destroy any current sessions - $this->destroy(); - - if (Session::$config['driver'] !== 'native') - { - // Set driver name - $driver = 'Session_'.ucfirst(Session::$config['driver']).'_Driver'; - - // Load the driver - if ( ! Kohana::auto_load($driver)) - throw new Kohana_Exception('core.driver_not_found', Session::$config['driver'], get_class($this)); - - // Initialize the driver - Session::$driver = new $driver(); - - // Validate the driver - if ( ! (Session::$driver instanceof Session_Driver)) - throw new Kohana_Exception('core.driver_implements', Session::$config['driver'], get_class($this), 'Session_Driver'); - - // Register non-native driver as the session handler - session_set_save_handler - ( - array(Session::$driver, 'open'), - array(Session::$driver, 'close'), - array(Session::$driver, 'read'), - array(Session::$driver, 'write'), - array(Session::$driver, 'destroy'), - array(Session::$driver, 'gc') - ); - } - - // Validate the session name - if ( ! preg_match('~^(?=.*[a-z])[a-z0-9_]++$~iD', Session::$config['name'])) - throw new Kohana_Exception('session.invalid_session_name', Session::$config['name']); - - // Name the session, this will also be the name of the cookie - session_name(Session::$config['name']); - - // Set the session cookie parameters - session_set_cookie_params - ( - Session::$config['expiration'], - Kohana::config('cookie.path'), - Kohana::config('cookie.domain'), - Kohana::config('cookie.secure'), - Kohana::config('cookie.httponly') - ); - - // Start the session! - session_start(); - - // Put session_id in the session variable - $_SESSION['session_id'] = session_id(); - - // Set defaults - if ( ! isset($_SESSION['_kf_flash_'])) - { - $_SESSION['total_hits'] = 0; - $_SESSION['_kf_flash_'] = array(); - - $_SESSION['user_agent'] = Kohana::$user_agent; - $_SESSION['ip_address'] = $this->input->ip_address(); - } - - // Set up flash variables - Session::$flash =& $_SESSION['_kf_flash_']; - - // Increase total hits - $_SESSION['total_hits'] += 1; - - // Validate data only on hits after one - if ($_SESSION['total_hits'] > 1) - { - // Validate the session - foreach (Session::$config['validate'] as $valid) - { - switch ($valid) - { - // Check user agent for consistency - case 'user_agent': - if ($_SESSION[$valid] !== Kohana::$user_agent) - return $this->create(); - break; - - // Check ip address for consistency - case 'ip_address': - if ($_SESSION[$valid] !== $this->input->$valid()) - return $this->create(); - break; - - // Check expiration time to prevent users from manually modifying it - case 'expiration': - if (time() - $_SESSION['last_activity'] > ini_get('session.gc_maxlifetime')) - return $this->create(); - break; - } - } - } - - // Expire flash keys - $this->expire_flash(); - - // Update last activity - $_SESSION['last_activity'] = time(); - - // Set the new data - Session::set($vars); - } - - /** - * Regenerates the global session id. - * - * @return void - */ - public function regenerate() - { - if (Session::$config['driver'] === 'native') - { - // Generate a new session id - // Note: also sets a new session cookie with the updated id - session_regenerate_id(TRUE); - - // Update session with new id - $_SESSION['session_id'] = session_id(); - } - else - { - // Pass the regenerating off to the driver in case it wants to do anything special - $_SESSION['session_id'] = Session::$driver->regenerate(); - } - - // Get the session name - $name = session_name(); - - if (isset($_COOKIE[$name])) - { - // Change the cookie value to match the new session id to prevent "lag" - $_COOKIE[$name] = $_SESSION['session_id']; - } - } - - /** - * Destroys the current session. - * - * @return void - */ - public function destroy() - { - if (session_id() !== '') - { - // Get the session name - $name = session_name(); - - // Destroy the session - session_destroy(); - - // Re-initialize the array - $_SESSION = array(); - - // Delete the session cookie - cookie::delete($name); - } - } - - /** - * Runs the system.session_write event, then calls session_write_close. - * - * @return void - */ - public function write_close() - { - static $run; - - if ($run === NULL) - { - $run = TRUE; - - // Run the events that depend on the session being open - Event::run('system.session_write'); - - // Expire flash keys - $this->expire_flash(); - - // Close the session - session_write_close(); - } - } - - /** - * Set a session variable. - * - * @param string|array key, or array of values - * @param mixed value (if keys is not an array) - * @return void - */ - public function set($keys, $val = FALSE) - { - if (empty($keys)) - return FALSE; - - if ( ! is_array($keys)) - { - $keys = array($keys => $val); - } - - foreach ($keys as $key => $val) - { - if (isset(Session::$protect[$key])) - continue; - - // Set the key - $_SESSION[$key] = $val; - } - } - - /** - * Set a flash variable. - * - * @param string|array key, or array of values - * @param mixed value (if keys is not an array) - * @return void - */ - public function set_flash($keys, $val = FALSE) - { - if (empty($keys)) - return FALSE; - - if ( ! is_array($keys)) - { - $keys = array($keys => $val); - } - - foreach ($keys as $key => $val) - { - if ($key == FALSE) - continue; - - Session::$flash[$key] = 'new'; - Session::set($key, $val); - } - } - - /** - * Freshen one, multiple or all flash variables. - * - * @param string variable key(s) - * @return void - */ - public function keep_flash($keys = NULL) - { - $keys = ($keys === NULL) ? array_keys(Session::$flash) : func_get_args(); - - foreach ($keys as $key) - { - if (isset(Session::$flash[$key])) - { - Session::$flash[$key] = 'new'; - } - } - } - - /** - * Expires old flash data and removes it from the session. - * - * @return void - */ - public function expire_flash() - { - static $run; - - // Method can only be run once - if ($run === TRUE) - return; - - if ( ! empty(Session::$flash)) - { - foreach (Session::$flash as $key => $state) - { - if ($state === 'old') - { - // Flash has expired - unset(Session::$flash[$key], $_SESSION[$key]); - } - else - { - // Flash will expire - Session::$flash[$key] = 'old'; - } - } - } - - // Method has been run - $run = TRUE; - } - - /** - * Get a variable. Access to sub-arrays is supported with key.subkey. - * - * @param string variable key - * @param mixed default value returned if variable does not exist - * @return mixed Variable data if key specified, otherwise array containing all session data. - */ - public function get($key = FALSE, $default = FALSE) - { - if (empty($key)) - return $_SESSION; - - $result = isset($_SESSION[$key]) ? $_SESSION[$key] : Kohana::key_string($_SESSION, $key); - - return ($result === NULL) ? $default : $result; - } - - /** - * Get a variable, and delete it. - * - * @param string variable key - * @param mixed default value returned if variable does not exist - * @return mixed - */ - public function get_once($key, $default = FALSE) - { - $return = Session::get($key, $default); - Session::delete($key); - - return $return; - } - - /** - * Delete one or more variables. - * - * @param string variable key(s) - * @return void - */ - public function delete($keys) - { - $args = func_get_args(); - - foreach ($args as $key) - { - if (isset(Session::$protect[$key])) - continue; - - // Unset the key - unset($_SESSION[$key]); - } - } - -} // End Session Class diff --git a/kohana/libraries/URI.php b/kohana/libraries/URI.php deleted file mode 100644 index d9ccdcf7..00000000 --- a/kohana/libraries/URI.php +++ /dev/null @@ -1,279 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * URI library. - * - * $Id: URI.php 4072 2009-03-13 17:20:38Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class URI_Core extends Router { - - /** - * Returns a singleton instance of URI. - * - * @return object - */ - public static function instance() - { - static $instance; - - if ($instance == NULL) - { - // Initialize the URI instance - $instance = new URI; - } - - return $instance; - } - - /** - * Retrieve a specific URI segment. - * - * @param integer|string segment number or label - * @param mixed default value returned if segment does not exist - * @return string - */ - public function segment($index = 1, $default = FALSE) - { - if (is_string($index)) - { - if (($key = array_search($index, URI::$segments)) === FALSE) - return $default; - - $index = $key + 2; - } - - $index = (int) $index - 1; - - return isset(URI::$segments[$index]) ? URI::$segments[$index] : $default; - } - - /** - * Retrieve a specific routed URI segment. - * - * @param integer|string rsegment number or label - * @param mixed default value returned if segment does not exist - * @return string - */ - public function rsegment($index = 1, $default = FALSE) - { - if (is_string($index)) - { - if (($key = array_search($index, URI::$rsegments)) === FALSE) - return $default; - - $index = $key + 2; - } - - $index = (int) $index - 1; - - return isset(URI::$rsegments[$index]) ? URI::$rsegments[$index] : $default; - } - - /** - * Retrieve a specific URI argument. - * This is the part of the segments that does not indicate controller or method - * - * @param integer|string argument number or label - * @param mixed default value returned if segment does not exist - * @return string - */ - public function argument($index = 1, $default = FALSE) - { - if (is_string($index)) - { - if (($key = array_search($index, URI::$arguments)) === FALSE) - return $default; - - $index = $key + 2; - } - - $index = (int) $index - 1; - - return isset(URI::$arguments[$index]) ? URI::$arguments[$index] : $default; - } - - /** - * Returns an array containing all the URI segments. - * - * @param integer segment offset - * @param boolean return an associative array - * @return array - */ - public function segment_array($offset = 0, $associative = FALSE) - { - return $this->build_array(URI::$segments, $offset, $associative); - } - - /** - * Returns an array containing all the re-routed URI segments. - * - * @param integer rsegment offset - * @param boolean return an associative array - * @return array - */ - public function rsegment_array($offset = 0, $associative = FALSE) - { - return $this->build_array(URI::$rsegments, $offset, $associative); - } - - /** - * Returns an array containing all the URI arguments. - * - * @param integer segment offset - * @param boolean return an associative array - * @return array - */ - public function argument_array($offset = 0, $associative = FALSE) - { - return $this->build_array(URI::$arguments, $offset, $associative); - } - - /** - * Creates a simple or associative array from an array and an offset. - * Used as a helper for (r)segment_array and argument_array. - * - * @param array array to rebuild - * @param integer offset to start from - * @param boolean create an associative array - * @return array - */ - public function build_array($array, $offset = 0, $associative = FALSE) - { - // Prevent the keys from being improperly indexed - array_unshift($array, 0); - - // Slice the array, preserving the keys - $array = array_slice($array, $offset + 1, count($array) - 1, TRUE); - - if ($associative === FALSE) - return $array; - - $associative = array(); - $pairs = array_chunk($array, 2); - - foreach ($pairs as $pair) - { - // Add the key/value pair to the associative array - $associative[$pair[0]] = isset($pair[1]) ? $pair[1] : ''; - } - - return $associative; - } - - /** - * Returns the complete URI as a string. - * - * @return string - */ - public function string() - { - return URI::$current_uri; - } - - /** - * Magic method for converting an object to a string. - * - * @return string - */ - public function __toString() - { - return URI::$current_uri; - } - - /** - * Returns the total number of URI segments. - * - * @return integer - */ - public function total_segments() - { - return count(URI::$segments); - } - - /** - * Returns the total number of re-routed URI segments. - * - * @return integer - */ - public function total_rsegments() - { - return count(URI::$rsegments); - } - - /** - * Returns the total number of URI arguments. - * - * @return integer - */ - public function total_arguments() - { - return count(URI::$arguments); - } - - /** - * Returns the last URI segment. - * - * @param mixed default value returned if segment does not exist - * @return string - */ - public function last_segment($default = FALSE) - { - if (($end = $this->total_segments()) < 1) - return $default; - - return URI::$segments[$end - 1]; - } - - /** - * Returns the last re-routed URI segment. - * - * @param mixed default value returned if segment does not exist - * @return string - */ - public function last_rsegment($default = FALSE) - { - if (($end = $this->total_segments()) < 1) - return $default; - - return URI::$rsegments[$end - 1]; - } - - /** - * Returns the path to the current controller (not including the actual - * controller), as a web path. - * - * @param boolean return a full url, or only the path specifically - * @return string - */ - public function controller_path($full = TRUE) - { - return ($full) ? url::site(URI::$controller_path) : URI::$controller_path; - } - - /** - * Returns the current controller, as a web path. - * - * @param boolean return a full url, or only the controller specifically - * @return string - */ - public function controller($full = TRUE) - { - return ($full) ? url::site(URI::$controller_path.URI::$controller) : URI::$controller; - } - - /** - * Returns the current method, as a web path. - * - * @param boolean return a full url, or only the method specifically - * @return string - */ - public function method($full = TRUE) - { - return ($full) ? url::site(URI::$controller_path.URI::$controller.'/'.URI::$method) : URI::$method; - } - -} // End URI Class diff --git a/kohana/libraries/Validation.php b/kohana/libraries/Validation.php deleted file mode 100644 index 5a48bfc5..00000000 --- a/kohana/libraries/Validation.php +++ /dev/null @@ -1,826 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Validation library. - * - * $Id: Validation.php 4120 2009-03-25 19:22:31Z jheathco $ - * - * @package Validation - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Validation_Core extends ArrayObject { - - // Filters - protected $pre_filters = array(); - protected $post_filters = array(); - - // Rules and callbacks - protected $rules = array(); - protected $callbacks = array(); - - // Rules that are allowed to run on empty fields - protected $empty_rules = array('required', 'matches'); - - // Errors - protected $errors = array(); - protected $messages = array(); - - // Fields that are expected to be arrays - protected $array_fields = array(); - - // Checks if there is data to validate. - protected $submitted; - - /** - * Creates a new Validation instance. - * - * @param array array to use for validation - * @return object - */ - public static function factory(array $array) - { - return new Validation($array); - } - - /** - * Sets the unique "any field" key and creates an ArrayObject from the - * passed array. - * - * @param array array to validate - * @return void - */ - public function __construct(array $array) - { - // The array is submitted if the array is not empty - $this->submitted = ! empty($array); - - parent::__construct($array, ArrayObject::ARRAY_AS_PROPS | ArrayObject::STD_PROP_LIST); - } - - /** - * Magic clone method, clears errors and messages. - * - * @return void - */ - public function __clone() - { - $this->errors = array(); - $this->messages = array(); - } - - /** - * Create a copy of the current validation rules and change the array. - * - * @chainable - * @param array new array to validate - * @return Validation - */ - public function copy(array $array) - { - $copy = clone $this; - - $copy->exchangeArray($array); - - return $copy; - } - - /** - * Test if the data has been submitted. - * - * @return boolean - */ - public function submitted($value = NULL) - { - if (is_bool($value)) - { - $this->submitted = $value; - } - - return $this->submitted; - } - - /** - * Returns an array of all the field names that have filters, rules, or callbacks. - * - * @return array - */ - public function field_names() - { - // All the fields that are being validated - $fields = array_keys(array_merge - ( - $this->pre_filters, - $this->rules, - $this->callbacks, - $this->post_filters - )); - - // Remove wildcard fields - $fields = array_diff($fields, array('*')); - - return $fields; - } - - /** - * Returns the array values of the current object. - * - * @return array - */ - public function as_array() - { - return $this->getArrayCopy(); - } - - /** - * Returns the ArrayObject values, removing all inputs without rules. - * To choose specific inputs, list the field name as arguments. - * - * @param boolean return only fields with filters, rules, and callbacks - * @return array - */ - public function safe_array() - { - // Load choices - $choices = func_get_args(); - $choices = empty($choices) ? NULL : array_combine($choices, $choices); - - // Get field names - $fields = $this->field_names(); - - $safe = array(); - foreach ($fields as $field) - { - if ($choices === NULL OR isset($choices[$field])) - { - if (isset($this[$field])) - { - $value = $this[$field]; - - if (is_object($value)) - { - // Convert the value back into an array - $value = $value->getArrayCopy(); - } - } - else - { - // Even if the field is not in this array, it must be set - $value = NULL; - } - - // Add the field to the array - $safe[$field] = $value; - } - } - - return $safe; - } - - /** - * Add additional rules that will forced, even for empty fields. All arguments - * passed will be appended to the list. - * - * @chainable - * @param string rule name - * @return object - */ - public function allow_empty_rules($rules) - { - // Any number of args are supported - $rules = func_get_args(); - - // Merge the allowed rules - $this->empty_rules = array_merge($this->empty_rules, $rules); - - return $this; - } - - /** - * Converts a filter, rule, or callback into a fully-qualified callback array. - * - * @return mixed - */ - protected function callback($callback) - { - if (is_string($callback)) - { - if (strpos($callback, '::') !== FALSE) - { - $callback = explode('::', $callback); - } - elseif (function_exists($callback)) - { - // No need to check if the callback is a method - $callback = $callback; - } - elseif (method_exists($this, $callback)) - { - // The callback exists in Validation - $callback = array($this, $callback); - } - elseif (method_exists('valid', $callback)) - { - // The callback exists in valid:: - $callback = array('valid', $callback); - } - } - - if ( ! is_callable($callback, FALSE)) - { - if (is_array($callback)) - { - if (is_object($callback[0])) - { - // Object instance syntax - $name = get_class($callback[0]).'->'.$callback[1]; - } - else - { - // Static class syntax - $name = $callback[0].'::'.$callback[1]; - } - } - else - { - // Function syntax - $name = $callback; - } - - throw new Kohana_Exception('validation.not_callable', $name); - } - - return $callback; - } - - /** - * Add a pre-filter to one or more inputs. Pre-filters are applied before - * rules or callbacks are executed. - * - * @chainable - * @param callback filter - * @param string fields to apply filter to, use TRUE for all fields - * @return object - */ - public function pre_filter($filter, $field = TRUE) - { - if ($field === TRUE OR $field === '*') - { - // Use wildcard - $fields = array('*'); - } - else - { - // Add the filter to specific inputs - $fields = func_get_args(); - $fields = array_slice($fields, 1); - } - - // Convert to a proper callback - $filter = $this->callback($filter); - - foreach ($fields as $field) - { - // Add the filter to specified field - $this->pre_filters[$field][] = $filter; - } - - return $this; - } - - /** - * Add a post-filter to one or more inputs. Post-filters are applied after - * rules and callbacks have been executed. - * - * @chainable - * @param callback filter - * @param string fields to apply filter to, use TRUE for all fields - * @return object - */ - public function post_filter($filter, $field = TRUE) - { - if ($field === TRUE) - { - // Use wildcard - $fields = array('*'); - } - else - { - // Add the filter to specific inputs - $fields = func_get_args(); - $fields = array_slice($fields, 1); - } - - // Convert to a proper callback - $filter = $this->callback($filter); - - foreach ($fields as $field) - { - // Add the filter to specified field - $this->post_filters[$field][] = $filter; - } - - return $this; - } - - /** - * Add rules to a field. Validation rules may only return TRUE or FALSE and - * can not manipulate the value of a field. - * - * @chainable - * @param string field name - * @param callback rules (one or more arguments) - * @return object - */ - public function add_rules($field, $rules) - { - // Get the rules - $rules = func_get_args(); - $rules = array_slice($rules, 1); - - if ($field === TRUE) - { - // Use wildcard - $field = '*'; - } - - foreach ($rules as $rule) - { - // Arguments for rule - $args = NULL; - - if (is_string($rule)) - { - if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) - { - // Split the rule into the function and args - $rule = $matches[1]; - $args = preg_split('/(?<!\\\\),\s*/', $matches[2]); - - // Replace escaped comma with comma - $args = str_replace('\,', ',', $args); - } - } - - if ($rule === 'is_array') - { - // This field is expected to be an array - $this->array_fields[$field] = $field; - } - - // Convert to a proper callback - $rule = $this->callback($rule); - - // Add the rule, with args, to the field - $this->rules[$field][] = array($rule, $args); - } - - return $this; - } - - /** - * Add callbacks to a field. Callbacks must accept the Validation object - * and the input name. Callback returns are not processed. - * - * @chainable - * @param string field name - * @param callbacks callbacks (unlimited number) - * @return object - */ - public function add_callbacks($field, $callbacks) - { - // Get all callbacks as an array - $callbacks = func_get_args(); - $callbacks = array_slice($callbacks, 1); - - if ($field === TRUE) - { - // Use wildcard - $field = '*'; - } - - foreach ($callbacks as $callback) - { - // Convert to a proper callback - $callback = $this->callback($callback); - - // Add the callback to specified field - $this->callbacks[$field][] = $callback; - } - - return $this; - } - - /** - * Validate by processing pre-filters, rules, callbacks, and post-filters. - * All fields that have filters, rules, or callbacks will be initialized if - * they are undefined. Validation will only be run if there is data already - * in the array. - * - * @param object Validation object, used only for recursion - * @param object name of field for errors - * @return bool - */ - public function validate($object = NULL, $field_name = NULL) - { - if ($object === NULL) - { - // Use the current object - $object = $this; - } - - // Get all field names - $fields = $this->field_names(); - - // Copy the array from the object, to optimize multiple sets - $array = $this->getArrayCopy(); - - foreach ($fields as $field) - { - if ($field === '*') - { - // Ignore wildcard - continue; - } - - if ( ! isset($array[$field])) - { - if (isset($this->array_fields[$field])) - { - // This field must be an array - $array[$field] = array(); - } - else - { - $array[$field] = NULL; - } - } - } - - // Swap the array back into the object - $this->exchangeArray($array); - - // Get all defined field names - $fields = array_keys($array); - - foreach ($this->pre_filters as $field => $callbacks) - { - foreach ($callbacks as $callback) - { - if ($field === '*') - { - foreach ($fields as $f) - { - $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); - } - } - else - { - $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); - } - } - } - - if ($this->submitted === FALSE) - return FALSE; - - foreach ($this->rules as $field => $callbacks) - { - foreach ($callbacks as $callback) - { - // Separate the callback and arguments - list ($callback, $args) = $callback; - - // Function or method name of the rule - $rule = is_array($callback) ? $callback[1] : $callback; - - if ($field === '*') - { - foreach ($fields as $f) - { - // Note that continue, instead of break, is used when - // applying rules using a wildcard, so that all fields - // will be validated. - - if (isset($this->errors[$f])) - { - // Prevent other rules from being evaluated if an error has occurred - continue; - } - - if (empty($this[$f]) AND ! in_array($rule, $this->empty_rules)) - { - // This rule does not need to be processed on empty fields - continue; - } - - if ($args === NULL) - { - if ( ! call_user_func($callback, $this[$f])) - { - $this->errors[$f] = $rule; - - // Stop validating this field when an error is found - continue; - } - } - else - { - if ( ! call_user_func($callback, $this[$f], $args)) - { - $this->errors[$f] = $rule; - - // Stop validating this field when an error is found - continue; - } - } - } - } - else - { - if (isset($this->errors[$field])) - { - // Prevent other rules from being evaluated if an error has occurred - break; - } - - if ( ! in_array($rule, $this->empty_rules) AND ! $this->required($this[$field])) - { - // This rule does not need to be processed on empty fields - continue; - } - - if ($args === NULL) - { - if ( ! call_user_func($callback, $this[$field])) - { - $this->errors[$field] = $rule; - - // Stop validating this field when an error is found - break; - } - } - else - { - if ( ! call_user_func($callback, $this[$field], $args)) - { - $this->errors[$field] = $rule; - - // Stop validating this field when an error is found - break; - } - } - } - } - } - - foreach ($this->callbacks as $field => $callbacks) - { - foreach ($callbacks as $callback) - { - if ($field === '*') - { - foreach ($fields as $f) - { - // Note that continue, instead of break, is used when - // applying rules using a wildcard, so that all fields - // will be validated. - - if (isset($this->errors[$f])) - { - // Stop validating this field when an error is found - continue; - } - - call_user_func($callback, $this, $f); - } - } - else - { - if (isset($this->errors[$field])) - { - // Stop validating this field when an error is found - break; - } - - call_user_func($callback, $this, $field); - } - } - } - - foreach ($this->post_filters as $field => $callbacks) - { - foreach ($callbacks as $callback) - { - if ($field === '*') - { - foreach ($fields as $f) - { - $this[$f] = is_array($this[$f]) ? array_map($callback, $this[$f]) : call_user_func($callback, $this[$f]); - } - } - else - { - $this[$field] = is_array($this[$field]) ? array_map($callback, $this[$field]) : call_user_func($callback, $this[$field]); - } - } - } - - // Return TRUE if there are no errors - return $this->errors === array(); - } - - /** - * Add an error to an input. - * - * @chainable - * @param string input name - * @param string unique error name - * @return object - */ - public function add_error($field, $name) - { - $this->errors[$field] = $name; - - return $this; - } - - /** - * Sets or returns the message for an input. - * - * @chainable - * @param string input key - * @param string message to set - * @return string|object - */ - public function message($input = NULL, $message = NULL) - { - if ($message === NULL) - { - if ($input === NULL) - { - $messages = array(); - $keys = array_keys($this->messages); - - foreach ($keys as $input) - { - $messages[] = $this->message($input); - } - - return implode("\n", $messages); - } - - // Return nothing if no message exists - if (empty($this->messages[$input])) - return ''; - - // Return the HTML message string - return $this->messages[$input]; - } - else - { - $this->messages[$input] = $message; - } - - return $this; - } - - /** - * Return the errors array. - * - * @param boolean load errors from a lang file - * @return array - */ - public function errors($file = NULL) - { - if ($file === NULL) - { - return $this->errors; - } - else - { - - $errors = array(); - foreach ($this->errors as $input => $error) - { - // Key for this input error - $key = "$file.$input.$error"; - - if (($errors[$input] = Kohana::lang($key)) === $key) - { - // Get the default error message - $errors[$input] = Kohana::lang("$file.$input.default"); - } - } - - return $errors; - } - } - - /** - * Rule: required. Generates an error if the field has an empty value. - * - * @param mixed input value - * @return bool - */ - public function required($str) - { - if (is_object($str) AND $str instanceof ArrayObject) - { - // Get the array from the ArrayObject - $str = $str->getArrayCopy(); - } - - if (is_array($str)) - { - return ! empty($str); - } - else - { - return ! ($str === '' OR $str === NULL OR $str === FALSE); - } - } - - /** - * Rule: matches. Generates an error if the field does not match one or more - * other fields. - * - * @param mixed input value - * @param array input names to match against - * @return bool - */ - public function matches($str, array $inputs) - { - foreach ($inputs as $key) - { - if ($str !== (isset($this[$key]) ? $this[$key] : NULL)) - return FALSE; - } - - return TRUE; - } - - /** - * Rule: length. Generates an error if the field is too long or too short. - * - * @param mixed input value - * @param array minimum, maximum, or exact length to match - * @return bool - */ - public function length($str, array $length) - { - if ( ! is_string($str)) - return FALSE; - - $size = utf8::strlen($str); - $status = FALSE; - - if (count($length) > 1) - { - list ($min, $max) = $length; - - if ($size >= $min AND $size <= $max) - { - $status = TRUE; - } - } - else - { - $status = ($size === (int) $length[0]); - } - - return $status; - } - - /** - * Rule: depends_on. Generates an error if the field does not depend on one - * or more other fields. - * - * @param mixed field name - * @param array field names to check dependency - * @return bool - */ - public function depends_on($field, array $fields) - { - foreach ($fields as $depends_on) - { - if ( ! isset($this[$depends_on]) OR $this[$depends_on] == NULL) - return FALSE; - } - - return TRUE; - } - - /** - * Rule: chars. Generates an error if the field contains characters outside of the list. - * - * @param string field value - * @param array allowed characters - * @return bool - */ - public function chars($value, array $chars) - { - return ! preg_match('![^'.implode('', $chars).']!u', $value); - } - -} // End Validation diff --git a/kohana/libraries/View.php b/kohana/libraries/View.php deleted file mode 100644 index 2b8471c6..00000000 --- a/kohana/libraries/View.php +++ /dev/null @@ -1,309 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Loads and displays Kohana view files. Can also handle output of some binary - * files, such as image, Javascript, and CSS files. - * - * $Id: View.php 4072 2009-03-13 17:20:38Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class View_Core { - - // The view file name and type - protected $kohana_filename = FALSE; - protected $kohana_filetype = FALSE; - - // View variable storage - protected $kohana_local_data = array(); - protected static $kohana_global_data = array(); - - /** - * Creates a new View using the given parameters. - * - * @param string view name - * @param array pre-load data - * @param string type of file: html, css, js, etc. - * @return object - */ - public static function factory($name = NULL, $data = NULL, $type = NULL) - { - return new View($name, $data, $type); - } - - /** - * Attempts to load a view and pre-load view data. - * - * @throws Kohana_Exception if the requested view cannot be found - * @param string view name - * @param array pre-load data - * @param string type of file: html, css, js, etc. - * @return void - */ - public function __construct($name = NULL, $data = NULL, $type = NULL) - { - if (is_string($name) AND $name !== '') - { - // Set the filename - $this->set_filename($name, $type); - } - - if (is_array($data) AND ! empty($data)) - { - // Preload data using array_merge, to allow user extensions - $this->kohana_local_data = array_merge($this->kohana_local_data, $data); - } - } - - /** - * Magic method access to test for view property - * - * @param string View property to test for - * @return boolean - */ - public function __isset($key = NULL) - { - return $this->is_set($key); - } - - /** - * Sets the view filename. - * - * @chainable - * @param string view filename - * @param string view file type - * @return object - */ - public function set_filename($name, $type = NULL) - { - if ($type == NULL) - { - // Load the filename and set the content type - $this->kohana_filename = Kohana::find_file('views', $name, TRUE); - $this->kohana_filetype = EXT; - } - else - { - // Check if the filetype is allowed by the configuration - if ( ! in_array($type, Kohana::config('view.allowed_filetypes'))) - throw new Kohana_Exception('core.invalid_filetype', $type); - - // Load the filename and set the content type - $this->kohana_filename = Kohana::find_file('views', $name, TRUE, $type); - $this->kohana_filetype = Kohana::config('mimes.'.$type); - - if ($this->kohana_filetype == NULL) - { - // Use the specified type - $this->kohana_filetype = $type; - } - } - - return $this; - } - - /** - * Sets a view variable. - * - * @param string|array name of variable or an array of variables - * @param mixed value when using a named variable - * @return object - */ - public function set($name, $value = NULL) - { - if (is_array($name)) - { - foreach ($name as $key => $value) - { - $this->__set($key, $value); - } - } - else - { - $this->__set($name, $value); - } - - return $this; - } - - /** - * Checks for a property existence in the view locally or globally. Unlike the built in __isset(), - * this method can take an array of properties to test simultaneously. - * - * @param string $key property name to test for - * @param array $key array of property names to test for - * @return boolean property test result - * @return array associative array of keys and boolean test result - */ - public function is_set( $key = FALSE ) - { - // Setup result; - $result = FALSE; - - // If key is an array - if (is_array($key)) - { - // Set the result to an array - $result = array(); - - // Foreach key - foreach ($key as $property) - { - // Set the result to an associative array - $result[$property] = (array_key_exists($property, $this->kohana_local_data) OR array_key_exists($property, View::$kohana_global_data)) ? TRUE : FALSE; - } - } - else - { - // Otherwise just check one property - $result = (array_key_exists($key, $this->kohana_local_data) OR array_key_exists($key, View::$kohana_global_data)) ? TRUE : FALSE; - } - - // Return the result - return $result; - } - - /** - * Sets a bound variable by reference. - * - * @param string name of variable - * @param mixed variable to assign by reference - * @return object - */ - public function bind($name, & $var) - { - $this->kohana_local_data[$name] =& $var; - - return $this; - } - - /** - * Sets a view global variable. - * - * @param string|array name of variable or an array of variables - * @param mixed value when using a named variable - * @return void - */ - public static function set_global($name, $value = NULL) - { - if (is_array($name)) - { - foreach ($name as $key => $value) - { - View::$kohana_global_data[$key] = $value; - } - } - else - { - View::$kohana_global_data[$name] = $value; - } - } - - /** - * Magically sets a view variable. - * - * @param string variable key - * @param string variable value - * @return void - */ - public function __set($key, $value) - { - $this->kohana_local_data[$key] = $value; - } - - /** - * Magically gets a view variable. - * - * @param string variable key - * @return mixed variable value if the key is found - * @return void if the key is not found - */ - public function &__get($key) - { - if (isset($this->kohana_local_data[$key])) - return $this->kohana_local_data[$key]; - - if (isset(View::$kohana_global_data[$key])) - return View::$kohana_global_data[$key]; - - if (isset($this->$key)) - return $this->$key; - } - - /** - * Magically converts view object to string. - * - * @return string - */ - public function __toString() - { - try - { - return $this->render(); - } - catch (Exception $e) - { - // Display the exception using its internal __toString method - return (string) $e; - } - } - - /** - * Renders a view. - * - * @param boolean set to TRUE to echo the output instead of returning it - * @param callback special renderer to pass the output through - * @return string if print is FALSE - * @return void if print is TRUE - */ - public function render($print = FALSE, $renderer = FALSE) - { - if (empty($this->kohana_filename)) - throw new Kohana_Exception('core.view_set_filename'); - - if (is_string($this->kohana_filetype)) - { - // Merge global and local data, local overrides global with the same name - $data = array_merge(View::$kohana_global_data, $this->kohana_local_data); - - // Load the view in the controller for access to $this - $output = Kohana::$instance->_kohana_load_view($this->kohana_filename, $data); - - if ($renderer !== FALSE AND is_callable($renderer, TRUE)) - { - // Pass the output through the user defined renderer - $output = call_user_func($renderer, $output); - } - - if ($print === TRUE) - { - // Display the output - echo $output; - return; - } - } - else - { - // Set the content type and size - header('Content-Type: '.$this->kohana_filetype[0]); - - if ($print === TRUE) - { - if ($file = fopen($this->kohana_filename, 'rb')) - { - // Display the output - fpassthru($file); - fclose($file); - } - return; - } - - // Fetch the file contents - $output = file_get_contents($this->kohana_filename); - } - - return $output; - } -} // End View
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache.php b/kohana/libraries/drivers/Cache.php deleted file mode 100644 index 7c5e3c31..00000000 --- a/kohana/libraries/drivers/Cache.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Cache driver interface. - * - * $Id: Cache.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -interface Cache_Driver { - - /** - * Set a cache item. - */ - public function set($id, $data, array $tags = NULL, $lifetime); - - /** - * Find all of the cache ids for a given tag. - */ - public function find($tag); - - /** - * Get a cache item. - * Return NULL if the cache item is not found. - */ - public function get($id); - - /** - * Delete cache items by id or tag. - */ - public function delete($id, $tag = FALSE); - - /** - * Deletes all expired cache items. - */ - public function delete_expired(); - -} // End Cache Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Apc.php b/kohana/libraries/drivers/Cache/Apc.php deleted file mode 100644 index f7be048f..00000000 --- a/kohana/libraries/drivers/Cache/Apc.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * APC-based Cache driver. - * - * $Id: Apc.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Apc_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('apc')) - throw new Kohana_Exception('cache.extension_not_loaded', 'apc'); - } - - public function get($id) - { - return (($return = apc_fetch($id)) === FALSE) ? NULL : $return; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - } - - return apc_store($id, $data, $lifetime); - } - - public function find($tag) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - - return array(); - } - - public function delete($id, $tag = FALSE) - { - if ($tag === TRUE) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - return FALSE; - } - elseif ($id === TRUE) - { - return apc_clear_cache('user'); - } - else - { - return apc_delete($id); - } - } - - public function delete_expired() - { - return TRUE; - } - -} // End Cache APC Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Eaccelerator.php b/kohana/libraries/drivers/Cache/Eaccelerator.php deleted file mode 100644 index a45616d5..00000000 --- a/kohana/libraries/drivers/Cache/Eaccelerator.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Eaccelerator-based Cache driver. - * - * $Id: Eaccelerator.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Eaccelerator_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('eaccelerator')) - throw new Kohana_Exception('cache.extension_not_loaded', 'eaccelerator'); - } - - public function get($id) - { - return eaccelerator_get($id); - } - - public function find($tag) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - - return array(); - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - } - - return eaccelerator_put($id, $data, $lifetime); - } - - public function delete($id, $tag = FALSE) - { - if ($tag === TRUE) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - return FALSE; - } - elseif ($id === TRUE) - { - return eaccelerator_clean(); - } - else - { - return eaccelerator_rm($id); - } - } - - public function delete_expired() - { - eaccelerator_gc(); - - return TRUE; - } - -} // End Cache eAccelerator Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/File.php b/kohana/libraries/drivers/Cache/File.php deleted file mode 100644 index cc9d48d3..00000000 --- a/kohana/libraries/drivers/Cache/File.php +++ /dev/null @@ -1,261 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * File-based Cache driver. - * - * $Id: File.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_File_Driver implements Cache_Driver { - - protected $directory = ''; - - /** - * Tests that the storage location is a directory and is writable. - */ - public function __construct($directory) - { - // Find the real path to the directory - $directory = str_replace('\\', '/', realpath($directory)).'/'; - - // Make sure the cache directory is writable - if ( ! is_dir($directory) OR ! is_writable($directory)) - throw new Kohana_Exception('cache.unwritable', $directory); - - // Directory is valid - $this->directory = $directory; - } - - /** - * Finds an array of files matching the given id or tag. - * - * @param string cache id or tag - * @param bool search for tags - * @return array of filenames matching the id or tag - */ - public function exists($id, $tag = FALSE) - { - if ($id === TRUE) - { - // Find all the files - return glob($this->directory.'*~*~*'); - } - elseif ($tag === TRUE) - { - // Find all the files that have the tag name - $paths = glob($this->directory.'*~*'.$id.'*~*'); - - // Find all tags matching the given tag - $files = array(); - foreach ($paths as $path) - { - // Split the files - $tags = explode('~', basename($path)); - - // Find valid tags - if (count($tags) !== 3 OR empty($tags[1])) - continue; - - // Split the tags by plus signs, used to separate tags - $tags = explode('+', $tags[1]); - - if (in_array($tag, $tags)) - { - // Add the file to the array, it has the requested tag - $files[] = $path; - } - } - - return $files; - } - else - { - // Find the file matching the given id - return glob($this->directory.$id.'~*'); - } - } - - /** - * Sets a cache item to the given data, tags, and lifetime. - * - * @param string cache id to set - * @param string data in the cache - * @param array cache tags - * @param integer lifetime - * @return bool - */ - public function set($id, $data, array $tags = NULL, $lifetime) - { - // Remove old cache files - $this->delete($id); - - // Cache File driver expects unix timestamp - if ($lifetime !== 0) - { - $lifetime += time(); - } - - if ( ! empty($tags)) - { - // Convert the tags into a string list - $tags = implode('+', $tags); - } - - // Write out a serialized cache - return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data)); - } - - /** - * Finds an array of ids for a given tag. - * - * @param string tag name - * @return array of ids that match the tag - */ - public function find($tag) - { - // An array will always be returned - $result = array(); - - if ($paths = $this->exists($tag, TRUE)) - { - // Length of directory name - $offset = strlen($this->directory); - - // Find all the files with the given tag - foreach ($paths as $path) - { - // Get the id from the filename - list($id, $junk) = explode('~', basename($path), 2); - - if (($data = $this->get($id)) !== FALSE) - { - // Add the result to the array - $result[$id] = $data; - } - } - } - - return $result; - } - - /** - * Fetches a cache item. This will delete the item if it is expired or if - * the hash does not match the stored hash. - * - * @param string cache id - * @return mixed|NULL - */ - public function get($id) - { - if ($file = $this->exists($id)) - { - // Use the first file - $file = current($file); - - // Validate that the cache has not expired - if ($this->expired($file)) - { - // Remove this cache, it has expired - $this->delete($id); - } - else - { - // Turn off errors while reading the file - $ER = error_reporting(0); - - if (($data = file_get_contents($file)) !== FALSE) - { - // Unserialize the data - $data = unserialize($data); - } - else - { - // Delete the data - unset($data); - } - - // Turn errors back on - error_reporting($ER); - } - } - - // Return NULL if there is no data - return isset($data) ? $data : NULL; - } - - /** - * Deletes a cache item by id or tag - * - * @param string cache id or tag, or TRUE for "all items" - * @param boolean use tags - * @return boolean - */ - public function delete($id, $tag = FALSE) - { - $files = $this->exists($id, $tag); - - if (empty($files)) - return FALSE; - - // Disable all error reporting while deleting - $ER = error_reporting(0); - - foreach ($files as $file) - { - // Remove the cache file - if ( ! unlink($file)) - Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); - } - - // Turn on error reporting again - error_reporting($ER); - - return TRUE; - } - - /** - * Deletes all cache files that are older than the current time. - * - * @return void - */ - public function delete_expired() - { - if ($files = $this->exists(TRUE)) - { - // Disable all error reporting while deleting - $ER = error_reporting(0); - - foreach ($files as $file) - { - if ($this->expired($file)) - { - // The cache file has already expired, delete it - if ( ! unlink($file)) - Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); - } - } - - // Turn on error reporting again - error_reporting($ER); - } - } - - /** - * Check if a cache file has expired by filename. - * - * @param string filename - * @return bool - */ - protected function expired($file) - { - // Get the expiration time - $expires = (int) substr($file, strrpos($file, '~') + 1); - - // Expirations of 0 are "never expire" - return ($expires !== 0 AND $expires <= time()); - } - -} // End Cache File Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Memcache.php b/kohana/libraries/drivers/Cache/Memcache.php deleted file mode 100644 index d801de9c..00000000 --- a/kohana/libraries/drivers/Cache/Memcache.php +++ /dev/null @@ -1,191 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Memcache-based Cache driver. - * - * $Id: Memcache.php 4102 2009-03-19 12:55:54Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Memcache_Driver implements Cache_Driver { - - const TAGS_KEY = 'memcache_tags_array'; - - // Cache backend object and flags - protected $backend; - protected $flags; - - // Tags array - protected static $tags; - - // Have the tags been changed? - protected static $tags_changed = FALSE; - - public function __construct() - { - if ( ! extension_loaded('memcache')) - throw new Kohana_Exception('cache.extension_not_loaded', 'memcache'); - - $this->backend = new Memcache; - $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE; - - $servers = Kohana::config('cache_memcache.servers'); - - foreach ($servers as $server) - { - // Make sure all required keys are set - $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE); - - // Add the server to the pool - $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent']) - or Kohana::log('error', 'Cache: Connection failed: '.$server['host']); - } - - // Load tags - self::$tags = $this->backend->get(self::TAGS_KEY); - - if ( ! is_array(self::$tags)) - { - // Create a new tags array - self::$tags = array(); - - // Tags have been created - self::$tags_changed = TRUE; - } - } - - public function __destruct() - { - if (self::$tags_changed === TRUE) - { - // Save the tags - $this->backend->set(self::TAGS_KEY, self::$tags, $this->flags, 0); - - // Tags are now unchanged - self::$tags_changed = FALSE; - } - } - - public function find($tag) - { - if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag])) - { - // Return all the found caches - return $results; - } - else - { - // No matching tags - return array(); - } - } - - public function get($id) - { - return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - // Tags will be changed - self::$tags_changed = TRUE; - - foreach ($tags as $tag) - { - // Add the id to each tag - self::$tags[$tag][$id] = $id; - } - } - - if ($lifetime !== 0) - { - // Memcache driver expects unix timestamp - $lifetime += time(); - } - - // Set a new value - return $this->backend->set($id, $data, $this->flags, $lifetime); - } - - public function delete($id, $tag = FALSE) - { - // Tags will be changed - self::$tags_changed = TRUE; - - if ($id === TRUE) - { - if ($status = $this->backend->flush()) - { - // Remove all tags, all items have been deleted - self::$tags = array(); - - // We must sleep after flushing, or overwriting will not work! - // @see http://php.net/manual/en/function.memcache-flush.php#81420 - sleep(1); - } - - return $status; - } - elseif ($tag === TRUE) - { - if (isset(self::$tags[$id])) - { - foreach (self::$tags[$id] as $_id) - { - // Delete each id in the tag - $this->backend->delete($_id); - } - - // Delete the tag - unset(self::$tags[$id]); - } - - return TRUE; - } - else - { - foreach (self::$tags as $tag => $_ids) - { - if (isset(self::$tags[$tag][$id])) - { - // Remove the id from the tags - unset(self::$tags[$tag][$id]); - } - } - - return $this->backend->delete($id); - } - } - - public function delete_expired() - { - // Tags will be changed - self::$tags_changed = TRUE; - - foreach (self::$tags as $tag => $_ids) - { - foreach ($_ids as $id) - { - if ( ! $this->backend->get($id)) - { - // This id has disappeared, delete it from the tags - unset(self::$tags[$tag][$id]); - } - } - - if (empty(self::$tags[$tag])) - { - // The tag no longer has any valid ids - unset(self::$tags[$tag]); - } - } - - // Memcache handles garbage collection internally - return TRUE; - } - -} // End Cache Memcache Driver diff --git a/kohana/libraries/drivers/Cache/Sqlite.php b/kohana/libraries/drivers/Cache/Sqlite.php deleted file mode 100644 index 9458d851..00000000 --- a/kohana/libraries/drivers/Cache/Sqlite.php +++ /dev/null @@ -1,257 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * SQLite-based Cache driver. - * - * $Id: Sqlite.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Sqlite_Driver implements Cache_Driver { - - // SQLite database instance - protected $db; - - // Database error messages - protected $error; - - /** - * Logs an SQLite error. - */ - protected static function log_error($code) - { - // Log an error - Kohana::log('error', 'Cache: SQLite error: '.sqlite_error_string($error)); - } - - /** - * Tests that the storage location is a directory and is writable. - */ - public function __construct($filename) - { - // Get the directory name - $directory = str_replace('\\', '/', realpath(pathinfo($filename, PATHINFO_DIRNAME))).'/'; - - // Set the filename from the real directory path - $filename = $directory.basename($filename); - - // Make sure the cache directory is writable - if ( ! is_dir($directory) OR ! is_writable($directory)) - throw new Kohana_Exception('cache.unwritable', $directory); - - // Make sure the cache database is writable - if (is_file($filename) AND ! is_writable($filename)) - throw new Kohana_Exception('cache.unwritable', $filename); - - // Open up an instance of the database - $this->db = new SQLiteDatabase($filename, '0666', $error); - - // Throw an exception if there's an error - if ( ! empty($error)) - throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); - - $query = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'caches'"; - $tables = $this->db->query($query, SQLITE_BOTH, $error); - - // Throw an exception if there's an error - if ( ! empty($error)) - throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); - - if ($tables->numRows() == 0) - { - Kohana::log('error', 'Cache: Initializing new SQLite cache database'); - - // Issue a CREATE TABLE command - $this->db->unbufferedQuery(Kohana::config('cache_sqlite.schema')); - } - } - - /** - * Checks if a cache id is already set. - * - * @param string cache id - * @return boolean - */ - public function exists($id) - { - // Find the id that matches - $query = "SELECT id FROM caches WHERE id = '$id'"; - - return ($this->db->query($query)->numRows() > 0); - } - - /** - * Sets a cache item to the given data, tags, and lifetime. - * - * @param string cache id to set - * @param string data in the cache - * @param array cache tags - * @param integer lifetime - * @return bool - */ - public function set($id, $data, array $tags = NULL, $lifetime) - { - // Serialize and escape the data - $data = sqlite_escape_string(serialize($data)); - - if ( ! empty($tags)) - { - // Escape the tags, adding brackets so the tag can be explicitly matched - $tags = sqlite_escape_string('<'.implode('>,<', $tags).'>'); - } - - // Cache Sqlite driver expects unix timestamp - if ($lifetime !== 0) - { - $lifetime += time(); - } - - $query = $this->exists($id) - ? "UPDATE caches SET tags = '$tags', expiration = '$lifetime', cache = '$data' WHERE id = '$id'" - : "INSERT INTO caches VALUES('$id', '$tags', '$lifetime', '$data')"; - - // Run the query - $this->db->unbufferedQuery($query, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - return FALSE; - } - else - { - return TRUE; - } - } - - /** - * Finds an array of ids for a given tag. - * - * @param string tag name - * @return array of ids that match the tag - */ - public function find($tag) - { - $query = "SELECT id,cache FROM caches WHERE tags LIKE '%<{$tag}>%'"; - $query = $this->db->query($query, SQLITE_BOTH, $error); - - // An array will always be returned - $result = array(); - - if ( ! empty($error)) - { - self::log_error($error); - } - elseif ($query->numRows() > 0) - { - // Disable notices for unserializing - $ER = error_reporting(~E_NOTICE); - - while ($row = $query->fetchObject()) - { - // Add each cache to the array - $result[$row->id] = unserialize($row->cache); - } - - // Turn notices back on - error_reporting($ER); - } - - return $result; - } - - /** - * Fetches a cache item. This will delete the item if it is expired or if - * the hash does not match the stored hash. - * - * @param string cache id - * @return mixed|NULL - */ - public function get($id) - { - $query = "SELECT id, expiration, cache FROM caches WHERE id = '$id' LIMIT 0, 1"; - $query = $this->db->query($query, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - } - elseif ($cache = $query->fetchObject()) - { - // Make sure the expiration is valid and that the hash matches - if ($cache->expiration != 0 AND $cache->expiration <= time()) - { - // Cache is not valid, delete it now - $this->delete($cache->id); - } - else - { - // Disable notices for unserializing - $ER = error_reporting(~E_NOTICE); - - // Return the valid cache data - $data = $cache->cache; - - // Turn notices back on - error_reporting($ER); - } - } - - // No valid cache found - return NULL; - } - - /** - * Deletes a cache item by id or tag - * - * @param string cache id or tag, or TRUE for "all items" - * @param bool delete a tag - * @return bool - */ - public function delete($id, $tag = FALSE) - { - if ($id === TRUE) - { - // Delete all caches - $where = '1'; - } - elseif ($tag === TRUE) - { - // Delete by tag - $where = "tags LIKE '%<{$id}>%'"; - } - else - { - // Delete by id - $where = "id = '$id'"; - } - - $this->db->unbufferedQuery('DELETE FROM caches WHERE '.$where, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - return FALSE; - } - else - { - return TRUE; - } - } - - /** - * Deletes all cache files that are older than the current time. - */ - public function delete_expired() - { - // Delete all expired caches - $query = 'DELETE FROM caches WHERE expiration != 0 AND expiration <= '.time(); - - $this->db->unbufferedQuery($query); - - return TRUE; - } - -} // End Cache SQLite Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Xcache.php b/kohana/libraries/drivers/Cache/Xcache.php deleted file mode 100644 index 6254bbb6..00000000 --- a/kohana/libraries/drivers/Cache/Xcache.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Xcache Cache driver. - * - * $Id: Xcache.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Xcache_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('xcache')) - throw new Kohana_Exception('cache.extension_not_loaded', 'xcache'); - } - - public function get($id) - { - if (xcache_isset($id)) - return xcache_get($id); - - return NULL; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - } - - return xcache_set($id, $data, $lifetime); - } - - public function find($tag) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return FALSE; - } - - public function delete($id, $tag = FALSE) - { - if ($tag !== FALSE) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return TRUE; - } - elseif ($id !== TRUE) - { - if (xcache_isset($id)) - return xcache_unset($id); - - return FALSE; - } - else - { - // Do the login - $this->auth(); - $result = TRUE; - for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) - { - if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL) - { - $result = FALSE; - break; - } - } - - // Undo the login - $this->auth(TRUE); - return $result; - } - - return TRUE; - } - - public function delete_expired() - { - return TRUE; - } - - private function auth($reverse = FALSE) - { - static $backup = array(); - - $keys = array('PHP_AUTH_USER', 'PHP_AUTH_PW'); - - foreach ($keys as $key) - { - if ($reverse) - { - if (isset($backup[$key])) - { - $_SERVER[$key] = $backup[$key]; - unset($backup[$key]); - } - else - { - unset($_SERVER[$key]); - } - } - else - { - $value = getenv($key); - - if ( ! empty($value)) - { - $backup[$key] = $value; - } - - $_SERVER[$key] = Kohana::config('cache_xcache.'.$key); - } - } - } - -} // End Cache Xcache Driver diff --git a/kohana/libraries/drivers/Captcha.php b/kohana/libraries/drivers/Captcha.php deleted file mode 100644 index a4343e19..00000000 --- a/kohana/libraries/drivers/Captcha.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver class. - * - * $Id: Captcha.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Captcha_Driver { - - // The correct Captcha challenge answer - protected $response; - - // Image resource identifier and type ("png", "gif" or "jpeg") - protected $image; - protected $image_type = 'png'; - - /** - * Constructs a new challenge. - * - * @return void - */ - public function __construct() - { - // Generate a new challenge - $this->response = $this->generate_challenge(); - - // Store the correct Captcha response in a session - Event::add('system.post_controller', array($this, 'update_response_session')); - } - - /** - * Generate a new Captcha challenge. - * - * @return string the challenge answer - */ - abstract public function generate_challenge(); - - /** - * Output the Captcha challenge. - * - * @param boolean html output - * @return mixed the rendered Captcha (e.g. an image, riddle, etc.) - */ - abstract public function render($html); - - /** - * Stores the response for the current Captcha challenge in a session so it is available - * on the next page load for Captcha::valid(). This method is called after controller - * execution (in the system.post_controller event) in order not to overwrite itself too soon. - * - * @return void - */ - public function update_response_session() - { - Session::instance()->set('captcha_response', sha1(strtoupper($this->response))); - } - - /** - * Validates a Captcha response from a user. - * - * @param string captcha response - * @return boolean - */ - public function valid($response) - { - return (sha1(strtoupper($response)) === Session::instance()->get('captcha_response')); - } - - /** - * Returns the image type. - * - * @param string filename - * @return string|FALSE image type ("png", "gif" or "jpeg") - */ - public function image_type($filename) - { - switch (strtolower(substr(strrchr($filename, '.'), 1))) - { - case 'png': - return 'png'; - - case 'gif': - return 'gif'; - - case 'jpg': - case 'jpeg': - // Return "jpeg" and not "jpg" because of the GD2 function names - return 'jpeg'; - - default: - return FALSE; - } - } - - /** - * Creates an image resource with the dimensions specified in config. - * If a background image is supplied, the image dimensions are used. - * - * @throws Kohana_Exception if no GD2 support - * @param string path to the background image file - * @return void - */ - public function image_create($background = NULL) - { - // Check for GD2 support - if ( ! function_exists('imagegd2')) - throw new Kohana_Exception('captcha.requires_GD2'); - - // Create a new image (black) - $this->image = imagecreatetruecolor(Captcha::$config['width'], Captcha::$config['height']); - - // Use a background image - if ( ! empty($background)) - { - // Create the image using the right function for the filetype - $function = 'imagecreatefrom'.$this->image_type($background); - $this->background_image = $function($background); - - // Resize the image if needed - if (imagesx($this->background_image) !== Captcha::$config['width'] - OR imagesy($this->background_image) !== Captcha::$config['height']) - { - imagecopyresampled - ( - $this->image, $this->background_image, 0, 0, 0, 0, - Captcha::$config['width'], Captcha::$config['height'], - imagesx($this->background_image), imagesy($this->background_image) - ); - } - - // Free up resources - imagedestroy($this->background_image); - } - } - - /** - * Fills the background with a gradient. - * - * @param resource gd image color identifier for start color - * @param resource gd image color identifier for end color - * @param string direction: 'horizontal' or 'vertical', 'random' by default - * @return void - */ - public function image_gradient($color1, $color2, $direction = NULL) - { - $directions = array('horizontal', 'vertical'); - - // Pick a random direction if needed - if ( ! in_array($direction, $directions)) - { - $direction = $directions[array_rand($directions)]; - - // Switch colors - if (mt_rand(0, 1) === 1) - { - $temp = $color1; - $color1 = $color2; - $color2 = $temp; - } - } - - // Extract RGB values - $color1 = imagecolorsforindex($this->image, $color1); - $color2 = imagecolorsforindex($this->image, $color2); - - // Preparations for the gradient loop - $steps = ($direction === 'horizontal') ? Captcha::$config['width'] : Captcha::$config['height']; - - $r1 = ($color1['red'] - $color2['red']) / $steps; - $g1 = ($color1['green'] - $color2['green']) / $steps; - $b1 = ($color1['blue'] - $color2['blue']) / $steps; - - if ($direction === 'horizontal') - { - $x1 =& $i; - $y1 = 0; - $x2 =& $i; - $y2 = Captcha::$config['height']; - } - else - { - $x1 = 0; - $y1 =& $i; - $x2 = Captcha::$config['width']; - $y2 =& $i; - } - - // Execute the gradient loop - for ($i = 0; $i <= $steps; $i++) - { - $r2 = $color1['red'] - floor($i * $r1); - $g2 = $color1['green'] - floor($i * $g1); - $b2 = $color1['blue'] - floor($i * $b1); - $color = imagecolorallocate($this->image, $r2, $g2, $b2); - - imageline($this->image, $x1, $y1, $x2, $y2, $color); - } - } - - /** - * Returns the img html element or outputs the image to the browser. - * - * @param boolean html output - * @return mixed html string or void - */ - public function image_render($html) - { - // Output html element - if ($html) - return '<img alt="Captcha" src="'.url::site('captcha/'.Captcha::$config['group']).'" width="'.Captcha::$config['width'].'" height="'.Captcha::$config['height'].'" />'; - - // Send the correct HTTP header - header('Content-Type: image/'.$this->image_type); - - // Pick the correct output function - $function = 'image'.$this->image_type; - $function($this->image); - - // Free up resources - imagedestroy($this->image); - } - -} // End Captcha Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Alpha.php b/kohana/libraries/drivers/Captcha/Alpha.php deleted file mode 100644 index b3a9c9d7..00000000 --- a/kohana/libraries/drivers/Captcha/Alpha.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "alpha" style. - * - * $Id: Alpha.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Alpha_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, Captcha::$config['complexity'])); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates $this->image - $this->image_create(Captcha::$config['background']); - - // Add a random gradient - if (empty(Captcha::$config['background'])) - { - $color1 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); - $color2 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); - $this->image_gradient($color1, $color2); - } - - // Add a few random circles - for ($i = 0, $count = mt_rand(10, Captcha::$config['complexity'] * 3); $i < $count; $i++) - { - $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255), mt_rand(80, 120)); - $size = mt_rand(5, Captcha::$config['height'] / 3); - imagefilledellipse($this->image, mt_rand(0, Captcha::$config['width']), mt_rand(0, Captcha::$config['height']), $size, $size, $color); - } - - // Calculate character font-size and spacing - $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / strlen($this->response); - $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); - - // Background alphabetic character attributes - $color_limit = mt_rand(96, 160); - $chars = 'ABEFGJKLPQRTVY'; - - // Draw each Captcha character with varying attributes - for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) - { - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - $angle = mt_rand(-40, 20); - // Scale the character size on image height - $size = $default_size / 10 * mt_rand(8, 12); - $box = imageftbbox($size, $angle, $font, $this->response[$i]); - - // Calculate character starting coordinates - $x = $spacing / 4 + $i * $spacing; - $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; - - // Draw captcha text character - // Allocate random color, size and rotation attributes to text - $color = imagecolorallocate($this->image, mt_rand(150, 255), mt_rand(200, 255), mt_rand(0, 255)); - - // Write text character to image - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); - - // Draw "ghost" alphabetic character - $text_color = imagecolorallocatealpha($this->image, mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand(70, 120)); - $char = substr($chars, mt_rand(0, 14), 1); - imagettftext($this->image, $size * 2, mt_rand(-45, 45), ($x - (mt_rand(5, 10))), ($y + (mt_rand(5, 10))), $text_color, $font, $char); - } - - // Output - return $this->image_render($html); - } - -} // End Captcha Alpha Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Basic.php b/kohana/libraries/drivers/Captcha/Basic.php deleted file mode 100644 index d212e72c..00000000 --- a/kohana/libraries/drivers/Captcha/Basic.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "basic" style. - * - * $Id: Basic.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Basic_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, Captcha::$config['complexity'])); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates $this->image - $this->image_create(Captcha::$config['background']); - - // Add a random gradient - if (empty(Captcha::$config['background'])) - { - $color1 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); - $color2 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); - $this->image_gradient($color1, $color2); - } - - // Add a few random lines - for ($i = 0, $count = mt_rand(5, Captcha::$config['complexity'] * 4); $i < $count; $i++) - { - $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(100, 255), mt_rand(50, 120)); - imageline($this->image, mt_rand(0, Captcha::$config['width']), 0, mt_rand(0, Captcha::$config['width']), Captcha::$config['height'], $color); - } - - // Calculate character font-size and spacing - $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / (strlen($this->response) + 1); - $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); - - // Draw each Captcha character with varying attributes - for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) - { - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - // Allocate random color, size and rotation attributes to text - $color = imagecolorallocate($this->image, mt_rand(0, 150), mt_rand(0, 150), mt_rand(0, 150)); - $angle = mt_rand(-40, 20); - - // Scale the character size on image height - $size = $default_size / 10 * mt_rand(8, 12); - $box = imageftbbox($size, $angle, $font, $this->response[$i]); - - // Calculate character starting coordinates - $x = $spacing / 4 + $i * $spacing; - $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; - - // Write text character to image - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); - } - - // Output - return $this->image_render($html); - } - -} // End Captcha Basic Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Black.php b/kohana/libraries/drivers/Captcha/Black.php deleted file mode 100644 index 6a2e2226..00000000 --- a/kohana/libraries/drivers/Captcha/Black.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "black" style. - * - * $Id: Black.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Black_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, ceil(Captcha::$config['complexity'] / 1.5))); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates a black image to start from - $this->image_create(Captcha::$config['background']); - - // Add random white/gray arcs, amount depends on complexity setting - $count = (Captcha::$config['width'] + Captcha::$config['height']) / 2; - $count = $count / 5 * min(10, Captcha::$config['complexity']); - for ($i = 0; $i < $count; $i++) - { - imagesetthickness($this->image, mt_rand(1, 2)); - $color = imagecolorallocatealpha($this->image, 255, 255, 255, mt_rand(0, 120)); - imagearc($this->image, mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(0, 360), mt_rand(0, 360), $color); - } - - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - // Draw the character's white shadows - $size = (int) min(Captcha::$config['height'] / 2, Captcha::$config['width'] * 0.8 / strlen($this->response)); - $angle = mt_rand(-15 + strlen($this->response), 15 - strlen($this->response)); - $x = mt_rand(1, Captcha::$config['width'] * 0.9 - $size * strlen($this->response)); - $y = ((Captcha::$config['height'] - $size) / 2) + $size; - $color = imagecolorallocate($this->image, 255, 255, 255); - imagefttext($this->image, $size, $angle, $x + 1, $y + 1, $color, $font, $this->response); - - // Add more shadows for lower complexities - (Captcha::$config['complexity'] < 10) and imagefttext($this->image, $size, $angle, $x - 1, $y - 1, $color, $font , $this->response); - (Captcha::$config['complexity'] < 8) and imagefttext($this->image, $size, $angle, $x - 2, $y + 2, $color, $font , $this->response); - (Captcha::$config['complexity'] < 6) and imagefttext($this->image, $size, $angle, $x + 2, $y - 2, $color, $font , $this->response); - (Captcha::$config['complexity'] < 4) and imagefttext($this->image, $size, $angle, $x + 3, $y + 3, $color, $font , $this->response); - (Captcha::$config['complexity'] < 2) and imagefttext($this->image, $size, $angle, $x - 3, $y - 3, $color, $font , $this->response); - - // Finally draw the foreground characters - $color = imagecolorallocate($this->image, 0, 0, 0); - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response); - - // Output - return $this->image_render($html); - } - -} // End Captcha Black Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Math.php b/kohana/libraries/drivers/Captcha/Math.php deleted file mode 100644 index 4ac20248..00000000 --- a/kohana/libraries/drivers/Captcha/Math.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "math" style. - * - * $Id: Math.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Math_Driver extends Captcha_Driver { - - private $math_exercice; - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Easy - if (Captcha::$config['complexity'] < 4) - { - $numbers[] = mt_rand(1, 5); - $numbers[] = mt_rand(1, 4); - } - // Normal - elseif (Captcha::$config['complexity'] < 7) - { - $numbers[] = mt_rand(10, 20); - $numbers[] = mt_rand(1, 10); - } - // Difficult, well, not really ;) - else - { - $numbers[] = mt_rand(100, 200); - $numbers[] = mt_rand(10, 20); - $numbers[] = mt_rand(1, 10); - } - - // Store the question for output - $this->math_exercice = implode(' + ', $numbers).' = '; - - // Return the answer - return array_sum($numbers); - } - - /** - * Outputs the Captcha riddle. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - return $this->math_exercice; - } - -} // End Captcha Math Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Riddle.php b/kohana/libraries/drivers/Captcha/Riddle.php deleted file mode 100644 index 765eeaad..00000000 --- a/kohana/libraries/drivers/Captcha/Riddle.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "riddle" style. - * - * $Id: Riddle.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Riddle_Driver extends Captcha_Driver { - - private $riddle; - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Load riddles from the current language - $riddles = Kohana::lang('captcha.riddles'); - - // Pick a random riddle - $riddle = $riddles[array_rand($riddles)]; - - // Store the question for output - $this->riddle = $riddle[0]; - - // Return the answer - return $riddle[1]; - } - - /** - * Outputs the Captcha riddle. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - return $this->riddle; - } - -} // End Captcha Riddle Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Word.php b/kohana/libraries/drivers/Captcha/Word.php deleted file mode 100644 index 856bd9b4..00000000 --- a/kohana/libraries/drivers/Captcha/Word.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "word" style. - * - * $Id: Word.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Word_Driver extends Captcha_Basic_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Load words from the current language and randomize them - $words = Kohana::lang('captcha.words'); - shuffle($words); - - // Loop over each word... - foreach ($words as $word) - { - // ...until we find one of the desired length - if (abs(Captcha::$config['complexity'] - strlen($word)) < 2) - return strtoupper($word); - } - - // Return any random word as final fallback - return strtoupper($words[array_rand($words)]); - } - -} // End Captcha Word Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Database.php b/kohana/libraries/drivers/Database.php deleted file mode 100644 index 807469f6..00000000 --- a/kohana/libraries/drivers/Database.php +++ /dev/null @@ -1,636 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Database API driver - * - * $Id: Database.php 4343 2009-05-08 17:04:48Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Database_Driver { - - protected $query_cache; - - /** - * Connect to our database. - * Returns FALSE on failure or a MySQL resource. - * - * @return mixed - */ - abstract public function connect(); - - /** - * Perform a query based on a manually written query. - * - * @param string SQL query to execute - * @return Database_Result - */ - abstract public function query($sql); - - /** - * Builds a DELETE query. - * - * @param string table name - * @param array where clause - * @return string - */ - public function delete($table, $where) - { - return 'DELETE FROM '.$this->escape_table($table).' WHERE '.implode(' ', $where); - } - - /** - * Builds an UPDATE query. - * - * @param string table name - * @param array key => value pairs - * @param array where clause - * @return string - */ - public function update($table, $values, $where) - { - foreach ($values as $key => $val) - { - $valstr[] = $this->escape_column($key).' = '.$val; - } - return 'UPDATE '.$this->escape_table($table).' SET '.implode(', ', $valstr).' WHERE '.implode(' ',$where); - } - - /** - * Set the charset using 'SET NAMES <charset>'. - * - * @param string character set to use - */ - public function set_charset($charset) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Wrap the tablename in backticks, has support for: table.field syntax. - * - * @param string table name - * @return string - */ - abstract public function escape_table($table); - - /** - * Escape a column/field name, has support for special commands. - * - * @param string column name - * @return string - */ - abstract public function escape_column($column); - - /** - * Builds a WHERE portion of a query. - * - * @param mixed key - * @param string value - * @param string type - * @param int number of where clauses - * @param boolean escape the value - * @return string - */ - public function where($key, $value, $type, $num_wheres, $quote) - { - $prefix = ($num_wheres == 0) ? '' : $type; - - if ($quote === -1) - { - $value = ''; - } - else - { - if ($value === NULL) - { - if ( ! $this->has_operator($key)) - { - $key .= ' IS'; - } - - $value = ' NULL'; - } - elseif (is_bool($value)) - { - if ( ! $this->has_operator($key)) - { - $key .= ' ='; - } - - $value = ($value == TRUE) ? ' 1' : ' 0'; - } - else - { - if ( ! $this->has_operator($key) AND ! empty($key)) - { - $key = $this->escape_column($key).' ='; - } - else - { - preg_match('/^(.+?)([<>!=]+|\bIS(?:\s+NULL))\s*$/i', $key, $matches); - if (isset($matches[1]) AND isset($matches[2])) - { - $key = $this->escape_column(trim($matches[1])).' '.trim($matches[2]); - } - } - - $value = ' '.(($quote == TRUE) ? $this->escape($value) : $value); - } - } - - return $prefix.$key.$value; - } - - /** - * Builds a LIKE portion of a query. - * - * @param mixed field name - * @param string value to match with field - * @param boolean add wildcards before and after the match - * @param string clause type (AND or OR) - * @param int number of likes - * @return string - */ - public function like($field, $match, $auto, $type, $num_likes) - { - $prefix = ($num_likes == 0) ? '' : $type; - - $match = $this->escape_str($match); - - if ($auto === TRUE) - { - // Add the start and end quotes - $match = '%'.str_replace('%', '\\%', $match).'%'; - } - - return $prefix.' '.$this->escape_column($field).' LIKE \''.$match . '\''; - } - - /** - * Builds a NOT LIKE portion of a query. - * - * @param mixed field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param int number of likes - * @return string - */ - public function notlike($field, $match, $auto, $type, $num_likes) - { - $prefix = ($num_likes == 0) ? '' : $type; - - $match = $this->escape_str($match); - - if ($auto === TRUE) - { - // Add the start and end quotes - $match = '%'.$match.'%'; - } - - return $prefix.' '.$this->escape_column($field).' NOT LIKE \''.$match.'\''; - } - - /** - * Builds a REGEX portion of a query. - * - * @param string field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param integer number of regexes - * @return string - */ - public function regex($field, $match, $type, $num_regexs) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds a NOT REGEX portion of a query. - * - * @param string field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param integer number of regexes - * @return string - */ - public function notregex($field, $match, $type, $num_regexs) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds an INSERT query. - * - * @param string table name - * @param array keys - * @param array values - * @return string - */ - public function insert($table, $keys, $values) - { - // Escape the column names - foreach ($keys as $key => $value) - { - $keys[$key] = $this->escape_column($value); - } - return 'INSERT INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - /** - * Builds a MERGE portion of a query. - * - * @param string table name - * @param array keys - * @param array values - * @return string - */ - public function merge($table, $keys, $values) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds a LIMIT portion of a query. - * - * @param integer limit - * @param integer offset - * @return string - */ - abstract public function limit($limit, $offset = 0); - - /** - * Creates a prepared statement. - * - * @param string SQL query - * @return Database_Stmt - */ - public function stmt_prepare($sql = '') - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Compiles the SELECT statement. - * Generates a query string based on which functions were used. - * Should not be called directly, the get() function calls it. - * - * @param array select query values - * @return string - */ - abstract public function compile_select($database); - - /** - * Determines if the string has an arithmetic operator in it. - * - * @param string string to check - * @return boolean - */ - public function has_operator($str) - { - return (bool) preg_match('/[<>!=]|\sIS(?:\s+NOT\s+)?\b|BETWEEN/i', trim($str)); - } - - /** - * Escapes any input value. - * - * @param mixed value to escape - * @return string - */ - public function escape($value) - { - if ( ! $this->db_config['escape']) - return $value; - - switch (gettype($value)) - { - case 'string': - $value = '\''.$this->escape_str($value).'\''; - break; - case 'boolean': - $value = (int) $value; - break; - case 'double': - // Convert to non-locale aware float to prevent possible commas - $value = sprintf('%F', $value); - break; - default: - $value = ($value === NULL) ? 'NULL' : $value; - break; - } - - return (string) $value; - } - - /** - * Escapes a string for a query. - * - * @param mixed value to escape - * @return string - */ - abstract public function escape_str($str); - - /** - * Lists all tables in the database. - * - * @return array - */ - abstract public function list_tables(); - - /** - * Lists all fields in a table. - * - * @param string table name - * @return array - */ - abstract function list_fields($table); - - /** - * Returns the last database error. - * - * @return string - */ - abstract public function show_error(); - - /** - * Returns field data about a table. - * - * @param string table name - * @return array - */ - abstract public function field_data($table); - - /** - * Fetches SQL type information about a field, in a generic format. - * - * @param string field datatype - * @return array - */ - protected function sql_type($str) - { - static $sql_types; - - if ($sql_types === NULL) - { - // Load SQL data types - $sql_types = Kohana::config('sql_types'); - } - - $str = strtolower(trim($str)); - - if (($open = strpos($str, '(')) !== FALSE) - { - // Find closing bracket - $close = strpos($str, ')', $open) - 1; - - // Find the type without the size - $type = substr($str, 0, $open); - } - else - { - // No length - $type = $str; - } - - empty($sql_types[$type]) and exit - ( - 'Unknown field type: '.$type.'. '. - 'Please report this: http://trac.kohanaphp.com/newticket' - ); - - // Fetch the field definition - $field = $sql_types[$type]; - - switch ($field['type']) - { - case 'string': - case 'float': - if (isset($close)) - { - // Add the length to the field info - $field['length'] = substr($str, $open + 1, $close - $open); - } - break; - case 'int': - // Add unsigned value - $field['unsigned'] = (strpos($str, 'unsigned') !== FALSE); - break; - } - - return $field; - } - - /** - * Clears the internal query cache. - * - * @param string SQL query - */ - public function clear_cache($sql = NULL) - { - if (empty($sql)) - { - $this->query_cache = array(); - } - else - { - unset($this->query_cache[$this->query_hash($sql)]); - } - - Kohana::log('debug', 'Database cache cleared: '.get_class($this)); - } - - /** - * Creates a hash for an SQL query string. Replaces newlines with spaces, - * trims, and hashes. - * - * @param string SQL query - * @return string - */ - protected function query_hash($sql) - { - return sha1(str_replace("\n", ' ', trim($sql))); - } - -} // End Database Driver Interface - -/** - * Database_Result - * - */ -abstract class Database_Result implements ArrayAccess, Iterator, Countable { - - // Result resource, insert id, and SQL - protected $result; - protected $insert_id; - protected $sql; - - // Current and total rows - protected $current_row = 0; - protected $total_rows = 0; - - // Fetch function and return type - protected $fetch_type; - protected $return_type; - - /** - * Returns the SQL used to fetch the result. - * - * @return string - */ - public function sql() - { - return $this->sql; - } - - /** - * Returns the insert id from the result. - * - * @return mixed - */ - public function insert_id() - { - return $this->insert_id; - } - - /** - * Prepares the query result. - * - * @param boolean return rows as objects - * @param mixed type - * @return Database_Result - */ - abstract function result($object = TRUE, $type = FALSE); - - /** - * Builds an array of query results. - * - * @param boolean return rows as objects - * @param mixed type - * @return array - */ - abstract function result_array($object = NULL, $type = FALSE); - - /** - * Gets the fields of an already run query. - * - * @return array - */ - abstract public function list_fields(); - - /** - * Seek to an offset in the results. - * - * @return boolean - */ - abstract public function seek($offset); - - /** - * Countable: count - */ - public function count() - { - return $this->total_rows; - } - - /** - * ArrayAccess: offsetExists - */ - public function offsetExists($offset) - { - if ($this->total_rows > 0) - { - $min = 0; - $max = $this->total_rows - 1; - - return ! ($offset < $min OR $offset > $max); - } - - return FALSE; - } - - /** - * ArrayAccess: offsetGet - */ - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row by calling the defined fetching callback - return call_user_func($this->fetch_type, $this->result, $this->return_type); - } - - /** - * ArrayAccess: offsetSet - * - * @throws Kohana_Database_Exception - */ - final public function offsetSet($offset, $value) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - - /** - * ArrayAccess: offsetUnset - * - * @throws Kohana_Database_Exception - */ - final public function offsetUnset($offset) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - - /** - * Iterator: current - */ - public function current() - { - return $this->offsetGet($this->current_row); - } - - /** - * Iterator: key - */ - public function key() - { - return $this->current_row; - } - - /** - * Iterator: next - */ - public function next() - { - ++$this->current_row; - return $this; - } - - /** - * Iterator: prev - */ - public function prev() - { - --$this->current_row; - return $this; - } - - /** - * Iterator: rewind - */ - public function rewind() - { - $this->current_row = 0; - return $this; - } - - /** - * Iterator: valid - */ - public function valid() - { - return $this->offsetExists($this->current_row); - } - -} // End Database Result Interface diff --git a/kohana/libraries/drivers/Database/Mssql.php b/kohana/libraries/drivers/Database/Mssql.php deleted file mode 100644 index 6947679a..00000000 --- a/kohana/libraries/drivers/Database/Mssql.php +++ /dev/null @@ -1,462 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MSSQL Database Driver - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mssql_Driver extends Database_Driver -{ - /** - * Database connection link - */ - protected $link; - - /** - * Database configuration - */ - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MSSQL Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_resource($this->link) and mssql_close($this->link); - } - - /** - * Make the connection - * - * @return return connection - */ - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'mssql_pconnect' : 'mssql_connect'; - - // Build the connection info - $host = isset($host) ? $host : $socket; - - // Windows uses a comma instead of a colon - $port = (isset($port) AND is_string($port)) ? (KOHANA_IS_WIN ? ',' : ':').$port : ''; - - // Make the connection and select the database - if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mssql_select_db($database, $this->link)) - { - /* This is being removed so I can use it, will need to come up with a more elegant workaround in the future... - * - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - */ - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - - public function escape_table($table) - { - if (stripos($table, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $table = str_ireplace(' AS ', ' AS ', $table); - - // Runs escape_table on both sides of an AS statement - $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); - - // Re-create the AS statement - return implode(' AS ', $table); - } - return '['.str_replace('.', '[.]', $table).']'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '[$0]', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '[$0]', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - /** - * Limit in SQL Server 2000 only uses the keyword - * 'TOP'; 2007 may have an offset keyword, but - * I am unsure - for pagination style limit,offset - * functionality, a fancy query needs to be built. - * - * @param unknown_type $limit - * @return unknown - */ - public function limit($limit, $offset=null) - { - return 'TOP '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - // Escape the tables - $froms = array(); - foreach ($database['from'] as $from) - $froms[] = $this->escape_column($from); - $sql .= "\nFROM "; - $sql .= implode(', ', $froms); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - //mssql_real_escape_string($str, $this->link); <-- this function doesn't exist - - $characters = array('/\x00/', '/\x1a/', '/\n/', '/\r/', '/\\\/', '/\'/'); - $replace = array('\\\x00', '\\x1a', '\\n', '\\r', '\\\\', "''"); - return preg_replace($characters, $replace, $str); - } - - public function list_tables() - { - $sql = 'SHOW TABLES FROM ['.$this->db_config['connection']['database'].']'; - $result = $this->query($sql)->result(FALSE, MSSQL_ASSOC); - - $retval = array(); - foreach ($result as $row) - { - $retval[] = current($row); - } - - return $retval; - } - - public function show_error() - { - return mssql_get_last_message($this->link); - } - - public function list_fields($table) - { - $result = array(); - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->Field] = $this->sql_type($row->Type); - } - - return $result; - } - - public function field_data($table) - { - $query = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table), $this->link); - - return $query->result_array(TRUE); - } -} - -/** - * MSSQL Result - */ -class Mssql_Result extends Database_Result { - - // Fetch function and return type - protected $fetch_type = 'mssql_fetch_object'; - protected $return_type = MSSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - $this->current_row = 0; - $this->total_rows = mssql_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'mssql_fetch_object' : 'mssql_fetch_array'; - } - elseif (is_bool($result)) - { - if ($result == FALSE) - { - // SQL error - throw new Kohana_Database_Exception('database.error', mssql_get_last_message($link).' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE querys - $last_id = mssql_query('SELECT @@IDENTITY AS last_id', $link); - $result = mssql_fetch_assoc($last_id); - $this->insert_id = $result['last_id']; - $this->total_rows = mssql_rows_affected($link); - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Destruct, the cleanup crew! - */ - public function __destruct() - { - if (is_resource($this->result)) - { - mssql_free_result($this->result); - } - } - - public function result($object = TRUE, $type = MSSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'mssql_fetch_object' : 'mssql_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'mssql_fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MSSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MSSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'mssql_fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'mssql_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'mssql_fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if (mssql_num_rows($this->result)) - { - // Reset the pointer location to make sure things work properly - mssql_data_seek($this->result, 0); - - while ($row = $fetch($this->result, $type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = mssql_fetch_field($this->result)) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ( ! $this->offsetExists($offset)) - return FALSE; - - return mssql_data_seek($this->result, $offset); - } - -} // End mssql_Result Class diff --git a/kohana/libraries/drivers/Database/Mysql.php b/kohana/libraries/drivers/Database/Mysql.php deleted file mode 100644 index d5222f50..00000000 --- a/kohana/libraries/drivers/Database/Mysql.php +++ /dev/null @@ -1,496 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MySQL Database Driver - * - * $Id: Mysql.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mysql_Driver extends Database_Driver { - - /** - * Database connection link - */ - protected $link; - - /** - * Database configuration - */ - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MySQL Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_resource($this->link) and mysql_close($this->link); - } - - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'mysql_pconnect' : 'mysql_connect'; - - // Build the connection info - $host = isset($host) ? $host : $socket; - $port = isset($port) ? ':'.$port : ''; - - // Make the connection and select the database - if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mysql_select_db($database, $this->link)) - { - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->query('SET NAMES '.$this->escape_str($charset)); - } - - public function escape_table($table) - { - if (!$this->db_config['escape']) - return $table; - - if (stripos($table, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $table = str_ireplace(' AS ', ' AS ', $table); - - // Runs escape_table on both sides of an AS statement - $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); - - // Re-create the AS statement - return implode(' AS ', $table); - } - return '`'.str_replace('.', '`.`', $table).'`'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '`$0`', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function regex($field, $match, $type, $num_regexs) - { - $prefix = ($num_regexs == 0) ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\''; - } - - public function notregex($field, $match, $type, $num_regexs) - { - $prefix = $num_regexs == 0 ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' NOT REGEXP \''.$this->escape_str($match) . '\''; - } - - public function merge($table, $keys, $values) - { - // Escape the column names - foreach ($keys as $key => $value) - { - $keys[$key] = $this->escape_column($value); - } - return 'REPLACE INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$offset.', '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - // Escape the tables - $froms = array(); - foreach ($database['from'] as $from) - { - $froms[] = $this->escape_column($from); - } - $sql .= "\nFROM ("; - $sql .= implode(', ', $froms).")"; - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - - return mysql_real_escape_string($str, $this->link); - } - - public function list_tables() - { - $tables = array(); - - if ($query = $this->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database']))) - { - foreach ($query->result(FALSE) as $row) - { - $tables[] = current($row); - } - } - - return $tables; - } - - public function show_error() - { - return mysql_error($this->link); - } - - public function list_fields($table) - { - $result = NULL; - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->Field] = $this->sql_type($row->Type); - - if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment') - { - // For sequenced (AUTO_INCREMENT) tables - $result[$row->Field]['sequenced'] = TRUE; - } - - if ($row->Null === 'YES') - { - // Set NULL status - $result[$row->Field]['null'] = TRUE; - } - } - - if (!isset($result)) - throw new Kohana_Database_Exception('database.table_not_found', $table); - - return $result; - } - - public function field_data($table) - { - $result = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table)); - - return $result->result_array(TRUE); - } - -} // End Database_Mysql_Driver Class - -/** - * MySQL Result - */ -class Mysql_Result extends Database_Result { - - // Fetch function and return type - protected $fetch_type = 'mysql_fetch_object'; - protected $return_type = MYSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - $this->current_row = 0; - $this->total_rows = mysql_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'mysql_fetch_object' : 'mysql_fetch_array'; - } - elseif (is_bool($result)) - { - if ($result == FALSE) - { - // SQL error - throw new Kohana_Database_Exception('database.error', mysql_error($link).' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - $this->insert_id = mysql_insert_id($link); - $this->total_rows = mysql_affected_rows($link); - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Destruct, the cleanup crew! - */ - public function __destruct() - { - if (is_resource($this->result)) - { - mysql_free_result($this->result); - } - } - - public function result($object = TRUE, $type = MYSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'mysql_fetch_object' : 'mysql_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'mysql_fetch_object' AND $object === TRUE) - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MYSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MYSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'mysql_fetch_object'; - - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'mysql_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'mysql_fetch_object') - { - $type = (is_string($this->return_type) AND Kohana::auto_load($this->return_type)) ? $this->return_type : 'stdClass'; - } - } - - if (mysql_num_rows($this->result)) - { - // Reset the pointer location to make sure things work properly - mysql_data_seek($this->result, 0); - - while ($row = $fetch($this->result, $type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = mysql_fetch_field($this->result)) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND mysql_data_seek($this->result, $offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - else - { - return FALSE; - } - } - -} // End Mysql_Result Class diff --git a/kohana/libraries/drivers/Database/Mysqli.php b/kohana/libraries/drivers/Database/Mysqli.php deleted file mode 100644 index 0dd9f05c..00000000 --- a/kohana/libraries/drivers/Database/Mysqli.php +++ /dev/null @@ -1,358 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MySQLi Database Driver - * - * $Id: Mysqli.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mysqli_Driver extends Database_Mysql_Driver { - - // Database connection link - protected $link; - protected $db_config; - protected $statements = array(); - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MySQLi Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_object($this->link) and $this->link->close(); - } - - public function connect() - { - // Check if link already exists - if (is_object($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Build the connection info - $host = isset($host) ? $host : $socket; - - // Make the connection and select the database - if ($this->link = new mysqli($host, $user, $pass, $database, $port)) - { - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - if ($this->link->set_charset($charset) === FALSE) - throw new Kohana_Database_Exception('database.error', $this->show_error()); - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_object($this->link) or $this->connect(); - - return $this->link->real_escape_string($str); - } - - public function show_error() - { - return $this->link->error; - } - -} // End Database_Mysqli_Driver Class - -/** - * MySQLi Result - */ -class Kohana_Mysqli_Result extends Database_Result { - - // Database connection - protected $link; - - // Data fetching types - protected $fetch_type = 'mysqli_fetch_object'; - protected $return_type = MYSQLI_ASSOC; - - /** - * Sets up the result variables. - * - * @param object database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($link, $object = TRUE, $sql) - { - $this->link = $link; - - if ( ! $this->link->multi_query($sql)) - { - // SQL error - throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); - } - else - { - $this->result = $this->link->store_result(); - - // If the query is an object, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_object($this->result)) - { - $this->current_row = 0; - $this->total_rows = $this->result->num_rows; - $this->fetch_type = ($object === TRUE) ? 'fetch_object' : 'fetch_array'; - } - elseif ($this->link->error) - { - // SQL error - throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - $this->insert_id = $this->link->insert_id; - $this->total_rows = $this->link->affected_rows; - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_object($this->result)) - { - $this->result->free_result(); - - // this is kinda useless, but needs to be done to avoid the "Commands out of sync; you - // can't run this command now" error. Basically, we get all results after the first one - // (the one we actually need) and free them. - if (is_resource($this->link) AND $this->link->more_results()) - { - do - { - if ($result = $this->link->store_result()) - { - $result->free_result(); - } - } while ($this->link->next_result()); - } - } - } - - public function result($object = TRUE, $type = MYSQLI_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'fetch_object' : 'fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MYSQLI_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MYSQLI_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if ($this->result->num_rows) - { - // Reset the pointer location to make sure things work properly - $this->result->data_seek(0); - - while ($row = $this->result->$fetch($type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = $this->result->fetch_field()) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND $this->result->data_seek($offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - - return FALSE; - } - - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row - $fetch = $this->fetch_type; - return $this->result->$fetch($this->return_type); - } - -} // End Mysqli_Result Class - -/** - * MySQLi Prepared Statement (experimental) - */ -class Kohana_Mysqli_Statement { - - protected $link = NULL; - protected $stmt; - protected $var_names = array(); - protected $var_values = array(); - - public function __construct($sql, $link) - { - $this->link = $link; - - $this->stmt = $this->link->prepare($sql); - - return $this; - } - - public function __destruct() - { - $this->stmt->close(); - } - - // Sets the bind parameters - public function bind_params($param_types, $params) - { - $this->var_names = array_keys($params); - $this->var_values = array_values($params); - call_user_func_array(array($this->stmt, 'bind_param'), array_merge($param_types, $var_names)); - - return $this; - } - - public function bind_result($params) - { - call_user_func_array(array($this->stmt, 'bind_result'), $params); - } - - // Runs the statement - public function execute() - { - foreach ($this->var_names as $key => $name) - { - $$name = $this->var_values[$key]; - } - $this->stmt->execute(); - return $this->stmt; - } -} diff --git a/kohana/libraries/drivers/Database/Pdosqlite.php b/kohana/libraries/drivers/Database/Pdosqlite.php deleted file mode 100644 index c2d1bb21..00000000 --- a/kohana/libraries/drivers/Database/Pdosqlite.php +++ /dev/null @@ -1,486 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/* - * Class: Database_PdoSqlite_Driver - * Provides specific database items for Sqlite. - * - * Connection string should be, eg: "pdosqlite://path/to/database.db" - * - * Version 1.0 alpha - * author - Doutu, updated by gregmac - * copyright - (c) BSD - * license - <no> - */ - -class Database_Pdosqlite_Driver extends Database_Driver { - - // Database connection link - protected $link; - protected $db_config; - - /* - * Constructor: __construct - * Sets up the config for the class. - * - * Parameters: - * config - database configuration - * - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'PDO:Sqlite Database Driver Initialized'); - } - - public function connect() - { - // Import the connect variables - extract($this->db_config['connection']); - - try - { - $this->link = new PDO('sqlite:'.$socket.$database, $user, $pass, - array(PDO::ATTR_PERSISTENT => $this->db_config['persistent'])); - - $this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); - //$this->link->query('PRAGMA count_changes=1;'); - - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - public function query($sql) - { - try - { - $sth = $this->link->prepare($sql); - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - return new Pdosqlite_Result($sth, $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->link->query('PRAGMA encoding = '.$this->escape_str($charset)); - } - - public function escape_table($table) - { - if ( ! $this->db_config['escape']) - return $table; - - return '`'.str_replace('.', '`.`', $table).'`'; - } - - public function escape_column($column) - { - if ( ! $this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '`$0`', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$offset.', '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - $sql .= "\nFROM "; - $sql .= implode(', ', $database['from']); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if ( ! $this->db_config['escape']) - return $str; - - if (function_exists('sqlite_escape_string')) - { - $res = sqlite_escape_string($str); - } - else - { - $res = str_replace("'", "''", $str); - } - return $res; - } - - public function list_tables() - { - $sql = "SELECT `name` FROM `sqlite_master` WHERE `type`='table' ORDER BY `name`;"; - try - { - $result = $this->query($sql)->result(FALSE, PDO::FETCH_ASSOC); - $tables = array(); - foreach ($result as $row) - { - $tables[] = current($row); - } - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - return $tables; - } - - public function show_error() - { - $err = $this->link->errorInfo(); - return isset($err[2]) ? $err[2] : 'Unknown error!'; - } - - public function list_fields($table, $query = FALSE) - { - static $tables; - if (is_object($query)) - { - if (empty($tables[$table])) - { - $tables[$table] = array(); - - foreach ($query->result() as $row) - { - $tables[$table][] = $row->name; - } - } - - return $tables[$table]; - } - else - { - $result = $this->link->query( 'PRAGMA table_info('.$this->escape_table($table).')' ); - - foreach ($result as $row) - { - $tables[$table][$row['name']] = $this->sql_type($row['type']); - } - - return $tables[$table]; - } - } - - public function field_data($table) - { - Kohana::log('error', 'This method is under developing'); - } - /** - * Version number query string - * - * @access public - * @return string - */ - function version() - { - return $this->link->getAttribute(constant("PDO::ATTR_SERVER_VERSION")); - } - -} // End Database_PdoSqlite_Driver Class - -/* - * PDO-sqlite Result - */ -class Pdosqlite_Result extends Database_Result { - - // Data fetching types - protected $fetch_type = PDO::FETCH_OBJ; - protected $return_type = PDO::FETCH_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - if (is_object($result) OR $result = $link->prepare($sql)) - { - // run the query. Return true if success, false otherwise - if( ! $result->execute()) - { - // Throw Kohana Exception with error message. See PDOStatement errorInfo() method - $arr_infos = $result->errorInfo(); - throw new Kohana_Database_Exception('database.error', $arr_infos[2]); - } - - if (preg_match('/^SELECT|PRAGMA|EXPLAIN/i', $sql)) - { - $this->result = $result; - $this->current_row = 0; - - $this->total_rows = $this->sqlite_row_count(); - - $this->fetch_type = ($object === TRUE) ? PDO::FETCH_OBJ : PDO::FETCH_ASSOC; - } - elseif (preg_match('/^DELETE|INSERT|UPDATE/i', $sql)) - { - $this->insert_id = $link->lastInsertId(); - - $this->total_rows = $result->rowCount(); - } - } - else - { - // SQL error - throw new Kohana_Database_Exception('database.error', $link->errorInfo().' - '.$sql); - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - private function sqlite_row_count() - { - $count = 0; - while ($this->result->fetch()) - { - $count++; - } - - // The query must be re-fetched now. - $this->result->execute(); - - return $count; - } - - /* - * Destructor: __destruct - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_object($this->result)) - { - $this->result->closeCursor(); - $this->result = NULL; - } - } - - public function result($object = TRUE, $type = PDO::FETCH_BOTH) - { - $this->fetch_type = (bool) $object ? PDO::FETCH_OBJ : PDO::FETCH_BOTH; - - if ($this->fetch_type == PDO::FETCH_OBJ) - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = PDO::FETCH_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = PDO::FETCH_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = PDO::FETCH_OBJ; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = PDO::FETCH_OBJ; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == PDO::FETCH_OBJ) - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - try - { - while ($row = $this->result->fetch($fetch)) - { - $rows[] = $row; - } - } - catch(PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - return FALSE; - } - return $rows; - } - - public function list_fields() - { - $field_names = array(); - for ($i = 0, $max = $this->result->columnCount(); $i < $max; $i++) - { - $info = $this->result->getColumnMeta($i); - $field_names[] = $info['name']; - } - return $field_names; - } - - public function seek($offset) - { - // To request a scrollable cursor for your PDOStatement object, you must - // set the PDO::ATTR_CURSOR attribute to PDO::CURSOR_SCROLL when you - // prepare the statement. - Kohana::log('error', get_class($this).' does not support scrollable cursors, '.__FUNCTION__.' call ignored'); - - return FALSE; - } - - public function offsetGet($offset) - { - try - { - return $this->result->fetch($this->fetch_type, PDO::FETCH_ORI_ABS, $offset); - } - catch(PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - } - - public function rewind() - { - // Same problem that seek() has, see above. - return $this->seek(0); - } - -} // End PdoSqlite_Result Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Database/Pgsql.php b/kohana/libraries/drivers/Database/Pgsql.php deleted file mode 100644 index c53c8439..00000000 --- a/kohana/libraries/drivers/Database/Pgsql.php +++ /dev/null @@ -1,538 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * PostgreSQL 8.1+ Database Driver - * - * $Id: Pgsql.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Pgsql_Driver extends Database_Driver { - - // Database connection link - protected $link; - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'PgSQL Database Driver Initialized'); - } - - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'pg_pconnect' : 'pg_connect'; - - // Build the connection info - $port = isset($port) ? 'port=\''.$port.'\'' : ''; - $host = isset($host) ? 'host=\''.$host.'\' '.$port : ''; // if no host, connect with the socket - - $connection_string = $host.' dbname=\''.$database.'\' user=\''.$user.'\' password=\''.$pass.'\''; - // Make the connection and select the database - if ($this->link = $connect($connection_string)) - { - if ($charset = $this->db_config['character_set']) - { - echo $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|SET)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - return $this->query_cache[$hash]; - } - - // Suppress warning triggered when a database error occurs (e.g., a constraint violation) - return new Pgsql_Result(@pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->query('SET client_encoding TO '.pg_escape_string($this->link, $charset)); - } - - public function escape_table($table) - { - if (!$this->db_config['escape']) - return $table; - - return '"'.str_replace('.', '"."', $table).'"'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:all|distinct)\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '"$0"', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '"$0"', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function regex($field, $match, $type, $num_regexs) - { - $prefix = ($num_regexs == 0) ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' ~* \''.$this->escape_str($match).'\''; - } - - public function notregex($field, $match, $type, $num_regexs) - { - $prefix = $num_regexs == 0 ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' !~* \''.$this->escape_str($match) . '\''; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$limit.' OFFSET '.$offset; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - $sql .= "\nFROM "; - $sql .= implode(', ', $database['from']); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - - return pg_escape_string($this->link, $str); - } - - public function list_tables() - { - $sql = 'SELECT table_schema || \'.\' || table_name FROM information_schema.tables WHERE table_schema NOT IN (\'pg_catalog\', \'information_schema\')'; - $result = $this->query($sql)->result(FALSE, PGSQL_ASSOC); - - $retval = array(); - foreach ($result as $row) - { - $retval[] = current($row); - } - - return $retval; - } - - public function show_error() - { - return pg_last_error($this->link); - } - - public function list_fields($table) - { - $result = NULL; - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->column_name] = $this->sql_type($row->data_type); - - if (!strncmp($row->column_default, 'nextval(', 8)) - { - $result[$row->column_name]['sequenced'] = TRUE; - } - - if ($row->is_nullable === 'YES') - { - $result[$row->column_name]['null'] = TRUE; - } - } - - if (!isset($result)) - throw new Kohana_Database_Exception('database.table_not_found', $table); - - return $result; - } - - public function field_data($table) - { - // http://www.postgresql.org/docs/8.3/static/infoschema-columns.html - $result = $this->query(' - SELECT column_name, column_default, is_nullable, data_type, udt_name, - character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale - FROM information_schema.columns - WHERE table_name = \''. $this->escape_str($table) .'\' - ORDER BY ordinal_position - '); - - return $result->result_array(TRUE); - } - -} // End Database_Pgsql_Driver Class - -/** - * PostgreSQL Result - */ -class Pgsql_Result extends Database_Result { - - // Data fetching types - protected $fetch_type = 'pgsql_fetch_object'; - protected $return_type = PGSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->link = $link; - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - if (preg_match('/^(?:delete|insert|replace|update)\b/iD', trim($sql), $matches)) - { - $this->insert_id = (strtolower($matches[0]) == 'insert') ? $this->insert_id() : FALSE; - $this->total_rows = pg_affected_rows($this->result); - } - else - { - $this->current_row = 0; - $this->total_rows = pg_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'pg_fetch_object' : 'pg_fetch_array'; - } - } - else - { - throw new Kohana_Database_Exception('database.error', pg_last_error().' - '.$sql); - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_resource($this->result)) - { - pg_free_result($this->result); - } - } - - public function result($object = TRUE, $type = PGSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'pg_fetch_object' : 'pg_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'pg_fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = PGSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = PGSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'pg_fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'pg_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'pg_fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if ($this->total_rows) - { - pg_result_seek($this->result, 0); - - while ($row = $fetch($this->result, NULL, $type)) - { - $rows[] = $row; - } - } - - return $rows; - } - - public function insert_id() - { - if ($this->insert_id === NULL) - { - $query = 'SELECT LASTVAL() AS insert_id'; - - // Disable error reporting for this, just to silence errors on - // tables that have no serial column. - $ER = error_reporting(0); - - $result = pg_query($this->link, $query); - $insert_id = pg_fetch_array($result, NULL, PGSQL_ASSOC); - - $this->insert_id = $insert_id['insert_id']; - - // Reset error reporting - error_reporting($ER); - } - - return $this->insert_id; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND pg_result_seek($this->result, $offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - - return FALSE; - } - - public function list_fields() - { - $field_names = array(); - - $fields = pg_num_fields($this->result); - for ($i = 0; $i < $fields; ++$i) - { - $field_names[] = pg_field_name($this->result, $i); - } - - return $field_names; - } - - /** - * ArrayAccess: offsetGet - */ - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row by calling the defined fetching callback - $fetch = $this->fetch_type; - return $fetch($this->result, NULL, $this->return_type); - } - -} // End Pgsql_Result Class - -/** - * PostgreSQL Prepared Statement (experimental) - */ -class Kohana_Pgsql_Statement { - - protected $link = NULL; - protected $stmt; - - public function __construct($sql, $link) - { - $this->link = $link; - - $this->stmt = $this->link->prepare($sql); - - return $this; - } - - public function __destruct() - { - $this->stmt->close(); - } - - // Sets the bind parameters - public function bind_params() - { - $argv = func_get_args(); - return $this; - } - - // sets the statement values to the bound parameters - public function set_vals() - { - return $this; - } - - // Runs the statement - public function execute() - { - return $this; - } -} diff --git a/kohana/libraries/drivers/Image.php b/kohana/libraries/drivers/Image.php deleted file mode 100644 index f89ba953..00000000 --- a/kohana/libraries/drivers/Image.php +++ /dev/null @@ -1,156 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Image API driver. - * - * $Id: Image.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Image_Driver { - - // Reference to the current image - protected $image; - - // Reference to the temporary processing image - protected $tmp_image; - - // Processing errors - protected $errors = array(); - - /** - * Executes a set of actions, defined in pairs. - * - * @param array actions - * @return boolean - */ - public function execute($actions) - { - foreach ($actions as $func => $args) - { - if ( ! $this->$func($args)) - return FALSE; - } - - return TRUE; - } - - /** - * Sanitize and normalize a geometry array based on the temporary image - * width and height. Valid properties are: width, height, top, left. - * - * @param array geometry properties - * @return void - */ - protected function sanitize_geometry( & $geometry) - { - list($width, $height) = $this->properties(); - - // Turn off error reporting - $reporting = error_reporting(0); - - // Width and height cannot exceed current image size - $geometry['width'] = min($geometry['width'], $width); - $geometry['height'] = min($geometry['height'], $height); - - // Set standard coordinates if given, otherwise use pixel values - if ($geometry['top'] === 'center') - { - $geometry['top'] = floor(($height / 2) - ($geometry['height'] / 2)); - } - elseif ($geometry['top'] === 'top') - { - $geometry['top'] = 0; - } - elseif ($geometry['top'] === 'bottom') - { - $geometry['top'] = $height - $geometry['height']; - } - - // Set standard coordinates if given, otherwise use pixel values - if ($geometry['left'] === 'center') - { - $geometry['left'] = floor(($width / 2) - ($geometry['width'] / 2)); - } - elseif ($geometry['left'] === 'left') - { - $geometry['left'] = 0; - } - elseif ($geometry['left'] === 'right') - { - $geometry['left'] = $width - $geometry['height']; - } - - // Restore error reporting - error_reporting($reporting); - } - - /** - * Return the current width and height of the temporary image. This is mainly - * needed for sanitizing the geometry. - * - * @return array width, height - */ - abstract protected function properties(); - - /** - * Process an image with a set of actions. - * - * @param string image filename - * @param array actions to execute - * @param string destination directory path - * @param string destination filename - * @return boolean - */ - abstract public function process($image, $actions, $dir, $file); - - /** - * Flip an image. Valid directions are horizontal and vertical. - * - * @param integer direction to flip - * @return boolean - */ - abstract function flip($direction); - - /** - * Crop an image. Valid properties are: width, height, top, left. - * - * @param array new properties - * @return boolean - */ - abstract function crop($properties); - - /** - * Resize an image. Valid properties are: width, height, and master. - * - * @param array new properties - * @return boolean - */ - abstract public function resize($properties); - - /** - * Rotate an image. Valid amounts are -180 to 180. - * - * @param integer amount to rotate - * @return boolean - */ - abstract public function rotate($amount); - - /** - * Sharpen and image. Valid amounts are 1 to 100. - * - * @param integer amount to sharpen - * @return boolean - */ - abstract public function sharpen($amount); - - /** - * Overlay a second image. Valid properties are: overlay_file, mime, x, y and transparency. - * - * @return boolean - */ - abstract public function composite($properties); - -} // End Image Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/GD.php b/kohana/libraries/drivers/Image/GD.php deleted file mode 100644 index be2af4e2..00000000 --- a/kohana/libraries/drivers/Image/GD.php +++ /dev/null @@ -1,401 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * GD Image Driver. - * - * $Id: GD.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_GD_Driver extends Image_Driver { - - // A transparent PNG as a string - protected static $blank_png; - protected static $blank_png_width; - protected static $blank_png_height; - - public function __construct() - { - // Make sure that GD2 is available - if ( ! function_exists('gd_info')) - throw new Kohana_Exception('image.gd.requires_v2'); - - // Get the GD information - $info = gd_info(); - - // Make sure that the GD2 is installed - if (strpos($info['GD Version'], '2.') === FALSE) - throw new Kohana_Exception('image.gd.requires_v2'); - } - - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // Set the "create" function - switch ($image['type']) - { - case IMAGETYPE_JPEG: - $create = 'imagecreatefromjpeg'; - break; - case IMAGETYPE_GIF: - $create = 'imagecreatefromgif'; - break; - case IMAGETYPE_PNG: - $create = 'imagecreatefrompng'; - break; - } - - // Set the "save" function - switch (strtolower(substr(strrchr($file, '.'), 1))) - { - case 'jpg': - case 'jpeg': - $save = 'imagejpeg'; - break; - case 'gif': - $save = 'imagegif'; - break; - case 'png': - $save = 'imagepng'; - break; - } - - // Make sure the image type is supported for import - if (empty($create) OR ! function_exists($create)) - throw new Kohana_Exception('image.type_not_allowed', $image['file']); - - // Make sure the image type is supported for saving - if (empty($save) OR ! function_exists($save)) - throw new Kohana_Exception('image.type_not_allowed', $dir.$file); - - // Load the image - $this->image = $image; - - // Create the GD image resource - $this->tmp_image = $create($image['file']); - - // Get the quality setting from the actions - $quality = arr::remove('quality', $actions); - - if ($status = $this->execute($actions)) - { - // Prevent the alpha from being lost - imagealphablending($this->tmp_image, TRUE); - imagesavealpha($this->tmp_image, TRUE); - - switch ($save) - { - case 'imagejpeg': - // Default the quality to 95 - ($quality === NULL) and $quality = 95; - break; - case 'imagegif': - // Remove the quality setting, GIF doesn't use it - unset($quality); - break; - case 'imagepng': - // Always use a compression level of 9 for PNGs. This does not - // affect quality, it only increases the level of compression! - $quality = 9; - break; - } - - if ($render === FALSE) - { - // Set the status to the save return value, saving with the quality requested - $status = isset($quality) ? $save($this->tmp_image, $dir.$file, $quality) : $save($this->tmp_image, $dir.$file); - } - else - { - // Output the image directly to the browser - switch ($save) - { - case 'imagejpeg': - header('Content-Type: image/jpeg'); - break; - case 'imagegif': - header('Content-Type: image/gif'); - break; - case 'imagepng': - header('Content-Type: image/png'); - break; - } - - $status = isset($quality) ? $save($this->tmp_image, NULL, $quality) : $save($this->tmp_image); - } - - // Destroy the temporary image - imagedestroy($this->tmp_image); - } - - return $status; - } - - public function flip($direction) - { - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - // Create the flipped image - $flipped = $this->imagecreatetransparent($width, $height); - - if ($direction === Image::HORIZONTAL) - { - for ($x = 0; $x < $width; $x++) - { - $status = imagecopy($flipped, $this->tmp_image, $x, 0, $width - $x - 1, 0, 1, $height); - } - } - elseif ($direction === Image::VERTICAL) - { - for ($y = 0; $y < $height; $y++) - { - $status = imagecopy($flipped, $this->tmp_image, 0, $y, 0, $height - $y - 1, $width, 1); - } - } - else - { - // Do nothing - return TRUE; - } - - if ($status === TRUE) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $flipped; - } - - return $status; - } - - public function crop($properties) - { - // Sanitize the cropping settings - $this->sanitize_geometry($properties); - - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($properties['width'], $properties['height']); - - // Execute the crop - if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, $properties['left'], $properties['top'], $width, $height, $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function resize($properties) - { - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - if (substr($properties['width'], -1) === '%') - { - // Recalculate the percentage to a pixel size - $properties['width'] = round($width * (substr($properties['width'], 0, -1) / 100)); - } - - if (substr($properties['height'], -1) === '%') - { - // Recalculate the percentage to a pixel size - $properties['height'] = round($height * (substr($properties['height'], 0, -1) / 100)); - } - - // Recalculate the width and height, if they are missing - empty($properties['width']) and $properties['width'] = round($width * $properties['height'] / $height); - empty($properties['height']) and $properties['height'] = round($height * $properties['width'] / $width); - - if ($properties['master'] === Image::AUTO) - { - // Change an automatic master dim to the correct type - $properties['master'] = (($width / $properties['width']) > ($height / $properties['height'])) ? Image::WIDTH : Image::HEIGHT; - } - - if (empty($properties['height']) OR $properties['master'] === Image::WIDTH) - { - // Recalculate the height based on the width - $properties['height'] = round($height * $properties['width'] / $width); - } - - if (empty($properties['width']) OR $properties['master'] === Image::HEIGHT) - { - // Recalculate the width based on the height - $properties['width'] = round($width * $properties['height'] / $height); - } - - // Test if we can do a resize without resampling to speed up the final resize - if ($properties['width'] > $width / 2 AND $properties['height'] > $height / 2) - { - // Presize width and height - $pre_width = $width; - $pre_height = $height; - - // The maximum reduction is 10% greater than the final size - $max_reduction_width = round($properties['width'] * 1.1); - $max_reduction_height = round($properties['height'] * 1.1); - - // Reduce the size using an O(2n) algorithm, until it reaches the maximum reduction - while ($pre_width / 2 > $max_reduction_width AND $pre_height / 2 > $max_reduction_height) - { - $pre_width /= 2; - $pre_height /= 2; - } - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($pre_width, $pre_height); - - if ($status = imagecopyresized($img, $this->tmp_image, 0, 0, 0, 0, $pre_width, $pre_height, $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - // Set the width and height to the presize - $width = $pre_width; - $height = $pre_height; - } - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($properties['width'], $properties['height']); - - // Execute the resize - if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, 0, 0, $properties['width'], $properties['height'], $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function rotate($amount) - { - // Use current image to rotate - $img = $this->tmp_image; - - // White, with an alpha of 0 - $transparent = imagecolorallocatealpha($img, 255, 255, 255, 127); - - // Rotate, setting the transparent color - $img = imagerotate($img, 360 - $amount, $transparent, -1); - - // Fill the background with the transparent "color" - imagecolortransparent($img, $transparent); - - // Merge the images - if ($status = imagecopymerge($this->tmp_image, $img, 0, 0, 0, 0, imagesx($this->tmp_image), imagesy($this->tmp_image), 100)) - { - // Prevent the alpha from being lost - imagealphablending($img, TRUE); - imagesavealpha($img, TRUE); - - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function sharpen($amount) - { - // Make sure that the sharpening function is available - if ( ! function_exists('imageconvolution')) - throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); - - // Amount should be in the range of 18-10 - $amount = round(abs(-18 + ($amount * 0.08)), 2); - - // Gaussian blur matrix - $matrix = array - ( - array(-1, -1, -1), - array(-1, $amount, -1), - array(-1, -1, -1), - ); - - // Perform the sharpen - return imageconvolution($this->tmp_image, $matrix, $amount - 8, 0); - } - - public function composite($properties) - { - switch($properties['mime']) - { - case "image/jpeg": - $overlay_img = imagecreatefromjpeg($properties['overlay_file']); - break; - - case "image/gif": - $overlay_img = imagecreatefromgif($properties['overlay_file']); - break; - - case "image/png": - $overlay_img = imagecreatefrompng($properties['overlay_file']); - break; - } - - imagecopymerge($this->tmp_image, $overlay_img, $properties['x'], $properties['y'], 0, 0, imagesx($overlay_img), imagesy($overlay_img), $properties['transparency']); - imagedestroy($overlay_img); - return TRUE; - } - - protected function properties() - { - return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); - } - - /** - * Returns an image with a transparent background. Used for rotating to - * prevent unfilled backgrounds. - * - * @param integer image width - * @param integer image height - * @return resource - */ - protected function imagecreatetransparent($width, $height) - { - if (self::$blank_png === NULL) - { - // Decode the blank PNG if it has not been done already - self::$blank_png = imagecreatefromstring(base64_decode - ( - 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29'. - 'mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBN'. - 'CgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQ'. - 'AANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoH'. - 'AgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB'. - '3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=' - )); - - // Set the blank PNG width and height - self::$blank_png_width = imagesx(self::$blank_png); - self::$blank_png_height = imagesy(self::$blank_png); - } - - $img = imagecreatetruecolor($width, $height); - - // Resize the blank image - imagecopyresized($img, self::$blank_png, 0, 0, 0, 0, $width, $height, self::$blank_png_width, self::$blank_png_height); - - // Prevent the alpha from being lost - imagealphablending($img, FALSE); - imagesavealpha($img, TRUE); - - return $img; - } - -} // End Image GD Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/GraphicsMagick.php b/kohana/libraries/drivers/Image/GraphicsMagick.php deleted file mode 100644 index a8bc4d9b..00000000 --- a/kohana/libraries/drivers/Image/GraphicsMagick.php +++ /dev/null @@ -1,221 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * GraphicsMagick Image Driver. - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_GraphicsMagick_Driver extends Image_Driver { - - // Directory that GM is installed in - protected $dir = ''; - - // Command extension (exe for windows) - protected $ext = ''; - - // Temporary image filename - protected $tmp_image; - - /** - * Attempts to detect the GraphicsMagick installation directory. - * - * @throws Kohana_Exception - * @param array configuration - * @return void - */ - public function __construct($config) - { - if (empty($config['directory'])) - { - // Attempt to locate GM by using "which" (only works for *nix!) - if ( ! is_file($path = exec('which gm'))) - throw new Kohana_Exception('image.graphicsmagick.not_found'); - - $config['directory'] = dirname($path); - } - - // Set the command extension - $this->ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; - - // Check to make sure the provided path is correct - if ( ! is_file(realpath($config['directory']).'/gm'.$this->ext)) - throw new Kohana_Exception('image.graphicsmagick.not_found', 'gm'.$this->ext); - - - // Set the installation directory - $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; - } - - /** - * Creates a temporary image and executes the given actions. By creating a - * temporary copy of the image before manipulating it, this process is atomic. - */ - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // We only need the filename - $image = $image['file']; - - // Unique temporary filename - $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); - - // Copy the image to the temporary file - copy($image, $this->tmp_image); - - // Quality change is done last - $quality = (int) arr::remove('quality', $actions); - - // Use 95 for the default quality - empty($quality) and $quality = 95; - - // All calls to these will need to be escaped, so do it now - $this->cmd_image = escapeshellarg($this->tmp_image); - $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); - - if ($status = $this->execute($actions)) - { - // Use convert to change the image into its final version. This is - // done to allow the file type to change correctly, and to handle - // the quality conversion in the most effective way possible. - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) - { - $this->errors[] = $error; - } - else - { - // Output the image directly to the browser - if ($render !== FALSE) - { - $contents = file_get_contents($this->tmp_image); - switch (substr($file, strrpos($file, '.') + 1)) - { - case 'jpg': - case 'jpeg': - header('Content-Type: image/jpeg'); - break; - case 'gif': - header('Content-Type: image/gif'); - break; - case 'png': - header('Content-Type: image/png'); - break; - } - echo $contents; - } - } - } - - // Remove the temporary image - unlink($this->tmp_image); - $this->tmp_image = ''; - - return $status; - } - - public function crop($prop) - { - // Sanitize and normalize the properties into geometry - $this->sanitize_geometry($prop); - - // Set the IM geometry based on the properties - $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function flip($dir) - { - // Convert the direction into a GM command - $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function resize($prop) - { - switch ($prop['master']) - { - case Image::WIDTH: // Wx - $dim = escapeshellarg($prop['width'].'x'); - break; - case Image::HEIGHT: // xH - $dim = escapeshellarg('x'.$prop['height']); - break; - case Image::AUTO: // WxH - $dim = escapeshellarg($prop['width'].'x'.$prop['height']); - break; - case Image::NONE: // WxH! - $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); - break; - } - - // Use "convert" to change the width and height - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function rotate($amt) - { - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function sharpen($amount) - { - // Set the sigma, radius, and amount. The amount formula allows a nice - // spread between 1 and 100 without pixelizing the image badly. - $sigma = 0.5; - $radius = $sigma * 2; - $amount = round(($amount / 80) * 3.14, 2); - - // Convert the amount to an GM command - $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function composite($properties) - { - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' composite').' -geometry ' . escapeshellarg('+'.$properties['x'].'+'.$properties['y']).' -dissolve '.escapeshellarg($properties['transparency']).' '.escapeshellarg($properties['overlay_file']).' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - return TRUE; - } - - protected function properties() - { - return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); - } - -} // End Image GraphicsMagick Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/ImageMagick.php b/kohana/libraries/drivers/Image/ImageMagick.php deleted file mode 100644 index 4b381fd6..00000000 --- a/kohana/libraries/drivers/Image/ImageMagick.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * ImageMagick Image Driver. - * - * $Id: ImageMagick.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_ImageMagick_Driver extends Image_Driver { - - // Directory that IM is installed in - protected $dir = ''; - - // Command extension (exe for windows) - protected $ext = ''; - - // Temporary image filename - protected $tmp_image; - - /** - * Attempts to detect the ImageMagick installation directory. - * - * @throws Kohana_Exception - * @param array configuration - * @return void - */ - public function __construct($config) - { - if (empty($config['directory'])) - { - // Attempt to locate IM by using "which" (only works for *nix!) - if ( ! is_file($path = exec('which convert'))) - throw new Kohana_Exception('image.imagemagick.not_found'); - - $config['directory'] = dirname($path); - } - - // Set the command extension - $this->ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; - - // Check to make sure the provided path is correct - if ( ! is_file(realpath($config['directory']).'/convert'.$this->ext)) - throw new Kohana_Exception('image.imagemagick.not_found', 'convert'.$this->ext); - - // Set the installation directory - $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; - } - - /** - * Creates a temporary image and executes the given actions. By creating a - * temporary copy of the image before manipulating it, this process is atomic. - */ - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // We only need the filename - $image = $image['file']; - - // Unique temporary filename - $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); - - // Copy the image to the temporary file - copy($image, $this->tmp_image); - - // Quality change is done last - $quality = (int) arr::remove('quality', $actions); - - // Use 95 for the default quality - empty($quality) and $quality = 95; - - // All calls to these will need to be escaped, so do it now - $this->cmd_image = escapeshellarg($this->tmp_image); - $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); - - if ($status = $this->execute($actions)) - { - // Use convert to change the image into its final version. This is - // done to allow the file type to change correctly, and to handle - // the quality conversion in the most effective way possible. - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) - { - $this->errors[] = $error; - } - else - { - // Output the image directly to the browser - if ($render !== FALSE) - { - $contents = file_get_contents($this->tmp_image); - switch (substr($file, strrpos($file, '.') + 1)) - { - case 'jpg': - case 'jpeg': - header('Content-Type: image/jpeg'); - break; - case 'gif': - header('Content-Type: image/gif'); - break; - case 'png': - header('Content-Type: image/png'); - break; - } - echo $contents; - } - } - } - - // Remove the temporary image - unlink($this->tmp_image); - $this->tmp_image = ''; - - return $status; - } - - public function crop($prop) - { - // Sanitize and normalize the properties into geometry - $this->sanitize_geometry($prop); - - // Set the IM geometry based on the properties - $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function flip($dir) - { - // Convert the direction into a IM command - $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function resize($prop) - { - switch ($prop['master']) - { - case Image::WIDTH: // Wx - $dim = escapeshellarg($prop['width'].'x'); - break; - case Image::HEIGHT: // xH - $dim = escapeshellarg('x'.$prop['height']); - break; - case Image::AUTO: // WxH - $dim = escapeshellarg($prop['width'].'x'.$prop['height']); - break; - case Image::NONE: // WxH! - $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); - break; - } - - // Use "convert" to change the width and height - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function rotate($amt) - { - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function sharpen($amount) - { - // Set the sigma, radius, and amount. The amount formula allows a nice - // spread between 1 and 100 without pixelizing the image badly. - $sigma = 0.5; - $radius = $sigma * 2; - $amount = round(($amount / 80) * 3.14, 2); - - // Convert the amount to an IM command - $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function composite($properties) - { - if ($error = exec(escapeshellcmd($this->dir.'composite'.$this->ext).' -geometry ' . escapeshellarg('+'.$properties['x'].'+'.$properties['y']).' -dissolve '.escapeshellarg($properties['transparency']).' '.escapeshellarg($properties['overlay_file']).' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - return TRUE; - } - - protected function properties() - { - return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); - } - -} // End Image ImageMagick Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session.php b/kohana/libraries/drivers/Session.php deleted file mode 100644 index fb58c8d3..00000000 --- a/kohana/libraries/drivers/Session.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session driver interface - * - * $Id: Session.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -interface Session_Driver { - - /** - * Opens a session. - * - * @param string save path - * @param string session name - * @return boolean - */ - public function open($path, $name); - - /** - * Closes a session. - * - * @return boolean - */ - public function close(); - - /** - * Reads a session. - * - * @param string session id - * @return string - */ - public function read($id); - - /** - * Writes a session. - * - * @param string session id - * @param string session data - * @return boolean - */ - public function write($id, $data); - - /** - * Destroys a session. - * - * @param string session id - * @return boolean - */ - public function destroy($id); - - /** - * Regenerates the session id. - * - * @return string - */ - public function regenerate(); - - /** - * Garbage collection. - * - * @param integer session expiration period - * @return boolean - */ - public function gc($maxlifetime); - -} // End Session Driver Interface
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session/Cache.php b/kohana/libraries/drivers/Session/Cache.php deleted file mode 100644 index 7221c9f2..00000000 --- a/kohana/libraries/drivers/Session/Cache.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session cache driver. - * - * Cache library config goes in the session.storage config entry: - * $config['storage'] = array( - * 'driver' => 'apc', - * 'requests' => 10000 - * ); - * Lifetime does not need to be set as it is - * overridden by the session expiration setting. - * - * $Id: Cache.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Cache_Driver implements Session_Driver { - - protected $cache; - protected $encrypt; - - public function __construct() - { - // Load Encrypt library - if (Kohana::config('session.encryption')) - { - $this->encrypt = new Encrypt; - } - - Kohana::log('debug', 'Session Cache Driver Initialized'); - } - - public function open($path, $name) - { - $config = Kohana::config('session.storage'); - - if (empty($config)) - { - // Load the default group - $config = Kohana::config('cache.default'); - } - elseif (is_string($config)) - { - $name = $config; - - // Test the config group name - if (($config = Kohana::config('cache.'.$config)) === NULL) - throw new Kohana_Exception('cache.undefined_group', $name); - } - - $config['lifetime'] = (Kohana::config('session.expiration') == 0) ? 86400 : Kohana::config('session.expiration'); - $this->cache = new Cache($config); - - return is_object($this->cache); - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - $id = 'session_'.$id; - if ($data = $this->cache->get($id)) - { - return Kohana::config('session.encryption') ? $this->encrypt->decode($data) : $data; - } - - // Return value must be string, NOT a boolean - return ''; - } - - public function write($id, $data) - { - $id = 'session_'.$id; - $data = Kohana::config('session.encryption') ? $this->encrypt->encode($data) : $data; - - return $this->cache->set($id, $data); - } - - public function destroy($id) - { - $id = 'session_'.$id; - return $this->cache->delete($id); - } - - public function regenerate() - { - session_regenerate_id(TRUE); - - // Return new session id - return session_id(); - } - - public function gc($maxlifetime) - { - // Just return, caches are automatically cleaned up - return TRUE; - } - -} // End Session Cache Driver diff --git a/kohana/libraries/drivers/Session/Cookie.php b/kohana/libraries/drivers/Session/Cookie.php deleted file mode 100644 index 7b791064..00000000 --- a/kohana/libraries/drivers/Session/Cookie.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session cookie driver. - * - * $Id: Cookie.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Cookie_Driver implements Session_Driver { - - protected $cookie_name; - protected $encrypt; // Library - - public function __construct() - { - $this->cookie_name = Kohana::config('session.name').'_data'; - - if (Kohana::config('session.encryption')) - { - $this->encrypt = Encrypt::instance(); - } - - Kohana::log('debug', 'Session Cookie Driver Initialized'); - } - - public function open($path, $name) - { - return TRUE; - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - $data = (string) cookie::get($this->cookie_name); - - if ($data == '') - return $data; - - return empty($this->encrypt) ? base64_decode($data) : $this->encrypt->decode($data); - } - - public function write($id, $data) - { - $data = empty($this->encrypt) ? base64_encode($data) : $this->encrypt->encode($data); - - if (strlen($data) > 4048) - { - Kohana::log('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); - return FALSE; - } - - return cookie::set($this->cookie_name, $data, Kohana::config('session.expiration')); - } - - public function destroy($id) - { - return cookie::delete($this->cookie_name); - } - - public function regenerate() - { - session_regenerate_id(TRUE); - - // Return new id - return session_id(); - } - - public function gc($maxlifetime) - { - return TRUE; - } - -} // End Session Cookie Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session/Database.php b/kohana/libraries/drivers/Session/Database.php deleted file mode 100644 index b4144ffb..00000000 --- a/kohana/libraries/drivers/Session/Database.php +++ /dev/null @@ -1,163 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session database driver. - * - * $Id: Database.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Database_Driver implements Session_Driver { - - /* - CREATE TABLE sessions - ( - session_id VARCHAR(127) NOT NULL, - last_activity INT(10) UNSIGNED NOT NULL, - data TEXT NOT NULL, - PRIMARY KEY (session_id) - ); - */ - - // Database settings - protected $db = 'default'; - protected $table = 'sessions'; - - // Encryption - protected $encrypt; - - // Session settings - protected $session_id; - protected $written = FALSE; - - public function __construct() - { - // Load configuration - $config = Kohana::config('session'); - - if ( ! empty($config['encryption'])) - { - // Load encryption - $this->encrypt = Encrypt::instance(); - } - - if (is_array($config['storage'])) - { - if ( ! empty($config['storage']['group'])) - { - // Set the group name - $this->db = $config['storage']['group']; - } - - if ( ! empty($config['storage']['table'])) - { - // Set the table name - $this->table = $config['storage']['table']; - } - } - - // Load database - $this->db = Database::instance($this->db); - - Kohana::log('debug', 'Session Database Driver Initialized'); - } - - public function open($path, $name) - { - return TRUE; - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - // Load the session - $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); - - if ($query->count() === 0) - { - // No current session - $this->session_id = NULL; - - return ''; - } - - // Set the current session id - $this->session_id = $id; - - // Load the data - $data = $query->current()->data; - - return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data); - } - - public function write($id, $data) - { - $data = array - ( - 'session_id' => $id, - 'last_activity' => time(), - 'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data) - ); - - if ($this->session_id === NULL) - { - // Insert a new session - $query = $this->db->insert($this->table, $data); - } - elseif ($id === $this->session_id) - { - // Do not update the session_id - unset($data['session_id']); - - // Update the existing session - $query = $this->db->update($this->table, $data, array('session_id' => $id)); - } - else - { - // Update the session and id - $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); - - // Set the new session id - $this->session_id = $id; - } - - return (bool) $query->count(); - } - - public function destroy($id) - { - // Delete the requested session - $this->db->delete($this->table, array('session_id' => $id)); - - // Session id is no longer valid - $this->session_id = NULL; - - return TRUE; - } - - public function regenerate() - { - // Generate a new session id - session_regenerate_id(); - - // Return new session id - return session_id(); - } - - public function gc($maxlifetime) - { - // Delete all expired sessions - $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); - - Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); - - return TRUE; - } - -} // End Session Database Driver |