diff options
Diffstat (limited to 'system/libraries/drivers')
34 files changed, 927 insertions, 4380 deletions
diff --git a/system/libraries/drivers/Cache.php b/system/libraries/drivers/Cache.php index 7c5e3c31..97415096 100644 --- a/system/libraries/drivers/Cache.php +++ b/system/libraries/drivers/Cache.php @@ -1,40 +1,42 @@ <?php defined('SYSPATH') OR die('No direct access allowed.'); /** - * Cache driver interface. + * Cache driver abstract class. * - * $Id: Cache.php 4046 2009-03-05 19:23:29Z Shadowhand $ + * $Id$ * * @package Cache * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ -interface Cache_Driver { - +abstract class Cache_Driver { /** - * Set a cache item. + * Set cache items */ - public function set($id, $data, array $tags = NULL, $lifetime); + abstract public function set($items, $tags = NULL, $lifetime = NULL); /** - * Find all of the cache ids for a given tag. + * Get a cache items by key */ - public function find($tag); + abstract public function get($keys, $single = FALSE); /** - * Get a cache item. - * Return NULL if the cache item is not found. + * Get cache items by tag */ - public function get($id); + abstract public function get_tag($tags); /** - * Delete cache items by id or tag. + * Delete cache item by key */ - public function delete($id, $tag = FALSE); + abstract public function delete($keys); /** - * Deletes all expired cache items. + * Delete cache items by tag */ - public function delete_expired(); + abstract public function delete_tag($tags); + /** + * Empty the cache + */ + abstract public function delete_all(); } // End Cache Driver
\ No newline at end of file diff --git a/system/libraries/drivers/Cache/Apc.php b/system/libraries/drivers/Cache/Apc.php deleted file mode 100644 index f7be048f..00000000 --- a/system/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/system/libraries/drivers/Cache/Eaccelerator.php b/system/libraries/drivers/Cache/Eaccelerator.php deleted file mode 100644 index a45616d5..00000000 --- a/system/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/system/libraries/drivers/Cache/File.php b/system/libraries/drivers/Cache/File.php index cc9d48d3..d6ec0378 100644 --- a/system/libraries/drivers/Cache/File.php +++ b/system/libraries/drivers/Cache/File.php @@ -1,55 +1,54 @@ <?php defined('SYSPATH') OR die('No direct access allowed.'); /** - * File-based Cache driver. + * Memcache-based Cache driver. * - * $Id: File.php 4046 2009-03-05 19:23:29Z Shadowhand $ + * $Id: File.php 4605 2009-09-14 17:22:21Z kiall $ * * @package Cache * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ -class Cache_File_Driver implements Cache_Driver { +class Cache_File_Driver extends Cache_Driver { + protected $config; + protected $backend; - protected $directory = ''; - - /** - * Tests that the storage location is a directory and is writable. - */ - public function __construct($directory) + public function __construct($config) { - // Find the real path to the directory - $directory = str_replace('\\', '/', realpath($directory)).'/'; + $this->config = $config; + $this->config['directory'] = str_replace('\\', '/', realpath($this->config['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; + if ( ! is_dir($this->config['directory']) OR ! is_writable($this->config['directory'])) + throw new Cache_Exception('The configured cache directory, :directory:, is not writable.', array(':directory:' => $this->config['directory'])); } /** * Finds an array of files matching the given id or tag. * - * @param string cache id or tag + * @param string cache key or tag * @param bool search for tags * @return array of filenames matching the id or tag */ - public function exists($id, $tag = FALSE) + public function exists($keys, $tag = FALSE) { - if ($id === TRUE) + if ($keys === TRUE) { // Find all the files - return glob($this->directory.'*~*~*'); + return glob($this->config['directory'].'*~*~*'); } elseif ($tag === TRUE) { // Find all the files that have the tag name - $paths = glob($this->directory.'*~*'.$id.'*~*'); + $paths = array(); + + foreach ( (array) $keys as $tag) + { + $paths = array_merge($paths, glob($this->config['directory'].'*~*'.$tag.'*~*')); + } // Find all tags matching the given tag $files = array(); + foreach ($paths as $path) { // Split the files @@ -60,12 +59,16 @@ class Cache_File_Driver implements Cache_Driver { continue; // Split the tags by plus signs, used to separate tags - $tags = explode('+', $tags[1]); + $item_tags = explode('+', $tags[1]); - if (in_array($tag, $tags)) + // Check each supplied tag, and match aginst the tags on each item. + foreach ($keys as $tag) { - // Add the file to the array, it has the requested tag - $files[] = $path; + if (in_array($tag, $item_tags)) + { + // Add the file to the array, it has the requested tag + $files[] = $path; + } } } @@ -73,98 +76,68 @@ class Cache_File_Driver implements Cache_Driver { } else { - // Find the file matching the given id - return glob($this->directory.$id.'~*'); + $paths = array(); + + foreach ( (array) $keys as $key) + { + // Find the file matching the given key + $paths = array_merge($paths, glob($this->config['directory'].str_replace(array('/', '\\', ' '), '_', $key).'~*')); + } + + return $paths; } } - /** - * 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) + public function set($items, $tags = NULL, $lifetime = NULL) { - // Remove old cache files - $this->delete($id); - - // Cache File driver expects unix timestamp if ($lifetime !== 0) { + // File driver expects unix timestamp $lifetime += time(); } - if ( ! empty($tags)) + + if ( ! is_null($tags) AND ! empty($tags)) { // Convert the tags into a string list - $tags = implode('+', $tags); + $tags = implode('+', (array) $tags); } - // Write out a serialized cache - return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data)); - } + $success = 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) - { - // An array will always be returned - $result = array(); - - if ($paths = $this->exists($tag, TRUE)) + foreach ($items as $key => $value) { - // Length of directory name - $offset = strlen($this->directory); + if (is_resource($value)) + throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.'); - // 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); + // Remove old cache file + $this->delete($key); - if (($data = $this->get($id)) !== FALSE) - { - // Add the result to the array - $result[$id] = $data; - } + if ( ! (bool) file_put_contents($this->config['directory'].str_replace(array('/', '\\', ' '), '_', $key).'~'.$tags.'~'.$lifetime, serialize($value))) + { + $success = FALSE; } } - return $result; + return $success; } - /** - * 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) + public function get($keys, $single = FALSE) { - if ($file = $this->exists($id)) + $items = array(); + + if ($files = $this->exists($keys)) { - // Use the first file - $file = current($file); + // Turn off errors while reading the files + $ER = error_reporting(0); - // Validate that the cache has not expired - if ($this->expired($file)) - { - // Remove this cache, it has expired - $this->delete($id); - } - else + foreach ($files as $file) { - // Turn off errors while reading the file - $ER = error_reporting(0); + // Validate that the item has not expired + if ($this->expired($file)) + continue; + + list($key, $junk) = explode('~', basename($file), 2); if (($data = file_get_contents($file)) !== FALSE) { @@ -173,80 +146,102 @@ class Cache_File_Driver implements Cache_Driver { } else { - // Delete the data - unset($data); + $data = NULL; } - // Turn errors back on - error_reporting($ER); + $items[$key] = $data; } + + // Turn errors back on + error_reporting($ER); } - // Return NULL if there is no data - return isset($data) ? $data : NULL; + // Reutrn a single item if only one key was requested + if ($single) + { + return (count($items) > 0) ? current($items) : NULL; + } + else + { + return $items; + } } /** - * 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 + * Get cache items by tag + */ + public function get_tag($tags) + { + // An array will always be returned + $result = array(); + + if ($paths = $this->exists($tags, TRUE)) + { + // Find all the files with the given tag + foreach ($paths as $path) + { + // Get the id from the filename + list($key, $junk) = explode('~', basename($path), 2); + + if (($data = $this->get($key, TRUE)) !== FALSE) + { + // Add the result to the array + $result[$key] = $data; + } + } + } + + return $result; + } + + /** + * Delete cache items by keys or tags */ - public function delete($id, $tag = FALSE) + public function delete($keys, $tag = FALSE) { - $files = $this->exists($id, $tag); + $success = TRUE; - if (empty($files)) - return FALSE; + $paths = $this->exists($keys, $tag); // Disable all error reporting while deleting $ER = error_reporting(0); - foreach ($files as $file) + foreach ($paths as $path) { // Remove the cache file - if ( ! unlink($file)) - Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); + if ( ! unlink($path)) + { + Kohana_Log::add('error', 'Cache: Unable to delete cache file: '.$path); + $success = FALSE; + } } // Turn on error reporting again error_reporting($ER); - return TRUE; + return $success; } /** - * Deletes all cache files that are older than the current time. - * - * @return void + * Delete cache items by tag */ - public function delete_expired() + public function delete_tag($tags) { - 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); - } - } + return $this->delete($tags, TRUE); + } - // Turn on error reporting again - error_reporting($ER); - } + /** + * Empty the cache + */ + public function delete_all() + { + return $this->delete(TRUE); } /** * Check if a cache file has expired by filename. * - * @param string filename + * @param string|array array of filenames * @return bool */ protected function expired($file) @@ -257,5 +252,4 @@ class Cache_File_Driver implements Cache_Driver { // Expirations of 0 are "never expire" return ($expires !== 0 AND $expires <= time()); } - -} // End Cache File Driver
\ No newline at end of file +} // End Cache Memcache Driver diff --git a/system/libraries/drivers/Cache/Memcache.php b/system/libraries/drivers/Cache/Memcache.php index d801de9c..13d61d82 100644 --- a/system/libraries/drivers/Cache/Memcache.php +++ b/system/libraries/drivers/Cache/Memcache.php @@ -2,190 +2,131 @@ /** * Memcache-based Cache driver. * - * $Id: Memcache.php 4102 2009-03-19 12:55:54Z Shadowhand $ + * $Id$ * * @package Cache * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ -class Cache_Memcache_Driver implements Cache_Driver { - - const TAGS_KEY = 'memcache_tags_array'; - - // Cache backend object and flags +class Cache_Memcache_Driver extends Cache_Driver { + protected $config; protected $backend; protected $flags; - // Tags array - protected static $tags; - - // Have the tags been changed? - protected static $tags_changed = FALSE; - - public function __construct() + public function __construct($config) { if ( ! extension_loaded('memcache')) - throw new Kohana_Exception('cache.extension_not_loaded', 'memcache'); + throw new Cache_Exception('The memcache PHP extension must be loaded to use this driver.'); + ini_set('memcache.allow_failover', (isset($config['allow_failover']) AND $config['allow_failover']) ? TRUE : FALSE); + + $this->config = $config; $this->backend = new Memcache; - $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE; - $servers = Kohana::config('cache_memcache.servers'); + $this->flags = (isset($config['compression']) AND $config['compression']) ? MEMCACHE_COMPRESSED : FALSE; - foreach ($servers as $server) + foreach ($config['servers'] as $server) { // Make sure all required keys are set - $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE); + $server += array('host' => '127.0.0.1', + 'port' => 11211, + 'persistent' => FALSE, + 'weight' => 1, + 'timeout' => 1, + 'retry_interval' => 15 + ); // 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; + $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent'], (int) $server['weight'], (int) $server['timeout'], (int) $server['retry_interval'], TRUE, array($this,'_memcache_failure_callback')); } } - public function __destruct() + public function _memcache_failure_callback($host, $port) { - 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; - } + $this->backend->setServerParams($host, $port, 1, -1, FALSE); + Kohana_Log::add('error', __('Cache: Memcache server down: :host:::port:',array(':host:' => $host,':port:' => $port))); } - public function find($tag) + public function set($items, $tags = NULL, $lifetime = NULL) { - if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag])) - { - // Return all the found caches - return $results; - } - else + if ($lifetime !== 0) { - // No matching tags - return array(); + // Memcache driver expects unix timestamp + $lifetime += time(); } - } - public function get($id) - { - return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return; - } + if ($tags !== NULL) + throw new Cache_Exception('Memcache driver does not support tags'); - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) + foreach ($items as $key => $value) { - // Tags will be changed - self::$tags_changed = TRUE; + if (is_resource($value)) + throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.'); - foreach ($tags as $tag) + if ( ! $this->backend->set($key, $value, $this->flags, $lifetime)) { - // Add the id to each tag - self::$tags[$tag][$id] = $id; + return FALSE; } } - if ($lifetime !== 0) - { - // Memcache driver expects unix timestamp - $lifetime += time(); - } - - // Set a new value - return $this->backend->set($id, $data, $this->flags, $lifetime); + return TRUE; } - public function delete($id, $tag = FALSE) + public function get($keys, $single = FALSE) { - // Tags will be changed - self::$tags_changed = TRUE; + $items = $this->backend->get($keys); - if ($id === TRUE) + if ($single) { - 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); - } + if ($items === FALSE) + return NULL; - 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; + return (count($items) > 0) ? current($items) : NULL; } 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); + return ($items === FALSE) ? array() : $items; } } - public function delete_expired() + /** + * Get cache items by tag + */ + public function get_tag($tags) { - // Tags will be changed - self::$tags_changed = TRUE; + throw new Cache_Exception('Memcache driver does not support tags'); + } - foreach (self::$tags as $tag => $_ids) + /** + * Delete cache item by key + */ + public function delete($keys) + { + foreach ($keys as $key) { - 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])) + if ( ! $this->backend->delete($key)) { - // The tag no longer has any valid ids - unset(self::$tags[$tag]); + return FALSE; } } - // Memcache handles garbage collection internally return TRUE; } + /** + * Delete cache items by tag + */ + public function delete_tag($tags) + { + throw new Cache_Exception('Memcache driver does not support tags'); + } + + /** + * Empty the cache + */ + public function delete_all() + { + return $this->backend->flush(); + } } // End Cache Memcache Driver diff --git a/system/libraries/drivers/Cache/Sqlite.php b/system/libraries/drivers/Cache/Sqlite.php deleted file mode 100644 index 9458d851..00000000 --- a/system/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/system/libraries/drivers/Cache/Xcache.php b/system/libraries/drivers/Cache/Xcache.php index 6254bbb6..4c08405e 100644 --- a/system/libraries/drivers/Cache/Xcache.php +++ b/system/libraries/drivers/Cache/Xcache.php @@ -1,85 +1,128 @@ <?php defined('SYSPATH') OR die('No direct access allowed.'); /** - * Xcache Cache driver. - * - * $Id: Xcache.php 4046 2009-03-05 19:23:29Z Shadowhand $ + * XCache-based Cache driver. + * + * $Id: Memcache.php 4605 2009-09-14 17:22:21Z kiall $ * * @package Cache * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + * @TODO Check if XCache cleans its own keys. */ -class Cache_Xcache_Driver implements Cache_Driver { +class Cache_Xcache_Driver extends Cache_Driver { + protected $config; - public function __construct() + public function __construct($config) { 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); + throw new Cache_Exception('The xcache PHP extension must be loaded to use this driver.'); - return NULL; + $this->config = $config; } - public function set($id, $data, array $tags = NULL, $lifetime) + public function set($items, $tags = NULL, $lifetime = NULL) { - if ( ! empty($tags)) + if ($tags !== NULL) { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); + Kohana_Log::add('debug', __('Cache: XCache driver does not support tags')); } - return xcache_set($id, $data, $lifetime); - } + foreach ($items as $key => $value) + { + if (is_resource($value)) + throw new Cache_Exception('Caching of resources is impossible, because resources cannot be serialised.'); - public function find($tag) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return FALSE; + if ( ! xcache_set($key, $value, $lifetime)) + { + return FALSE; + } + } + + return TRUE; } - public function delete($id, $tag = FALSE) + public function get($keys, $single = FALSE) { - if ($tag !== FALSE) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return TRUE; - } - elseif ($id !== TRUE) + $items = array(); + + foreach ($keys as $key) { if (xcache_isset($id)) - return xcache_unset($id); + { + $items[$key] = xcache_get($id); + } + else + { + $items[$key] = NULL; + } + } - return FALSE; + if ($single) + { + return ($items === FALSE OR count($items) > 0) ? current($items) : NULL; } else { - // Do the login - $this->auth(); - $result = TRUE; - for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) + return ($items === FALSE) ? array() : $items; + } + } + + /** + * Get cache items by tag + */ + public function get_tag($tags) + { + Kohana_Log::add('debug', __('Cache: XCache driver does not support tags')); + return NULL; + } + + /** + * Delete cache item by key + */ + public function delete($keys) + { + foreach ($keys as $key) + { + if ( ! xcache_unset($key)) { - if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL) - { - $result = FALSE; - break; - } + return FALSE; } - - // Undo the login - $this->auth(TRUE); - return $result; } return TRUE; } - public function delete_expired() + /** + * Delete cache items by tag + */ + public function delete_tag($tags) { - return TRUE; + Kohana_Log::add('debug', __('Cache: XCache driver does not support tags')); + return NULL; + } + + /** + * Empty the cache + */ + public function delete_all() + { + $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; } private function auth($reverse = FALSE) @@ -111,9 +154,8 @@ class Cache_Xcache_Driver implements Cache_Driver { $backup[$key] = $value; } - $_SERVER[$key] = Kohana::config('cache_xcache.'.$key); + $_SERVER[$key] = $this->config->{$key}; } } } - -} // End Cache Xcache Driver +} // End Cache XCache Driver diff --git a/system/libraries/drivers/Captcha.php b/system/libraries/drivers/Captcha.php deleted file mode 100644 index a4343e19..00000000 --- a/system/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/system/libraries/drivers/Captcha/Alpha.php b/system/libraries/drivers/Captcha/Alpha.php deleted file mode 100644 index 27795804..00000000 --- a/system/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 4367 2009-05-27 21:23:57Z samsoir $ - * - * @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 = $chars[mt_rand(0, 14)]; - 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/system/libraries/drivers/Captcha/Basic.php b/system/libraries/drivers/Captcha/Basic.php deleted file mode 100644 index d212e72c..00000000 --- a/system/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/system/libraries/drivers/Captcha/Black.php b/system/libraries/drivers/Captcha/Black.php deleted file mode 100644 index 6a2e2226..00000000 --- a/system/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/system/libraries/drivers/Captcha/Math.php b/system/libraries/drivers/Captcha/Math.php deleted file mode 100644 index 4ac20248..00000000 --- a/system/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/system/libraries/drivers/Captcha/Riddle.php b/system/libraries/drivers/Captcha/Riddle.php deleted file mode 100644 index 765eeaad..00000000 --- a/system/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/system/libraries/drivers/Captcha/Word.php b/system/libraries/drivers/Captcha/Word.php deleted file mode 100644 index 856bd9b4..00000000 --- a/system/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/system/libraries/drivers/Config.php b/system/libraries/drivers/Config.php new file mode 100644 index 00000000..a82684bc --- /dev/null +++ b/system/libraries/drivers/Config.php @@ -0,0 +1,257 @@ +<?php defined('SYSPATH') or die('No direct script access.'); +/** + * Kohana_Config abstract driver to get and set + * configuration options. + * + * Specific drivers should implement caching and encryption + * as they deem appropriate. + * + * $Id: Config.php 4679 2009-11-10 01:45:52Z isaiah $ + * + * @package Kohana_Config + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + * @abstract + */ +abstract class Config_Driver { + + /** + * Internal caching + * + * @var Cache + */ + protected $cache; + + /** + * The name of the internal cache + * + * @var string + */ + protected $cache_name = 'Kohana_Config_Cache'; + + /** + * Cache Lifetime + * + * @var mixed + */ + protected $cache_lifetime = FALSE; + + /** + * The Encryption library + * + * @var Encrypt + */ + protected $encrypt; + + /** + * The config loaded + * + * @var array + */ + protected $config = array(); + + /** + * The changed status of configuration values, + * current state versus the stored state. + * + * @var bool + */ + protected $changed = FALSE; + + /** + * Determines if any config has been loaded yet + */ + public $loaded = FALSE; + + /** + * Array driver constructor. Sets up the PHP array + * driver, including caching and encryption if + * required + * + * @access public + */ + public function __construct($config) + { + + if (($cache_setting = $config['internal_cache']) !== FALSE) + { + $this->cache_lifetime = $cache_setting; + // Restore the cached configuration + $this->config = $this->load_cache(); + + if (count($this->config) > 0) + $this->loaded = TRUE; + + // Add the save cache method to system.shutshut event + Event::add('system.shutdown', array($this, 'save_cache')); + } + + } + + /** + * Gets a value from config. If required is TRUE + * then get will throw an exception if value cannot + * be loaded. + * + * @param string key the setting to get + * @param bool slash remove trailing slashes + * @param bool required is setting required? + * @return mixed + * @access public + */ + public function get($key, $slash = FALSE, $required = FALSE) + { + // Get the group name from the key + $group = explode('.', $key, 2); + $group = $group[0]; + + // Check for existing value and load it dynamically if required + if ( ! isset($this->config[$group])) + $this->config[$group] = $this->load($group, $required); + + // Get the value of the key string + $value = Kohana::key_string($this->config, $key); + + if ($slash === TRUE AND is_string($value) AND $value !== '') + { + // Force the value to end with "/" + $value = rtrim($value, '/').'/'; + } + + if (($required === TRUE) AND ($value === null)) + throw new Kohana_Config_Exception('Value not found in config driver'); + + $this->loaded = TRUE; + return $value; + } + + /** + * Sets a new value to the configuration + * + * @param string key + * @param mixed value + * @return bool + * @access public + */ + public function set($key, $value) + { + // Do this to make sure that the config array is already loaded + $this->get($key); + + if (substr($key, 0, 7) === 'routes.') + { + // Routes cannot contain sub keys due to possible dots in regex + $keys = explode('.', $key, 2); + } + else + { + // Convert dot-noted key string to an array + $keys = explode('.', $key); + } + + // Used for recursion + $conf =& $this->config; + $last = count($keys) - 1; + + foreach ($keys as $i => $k) + { + if ($i === $last) + { + $conf[$k] = $value; + } + else + { + $conf =& $conf[$k]; + } + } + + if (substr($key,0,12) === 'core.modules') + { + // Reprocess the include paths + Kohana::include_paths(TRUE); + } + + // Set config to changed + return $this->changed = TRUE; + } + + /** + * Clear the configuration + * + * @param string group + * @return bool + * @access public + */ + public function clear($group) + { + // Remove the group from config + unset($this->config[$group]); + + // Set config to changed + return $this->changed = TRUE; + } + + /** + * Checks whether the setting exists in + * config + * + * @param string $key + * @return bool + * @access public + */ + public function setting_exists($key) + { + return $this->get($key) === NULL; + } + + /** + * Loads a configuration group based on the setting + * + * @param string group + * @param bool required + * @return array + * @access public + * @abstract + */ + abstract public function load($group, $required = FALSE); + + /** + * Loads the cached version of this configuration driver + * + * @return array + * @access public + */ + public function load_cache() + { + // Load the cache for this configuration + $cached_config = Kohana::cache($this->cache_name, $this->cache_lifetime); + + // If the configuration wasn't loaded from the cache + if ($cached_config === NULL) + $cached_config = array(); + + // Return the cached config + return $cached_config; + } + + /** + * Saves a cached version of this configuration driver + * + * @return bool + * @access public + */ + public function save_cache() + { + // If this configuration has changed + if ($this->get('core.internal_cache') !== FALSE AND $this->changed) + { + $data = $this->config; + + // Save the cache + return Kohana::cache_save($this->cache_name, $data, $this->cache_lifetime); + } + + return TRUE; + } +} // End Kohana_Config_Driver
\ No newline at end of file diff --git a/system/libraries/drivers/Config/Array.php b/system/libraries/drivers/Config/Array.php new file mode 100644 index 00000000..b2ca19ba --- /dev/null +++ b/system/libraries/drivers/Config/Array.php @@ -0,0 +1,83 @@ +<?php defined('SYSPATH') or die('No direct script access.'); +/** + * Kohana_Config Array driver to get and set + * configuration options using PHP arrays. + * + * This driver can cache and encrypt settings + * if required. + * + * $Id: Array.php 4679 2009-11-10 01:45:52Z isaiah $ + * + * @package Kohana_Config + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + */ +class Config_Array_Driver extends Config_Driver { + + /** + * Internal caching + * + * @var Cache + */ + protected $cache; + + /** + * The name of the internal cache + * + * @var string + */ + protected $cache_name = 'Kohana_Config_Array_Cache'; + + /** + * The Encryption library + * + * @var Encrypt + */ + protected $encrypt; + + /** + * Loads a configuration group based on the setting + * + * @param string group + * @param bool required + * @return array + * @access public + */ + public function load($group, $required = FALSE) + { + if ($group === 'core') + { + // Load the application configuration file + require APPPATH.'config/config'.EXT; + + if ( ! isset($config['site_domain'])) + { + // Invalid config file + throw new Kohana_Config_Exception('Your Kohana application configuration file is not valid.'); + } + + return $config; + } + + // Load matching configs + $configuration = array(); + + if ($files = Kohana::find_file('config', $group, $required)) + { + foreach ($files as $file) + { + require $file; + + if (isset($config) AND is_array($config)) + { + // Merge in configuration + $configuration = array_merge($configuration, $config); + } + } + } + + // Return merged configuration + return $configuration; + } +} // End Config_Array_Driver
\ No newline at end of file diff --git a/system/libraries/drivers/Database.php b/system/libraries/drivers/Database.php deleted file mode 100644 index 27f6ea8e..00000000 --- a/system/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) ? ' TRUE' : ' FALSE'; - } - 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 = ($value == TRUE) ? 'TRUE' : 'FALSE'; - 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/system/libraries/drivers/Database/Mssql.php b/system/libraries/drivers/Database/Mssql.php deleted file mode 100644 index 8b5ed50b..00000000 --- a/system/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("SELECT COLUMN_NAME AS Field, DATA_TYPE as Type FROM INFORMATION_SCHEMA.Columns WHERE TABLE_NAME = '".$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/system/libraries/drivers/Database/Mysql.php b/system/libraries/drivers/Database/Mysql.php deleted file mode 100644 index d5222f50..00000000 --- a/system/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/system/libraries/drivers/Database/Mysqli.php b/system/libraries/drivers/Database/Mysqli.php deleted file mode 100644 index 0dd9f05c..00000000 --- a/system/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/system/libraries/drivers/Database/Pdosqlite.php b/system/libraries/drivers/Database/Pdosqlite.php deleted file mode 100644 index c2d1bb21..00000000 --- a/system/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/system/libraries/drivers/Database/Pgsql.php b/system/libraries/drivers/Database/Pgsql.php deleted file mode 100644 index c53c8439..00000000 --- a/system/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/system/libraries/drivers/Image.php b/system/libraries/drivers/Image.php index f89ba953..39936c30 100644 --- a/system/libraries/drivers/Image.php +++ b/system/libraries/drivers/Image.php @@ -2,12 +2,12 @@ /** * Image API driver. * - * $Id: Image.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: Image.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ abstract class Image_Driver { @@ -102,9 +102,11 @@ abstract class Image_Driver { * @param array actions to execute * @param string destination directory path * @param string destination filename + * @param boolean render the image + * @param string background color * @return boolean */ - abstract public function process($image, $actions, $dir, $file); + abstract public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL); /** * Flip an image. Valid directions are horizontal and vertical. diff --git a/system/libraries/drivers/Image/GD.php b/system/libraries/drivers/Image/GD.php index be2af4e2..6ffffe8a 100644 --- a/system/libraries/drivers/Image/GD.php +++ b/system/libraries/drivers/Image/GD.php @@ -2,12 +2,12 @@ /** * GD Image Driver. * - * $Id: GD.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: GD.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_GD_Driver extends Image_Driver { @@ -20,17 +20,17 @@ class Image_GD_Driver extends Image_Driver { { // Make sure that GD2 is available if ( ! function_exists('gd_info')) - throw new Kohana_Exception('image.gd.requires_v2'); + throw new Kohana_Exception('The Image library requires GD2. Please see http://php.net/gd_info for more information.'); // 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'); + throw new Kohana_Exception('The Image library requires GD2. Please see http://php.net/gd_info for more information.'); } - public function process($image, $actions, $dir, $file, $render = FALSE) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { // Set the "create" function switch ($image['type']) @@ -63,11 +63,11 @@ class Image_GD_Driver extends Image_Driver { // 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']); + throw new Kohana_Exception('The specified image, :type:, is not an allowed image type.', array(':type:' => $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); + throw new Kohana_Exception('The specified image, :type:, is not an allowed image type.', array(':type:' => $dir.$file)); // Load the image $this->image = $image; @@ -211,11 +211,11 @@ class Image_GD_Driver extends Image_Driver { // 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 @@ -314,7 +314,7 @@ class Image_GD_Driver extends Image_Driver { { // Make sure that the sharpening function is available if ( ! function_exists('imageconvolution')) - throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); + throw new Kohana_Exception('Your configured driver does not support the :method: image transformation.', array(':method:' => __FUNCTION__)); // Amount should be in the range of 18-10 $amount = round(abs(-18 + ($amount * 0.08)), 2); @@ -336,23 +336,52 @@ class Image_GD_Driver extends Image_Driver { switch($properties['mime']) { case "image/jpeg": - $overlay_img = imagecreatefromjpeg($properties['overlay_file']); + $overlay_img = imagecreatefromjpeg($properties['overlay_file']); break; case "image/gif": - $overlay_img = imagecreatefromgif($properties['overlay_file']); + $overlay_img = imagecreatefromgif($properties['overlay_file']); break; case "image/png": - $overlay_img = imagecreatefrompng($properties['overlay_file']); + $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']); + $this->imagecopymerge_alpha($this->tmp_image, $overlay_img, $properties['x'], $properties['y'], 0, 0, imagesx($overlay_img), imagesy($overlay_img), $properties['transparency']); + imagedestroy($overlay_img); + return TRUE; } + /** + * A replacement for php's imagecopymerge() function that supports the alpha channel + * See php bug #23815: http://bugs.php.net/bug.php?id=23815 + * + * @param resource $dst_im Destination image link resource + * @param resource $src_im Source image link resource + * @param integer $dst_x x-coordinate of destination point + * @param integer $dst_y y-coordinate of destination point + * @param integer $src_x x-coordinate of source point + * @param integer $src_y y-coordinate of source point + * @param integer $src_w Source width + * @param integer $src_h Source height + * @param integer $pct Transparency percent (0 to 100) + */ + protected function imagecopymerge_alpha($dst_im, $src_im, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct) + { + // Create a new blank image the site of our source image + $cut = imagecreatetruecolor($src_w, $src_h); + + // Copy the blank image into the destination image where the source goes + imagecopy($cut, $dst_im, 0, 0, $dst_x, $dst_y, $src_w, $src_h); + + // Place the source image in the destination image + imagecopy($cut, $src_im, 0, 0, $src_x, $src_y, $src_w, $src_h); + imagecopymerge($dst_im, $cut, $dst_x, $dst_y, $src_x, $src_y, $src_w, $src_h, $pct); + } + protected function properties() { return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); @@ -368,6 +397,16 @@ class Image_GD_Driver extends Image_Driver { */ protected function imagecreatetransparent($width, $height) { + if ($width < 1) + { + $width = 1; + } + + if ($height < 1) + { + $height = 1; + } + if (self::$blank_png === NULL) { // Decode the blank PNG if it has not been done already diff --git a/system/libraries/drivers/Image/GraphicsMagick.php b/system/libraries/drivers/Image/GraphicsMagick.php index a8bc4d9b..89b40b41 100644 --- a/system/libraries/drivers/Image/GraphicsMagick.php +++ b/system/libraries/drivers/Image/GraphicsMagick.php @@ -4,8 +4,8 @@ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_GraphicsMagick_Driver extends Image_Driver { @@ -31,7 +31,7 @@ class Image_GraphicsMagick_Driver extends Image_Driver { { // 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'); + throw new Kohana_Exception('The GraphicsMagick directory specified does not contain a required program.'); $config['directory'] = dirname($path); } @@ -41,7 +41,7 @@ class Image_GraphicsMagick_Driver extends Image_Driver { // 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); + throw new Kohana_Exception('The GraphicsMagick directory specified does not contain a required program, :gm:.', array(':gm:' => 'gm'.$this->ext)); // Set the installation directory @@ -52,8 +52,12 @@ class Image_GraphicsMagick_Driver extends Image_Driver { * 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) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { + // Need to implement $background support + if ($background !== NULL) + throw new Kohana_Exception('The GraphicsMagick driver does not support setting a background color'); + // We only need the filename $image = $image['file']; diff --git a/system/libraries/drivers/Image/ImageMagick.php b/system/libraries/drivers/Image/ImageMagick.php index 4b381fd6..31862f75 100644 --- a/system/libraries/drivers/Image/ImageMagick.php +++ b/system/libraries/drivers/Image/ImageMagick.php @@ -2,12 +2,12 @@ /** * ImageMagick Image Driver. * - * $Id: ImageMagick.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: ImageMagick.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Image * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Image_ImageMagick_Driver extends Image_Driver { @@ -33,7 +33,7 @@ class Image_ImageMagick_Driver extends Image_Driver { { // 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'); + throw new Kohana_Exception('The ImageMagick directory specified does not contain a required program.'); $config['directory'] = dirname($path); } @@ -43,7 +43,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // 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); + throw new Kohana_Exception('The ImageMagick directory specified does not contain a required program, :im:', array(':im:' => 'convert'.$this->ext)); // Set the installation directory $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; @@ -53,7 +53,7 @@ class Image_ImageMagick_Driver extends Image_Driver { * 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) + public function process($image, $actions, $dir, $file, $render = FALSE, $background = NULL) { // We only need the filename $image = $image['file']; @@ -70,23 +70,34 @@ class Image_ImageMagick_Driver extends Image_Driver { // Use 95 for the default quality empty($quality) and $quality = 95; + if (is_string($background)) + { + // Set the background color + $this->background = escapeshellarg($background); + } + else + { + // Use a transparent background + $this->background = 'transparent'; + } + // 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); + $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)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) { $this->errors[] = $error; } else { // Output the image directly to the browser - if ($render !== FALSE) + if ($render === TRUE) { $contents = file_get_contents($this->tmp_image); switch (substr($file, strrpos($file, '.') + 1)) @@ -122,7 +133,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // 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)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -136,7 +147,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // 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)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -164,7 +175,7 @@ class Image_ImageMagick_Driver extends Image_Driver { } // 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)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -175,7 +186,7 @@ class Image_ImageMagick_Driver extends Image_Driver { public function rotate($amt) { - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; @@ -195,7 +206,7 @@ class Image_ImageMagick_Driver extends Image_Driver { // 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)) + if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -background '.$this->background.' -flatten -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) { $this->errors[] = $error; return FALSE; diff --git a/system/libraries/drivers/Log.php b/system/libraries/drivers/Log.php new file mode 100644 index 00000000..cd6dba7d --- /dev/null +++ b/system/libraries/drivers/Log.php @@ -0,0 +1,22 @@ +<?php defined('SYSPATH') OR die('No direct access allowed.'); +/** + * Log API driver. + * + * $Id: Log.php 4679 2009-11-10 01:45:52Z isaiah $ + * + * @package Kohana_Log + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + */ +abstract class Log_Driver { + + protected $config = array(); + + public function __construct(array $config) + { + $this->config = $config; + } + + abstract public function save(array $messages); +}
\ No newline at end of file diff --git a/system/libraries/drivers/Log/Database.php b/system/libraries/drivers/Log/Database.php new file mode 100644 index 00000000..19db9747 --- /dev/null +++ b/system/libraries/drivers/Log/Database.php @@ -0,0 +1,40 @@ +<?php defined('SYSPATH') OR die('No direct access allowed.'); +/** + * Log API driver. + * + * $Id: Database.php 4679 2009-11-10 01:45:52Z isaiah $ + * + * @package Kohana_Log + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + */ +class Log_Database_Driver extends Log_Driver { + + public function save(array $messages) + { + $insert = db::build($this->config['group']) + ->insert($this->config['table']) + ->columns(array('date', 'level', 'message')); + + $run_insert = FALSE; + + foreach ($messages AS $message) + { + if ($this->config['log_levels'][$message['type']] <= $this->config['log_threshold']) + { + // Add new message to database + $insert->values($message); + + // There is data to insert + $run_insert = TRUE; + } + } + + // Update the database + if ($run_insert) + { + $insert->execute(); + } + } +}
\ No newline at end of file diff --git a/system/libraries/drivers/Log/File.php b/system/libraries/drivers/Log/File.php new file mode 100644 index 00000000..6ad565b4 --- /dev/null +++ b/system/libraries/drivers/Log/File.php @@ -0,0 +1,44 @@ +<?php defined('SYSPATH') OR die('No direct access allowed.'); +/** + * Log API driver. + * + * $Id: File.php 4679 2009-11-10 01:45:52Z isaiah $ + * + * @package Kohana_Log + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + */ +class Log_File_Driver extends Log_Driver { + + public function save(array $messages) + { + // Filename of the log + $filename = $this->config['log_directory'].'/'.date('Y-m-d').'.log'.EXT; + + if ( ! is_file($filename)) + { + // Write the SYSPATH checking header + file_put_contents($filename, + '<?php defined(\'SYSPATH\') or die(\'No direct script access.\'); ?>'.PHP_EOL.PHP_EOL); + + // Prevent external writes + chmod($filename, $this->config['posix_permissions']); + } + + foreach ($messages AS $message) + { + if ($this->config['log_levels'][$message['type']] <= $this->config['log_threshold']) + { + // Add a new message line + $messages_to_write[] = date($this->config['date_format'], $message['date']).' --- '.$message['type'].': '.$message['message']; + } + } + + if ( ! empty($messages_to_write)) + { + // Write messages to log file + file_put_contents($filename, implode(PHP_EOL, $messages_to_write).PHP_EOL, FILE_APPEND); + } + } +}
\ No newline at end of file diff --git a/system/libraries/drivers/Log/Syslog.php b/system/libraries/drivers/Log/Syslog.php new file mode 100644 index 00000000..5da5d255 --- /dev/null +++ b/system/libraries/drivers/Log/Syslog.php @@ -0,0 +1,34 @@ +<?php defined('SYSPATH') OR die('No direct access allowed.'); +/** + * Log API driver. + * + * @package Kohana_Log + * @author Kohana Team + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license + */ +class Log_Syslog_Driver extends Log_Driver { + + protected $syslog_levels = array('error' => LOG_ERR, + 'alert' => LOG_WARNING, + 'info' => LOG_INFO, + 'debug' => LOG_DEBUG); + + public function save(array $messages) + { + // Open the connection to syslog + openlog($this->config['ident'], LOG_CONS, LOG_USER); + + do + { + // Load the next message + list ($date, $type, $text) = array_shift($messages); + + syslog($this->syslog_levels[$type], $text); + } + while ( ! empty($messages)); + + // Close connection to syslog + closelog(); + } +}
\ No newline at end of file diff --git a/system/libraries/drivers/Session.php b/system/libraries/drivers/Session.php index fb58c8d3..759ccd84 100644 --- a/system/libraries/drivers/Session.php +++ b/system/libraries/drivers/Session.php @@ -2,12 +2,12 @@ /** * Session driver interface * - * $Id: Session.php 3769 2008-12-15 00:48:56Z zombor $ + * $Id: Session.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Core * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ interface Session_Driver { diff --git a/system/libraries/drivers/Session/Cache.php b/system/libraries/drivers/Session/Cache.php index 45e49495..c0d4d0a4 100644 --- a/system/libraries/drivers/Session/Cache.php +++ b/system/libraries/drivers/Session/Cache.php @@ -10,12 +10,12 @@ * Lifetime does not need to be set as it is * overridden by the session expiration setting. * - * $Id: Cache.php 4431 2009-07-01 03:41:41Z kiall $ + * $Id: Cache.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Core * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Session_Cache_Driver implements Session_Driver { @@ -30,7 +30,7 @@ class Session_Cache_Driver implements Session_Driver { $this->encrypt = new Encrypt; } - Kohana::log('debug', 'Session Cache Driver Initialized'); + Kohana_Log::add('debug', 'Session Cache Driver Initialized'); } public function open($path, $name) @@ -48,7 +48,7 @@ class Session_Cache_Driver implements Session_Driver { // Test the config group name if (($config = Kohana::config('cache.'.$config)) === NULL) - throw new Kohana_Exception('cache.undefined_group', $name); + throw new Kohana_Exception('The :group: group is not defined in your configuration.', array(':group:' => $name)); } $config['lifetime'] = (Kohana::config('session.expiration') == 0) ? 86400 : Kohana::config('session.expiration'); diff --git a/system/libraries/drivers/Session/Cookie.php b/system/libraries/drivers/Session/Cookie.php index 4cf18fc2..ef575cab 100644 --- a/system/libraries/drivers/Session/Cookie.php +++ b/system/libraries/drivers/Session/Cookie.php @@ -2,12 +2,12 @@ /** * Session cookie driver. * - * $Id: Cookie.php 4431 2009-07-01 03:41:41Z kiall $ + * $Id: Cookie.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Core * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Session_Cookie_Driver implements Session_Driver { @@ -23,7 +23,7 @@ class Session_Cookie_Driver implements Session_Driver { $this->encrypt = Encrypt::instance(); } - Kohana::log('debug', 'Session Cookie Driver Initialized'); + Kohana_Log::add('debug', 'Session Cookie Driver Initialized'); } public function open($path, $name) @@ -55,7 +55,7 @@ class Session_Cookie_Driver implements Session_Driver { if (strlen($data) > 4048) { - Kohana::log('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); + Kohana_Log::add('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); return FALSE; } diff --git a/system/libraries/drivers/Session/Database.php b/system/libraries/drivers/Session/Database.php index 490875a1..cbe76001 100644 --- a/system/libraries/drivers/Session/Database.php +++ b/system/libraries/drivers/Session/Database.php @@ -2,12 +2,12 @@ /** * Session database driver. * - * $Id: Database.php 4431 2009-07-01 03:41:41Z kiall $ + * $Id: Database.php 4679 2009-11-10 01:45:52Z isaiah $ * * @package Core * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html + * @copyright (c) 2007-2009 Kohana Team + * @license http://kohanaphp.com/license */ class Session_Database_Driver implements Session_Driver { @@ -58,10 +58,7 @@ class Session_Database_Driver implements Session_Driver { } } - // Load database - $this->db = Database::instance($this->db); - - Kohana::log('debug', 'Session Database Driver Initialized'); + Kohana_Log::add('debug', 'Session Database Driver Initialized'); } public function open($path, $name) @@ -77,7 +74,11 @@ class Session_Database_Driver implements Session_Driver { public function read($id) { // Load the session - $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); + $query = db::select('data') + ->from($this->table) + ->where('session_id', '=', $id) + ->limit(1) + ->execute($this->db); if ($query->count() === 0) { @@ -111,7 +112,8 @@ class Session_Database_Driver implements Session_Driver { if ($this->session_id === NULL) { // Insert a new session - $query = $this->db->insert($this->table, $data); + $query = db::insert($this->table, $data) + ->execute($this->db); } elseif ($id === $this->session_id) { @@ -119,12 +121,18 @@ class Session_Database_Driver implements Session_Driver { unset($data['session_id']); // Update the existing session - $query = $this->db->update($this->table, $data, array('session_id' => $id)); + $query = db::update($this->table) + ->set($data) + ->where('session_id', '=', $id) + ->execute($this->db); } else { // Update the session and id - $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); + $query = db::update($this->table) + ->set($data) + ->where('session_id', '=', $this->session_id) + ->execute($this->db); // Set the new session id $this->session_id = $id; @@ -136,7 +144,9 @@ class Session_Database_Driver implements Session_Driver { public function destroy($id) { // Delete the requested session - $this->db->delete($this->table, array('session_id' => $id)); + db::delete($this->table) + ->where('session_id', '=', $id) + ->execute($this->db); // Session id is no longer valid $this->session_id = NULL; @@ -156,9 +166,11 @@ class Session_Database_Driver implements Session_Driver { public function gc($maxlifetime) { // Delete all expired sessions - $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); + $query = db::delete($this->table) + ->where('last_activity', '<', time() - $maxlifetime) + ->execute($this->db); - Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); + Kohana_Log::add('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); return TRUE; } |