diff options
Diffstat (limited to 'kohana/libraries/drivers')
28 files changed, 0 insertions, 6009 deletions
diff --git a/kohana/libraries/drivers/Cache.php b/kohana/libraries/drivers/Cache.php deleted file mode 100644 index 7c5e3c31..00000000 --- a/kohana/libraries/drivers/Cache.php +++ /dev/null @@ -1,40 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Cache driver interface. - * - * $Id: Cache.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -interface Cache_Driver { - - /** - * Set a cache item. - */ - public function set($id, $data, array $tags = NULL, $lifetime); - - /** - * Find all of the cache ids for a given tag. - */ - public function find($tag); - - /** - * Get a cache item. - * Return NULL if the cache item is not found. - */ - public function get($id); - - /** - * Delete cache items by id or tag. - */ - public function delete($id, $tag = FALSE); - - /** - * Deletes all expired cache items. - */ - public function delete_expired(); - -} // End Cache Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Apc.php b/kohana/libraries/drivers/Cache/Apc.php deleted file mode 100644 index f7be048f..00000000 --- a/kohana/libraries/drivers/Cache/Apc.php +++ /dev/null @@ -1,64 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * APC-based Cache driver. - * - * $Id: Apc.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Apc_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('apc')) - throw new Kohana_Exception('cache.extension_not_loaded', 'apc'); - } - - public function get($id) - { - return (($return = apc_fetch($id)) === FALSE) ? NULL : $return; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - } - - return apc_store($id, $data, $lifetime); - } - - public function find($tag) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - - return array(); - } - - public function delete($id, $tag = FALSE) - { - if ($tag === TRUE) - { - Kohana::log('error', 'Cache: tags are unsupported by the APC driver'); - return FALSE; - } - elseif ($id === TRUE) - { - return apc_clear_cache('user'); - } - else - { - return apc_delete($id); - } - } - - public function delete_expired() - { - return TRUE; - } - -} // End Cache APC Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Eaccelerator.php b/kohana/libraries/drivers/Cache/Eaccelerator.php deleted file mode 100644 index a45616d5..00000000 --- a/kohana/libraries/drivers/Cache/Eaccelerator.php +++ /dev/null @@ -1,66 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Eaccelerator-based Cache driver. - * - * $Id: Eaccelerator.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Eaccelerator_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('eaccelerator')) - throw new Kohana_Exception('cache.extension_not_loaded', 'eaccelerator'); - } - - public function get($id) - { - return eaccelerator_get($id); - } - - public function find($tag) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - - return array(); - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - } - - return eaccelerator_put($id, $data, $lifetime); - } - - public function delete($id, $tag = FALSE) - { - if ($tag === TRUE) - { - Kohana::log('error', 'tags are unsupported by the eAccelerator driver'); - return FALSE; - } - elseif ($id === TRUE) - { - return eaccelerator_clean(); - } - else - { - return eaccelerator_rm($id); - } - } - - public function delete_expired() - { - eaccelerator_gc(); - - return TRUE; - } - -} // End Cache eAccelerator Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/File.php b/kohana/libraries/drivers/Cache/File.php deleted file mode 100644 index cc9d48d3..00000000 --- a/kohana/libraries/drivers/Cache/File.php +++ /dev/null @@ -1,261 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * File-based Cache driver. - * - * $Id: File.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_File_Driver implements Cache_Driver { - - protected $directory = ''; - - /** - * Tests that the storage location is a directory and is writable. - */ - public function __construct($directory) - { - // Find the real path to the directory - $directory = str_replace('\\', '/', realpath($directory)).'/'; - - // Make sure the cache directory is writable - if ( ! is_dir($directory) OR ! is_writable($directory)) - throw new Kohana_Exception('cache.unwritable', $directory); - - // Directory is valid - $this->directory = $directory; - } - - /** - * Finds an array of files matching the given id or tag. - * - * @param string cache id or tag - * @param bool search for tags - * @return array of filenames matching the id or tag - */ - public function exists($id, $tag = FALSE) - { - if ($id === TRUE) - { - // Find all the files - return glob($this->directory.'*~*~*'); - } - elseif ($tag === TRUE) - { - // Find all the files that have the tag name - $paths = glob($this->directory.'*~*'.$id.'*~*'); - - // Find all tags matching the given tag - $files = array(); - foreach ($paths as $path) - { - // Split the files - $tags = explode('~', basename($path)); - - // Find valid tags - if (count($tags) !== 3 OR empty($tags[1])) - continue; - - // Split the tags by plus signs, used to separate tags - $tags = explode('+', $tags[1]); - - if (in_array($tag, $tags)) - { - // Add the file to the array, it has the requested tag - $files[] = $path; - } - } - - return $files; - } - else - { - // Find the file matching the given id - return glob($this->directory.$id.'~*'); - } - } - - /** - * Sets a cache item to the given data, tags, and lifetime. - * - * @param string cache id to set - * @param string data in the cache - * @param array cache tags - * @param integer lifetime - * @return bool - */ - public function set($id, $data, array $tags = NULL, $lifetime) - { - // Remove old cache files - $this->delete($id); - - // Cache File driver expects unix timestamp - if ($lifetime !== 0) - { - $lifetime += time(); - } - - if ( ! empty($tags)) - { - // Convert the tags into a string list - $tags = implode('+', $tags); - } - - // Write out a serialized cache - return (bool) file_put_contents($this->directory.$id.'~'.$tags.'~'.$lifetime, serialize($data)); - } - - /** - * Finds an array of ids for a given tag. - * - * @param string tag name - * @return array of ids that match the tag - */ - public function find($tag) - { - // An array will always be returned - $result = array(); - - if ($paths = $this->exists($tag, TRUE)) - { - // Length of directory name - $offset = strlen($this->directory); - - // Find all the files with the given tag - foreach ($paths as $path) - { - // Get the id from the filename - list($id, $junk) = explode('~', basename($path), 2); - - if (($data = $this->get($id)) !== FALSE) - { - // Add the result to the array - $result[$id] = $data; - } - } - } - - return $result; - } - - /** - * Fetches a cache item. This will delete the item if it is expired or if - * the hash does not match the stored hash. - * - * @param string cache id - * @return mixed|NULL - */ - public function get($id) - { - if ($file = $this->exists($id)) - { - // Use the first file - $file = current($file); - - // Validate that the cache has not expired - if ($this->expired($file)) - { - // Remove this cache, it has expired - $this->delete($id); - } - else - { - // Turn off errors while reading the file - $ER = error_reporting(0); - - if (($data = file_get_contents($file)) !== FALSE) - { - // Unserialize the data - $data = unserialize($data); - } - else - { - // Delete the data - unset($data); - } - - // Turn errors back on - error_reporting($ER); - } - } - - // Return NULL if there is no data - return isset($data) ? $data : NULL; - } - - /** - * Deletes a cache item by id or tag - * - * @param string cache id or tag, or TRUE for "all items" - * @param boolean use tags - * @return boolean - */ - public function delete($id, $tag = FALSE) - { - $files = $this->exists($id, $tag); - - if (empty($files)) - return FALSE; - - // Disable all error reporting while deleting - $ER = error_reporting(0); - - foreach ($files as $file) - { - // Remove the cache file - if ( ! unlink($file)) - Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); - } - - // Turn on error reporting again - error_reporting($ER); - - return TRUE; - } - - /** - * Deletes all cache files that are older than the current time. - * - * @return void - */ - public function delete_expired() - { - if ($files = $this->exists(TRUE)) - { - // Disable all error reporting while deleting - $ER = error_reporting(0); - - foreach ($files as $file) - { - if ($this->expired($file)) - { - // The cache file has already expired, delete it - if ( ! unlink($file)) - Kohana::log('error', 'Cache: Unable to delete cache file: '.$file); - } - } - - // Turn on error reporting again - error_reporting($ER); - } - } - - /** - * Check if a cache file has expired by filename. - * - * @param string filename - * @return bool - */ - protected function expired($file) - { - // Get the expiration time - $expires = (int) substr($file, strrpos($file, '~') + 1); - - // Expirations of 0 are "never expire" - return ($expires !== 0 AND $expires <= time()); - } - -} // End Cache File Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Memcache.php b/kohana/libraries/drivers/Cache/Memcache.php deleted file mode 100644 index d801de9c..00000000 --- a/kohana/libraries/drivers/Cache/Memcache.php +++ /dev/null @@ -1,191 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Memcache-based Cache driver. - * - * $Id: Memcache.php 4102 2009-03-19 12:55:54Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Memcache_Driver implements Cache_Driver { - - const TAGS_KEY = 'memcache_tags_array'; - - // Cache backend object and flags - protected $backend; - protected $flags; - - // Tags array - protected static $tags; - - // Have the tags been changed? - protected static $tags_changed = FALSE; - - public function __construct() - { - if ( ! extension_loaded('memcache')) - throw new Kohana_Exception('cache.extension_not_loaded', 'memcache'); - - $this->backend = new Memcache; - $this->flags = Kohana::config('cache_memcache.compression') ? MEMCACHE_COMPRESSED : FALSE; - - $servers = Kohana::config('cache_memcache.servers'); - - foreach ($servers as $server) - { - // Make sure all required keys are set - $server += array('host' => '127.0.0.1', 'port' => 11211, 'persistent' => FALSE); - - // Add the server to the pool - $this->backend->addServer($server['host'], $server['port'], (bool) $server['persistent']) - or Kohana::log('error', 'Cache: Connection failed: '.$server['host']); - } - - // Load tags - self::$tags = $this->backend->get(self::TAGS_KEY); - - if ( ! is_array(self::$tags)) - { - // Create a new tags array - self::$tags = array(); - - // Tags have been created - self::$tags_changed = TRUE; - } - } - - public function __destruct() - { - if (self::$tags_changed === TRUE) - { - // Save the tags - $this->backend->set(self::TAGS_KEY, self::$tags, $this->flags, 0); - - // Tags are now unchanged - self::$tags_changed = FALSE; - } - } - - public function find($tag) - { - if (isset(self::$tags[$tag]) AND $results = $this->backend->get(self::$tags[$tag])) - { - // Return all the found caches - return $results; - } - else - { - // No matching tags - return array(); - } - } - - public function get($id) - { - return (($return = $this->backend->get($id)) === FALSE) ? NULL : $return; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - // Tags will be changed - self::$tags_changed = TRUE; - - foreach ($tags as $tag) - { - // Add the id to each tag - self::$tags[$tag][$id] = $id; - } - } - - if ($lifetime !== 0) - { - // Memcache driver expects unix timestamp - $lifetime += time(); - } - - // Set a new value - return $this->backend->set($id, $data, $this->flags, $lifetime); - } - - public function delete($id, $tag = FALSE) - { - // Tags will be changed - self::$tags_changed = TRUE; - - if ($id === TRUE) - { - if ($status = $this->backend->flush()) - { - // Remove all tags, all items have been deleted - self::$tags = array(); - - // We must sleep after flushing, or overwriting will not work! - // @see http://php.net/manual/en/function.memcache-flush.php#81420 - sleep(1); - } - - return $status; - } - elseif ($tag === TRUE) - { - if (isset(self::$tags[$id])) - { - foreach (self::$tags[$id] as $_id) - { - // Delete each id in the tag - $this->backend->delete($_id); - } - - // Delete the tag - unset(self::$tags[$id]); - } - - return TRUE; - } - else - { - foreach (self::$tags as $tag => $_ids) - { - if (isset(self::$tags[$tag][$id])) - { - // Remove the id from the tags - unset(self::$tags[$tag][$id]); - } - } - - return $this->backend->delete($id); - } - } - - public function delete_expired() - { - // Tags will be changed - self::$tags_changed = TRUE; - - foreach (self::$tags as $tag => $_ids) - { - foreach ($_ids as $id) - { - if ( ! $this->backend->get($id)) - { - // This id has disappeared, delete it from the tags - unset(self::$tags[$tag][$id]); - } - } - - if (empty(self::$tags[$tag])) - { - // The tag no longer has any valid ids - unset(self::$tags[$tag]); - } - } - - // Memcache handles garbage collection internally - return TRUE; - } - -} // End Cache Memcache Driver diff --git a/kohana/libraries/drivers/Cache/Sqlite.php b/kohana/libraries/drivers/Cache/Sqlite.php deleted file mode 100644 index 9458d851..00000000 --- a/kohana/libraries/drivers/Cache/Sqlite.php +++ /dev/null @@ -1,257 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * SQLite-based Cache driver. - * - * $Id: Sqlite.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Sqlite_Driver implements Cache_Driver { - - // SQLite database instance - protected $db; - - // Database error messages - protected $error; - - /** - * Logs an SQLite error. - */ - protected static function log_error($code) - { - // Log an error - Kohana::log('error', 'Cache: SQLite error: '.sqlite_error_string($error)); - } - - /** - * Tests that the storage location is a directory and is writable. - */ - public function __construct($filename) - { - // Get the directory name - $directory = str_replace('\\', '/', realpath(pathinfo($filename, PATHINFO_DIRNAME))).'/'; - - // Set the filename from the real directory path - $filename = $directory.basename($filename); - - // Make sure the cache directory is writable - if ( ! is_dir($directory) OR ! is_writable($directory)) - throw new Kohana_Exception('cache.unwritable', $directory); - - // Make sure the cache database is writable - if (is_file($filename) AND ! is_writable($filename)) - throw new Kohana_Exception('cache.unwritable', $filename); - - // Open up an instance of the database - $this->db = new SQLiteDatabase($filename, '0666', $error); - - // Throw an exception if there's an error - if ( ! empty($error)) - throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); - - $query = "SELECT name FROM sqlite_master WHERE type = 'table' AND name = 'caches'"; - $tables = $this->db->query($query, SQLITE_BOTH, $error); - - // Throw an exception if there's an error - if ( ! empty($error)) - throw new Kohana_Exception('cache.driver_error', sqlite_error_string($error)); - - if ($tables->numRows() == 0) - { - Kohana::log('error', 'Cache: Initializing new SQLite cache database'); - - // Issue a CREATE TABLE command - $this->db->unbufferedQuery(Kohana::config('cache_sqlite.schema')); - } - } - - /** - * Checks if a cache id is already set. - * - * @param string cache id - * @return boolean - */ - public function exists($id) - { - // Find the id that matches - $query = "SELECT id FROM caches WHERE id = '$id'"; - - return ($this->db->query($query)->numRows() > 0); - } - - /** - * Sets a cache item to the given data, tags, and lifetime. - * - * @param string cache id to set - * @param string data in the cache - * @param array cache tags - * @param integer lifetime - * @return bool - */ - public function set($id, $data, array $tags = NULL, $lifetime) - { - // Serialize and escape the data - $data = sqlite_escape_string(serialize($data)); - - if ( ! empty($tags)) - { - // Escape the tags, adding brackets so the tag can be explicitly matched - $tags = sqlite_escape_string('<'.implode('>,<', $tags).'>'); - } - - // Cache Sqlite driver expects unix timestamp - if ($lifetime !== 0) - { - $lifetime += time(); - } - - $query = $this->exists($id) - ? "UPDATE caches SET tags = '$tags', expiration = '$lifetime', cache = '$data' WHERE id = '$id'" - : "INSERT INTO caches VALUES('$id', '$tags', '$lifetime', '$data')"; - - // Run the query - $this->db->unbufferedQuery($query, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - return FALSE; - } - else - { - return TRUE; - } - } - - /** - * Finds an array of ids for a given tag. - * - * @param string tag name - * @return array of ids that match the tag - */ - public function find($tag) - { - $query = "SELECT id,cache FROM caches WHERE tags LIKE '%<{$tag}>%'"; - $query = $this->db->query($query, SQLITE_BOTH, $error); - - // An array will always be returned - $result = array(); - - if ( ! empty($error)) - { - self::log_error($error); - } - elseif ($query->numRows() > 0) - { - // Disable notices for unserializing - $ER = error_reporting(~E_NOTICE); - - while ($row = $query->fetchObject()) - { - // Add each cache to the array - $result[$row->id] = unserialize($row->cache); - } - - // Turn notices back on - error_reporting($ER); - } - - return $result; - } - - /** - * Fetches a cache item. This will delete the item if it is expired or if - * the hash does not match the stored hash. - * - * @param string cache id - * @return mixed|NULL - */ - public function get($id) - { - $query = "SELECT id, expiration, cache FROM caches WHERE id = '$id' LIMIT 0, 1"; - $query = $this->db->query($query, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - } - elseif ($cache = $query->fetchObject()) - { - // Make sure the expiration is valid and that the hash matches - if ($cache->expiration != 0 AND $cache->expiration <= time()) - { - // Cache is not valid, delete it now - $this->delete($cache->id); - } - else - { - // Disable notices for unserializing - $ER = error_reporting(~E_NOTICE); - - // Return the valid cache data - $data = $cache->cache; - - // Turn notices back on - error_reporting($ER); - } - } - - // No valid cache found - return NULL; - } - - /** - * Deletes a cache item by id or tag - * - * @param string cache id or tag, or TRUE for "all items" - * @param bool delete a tag - * @return bool - */ - public function delete($id, $tag = FALSE) - { - if ($id === TRUE) - { - // Delete all caches - $where = '1'; - } - elseif ($tag === TRUE) - { - // Delete by tag - $where = "tags LIKE '%<{$id}>%'"; - } - else - { - // Delete by id - $where = "id = '$id'"; - } - - $this->db->unbufferedQuery('DELETE FROM caches WHERE '.$where, SQLITE_BOTH, $error); - - if ( ! empty($error)) - { - self::log_error($error); - return FALSE; - } - else - { - return TRUE; - } - } - - /** - * Deletes all cache files that are older than the current time. - */ - public function delete_expired() - { - // Delete all expired caches - $query = 'DELETE FROM caches WHERE expiration != 0 AND expiration <= '.time(); - - $this->db->unbufferedQuery($query); - - return TRUE; - } - -} // End Cache SQLite Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Cache/Xcache.php b/kohana/libraries/drivers/Cache/Xcache.php deleted file mode 100644 index 6254bbb6..00000000 --- a/kohana/libraries/drivers/Cache/Xcache.php +++ /dev/null @@ -1,119 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Xcache Cache driver. - * - * $Id: Xcache.php 4046 2009-03-05 19:23:29Z Shadowhand $ - * - * @package Cache - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Cache_Xcache_Driver implements Cache_Driver { - - public function __construct() - { - if ( ! extension_loaded('xcache')) - throw new Kohana_Exception('cache.extension_not_loaded', 'xcache'); - } - - public function get($id) - { - if (xcache_isset($id)) - return xcache_get($id); - - return NULL; - } - - public function set($id, $data, array $tags = NULL, $lifetime) - { - if ( ! empty($tags)) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - } - - return xcache_set($id, $data, $lifetime); - } - - public function find($tag) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return FALSE; - } - - public function delete($id, $tag = FALSE) - { - if ($tag !== FALSE) - { - Kohana::log('error', 'Cache: tags are unsupported by the Xcache driver'); - return TRUE; - } - elseif ($id !== TRUE) - { - if (xcache_isset($id)) - return xcache_unset($id); - - return FALSE; - } - else - { - // Do the login - $this->auth(); - $result = TRUE; - for ($i = 0, $max = xcache_count(XC_TYPE_VAR); $i < $max; $i++) - { - if (xcache_clear_cache(XC_TYPE_VAR, $i) !== NULL) - { - $result = FALSE; - break; - } - } - - // Undo the login - $this->auth(TRUE); - return $result; - } - - return TRUE; - } - - public function delete_expired() - { - return TRUE; - } - - private function auth($reverse = FALSE) - { - static $backup = array(); - - $keys = array('PHP_AUTH_USER', 'PHP_AUTH_PW'); - - foreach ($keys as $key) - { - if ($reverse) - { - if (isset($backup[$key])) - { - $_SERVER[$key] = $backup[$key]; - unset($backup[$key]); - } - else - { - unset($_SERVER[$key]); - } - } - else - { - $value = getenv($key); - - if ( ! empty($value)) - { - $backup[$key] = $value; - } - - $_SERVER[$key] = Kohana::config('cache_xcache.'.$key); - } - } - } - -} // End Cache Xcache Driver diff --git a/kohana/libraries/drivers/Captcha.php b/kohana/libraries/drivers/Captcha.php deleted file mode 100644 index a4343e19..00000000 --- a/kohana/libraries/drivers/Captcha.php +++ /dev/null @@ -1,227 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver class. - * - * $Id: Captcha.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Captcha_Driver { - - // The correct Captcha challenge answer - protected $response; - - // Image resource identifier and type ("png", "gif" or "jpeg") - protected $image; - protected $image_type = 'png'; - - /** - * Constructs a new challenge. - * - * @return void - */ - public function __construct() - { - // Generate a new challenge - $this->response = $this->generate_challenge(); - - // Store the correct Captcha response in a session - Event::add('system.post_controller', array($this, 'update_response_session')); - } - - /** - * Generate a new Captcha challenge. - * - * @return string the challenge answer - */ - abstract public function generate_challenge(); - - /** - * Output the Captcha challenge. - * - * @param boolean html output - * @return mixed the rendered Captcha (e.g. an image, riddle, etc.) - */ - abstract public function render($html); - - /** - * Stores the response for the current Captcha challenge in a session so it is available - * on the next page load for Captcha::valid(). This method is called after controller - * execution (in the system.post_controller event) in order not to overwrite itself too soon. - * - * @return void - */ - public function update_response_session() - { - Session::instance()->set('captcha_response', sha1(strtoupper($this->response))); - } - - /** - * Validates a Captcha response from a user. - * - * @param string captcha response - * @return boolean - */ - public function valid($response) - { - return (sha1(strtoupper($response)) === Session::instance()->get('captcha_response')); - } - - /** - * Returns the image type. - * - * @param string filename - * @return string|FALSE image type ("png", "gif" or "jpeg") - */ - public function image_type($filename) - { - switch (strtolower(substr(strrchr($filename, '.'), 1))) - { - case 'png': - return 'png'; - - case 'gif': - return 'gif'; - - case 'jpg': - case 'jpeg': - // Return "jpeg" and not "jpg" because of the GD2 function names - return 'jpeg'; - - default: - return FALSE; - } - } - - /** - * Creates an image resource with the dimensions specified in config. - * If a background image is supplied, the image dimensions are used. - * - * @throws Kohana_Exception if no GD2 support - * @param string path to the background image file - * @return void - */ - public function image_create($background = NULL) - { - // Check for GD2 support - if ( ! function_exists('imagegd2')) - throw new Kohana_Exception('captcha.requires_GD2'); - - // Create a new image (black) - $this->image = imagecreatetruecolor(Captcha::$config['width'], Captcha::$config['height']); - - // Use a background image - if ( ! empty($background)) - { - // Create the image using the right function for the filetype - $function = 'imagecreatefrom'.$this->image_type($background); - $this->background_image = $function($background); - - // Resize the image if needed - if (imagesx($this->background_image) !== Captcha::$config['width'] - OR imagesy($this->background_image) !== Captcha::$config['height']) - { - imagecopyresampled - ( - $this->image, $this->background_image, 0, 0, 0, 0, - Captcha::$config['width'], Captcha::$config['height'], - imagesx($this->background_image), imagesy($this->background_image) - ); - } - - // Free up resources - imagedestroy($this->background_image); - } - } - - /** - * Fills the background with a gradient. - * - * @param resource gd image color identifier for start color - * @param resource gd image color identifier for end color - * @param string direction: 'horizontal' or 'vertical', 'random' by default - * @return void - */ - public function image_gradient($color1, $color2, $direction = NULL) - { - $directions = array('horizontal', 'vertical'); - - // Pick a random direction if needed - if ( ! in_array($direction, $directions)) - { - $direction = $directions[array_rand($directions)]; - - // Switch colors - if (mt_rand(0, 1) === 1) - { - $temp = $color1; - $color1 = $color2; - $color2 = $temp; - } - } - - // Extract RGB values - $color1 = imagecolorsforindex($this->image, $color1); - $color2 = imagecolorsforindex($this->image, $color2); - - // Preparations for the gradient loop - $steps = ($direction === 'horizontal') ? Captcha::$config['width'] : Captcha::$config['height']; - - $r1 = ($color1['red'] - $color2['red']) / $steps; - $g1 = ($color1['green'] - $color2['green']) / $steps; - $b1 = ($color1['blue'] - $color2['blue']) / $steps; - - if ($direction === 'horizontal') - { - $x1 =& $i; - $y1 = 0; - $x2 =& $i; - $y2 = Captcha::$config['height']; - } - else - { - $x1 = 0; - $y1 =& $i; - $x2 = Captcha::$config['width']; - $y2 =& $i; - } - - // Execute the gradient loop - for ($i = 0; $i <= $steps; $i++) - { - $r2 = $color1['red'] - floor($i * $r1); - $g2 = $color1['green'] - floor($i * $g1); - $b2 = $color1['blue'] - floor($i * $b1); - $color = imagecolorallocate($this->image, $r2, $g2, $b2); - - imageline($this->image, $x1, $y1, $x2, $y2, $color); - } - } - - /** - * Returns the img html element or outputs the image to the browser. - * - * @param boolean html output - * @return mixed html string or void - */ - public function image_render($html) - { - // Output html element - if ($html) - return '<img alt="Captcha" src="'.url::site('captcha/'.Captcha::$config['group']).'" width="'.Captcha::$config['width'].'" height="'.Captcha::$config['height'].'" />'; - - // Send the correct HTTP header - header('Content-Type: image/'.$this->image_type); - - // Pick the correct output function - $function = 'image'.$this->image_type; - $function($this->image); - - // Free up resources - imagedestroy($this->image); - } - -} // End Captcha Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Alpha.php b/kohana/libraries/drivers/Captcha/Alpha.php deleted file mode 100644 index b3a9c9d7..00000000 --- a/kohana/libraries/drivers/Captcha/Alpha.php +++ /dev/null @@ -1,92 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "alpha" style. - * - * $Id: Alpha.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Alpha_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, Captcha::$config['complexity'])); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates $this->image - $this->image_create(Captcha::$config['background']); - - // Add a random gradient - if (empty(Captcha::$config['background'])) - { - $color1 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); - $color2 = imagecolorallocate($this->image, mt_rand(0, 100), mt_rand(0, 100), mt_rand(0, 100)); - $this->image_gradient($color1, $color2); - } - - // Add a few random circles - for ($i = 0, $count = mt_rand(10, Captcha::$config['complexity'] * 3); $i < $count; $i++) - { - $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(0, 255), mt_rand(80, 120)); - $size = mt_rand(5, Captcha::$config['height'] / 3); - imagefilledellipse($this->image, mt_rand(0, Captcha::$config['width']), mt_rand(0, Captcha::$config['height']), $size, $size, $color); - } - - // Calculate character font-size and spacing - $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / strlen($this->response); - $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); - - // Background alphabetic character attributes - $color_limit = mt_rand(96, 160); - $chars = 'ABEFGJKLPQRTVY'; - - // Draw each Captcha character with varying attributes - for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) - { - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - $angle = mt_rand(-40, 20); - // Scale the character size on image height - $size = $default_size / 10 * mt_rand(8, 12); - $box = imageftbbox($size, $angle, $font, $this->response[$i]); - - // Calculate character starting coordinates - $x = $spacing / 4 + $i * $spacing; - $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; - - // Draw captcha text character - // Allocate random color, size and rotation attributes to text - $color = imagecolorallocate($this->image, mt_rand(150, 255), mt_rand(200, 255), mt_rand(0, 255)); - - // Write text character to image - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); - - // Draw "ghost" alphabetic character - $text_color = imagecolorallocatealpha($this->image, mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand($color_limit + 8, 255), mt_rand(70, 120)); - $char = substr($chars, mt_rand(0, 14), 1); - imagettftext($this->image, $size * 2, mt_rand(-45, 45), ($x - (mt_rand(5, 10))), ($y + (mt_rand(5, 10))), $text_color, $font, $char); - } - - // Output - return $this->image_render($html); - } - -} // End Captcha Alpha Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Basic.php b/kohana/libraries/drivers/Captcha/Basic.php deleted file mode 100644 index d212e72c..00000000 --- a/kohana/libraries/drivers/Captcha/Basic.php +++ /dev/null @@ -1,81 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "basic" style. - * - * $Id: Basic.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Basic_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, Captcha::$config['complexity'])); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates $this->image - $this->image_create(Captcha::$config['background']); - - // Add a random gradient - if (empty(Captcha::$config['background'])) - { - $color1 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); - $color2 = imagecolorallocate($this->image, mt_rand(200, 255), mt_rand(200, 255), mt_rand(150, 255)); - $this->image_gradient($color1, $color2); - } - - // Add a few random lines - for ($i = 0, $count = mt_rand(5, Captcha::$config['complexity'] * 4); $i < $count; $i++) - { - $color = imagecolorallocatealpha($this->image, mt_rand(0, 255), mt_rand(0, 255), mt_rand(100, 255), mt_rand(50, 120)); - imageline($this->image, mt_rand(0, Captcha::$config['width']), 0, mt_rand(0, Captcha::$config['width']), Captcha::$config['height'], $color); - } - - // Calculate character font-size and spacing - $default_size = min(Captcha::$config['width'], Captcha::$config['height'] * 2) / (strlen($this->response) + 1); - $spacing = (int) (Captcha::$config['width'] * 0.9 / strlen($this->response)); - - // Draw each Captcha character with varying attributes - for ($i = 0, $strlen = strlen($this->response); $i < $strlen; $i++) - { - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - // Allocate random color, size and rotation attributes to text - $color = imagecolorallocate($this->image, mt_rand(0, 150), mt_rand(0, 150), mt_rand(0, 150)); - $angle = mt_rand(-40, 20); - - // Scale the character size on image height - $size = $default_size / 10 * mt_rand(8, 12); - $box = imageftbbox($size, $angle, $font, $this->response[$i]); - - // Calculate character starting coordinates - $x = $spacing / 4 + $i * $spacing; - $y = Captcha::$config['height'] / 2 + ($box[2] - $box[5]) / 4; - - // Write text character to image - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response[$i]); - } - - // Output - return $this->image_render($html); - } - -} // End Captcha Basic Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Black.php b/kohana/libraries/drivers/Captcha/Black.php deleted file mode 100644 index 6a2e2226..00000000 --- a/kohana/libraries/drivers/Captcha/Black.php +++ /dev/null @@ -1,72 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "black" style. - * - * $Id: Black.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Black_Driver extends Captcha_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Complexity setting is used as character count - return text::random('distinct', max(1, ceil(Captcha::$config['complexity'] / 1.5))); - } - - /** - * Outputs the Captcha image. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - // Creates a black image to start from - $this->image_create(Captcha::$config['background']); - - // Add random white/gray arcs, amount depends on complexity setting - $count = (Captcha::$config['width'] + Captcha::$config['height']) / 2; - $count = $count / 5 * min(10, Captcha::$config['complexity']); - for ($i = 0; $i < $count; $i++) - { - imagesetthickness($this->image, mt_rand(1, 2)); - $color = imagecolorallocatealpha($this->image, 255, 255, 255, mt_rand(0, 120)); - imagearc($this->image, mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(-Captcha::$config['width'], Captcha::$config['width']), mt_rand(-Captcha::$config['height'], Captcha::$config['height']), mt_rand(0, 360), mt_rand(0, 360), $color); - } - - // Use different fonts if available - $font = Captcha::$config['fontpath'].Captcha::$config['fonts'][array_rand(Captcha::$config['fonts'])]; - - // Draw the character's white shadows - $size = (int) min(Captcha::$config['height'] / 2, Captcha::$config['width'] * 0.8 / strlen($this->response)); - $angle = mt_rand(-15 + strlen($this->response), 15 - strlen($this->response)); - $x = mt_rand(1, Captcha::$config['width'] * 0.9 - $size * strlen($this->response)); - $y = ((Captcha::$config['height'] - $size) / 2) + $size; - $color = imagecolorallocate($this->image, 255, 255, 255); - imagefttext($this->image, $size, $angle, $x + 1, $y + 1, $color, $font, $this->response); - - // Add more shadows for lower complexities - (Captcha::$config['complexity'] < 10) and imagefttext($this->image, $size, $angle, $x - 1, $y - 1, $color, $font , $this->response); - (Captcha::$config['complexity'] < 8) and imagefttext($this->image, $size, $angle, $x - 2, $y + 2, $color, $font , $this->response); - (Captcha::$config['complexity'] < 6) and imagefttext($this->image, $size, $angle, $x + 2, $y - 2, $color, $font , $this->response); - (Captcha::$config['complexity'] < 4) and imagefttext($this->image, $size, $angle, $x + 3, $y + 3, $color, $font , $this->response); - (Captcha::$config['complexity'] < 2) and imagefttext($this->image, $size, $angle, $x - 3, $y - 3, $color, $font , $this->response); - - // Finally draw the foreground characters - $color = imagecolorallocate($this->image, 0, 0, 0); - imagefttext($this->image, $size, $angle, $x, $y, $color, $font, $this->response); - - // Output - return $this->image_render($html); - } - -} // End Captcha Black Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Math.php b/kohana/libraries/drivers/Captcha/Math.php deleted file mode 100644 index 4ac20248..00000000 --- a/kohana/libraries/drivers/Captcha/Math.php +++ /dev/null @@ -1,61 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "math" style. - * - * $Id: Math.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Math_Driver extends Captcha_Driver { - - private $math_exercice; - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Easy - if (Captcha::$config['complexity'] < 4) - { - $numbers[] = mt_rand(1, 5); - $numbers[] = mt_rand(1, 4); - } - // Normal - elseif (Captcha::$config['complexity'] < 7) - { - $numbers[] = mt_rand(10, 20); - $numbers[] = mt_rand(1, 10); - } - // Difficult, well, not really ;) - else - { - $numbers[] = mt_rand(100, 200); - $numbers[] = mt_rand(10, 20); - $numbers[] = mt_rand(1, 10); - } - - // Store the question for output - $this->math_exercice = implode(' + ', $numbers).' = '; - - // Return the answer - return array_sum($numbers); - } - - /** - * Outputs the Captcha riddle. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - return $this->math_exercice; - } - -} // End Captcha Math Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Riddle.php b/kohana/libraries/drivers/Captcha/Riddle.php deleted file mode 100644 index 765eeaad..00000000 --- a/kohana/libraries/drivers/Captcha/Riddle.php +++ /dev/null @@ -1,47 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "riddle" style. - * - * $Id: Riddle.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Riddle_Driver extends Captcha_Driver { - - private $riddle; - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Load riddles from the current language - $riddles = Kohana::lang('captcha.riddles'); - - // Pick a random riddle - $riddle = $riddles[array_rand($riddles)]; - - // Store the question for output - $this->riddle = $riddle[0]; - - // Return the answer - return $riddle[1]; - } - - /** - * Outputs the Captcha riddle. - * - * @param boolean html output - * @return mixed - */ - public function render($html) - { - return $this->riddle; - } - -} // End Captcha Riddle Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Captcha/Word.php b/kohana/libraries/drivers/Captcha/Word.php deleted file mode 100644 index 856bd9b4..00000000 --- a/kohana/libraries/drivers/Captcha/Word.php +++ /dev/null @@ -1,37 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Captcha driver for "word" style. - * - * $Id: Word.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Captcha - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Captcha_Word_Driver extends Captcha_Basic_Driver { - - /** - * Generates a new Captcha challenge. - * - * @return string the challenge answer - */ - public function generate_challenge() - { - // Load words from the current language and randomize them - $words = Kohana::lang('captcha.words'); - shuffle($words); - - // Loop over each word... - foreach ($words as $word) - { - // ...until we find one of the desired length - if (abs(Captcha::$config['complexity'] - strlen($word)) < 2) - return strtoupper($word); - } - - // Return any random word as final fallback - return strtoupper($words[array_rand($words)]); - } - -} // End Captcha Word Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Database.php b/kohana/libraries/drivers/Database.php deleted file mode 100644 index 807469f6..00000000 --- a/kohana/libraries/drivers/Database.php +++ /dev/null @@ -1,636 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Database API driver - * - * $Id: Database.php 4343 2009-05-08 17:04:48Z jheathco $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Database_Driver { - - protected $query_cache; - - /** - * Connect to our database. - * Returns FALSE on failure or a MySQL resource. - * - * @return mixed - */ - abstract public function connect(); - - /** - * Perform a query based on a manually written query. - * - * @param string SQL query to execute - * @return Database_Result - */ - abstract public function query($sql); - - /** - * Builds a DELETE query. - * - * @param string table name - * @param array where clause - * @return string - */ - public function delete($table, $where) - { - return 'DELETE FROM '.$this->escape_table($table).' WHERE '.implode(' ', $where); - } - - /** - * Builds an UPDATE query. - * - * @param string table name - * @param array key => value pairs - * @param array where clause - * @return string - */ - public function update($table, $values, $where) - { - foreach ($values as $key => $val) - { - $valstr[] = $this->escape_column($key).' = '.$val; - } - return 'UPDATE '.$this->escape_table($table).' SET '.implode(', ', $valstr).' WHERE '.implode(' ',$where); - } - - /** - * Set the charset using 'SET NAMES <charset>'. - * - * @param string character set to use - */ - public function set_charset($charset) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Wrap the tablename in backticks, has support for: table.field syntax. - * - * @param string table name - * @return string - */ - abstract public function escape_table($table); - - /** - * Escape a column/field name, has support for special commands. - * - * @param string column name - * @return string - */ - abstract public function escape_column($column); - - /** - * Builds a WHERE portion of a query. - * - * @param mixed key - * @param string value - * @param string type - * @param int number of where clauses - * @param boolean escape the value - * @return string - */ - public function where($key, $value, $type, $num_wheres, $quote) - { - $prefix = ($num_wheres == 0) ? '' : $type; - - if ($quote === -1) - { - $value = ''; - } - else - { - if ($value === NULL) - { - if ( ! $this->has_operator($key)) - { - $key .= ' IS'; - } - - $value = ' NULL'; - } - elseif (is_bool($value)) - { - if ( ! $this->has_operator($key)) - { - $key .= ' ='; - } - - $value = ($value == TRUE) ? ' 1' : ' 0'; - } - else - { - if ( ! $this->has_operator($key) AND ! empty($key)) - { - $key = $this->escape_column($key).' ='; - } - else - { - preg_match('/^(.+?)([<>!=]+|\bIS(?:\s+NULL))\s*$/i', $key, $matches); - if (isset($matches[1]) AND isset($matches[2])) - { - $key = $this->escape_column(trim($matches[1])).' '.trim($matches[2]); - } - } - - $value = ' '.(($quote == TRUE) ? $this->escape($value) : $value); - } - } - - return $prefix.$key.$value; - } - - /** - * Builds a LIKE portion of a query. - * - * @param mixed field name - * @param string value to match with field - * @param boolean add wildcards before and after the match - * @param string clause type (AND or OR) - * @param int number of likes - * @return string - */ - public function like($field, $match, $auto, $type, $num_likes) - { - $prefix = ($num_likes == 0) ? '' : $type; - - $match = $this->escape_str($match); - - if ($auto === TRUE) - { - // Add the start and end quotes - $match = '%'.str_replace('%', '\\%', $match).'%'; - } - - return $prefix.' '.$this->escape_column($field).' LIKE \''.$match . '\''; - } - - /** - * Builds a NOT LIKE portion of a query. - * - * @param mixed field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param int number of likes - * @return string - */ - public function notlike($field, $match, $auto, $type, $num_likes) - { - $prefix = ($num_likes == 0) ? '' : $type; - - $match = $this->escape_str($match); - - if ($auto === TRUE) - { - // Add the start and end quotes - $match = '%'.$match.'%'; - } - - return $prefix.' '.$this->escape_column($field).' NOT LIKE \''.$match.'\''; - } - - /** - * Builds a REGEX portion of a query. - * - * @param string field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param integer number of regexes - * @return string - */ - public function regex($field, $match, $type, $num_regexs) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds a NOT REGEX portion of a query. - * - * @param string field name - * @param string value to match with field - * @param string clause type (AND or OR) - * @param integer number of regexes - * @return string - */ - public function notregex($field, $match, $type, $num_regexs) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds an INSERT query. - * - * @param string table name - * @param array keys - * @param array values - * @return string - */ - public function insert($table, $keys, $values) - { - // Escape the column names - foreach ($keys as $key => $value) - { - $keys[$key] = $this->escape_column($value); - } - return 'INSERT INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - /** - * Builds a MERGE portion of a query. - * - * @param string table name - * @param array keys - * @param array values - * @return string - */ - public function merge($table, $keys, $values) - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Builds a LIMIT portion of a query. - * - * @param integer limit - * @param integer offset - * @return string - */ - abstract public function limit($limit, $offset = 0); - - /** - * Creates a prepared statement. - * - * @param string SQL query - * @return Database_Stmt - */ - public function stmt_prepare($sql = '') - { - throw new Kohana_Database_Exception('database.not_implemented', __FUNCTION__); - } - - /** - * Compiles the SELECT statement. - * Generates a query string based on which functions were used. - * Should not be called directly, the get() function calls it. - * - * @param array select query values - * @return string - */ - abstract public function compile_select($database); - - /** - * Determines if the string has an arithmetic operator in it. - * - * @param string string to check - * @return boolean - */ - public function has_operator($str) - { - return (bool) preg_match('/[<>!=]|\sIS(?:\s+NOT\s+)?\b|BETWEEN/i', trim($str)); - } - - /** - * Escapes any input value. - * - * @param mixed value to escape - * @return string - */ - public function escape($value) - { - if ( ! $this->db_config['escape']) - return $value; - - switch (gettype($value)) - { - case 'string': - $value = '\''.$this->escape_str($value).'\''; - break; - case 'boolean': - $value = (int) $value; - break; - case 'double': - // Convert to non-locale aware float to prevent possible commas - $value = sprintf('%F', $value); - break; - default: - $value = ($value === NULL) ? 'NULL' : $value; - break; - } - - return (string) $value; - } - - /** - * Escapes a string for a query. - * - * @param mixed value to escape - * @return string - */ - abstract public function escape_str($str); - - /** - * Lists all tables in the database. - * - * @return array - */ - abstract public function list_tables(); - - /** - * Lists all fields in a table. - * - * @param string table name - * @return array - */ - abstract function list_fields($table); - - /** - * Returns the last database error. - * - * @return string - */ - abstract public function show_error(); - - /** - * Returns field data about a table. - * - * @param string table name - * @return array - */ - abstract public function field_data($table); - - /** - * Fetches SQL type information about a field, in a generic format. - * - * @param string field datatype - * @return array - */ - protected function sql_type($str) - { - static $sql_types; - - if ($sql_types === NULL) - { - // Load SQL data types - $sql_types = Kohana::config('sql_types'); - } - - $str = strtolower(trim($str)); - - if (($open = strpos($str, '(')) !== FALSE) - { - // Find closing bracket - $close = strpos($str, ')', $open) - 1; - - // Find the type without the size - $type = substr($str, 0, $open); - } - else - { - // No length - $type = $str; - } - - empty($sql_types[$type]) and exit - ( - 'Unknown field type: '.$type.'. '. - 'Please report this: http://trac.kohanaphp.com/newticket' - ); - - // Fetch the field definition - $field = $sql_types[$type]; - - switch ($field['type']) - { - case 'string': - case 'float': - if (isset($close)) - { - // Add the length to the field info - $field['length'] = substr($str, $open + 1, $close - $open); - } - break; - case 'int': - // Add unsigned value - $field['unsigned'] = (strpos($str, 'unsigned') !== FALSE); - break; - } - - return $field; - } - - /** - * Clears the internal query cache. - * - * @param string SQL query - */ - public function clear_cache($sql = NULL) - { - if (empty($sql)) - { - $this->query_cache = array(); - } - else - { - unset($this->query_cache[$this->query_hash($sql)]); - } - - Kohana::log('debug', 'Database cache cleared: '.get_class($this)); - } - - /** - * Creates a hash for an SQL query string. Replaces newlines with spaces, - * trims, and hashes. - * - * @param string SQL query - * @return string - */ - protected function query_hash($sql) - { - return sha1(str_replace("\n", ' ', trim($sql))); - } - -} // End Database Driver Interface - -/** - * Database_Result - * - */ -abstract class Database_Result implements ArrayAccess, Iterator, Countable { - - // Result resource, insert id, and SQL - protected $result; - protected $insert_id; - protected $sql; - - // Current and total rows - protected $current_row = 0; - protected $total_rows = 0; - - // Fetch function and return type - protected $fetch_type; - protected $return_type; - - /** - * Returns the SQL used to fetch the result. - * - * @return string - */ - public function sql() - { - return $this->sql; - } - - /** - * Returns the insert id from the result. - * - * @return mixed - */ - public function insert_id() - { - return $this->insert_id; - } - - /** - * Prepares the query result. - * - * @param boolean return rows as objects - * @param mixed type - * @return Database_Result - */ - abstract function result($object = TRUE, $type = FALSE); - - /** - * Builds an array of query results. - * - * @param boolean return rows as objects - * @param mixed type - * @return array - */ - abstract function result_array($object = NULL, $type = FALSE); - - /** - * Gets the fields of an already run query. - * - * @return array - */ - abstract public function list_fields(); - - /** - * Seek to an offset in the results. - * - * @return boolean - */ - abstract public function seek($offset); - - /** - * Countable: count - */ - public function count() - { - return $this->total_rows; - } - - /** - * ArrayAccess: offsetExists - */ - public function offsetExists($offset) - { - if ($this->total_rows > 0) - { - $min = 0; - $max = $this->total_rows - 1; - - return ! ($offset < $min OR $offset > $max); - } - - return FALSE; - } - - /** - * ArrayAccess: offsetGet - */ - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row by calling the defined fetching callback - return call_user_func($this->fetch_type, $this->result, $this->return_type); - } - - /** - * ArrayAccess: offsetSet - * - * @throws Kohana_Database_Exception - */ - final public function offsetSet($offset, $value) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - - /** - * ArrayAccess: offsetUnset - * - * @throws Kohana_Database_Exception - */ - final public function offsetUnset($offset) - { - throw new Kohana_Database_Exception('database.result_read_only'); - } - - /** - * Iterator: current - */ - public function current() - { - return $this->offsetGet($this->current_row); - } - - /** - * Iterator: key - */ - public function key() - { - return $this->current_row; - } - - /** - * Iterator: next - */ - public function next() - { - ++$this->current_row; - return $this; - } - - /** - * Iterator: prev - */ - public function prev() - { - --$this->current_row; - return $this; - } - - /** - * Iterator: rewind - */ - public function rewind() - { - $this->current_row = 0; - return $this; - } - - /** - * Iterator: valid - */ - public function valid() - { - return $this->offsetExists($this->current_row); - } - -} // End Database Result Interface diff --git a/kohana/libraries/drivers/Database/Mssql.php b/kohana/libraries/drivers/Database/Mssql.php deleted file mode 100644 index 6947679a..00000000 --- a/kohana/libraries/drivers/Database/Mssql.php +++ /dev/null @@ -1,462 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MSSQL Database Driver - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mssql_Driver extends Database_Driver -{ - /** - * Database connection link - */ - protected $link; - - /** - * Database configuration - */ - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MSSQL Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_resource($this->link) and mssql_close($this->link); - } - - /** - * Make the connection - * - * @return return connection - */ - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'mssql_pconnect' : 'mssql_connect'; - - // Build the connection info - $host = isset($host) ? $host : $socket; - - // Windows uses a comma instead of a colon - $port = (isset($port) AND is_string($port)) ? (KOHANA_IS_WIN ? ',' : ':').$port : ''; - - // Make the connection and select the database - if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mssql_select_db($database, $this->link)) - { - /* This is being removed so I can use it, will need to come up with a more elegant workaround in the future... - * - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - */ - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Mssql_Result(mssql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - - public function escape_table($table) - { - if (stripos($table, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $table = str_ireplace(' AS ', ' AS ', $table); - - // Runs escape_table on both sides of an AS statement - $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); - - // Re-create the AS statement - return implode(' AS ', $table); - } - return '['.str_replace('.', '[.]', $table).']'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '[$0]', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '[$0]', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - /** - * Limit in SQL Server 2000 only uses the keyword - * 'TOP'; 2007 may have an offset keyword, but - * I am unsure - for pagination style limit,offset - * functionality, a fancy query needs to be built. - * - * @param unknown_type $limit - * @return unknown - */ - public function limit($limit, $offset=null) - { - return 'TOP '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - // Escape the tables - $froms = array(); - foreach ($database['from'] as $from) - $froms[] = $this->escape_column($from); - $sql .= "\nFROM "; - $sql .= implode(', ', $froms); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - //mssql_real_escape_string($str, $this->link); <-- this function doesn't exist - - $characters = array('/\x00/', '/\x1a/', '/\n/', '/\r/', '/\\\/', '/\'/'); - $replace = array('\\\x00', '\\x1a', '\\n', '\\r', '\\\\', "''"); - return preg_replace($characters, $replace, $str); - } - - public function list_tables() - { - $sql = 'SHOW TABLES FROM ['.$this->db_config['connection']['database'].']'; - $result = $this->query($sql)->result(FALSE, MSSQL_ASSOC); - - $retval = array(); - foreach ($result as $row) - { - $retval[] = current($row); - } - - return $retval; - } - - public function show_error() - { - return mssql_get_last_message($this->link); - } - - public function list_fields($table) - { - $result = array(); - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->Field] = $this->sql_type($row->Type); - } - - return $result; - } - - public function field_data($table) - { - $query = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table), $this->link); - - return $query->result_array(TRUE); - } -} - -/** - * MSSQL Result - */ -class Mssql_Result extends Database_Result { - - // Fetch function and return type - protected $fetch_type = 'mssql_fetch_object'; - protected $return_type = MSSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - $this->current_row = 0; - $this->total_rows = mssql_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'mssql_fetch_object' : 'mssql_fetch_array'; - } - elseif (is_bool($result)) - { - if ($result == FALSE) - { - // SQL error - throw new Kohana_Database_Exception('database.error', mssql_get_last_message($link).' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE querys - $last_id = mssql_query('SELECT @@IDENTITY AS last_id', $link); - $result = mssql_fetch_assoc($last_id); - $this->insert_id = $result['last_id']; - $this->total_rows = mssql_rows_affected($link); - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Destruct, the cleanup crew! - */ - public function __destruct() - { - if (is_resource($this->result)) - { - mssql_free_result($this->result); - } - } - - public function result($object = TRUE, $type = MSSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'mssql_fetch_object' : 'mssql_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'mssql_fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MSSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MSSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'mssql_fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'mssql_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'mssql_fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if (mssql_num_rows($this->result)) - { - // Reset the pointer location to make sure things work properly - mssql_data_seek($this->result, 0); - - while ($row = $fetch($this->result, $type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = mssql_fetch_field($this->result)) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ( ! $this->offsetExists($offset)) - return FALSE; - - return mssql_data_seek($this->result, $offset); - } - -} // End mssql_Result Class diff --git a/kohana/libraries/drivers/Database/Mysql.php b/kohana/libraries/drivers/Database/Mysql.php deleted file mode 100644 index d5222f50..00000000 --- a/kohana/libraries/drivers/Database/Mysql.php +++ /dev/null @@ -1,496 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MySQL Database Driver - * - * $Id: Mysql.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mysql_Driver extends Database_Driver { - - /** - * Database connection link - */ - protected $link; - - /** - * Database configuration - */ - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MySQL Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_resource($this->link) and mysql_close($this->link); - } - - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'mysql_pconnect' : 'mysql_connect'; - - // Build the connection info - $host = isset($host) ? $host : $socket; - $port = isset($port) ? ':'.$port : ''; - - // Make the connection and select the database - if (($this->link = $connect($host.$port, $user, $pass, TRUE)) AND mysql_select_db($database, $this->link)) - { - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Mysql_Result(mysql_query($sql, $this->link), $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->query('SET NAMES '.$this->escape_str($charset)); - } - - public function escape_table($table) - { - if (!$this->db_config['escape']) - return $table; - - if (stripos($table, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $table = str_ireplace(' AS ', ' AS ', $table); - - // Runs escape_table on both sides of an AS statement - $table = array_map(array($this, __FUNCTION__), explode(' AS ', $table)); - - // Re-create the AS statement - return implode(' AS ', $table); - } - return '`'.str_replace('.', '`.`', $table).'`'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '`$0`', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function regex($field, $match, $type, $num_regexs) - { - $prefix = ($num_regexs == 0) ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' REGEXP \''.$this->escape_str($match).'\''; - } - - public function notregex($field, $match, $type, $num_regexs) - { - $prefix = $num_regexs == 0 ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' NOT REGEXP \''.$this->escape_str($match) . '\''; - } - - public function merge($table, $keys, $values) - { - // Escape the column names - foreach ($keys as $key => $value) - { - $keys[$key] = $this->escape_column($value); - } - return 'REPLACE INTO '.$this->escape_table($table).' ('.implode(', ', $keys).') VALUES ('.implode(', ', $values).')'; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$offset.', '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - // Escape the tables - $froms = array(); - foreach ($database['from'] as $from) - { - $froms[] = $this->escape_column($from); - } - $sql .= "\nFROM ("; - $sql .= implode(', ', $froms).")"; - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - - return mysql_real_escape_string($str, $this->link); - } - - public function list_tables() - { - $tables = array(); - - if ($query = $this->query('SHOW TABLES FROM '.$this->escape_table($this->db_config['connection']['database']))) - { - foreach ($query->result(FALSE) as $row) - { - $tables[] = current($row); - } - } - - return $tables; - } - - public function show_error() - { - return mysql_error($this->link); - } - - public function list_fields($table) - { - $result = NULL; - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->Field] = $this->sql_type($row->Type); - - if ($row->Key === 'PRI' AND $row->Extra === 'auto_increment') - { - // For sequenced (AUTO_INCREMENT) tables - $result[$row->Field]['sequenced'] = TRUE; - } - - if ($row->Null === 'YES') - { - // Set NULL status - $result[$row->Field]['null'] = TRUE; - } - } - - if (!isset($result)) - throw new Kohana_Database_Exception('database.table_not_found', $table); - - return $result; - } - - public function field_data($table) - { - $result = $this->query('SHOW COLUMNS FROM '.$this->escape_table($table)); - - return $result->result_array(TRUE); - } - -} // End Database_Mysql_Driver Class - -/** - * MySQL Result - */ -class Mysql_Result extends Database_Result { - - // Fetch function and return type - protected $fetch_type = 'mysql_fetch_object'; - protected $return_type = MYSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - $this->current_row = 0; - $this->total_rows = mysql_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'mysql_fetch_object' : 'mysql_fetch_array'; - } - elseif (is_bool($result)) - { - if ($result == FALSE) - { - // SQL error - throw new Kohana_Database_Exception('database.error', mysql_error($link).' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - $this->insert_id = mysql_insert_id($link); - $this->total_rows = mysql_affected_rows($link); - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Destruct, the cleanup crew! - */ - public function __destruct() - { - if (is_resource($this->result)) - { - mysql_free_result($this->result); - } - } - - public function result($object = TRUE, $type = MYSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'mysql_fetch_object' : 'mysql_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'mysql_fetch_object' AND $object === TRUE) - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MYSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MYSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'mysql_fetch_object'; - - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'mysql_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'mysql_fetch_object') - { - $type = (is_string($this->return_type) AND Kohana::auto_load($this->return_type)) ? $this->return_type : 'stdClass'; - } - } - - if (mysql_num_rows($this->result)) - { - // Reset the pointer location to make sure things work properly - mysql_data_seek($this->result, 0); - - while ($row = $fetch($this->result, $type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = mysql_fetch_field($this->result)) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND mysql_data_seek($this->result, $offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - else - { - return FALSE; - } - } - -} // End Mysql_Result Class diff --git a/kohana/libraries/drivers/Database/Mysqli.php b/kohana/libraries/drivers/Database/Mysqli.php deleted file mode 100644 index 0dd9f05c..00000000 --- a/kohana/libraries/drivers/Database/Mysqli.php +++ /dev/null @@ -1,358 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * MySQLi Database Driver - * - * $Id: Mysqli.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Mysqli_Driver extends Database_Mysql_Driver { - - // Database connection link - protected $link; - protected $db_config; - protected $statements = array(); - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'MySQLi Database Driver Initialized'); - } - - /** - * Closes the database connection. - */ - public function __destruct() - { - is_object($this->link) and $this->link->close(); - } - - public function connect() - { - // Check if link already exists - if (is_object($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Build the connection info - $host = isset($host) ? $host : $socket; - - // Make the connection and select the database - if ($this->link = new mysqli($host, $user, $pass, $database, $port)) - { - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|REPLACE|SET|DELETE|TRUNCATE)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - // Return the cached query - return $this->query_cache[$hash]; - } - - return new Kohana_Mysqli_Result($this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - if ($this->link->set_charset($charset) === FALSE) - throw new Kohana_Database_Exception('database.error', $this->show_error()); - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_object($this->link) or $this->connect(); - - return $this->link->real_escape_string($str); - } - - public function show_error() - { - return $this->link->error; - } - -} // End Database_Mysqli_Driver Class - -/** - * MySQLi Result - */ -class Kohana_Mysqli_Result extends Database_Result { - - // Database connection - protected $link; - - // Data fetching types - protected $fetch_type = 'mysqli_fetch_object'; - protected $return_type = MYSQLI_ASSOC; - - /** - * Sets up the result variables. - * - * @param object database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($link, $object = TRUE, $sql) - { - $this->link = $link; - - if ( ! $this->link->multi_query($sql)) - { - // SQL error - throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); - } - else - { - $this->result = $this->link->store_result(); - - // If the query is an object, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_object($this->result)) - { - $this->current_row = 0; - $this->total_rows = $this->result->num_rows; - $this->fetch_type = ($object === TRUE) ? 'fetch_object' : 'fetch_array'; - } - elseif ($this->link->error) - { - // SQL error - throw new Kohana_Database_Exception('database.error', $this->link->error.' - '.$sql); - } - else - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - $this->insert_id = $this->link->insert_id; - $this->total_rows = $this->link->affected_rows; - } - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_object($this->result)) - { - $this->result->free_result(); - - // this is kinda useless, but needs to be done to avoid the "Commands out of sync; you - // can't run this command now" error. Basically, we get all results after the first one - // (the one we actually need) and free them. - if (is_resource($this->link) AND $this->link->more_results()) - { - do - { - if ($result = $this->link->store_result()) - { - $result->free_result(); - } - } while ($this->link->next_result()); - } - } - } - - public function result($object = TRUE, $type = MYSQLI_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'fetch_object' : 'fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = MYSQLI_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = MYSQLI_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if ($this->result->num_rows) - { - // Reset the pointer location to make sure things work properly - $this->result->data_seek(0); - - while ($row = $this->result->$fetch($type)) - { - $rows[] = $row; - } - } - - return isset($rows) ? $rows : array(); - } - - public function list_fields() - { - $field_names = array(); - while ($field = $this->result->fetch_field()) - { - $field_names[] = $field->name; - } - - return $field_names; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND $this->result->data_seek($offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - - return FALSE; - } - - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row - $fetch = $this->fetch_type; - return $this->result->$fetch($this->return_type); - } - -} // End Mysqli_Result Class - -/** - * MySQLi Prepared Statement (experimental) - */ -class Kohana_Mysqli_Statement { - - protected $link = NULL; - protected $stmt; - protected $var_names = array(); - protected $var_values = array(); - - public function __construct($sql, $link) - { - $this->link = $link; - - $this->stmt = $this->link->prepare($sql); - - return $this; - } - - public function __destruct() - { - $this->stmt->close(); - } - - // Sets the bind parameters - public function bind_params($param_types, $params) - { - $this->var_names = array_keys($params); - $this->var_values = array_values($params); - call_user_func_array(array($this->stmt, 'bind_param'), array_merge($param_types, $var_names)); - - return $this; - } - - public function bind_result($params) - { - call_user_func_array(array($this->stmt, 'bind_result'), $params); - } - - // Runs the statement - public function execute() - { - foreach ($this->var_names as $key => $name) - { - $$name = $this->var_values[$key]; - } - $this->stmt->execute(); - return $this->stmt; - } -} diff --git a/kohana/libraries/drivers/Database/Pdosqlite.php b/kohana/libraries/drivers/Database/Pdosqlite.php deleted file mode 100644 index c2d1bb21..00000000 --- a/kohana/libraries/drivers/Database/Pdosqlite.php +++ /dev/null @@ -1,486 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/* - * Class: Database_PdoSqlite_Driver - * Provides specific database items for Sqlite. - * - * Connection string should be, eg: "pdosqlite://path/to/database.db" - * - * Version 1.0 alpha - * author - Doutu, updated by gregmac - * copyright - (c) BSD - * license - <no> - */ - -class Database_Pdosqlite_Driver extends Database_Driver { - - // Database connection link - protected $link; - protected $db_config; - - /* - * Constructor: __construct - * Sets up the config for the class. - * - * Parameters: - * config - database configuration - * - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'PDO:Sqlite Database Driver Initialized'); - } - - public function connect() - { - // Import the connect variables - extract($this->db_config['connection']); - - try - { - $this->link = new PDO('sqlite:'.$socket.$database, $user, $pass, - array(PDO::ATTR_PERSISTENT => $this->db_config['persistent'])); - - $this->link->setAttribute(PDO::ATTR_CASE, PDO::CASE_NATURAL); - //$this->link->query('PRAGMA count_changes=1;'); - - if ($charset = $this->db_config['character_set']) - { - $this->set_charset($charset); - } - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - public function query($sql) - { - try - { - $sth = $this->link->prepare($sql); - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - return new Pdosqlite_Result($sth, $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->link->query('PRAGMA encoding = '.$this->escape_str($charset)); - } - - public function escape_table($table) - { - if ( ! $this->db_config['escape']) - return $table; - - return '`'.str_replace('.', '`.`', $table).'`'; - } - - public function escape_column($column) - { - if ( ! $this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:rand|all|distinct(?:row)?|high_priority|sql_(?:small_result|b(?:ig_result|uffer_result)|no_cache|ca(?:che|lc_found_rows)))\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '`$0`', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '`$0`', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$offset.', '.$limit; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - $sql .= "\nFROM "; - $sql .= implode(', ', $database['from']); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if ( ! $this->db_config['escape']) - return $str; - - if (function_exists('sqlite_escape_string')) - { - $res = sqlite_escape_string($str); - } - else - { - $res = str_replace("'", "''", $str); - } - return $res; - } - - public function list_tables() - { - $sql = "SELECT `name` FROM `sqlite_master` WHERE `type`='table' ORDER BY `name`;"; - try - { - $result = $this->query($sql)->result(FALSE, PDO::FETCH_ASSOC); - $tables = array(); - foreach ($result as $row) - { - $tables[] = current($row); - } - } - catch (PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - return $tables; - } - - public function show_error() - { - $err = $this->link->errorInfo(); - return isset($err[2]) ? $err[2] : 'Unknown error!'; - } - - public function list_fields($table, $query = FALSE) - { - static $tables; - if (is_object($query)) - { - if (empty($tables[$table])) - { - $tables[$table] = array(); - - foreach ($query->result() as $row) - { - $tables[$table][] = $row->name; - } - } - - return $tables[$table]; - } - else - { - $result = $this->link->query( 'PRAGMA table_info('.$this->escape_table($table).')' ); - - foreach ($result as $row) - { - $tables[$table][$row['name']] = $this->sql_type($row['type']); - } - - return $tables[$table]; - } - } - - public function field_data($table) - { - Kohana::log('error', 'This method is under developing'); - } - /** - * Version number query string - * - * @access public - * @return string - */ - function version() - { - return $this->link->getAttribute(constant("PDO::ATTR_SERVER_VERSION")); - } - -} // End Database_PdoSqlite_Driver Class - -/* - * PDO-sqlite Result - */ -class Pdosqlite_Result extends Database_Result { - - // Data fetching types - protected $fetch_type = PDO::FETCH_OBJ; - protected $return_type = PDO::FETCH_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - if (is_object($result) OR $result = $link->prepare($sql)) - { - // run the query. Return true if success, false otherwise - if( ! $result->execute()) - { - // Throw Kohana Exception with error message. See PDOStatement errorInfo() method - $arr_infos = $result->errorInfo(); - throw new Kohana_Database_Exception('database.error', $arr_infos[2]); - } - - if (preg_match('/^SELECT|PRAGMA|EXPLAIN/i', $sql)) - { - $this->result = $result; - $this->current_row = 0; - - $this->total_rows = $this->sqlite_row_count(); - - $this->fetch_type = ($object === TRUE) ? PDO::FETCH_OBJ : PDO::FETCH_ASSOC; - } - elseif (preg_match('/^DELETE|INSERT|UPDATE/i', $sql)) - { - $this->insert_id = $link->lastInsertId(); - - $this->total_rows = $result->rowCount(); - } - } - else - { - // SQL error - throw new Kohana_Database_Exception('database.error', $link->errorInfo().' - '.$sql); - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - private function sqlite_row_count() - { - $count = 0; - while ($this->result->fetch()) - { - $count++; - } - - // The query must be re-fetched now. - $this->result->execute(); - - return $count; - } - - /* - * Destructor: __destruct - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_object($this->result)) - { - $this->result->closeCursor(); - $this->result = NULL; - } - } - - public function result($object = TRUE, $type = PDO::FETCH_BOTH) - { - $this->fetch_type = (bool) $object ? PDO::FETCH_OBJ : PDO::FETCH_BOTH; - - if ($this->fetch_type == PDO::FETCH_OBJ) - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = PDO::FETCH_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = PDO::FETCH_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = PDO::FETCH_OBJ; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = PDO::FETCH_OBJ; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == PDO::FETCH_OBJ) - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - try - { - while ($row = $this->result->fetch($fetch)) - { - $rows[] = $row; - } - } - catch(PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - return FALSE; - } - return $rows; - } - - public function list_fields() - { - $field_names = array(); - for ($i = 0, $max = $this->result->columnCount(); $i < $max; $i++) - { - $info = $this->result->getColumnMeta($i); - $field_names[] = $info['name']; - } - return $field_names; - } - - public function seek($offset) - { - // To request a scrollable cursor for your PDOStatement object, you must - // set the PDO::ATTR_CURSOR attribute to PDO::CURSOR_SCROLL when you - // prepare the statement. - Kohana::log('error', get_class($this).' does not support scrollable cursors, '.__FUNCTION__.' call ignored'); - - return FALSE; - } - - public function offsetGet($offset) - { - try - { - return $this->result->fetch($this->fetch_type, PDO::FETCH_ORI_ABS, $offset); - } - catch(PDOException $e) - { - throw new Kohana_Database_Exception('database.error', $e->getMessage()); - } - } - - public function rewind() - { - // Same problem that seek() has, see above. - return $this->seek(0); - } - -} // End PdoSqlite_Result Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Database/Pgsql.php b/kohana/libraries/drivers/Database/Pgsql.php deleted file mode 100644 index c53c8439..00000000 --- a/kohana/libraries/drivers/Database/Pgsql.php +++ /dev/null @@ -1,538 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * PostgreSQL 8.1+ Database Driver - * - * $Id: Pgsql.php 4344 2009-05-11 16:41:39Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Database_Pgsql_Driver extends Database_Driver { - - // Database connection link - protected $link; - protected $db_config; - - /** - * Sets the config for the class. - * - * @param array database configuration - */ - public function __construct($config) - { - $this->db_config = $config; - - Kohana::log('debug', 'PgSQL Database Driver Initialized'); - } - - public function connect() - { - // Check if link already exists - if (is_resource($this->link)) - return $this->link; - - // Import the connect variables - extract($this->db_config['connection']); - - // Persistent connections enabled? - $connect = ($this->db_config['persistent'] == TRUE) ? 'pg_pconnect' : 'pg_connect'; - - // Build the connection info - $port = isset($port) ? 'port=\''.$port.'\'' : ''; - $host = isset($host) ? 'host=\''.$host.'\' '.$port : ''; // if no host, connect with the socket - - $connection_string = $host.' dbname=\''.$database.'\' user=\''.$user.'\' password=\''.$pass.'\''; - // Make the connection and select the database - if ($this->link = $connect($connection_string)) - { - if ($charset = $this->db_config['character_set']) - { - echo $this->set_charset($charset); - } - - // Clear password after successful connect - $this->db_config['connection']['pass'] = NULL; - - return $this->link; - } - - return FALSE; - } - - public function query($sql) - { - // Only cache if it's turned on, and only cache if it's not a write statement - if ($this->db_config['cache'] AND ! preg_match('#\b(?:INSERT|UPDATE|SET)\b#i', $sql)) - { - $hash = $this->query_hash($sql); - - if ( ! isset($this->query_cache[$hash])) - { - // Set the cached object - $this->query_cache[$hash] = new Pgsql_Result(pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); - } - else - { - // Rewind cached result - $this->query_cache[$hash]->rewind(); - } - - return $this->query_cache[$hash]; - } - - // Suppress warning triggered when a database error occurs (e.g., a constraint violation) - return new Pgsql_Result(@pg_query($this->link, $sql), $this->link, $this->db_config['object'], $sql); - } - - public function set_charset($charset) - { - $this->query('SET client_encoding TO '.pg_escape_string($this->link, $charset)); - } - - public function escape_table($table) - { - if (!$this->db_config['escape']) - return $table; - - return '"'.str_replace('.', '"."', $table).'"'; - } - - public function escape_column($column) - { - if (!$this->db_config['escape']) - return $column; - - if ($column == '*') - return $column; - - // This matches any functions we support to SELECT. - if ( preg_match('/(avg|count|sum|max|min)\(\s*(.*)\s*\)(\s*as\s*(.+)?)?/i', $column, $matches)) - { - if ( count($matches) == 3) - { - return $matches[1].'('.$this->escape_column($matches[2]).')'; - } - else if ( count($matches) == 5) - { - return $matches[1].'('.$this->escape_column($matches[2]).') AS '.$this->escape_column($matches[2]); - } - } - - // This matches any modifiers we support to SELECT. - if ( ! preg_match('/\b(?:all|distinct)\s/i', $column)) - { - if (stripos($column, ' AS ') !== FALSE) - { - // Force 'AS' to uppercase - $column = str_ireplace(' AS ', ' AS ', $column); - - // Runs escape_column on both sides of an AS statement - $column = array_map(array($this, __FUNCTION__), explode(' AS ', $column)); - - // Re-create the AS statement - return implode(' AS ', $column); - } - - return preg_replace('/[^.*]+/', '"$0"', $column); - } - - $parts = explode(' ', $column); - $column = ''; - - for ($i = 0, $c = count($parts); $i < $c; $i++) - { - // The column is always last - if ($i == ($c - 1)) - { - $column .= preg_replace('/[^.*]+/', '"$0"', $parts[$i]); - } - else // otherwise, it's a modifier - { - $column .= $parts[$i].' '; - } - } - return $column; - } - - public function regex($field, $match, $type, $num_regexs) - { - $prefix = ($num_regexs == 0) ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' ~* \''.$this->escape_str($match).'\''; - } - - public function notregex($field, $match, $type, $num_regexs) - { - $prefix = $num_regexs == 0 ? '' : $type; - - return $prefix.' '.$this->escape_column($field).' !~* \''.$this->escape_str($match) . '\''; - } - - public function limit($limit, $offset = 0) - { - return 'LIMIT '.$limit.' OFFSET '.$offset; - } - - public function compile_select($database) - { - $sql = ($database['distinct'] == TRUE) ? 'SELECT DISTINCT ' : 'SELECT '; - $sql .= (count($database['select']) > 0) ? implode(', ', $database['select']) : '*'; - - if (count($database['from']) > 0) - { - $sql .= "\nFROM "; - $sql .= implode(', ', $database['from']); - } - - if (count($database['join']) > 0) - { - foreach($database['join'] AS $join) - { - $sql .= "\n".$join['type'].'JOIN '.implode(', ', $join['tables']).' ON '.$join['conditions']; - } - } - - if (count($database['where']) > 0) - { - $sql .= "\nWHERE "; - } - - $sql .= implode("\n", $database['where']); - - if (count($database['groupby']) > 0) - { - $sql .= "\nGROUP BY "; - $sql .= implode(', ', $database['groupby']); - } - - if (count($database['having']) > 0) - { - $sql .= "\nHAVING "; - $sql .= implode("\n", $database['having']); - } - - if (count($database['orderby']) > 0) - { - $sql .= "\nORDER BY "; - $sql .= implode(', ', $database['orderby']); - } - - if (is_numeric($database['limit'])) - { - $sql .= "\n"; - $sql .= $this->limit($database['limit'], $database['offset']); - } - - return $sql; - } - - public function escape_str($str) - { - if (!$this->db_config['escape']) - return $str; - - is_resource($this->link) or $this->connect(); - - return pg_escape_string($this->link, $str); - } - - public function list_tables() - { - $sql = 'SELECT table_schema || \'.\' || table_name FROM information_schema.tables WHERE table_schema NOT IN (\'pg_catalog\', \'information_schema\')'; - $result = $this->query($sql)->result(FALSE, PGSQL_ASSOC); - - $retval = array(); - foreach ($result as $row) - { - $retval[] = current($row); - } - - return $retval; - } - - public function show_error() - { - return pg_last_error($this->link); - } - - public function list_fields($table) - { - $result = NULL; - - foreach ($this->field_data($table) as $row) - { - // Make an associative array - $result[$row->column_name] = $this->sql_type($row->data_type); - - if (!strncmp($row->column_default, 'nextval(', 8)) - { - $result[$row->column_name]['sequenced'] = TRUE; - } - - if ($row->is_nullable === 'YES') - { - $result[$row->column_name]['null'] = TRUE; - } - } - - if (!isset($result)) - throw new Kohana_Database_Exception('database.table_not_found', $table); - - return $result; - } - - public function field_data($table) - { - // http://www.postgresql.org/docs/8.3/static/infoschema-columns.html - $result = $this->query(' - SELECT column_name, column_default, is_nullable, data_type, udt_name, - character_maximum_length, numeric_precision, numeric_precision_radix, numeric_scale - FROM information_schema.columns - WHERE table_name = \''. $this->escape_str($table) .'\' - ORDER BY ordinal_position - '); - - return $result->result_array(TRUE); - } - -} // End Database_Pgsql_Driver Class - -/** - * PostgreSQL Result - */ -class Pgsql_Result extends Database_Result { - - // Data fetching types - protected $fetch_type = 'pgsql_fetch_object'; - protected $return_type = PGSQL_ASSOC; - - /** - * Sets up the result variables. - * - * @param resource query result - * @param resource database link - * @param boolean return objects or arrays - * @param string SQL query that was run - */ - public function __construct($result, $link, $object = TRUE, $sql) - { - $this->link = $link; - $this->result = $result; - - // If the query is a resource, it was a SELECT, SHOW, DESCRIBE, EXPLAIN query - if (is_resource($result)) - { - // Its an DELETE, INSERT, REPLACE, or UPDATE query - if (preg_match('/^(?:delete|insert|replace|update)\b/iD', trim($sql), $matches)) - { - $this->insert_id = (strtolower($matches[0]) == 'insert') ? $this->insert_id() : FALSE; - $this->total_rows = pg_affected_rows($this->result); - } - else - { - $this->current_row = 0; - $this->total_rows = pg_num_rows($this->result); - $this->fetch_type = ($object === TRUE) ? 'pg_fetch_object' : 'pg_fetch_array'; - } - } - else - { - throw new Kohana_Database_Exception('database.error', pg_last_error().' - '.$sql); - } - - // Set result type - $this->result($object); - - // Store the SQL - $this->sql = $sql; - } - - /** - * Magic __destruct function, frees the result. - */ - public function __destruct() - { - if (is_resource($this->result)) - { - pg_free_result($this->result); - } - } - - public function result($object = TRUE, $type = PGSQL_ASSOC) - { - $this->fetch_type = ((bool) $object) ? 'pg_fetch_object' : 'pg_fetch_array'; - - // This check has to be outside the previous statement, because we do not - // know the state of fetch_type when $object = NULL - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - if ($this->fetch_type == 'pg_fetch_object') - { - $this->return_type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $this->return_type = $type; - } - - return $this; - } - - public function as_array($object = NULL, $type = PGSQL_ASSOC) - { - return $this->result_array($object, $type); - } - - public function result_array($object = NULL, $type = PGSQL_ASSOC) - { - $rows = array(); - - if (is_string($object)) - { - $fetch = $object; - } - elseif (is_bool($object)) - { - if ($object === TRUE) - { - $fetch = 'pg_fetch_object'; - - // NOTE - The class set by $type must be defined before fetching the result, - // autoloading is disabled to save a lot of stupid overhead. - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - else - { - $fetch = 'pg_fetch_array'; - } - } - else - { - // Use the default config values - $fetch = $this->fetch_type; - - if ($fetch == 'pg_fetch_object') - { - $type = (is_string($type) AND Kohana::auto_load($type)) ? $type : 'stdClass'; - } - } - - if ($this->total_rows) - { - pg_result_seek($this->result, 0); - - while ($row = $fetch($this->result, NULL, $type)) - { - $rows[] = $row; - } - } - - return $rows; - } - - public function insert_id() - { - if ($this->insert_id === NULL) - { - $query = 'SELECT LASTVAL() AS insert_id'; - - // Disable error reporting for this, just to silence errors on - // tables that have no serial column. - $ER = error_reporting(0); - - $result = pg_query($this->link, $query); - $insert_id = pg_fetch_array($result, NULL, PGSQL_ASSOC); - - $this->insert_id = $insert_id['insert_id']; - - // Reset error reporting - error_reporting($ER); - } - - return $this->insert_id; - } - - public function seek($offset) - { - if ($this->offsetExists($offset) AND pg_result_seek($this->result, $offset)) - { - // Set the current row to the offset - $this->current_row = $offset; - - return TRUE; - } - - return FALSE; - } - - public function list_fields() - { - $field_names = array(); - - $fields = pg_num_fields($this->result); - for ($i = 0; $i < $fields; ++$i) - { - $field_names[] = pg_field_name($this->result, $i); - } - - return $field_names; - } - - /** - * ArrayAccess: offsetGet - */ - public function offsetGet($offset) - { - if ( ! $this->seek($offset)) - return FALSE; - - // Return the row by calling the defined fetching callback - $fetch = $this->fetch_type; - return $fetch($this->result, NULL, $this->return_type); - } - -} // End Pgsql_Result Class - -/** - * PostgreSQL Prepared Statement (experimental) - */ -class Kohana_Pgsql_Statement { - - protected $link = NULL; - protected $stmt; - - public function __construct($sql, $link) - { - $this->link = $link; - - $this->stmt = $this->link->prepare($sql); - - return $this; - } - - public function __destruct() - { - $this->stmt->close(); - } - - // Sets the bind parameters - public function bind_params() - { - $argv = func_get_args(); - return $this; - } - - // sets the statement values to the bound parameters - public function set_vals() - { - return $this; - } - - // Runs the statement - public function execute() - { - return $this; - } -} diff --git a/kohana/libraries/drivers/Image.php b/kohana/libraries/drivers/Image.php deleted file mode 100644 index f89ba953..00000000 --- a/kohana/libraries/drivers/Image.php +++ /dev/null @@ -1,156 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Image API driver. - * - * $Id: Image.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -abstract class Image_Driver { - - // Reference to the current image - protected $image; - - // Reference to the temporary processing image - protected $tmp_image; - - // Processing errors - protected $errors = array(); - - /** - * Executes a set of actions, defined in pairs. - * - * @param array actions - * @return boolean - */ - public function execute($actions) - { - foreach ($actions as $func => $args) - { - if ( ! $this->$func($args)) - return FALSE; - } - - return TRUE; - } - - /** - * Sanitize and normalize a geometry array based on the temporary image - * width and height. Valid properties are: width, height, top, left. - * - * @param array geometry properties - * @return void - */ - protected function sanitize_geometry( & $geometry) - { - list($width, $height) = $this->properties(); - - // Turn off error reporting - $reporting = error_reporting(0); - - // Width and height cannot exceed current image size - $geometry['width'] = min($geometry['width'], $width); - $geometry['height'] = min($geometry['height'], $height); - - // Set standard coordinates if given, otherwise use pixel values - if ($geometry['top'] === 'center') - { - $geometry['top'] = floor(($height / 2) - ($geometry['height'] / 2)); - } - elseif ($geometry['top'] === 'top') - { - $geometry['top'] = 0; - } - elseif ($geometry['top'] === 'bottom') - { - $geometry['top'] = $height - $geometry['height']; - } - - // Set standard coordinates if given, otherwise use pixel values - if ($geometry['left'] === 'center') - { - $geometry['left'] = floor(($width / 2) - ($geometry['width'] / 2)); - } - elseif ($geometry['left'] === 'left') - { - $geometry['left'] = 0; - } - elseif ($geometry['left'] === 'right') - { - $geometry['left'] = $width - $geometry['height']; - } - - // Restore error reporting - error_reporting($reporting); - } - - /** - * Return the current width and height of the temporary image. This is mainly - * needed for sanitizing the geometry. - * - * @return array width, height - */ - abstract protected function properties(); - - /** - * Process an image with a set of actions. - * - * @param string image filename - * @param array actions to execute - * @param string destination directory path - * @param string destination filename - * @return boolean - */ - abstract public function process($image, $actions, $dir, $file); - - /** - * Flip an image. Valid directions are horizontal and vertical. - * - * @param integer direction to flip - * @return boolean - */ - abstract function flip($direction); - - /** - * Crop an image. Valid properties are: width, height, top, left. - * - * @param array new properties - * @return boolean - */ - abstract function crop($properties); - - /** - * Resize an image. Valid properties are: width, height, and master. - * - * @param array new properties - * @return boolean - */ - abstract public function resize($properties); - - /** - * Rotate an image. Valid amounts are -180 to 180. - * - * @param integer amount to rotate - * @return boolean - */ - abstract public function rotate($amount); - - /** - * Sharpen and image. Valid amounts are 1 to 100. - * - * @param integer amount to sharpen - * @return boolean - */ - abstract public function sharpen($amount); - - /** - * Overlay a second image. Valid properties are: overlay_file, mime, x, y and transparency. - * - * @return boolean - */ - abstract public function composite($properties); - -} // End Image Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/GD.php b/kohana/libraries/drivers/Image/GD.php deleted file mode 100644 index be2af4e2..00000000 --- a/kohana/libraries/drivers/Image/GD.php +++ /dev/null @@ -1,401 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * GD Image Driver. - * - * $Id: GD.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_GD_Driver extends Image_Driver { - - // A transparent PNG as a string - protected static $blank_png; - protected static $blank_png_width; - protected static $blank_png_height; - - public function __construct() - { - // Make sure that GD2 is available - if ( ! function_exists('gd_info')) - throw new Kohana_Exception('image.gd.requires_v2'); - - // Get the GD information - $info = gd_info(); - - // Make sure that the GD2 is installed - if (strpos($info['GD Version'], '2.') === FALSE) - throw new Kohana_Exception('image.gd.requires_v2'); - } - - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // Set the "create" function - switch ($image['type']) - { - case IMAGETYPE_JPEG: - $create = 'imagecreatefromjpeg'; - break; - case IMAGETYPE_GIF: - $create = 'imagecreatefromgif'; - break; - case IMAGETYPE_PNG: - $create = 'imagecreatefrompng'; - break; - } - - // Set the "save" function - switch (strtolower(substr(strrchr($file, '.'), 1))) - { - case 'jpg': - case 'jpeg': - $save = 'imagejpeg'; - break; - case 'gif': - $save = 'imagegif'; - break; - case 'png': - $save = 'imagepng'; - break; - } - - // Make sure the image type is supported for import - if (empty($create) OR ! function_exists($create)) - throw new Kohana_Exception('image.type_not_allowed', $image['file']); - - // Make sure the image type is supported for saving - if (empty($save) OR ! function_exists($save)) - throw new Kohana_Exception('image.type_not_allowed', $dir.$file); - - // Load the image - $this->image = $image; - - // Create the GD image resource - $this->tmp_image = $create($image['file']); - - // Get the quality setting from the actions - $quality = arr::remove('quality', $actions); - - if ($status = $this->execute($actions)) - { - // Prevent the alpha from being lost - imagealphablending($this->tmp_image, TRUE); - imagesavealpha($this->tmp_image, TRUE); - - switch ($save) - { - case 'imagejpeg': - // Default the quality to 95 - ($quality === NULL) and $quality = 95; - break; - case 'imagegif': - // Remove the quality setting, GIF doesn't use it - unset($quality); - break; - case 'imagepng': - // Always use a compression level of 9 for PNGs. This does not - // affect quality, it only increases the level of compression! - $quality = 9; - break; - } - - if ($render === FALSE) - { - // Set the status to the save return value, saving with the quality requested - $status = isset($quality) ? $save($this->tmp_image, $dir.$file, $quality) : $save($this->tmp_image, $dir.$file); - } - else - { - // Output the image directly to the browser - switch ($save) - { - case 'imagejpeg': - header('Content-Type: image/jpeg'); - break; - case 'imagegif': - header('Content-Type: image/gif'); - break; - case 'imagepng': - header('Content-Type: image/png'); - break; - } - - $status = isset($quality) ? $save($this->tmp_image, NULL, $quality) : $save($this->tmp_image); - } - - // Destroy the temporary image - imagedestroy($this->tmp_image); - } - - return $status; - } - - public function flip($direction) - { - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - // Create the flipped image - $flipped = $this->imagecreatetransparent($width, $height); - - if ($direction === Image::HORIZONTAL) - { - for ($x = 0; $x < $width; $x++) - { - $status = imagecopy($flipped, $this->tmp_image, $x, 0, $width - $x - 1, 0, 1, $height); - } - } - elseif ($direction === Image::VERTICAL) - { - for ($y = 0; $y < $height; $y++) - { - $status = imagecopy($flipped, $this->tmp_image, 0, $y, 0, $height - $y - 1, $width, 1); - } - } - else - { - // Do nothing - return TRUE; - } - - if ($status === TRUE) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $flipped; - } - - return $status; - } - - public function crop($properties) - { - // Sanitize the cropping settings - $this->sanitize_geometry($properties); - - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($properties['width'], $properties['height']); - - // Execute the crop - if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, $properties['left'], $properties['top'], $width, $height, $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function resize($properties) - { - // Get the current width and height - $width = imagesx($this->tmp_image); - $height = imagesy($this->tmp_image); - - if (substr($properties['width'], -1) === '%') - { - // Recalculate the percentage to a pixel size - $properties['width'] = round($width * (substr($properties['width'], 0, -1) / 100)); - } - - if (substr($properties['height'], -1) === '%') - { - // Recalculate the percentage to a pixel size - $properties['height'] = round($height * (substr($properties['height'], 0, -1) / 100)); - } - - // Recalculate the width and height, if they are missing - empty($properties['width']) and $properties['width'] = round($width * $properties['height'] / $height); - empty($properties['height']) and $properties['height'] = round($height * $properties['width'] / $width); - - if ($properties['master'] === Image::AUTO) - { - // Change an automatic master dim to the correct type - $properties['master'] = (($width / $properties['width']) > ($height / $properties['height'])) ? Image::WIDTH : Image::HEIGHT; - } - - if (empty($properties['height']) OR $properties['master'] === Image::WIDTH) - { - // Recalculate the height based on the width - $properties['height'] = round($height * $properties['width'] / $width); - } - - if (empty($properties['width']) OR $properties['master'] === Image::HEIGHT) - { - // Recalculate the width based on the height - $properties['width'] = round($width * $properties['height'] / $height); - } - - // Test if we can do a resize without resampling to speed up the final resize - if ($properties['width'] > $width / 2 AND $properties['height'] > $height / 2) - { - // Presize width and height - $pre_width = $width; - $pre_height = $height; - - // The maximum reduction is 10% greater than the final size - $max_reduction_width = round($properties['width'] * 1.1); - $max_reduction_height = round($properties['height'] * 1.1); - - // Reduce the size using an O(2n) algorithm, until it reaches the maximum reduction - while ($pre_width / 2 > $max_reduction_width AND $pre_height / 2 > $max_reduction_height) - { - $pre_width /= 2; - $pre_height /= 2; - } - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($pre_width, $pre_height); - - if ($status = imagecopyresized($img, $this->tmp_image, 0, 0, 0, 0, $pre_width, $pre_height, $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - // Set the width and height to the presize - $width = $pre_width; - $height = $pre_height; - } - - // Create the temporary image to copy to - $img = $this->imagecreatetransparent($properties['width'], $properties['height']); - - // Execute the resize - if ($status = imagecopyresampled($img, $this->tmp_image, 0, 0, 0, 0, $properties['width'], $properties['height'], $width, $height)) - { - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function rotate($amount) - { - // Use current image to rotate - $img = $this->tmp_image; - - // White, with an alpha of 0 - $transparent = imagecolorallocatealpha($img, 255, 255, 255, 127); - - // Rotate, setting the transparent color - $img = imagerotate($img, 360 - $amount, $transparent, -1); - - // Fill the background with the transparent "color" - imagecolortransparent($img, $transparent); - - // Merge the images - if ($status = imagecopymerge($this->tmp_image, $img, 0, 0, 0, 0, imagesx($this->tmp_image), imagesy($this->tmp_image), 100)) - { - // Prevent the alpha from being lost - imagealphablending($img, TRUE); - imagesavealpha($img, TRUE); - - // Swap the new image for the old one - imagedestroy($this->tmp_image); - $this->tmp_image = $img; - } - - return $status; - } - - public function sharpen($amount) - { - // Make sure that the sharpening function is available - if ( ! function_exists('imageconvolution')) - throw new Kohana_Exception('image.unsupported_method', __FUNCTION__); - - // Amount should be in the range of 18-10 - $amount = round(abs(-18 + ($amount * 0.08)), 2); - - // Gaussian blur matrix - $matrix = array - ( - array(-1, -1, -1), - array(-1, $amount, -1), - array(-1, -1, -1), - ); - - // Perform the sharpen - return imageconvolution($this->tmp_image, $matrix, $amount - 8, 0); - } - - public function composite($properties) - { - switch($properties['mime']) - { - case "image/jpeg": - $overlay_img = imagecreatefromjpeg($properties['overlay_file']); - break; - - case "image/gif": - $overlay_img = imagecreatefromgif($properties['overlay_file']); - break; - - case "image/png": - $overlay_img = imagecreatefrompng($properties['overlay_file']); - break; - } - - imagecopymerge($this->tmp_image, $overlay_img, $properties['x'], $properties['y'], 0, 0, imagesx($overlay_img), imagesy($overlay_img), $properties['transparency']); - imagedestroy($overlay_img); - return TRUE; - } - - protected function properties() - { - return array(imagesx($this->tmp_image), imagesy($this->tmp_image)); - } - - /** - * Returns an image with a transparent background. Used for rotating to - * prevent unfilled backgrounds. - * - * @param integer image width - * @param integer image height - * @return resource - */ - protected function imagecreatetransparent($width, $height) - { - if (self::$blank_png === NULL) - { - // Decode the blank PNG if it has not been done already - self::$blank_png = imagecreatefromstring(base64_decode - ( - 'iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29'. - 'mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAADqSURBVHjaYvz//z/DYAYAAcTEMMgBQAANegcCBN'. - 'CgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQ'. - 'AANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoH'. - 'AgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAAA16BwIE0KB'. - '3IEAADXoHAgTQoHcgQAANegcCBNCgdyBAgAEAMpcDTTQWJVEAAAAASUVORK5CYII=' - )); - - // Set the blank PNG width and height - self::$blank_png_width = imagesx(self::$blank_png); - self::$blank_png_height = imagesy(self::$blank_png); - } - - $img = imagecreatetruecolor($width, $height); - - // Resize the blank image - imagecopyresized($img, self::$blank_png, 0, 0, 0, 0, $width, $height, self::$blank_png_width, self::$blank_png_height); - - // Prevent the alpha from being lost - imagealphablending($img, FALSE); - imagesavealpha($img, TRUE); - - return $img; - } - -} // End Image GD Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/GraphicsMagick.php b/kohana/libraries/drivers/Image/GraphicsMagick.php deleted file mode 100644 index a8bc4d9b..00000000 --- a/kohana/libraries/drivers/Image/GraphicsMagick.php +++ /dev/null @@ -1,221 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * GraphicsMagick Image Driver. - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_GraphicsMagick_Driver extends Image_Driver { - - // Directory that GM is installed in - protected $dir = ''; - - // Command extension (exe for windows) - protected $ext = ''; - - // Temporary image filename - protected $tmp_image; - - /** - * Attempts to detect the GraphicsMagick installation directory. - * - * @throws Kohana_Exception - * @param array configuration - * @return void - */ - public function __construct($config) - { - if (empty($config['directory'])) - { - // Attempt to locate GM by using "which" (only works for *nix!) - if ( ! is_file($path = exec('which gm'))) - throw new Kohana_Exception('image.graphicsmagick.not_found'); - - $config['directory'] = dirname($path); - } - - // Set the command extension - $this->ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; - - // Check to make sure the provided path is correct - if ( ! is_file(realpath($config['directory']).'/gm'.$this->ext)) - throw new Kohana_Exception('image.graphicsmagick.not_found', 'gm'.$this->ext); - - - // Set the installation directory - $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; - } - - /** - * Creates a temporary image and executes the given actions. By creating a - * temporary copy of the image before manipulating it, this process is atomic. - */ - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // We only need the filename - $image = $image['file']; - - // Unique temporary filename - $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); - - // Copy the image to the temporary file - copy($image, $this->tmp_image); - - // Quality change is done last - $quality = (int) arr::remove('quality', $actions); - - // Use 95 for the default quality - empty($quality) and $quality = 95; - - // All calls to these will need to be escaped, so do it now - $this->cmd_image = escapeshellarg($this->tmp_image); - $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); - - if ($status = $this->execute($actions)) - { - // Use convert to change the image into its final version. This is - // done to allow the file type to change correctly, and to handle - // the quality conversion in the most effective way possible. - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) - { - $this->errors[] = $error; - } - else - { - // Output the image directly to the browser - if ($render !== FALSE) - { - $contents = file_get_contents($this->tmp_image); - switch (substr($file, strrpos($file, '.') + 1)) - { - case 'jpg': - case 'jpeg': - header('Content-Type: image/jpeg'); - break; - case 'gif': - header('Content-Type: image/gif'); - break; - case 'png': - header('Content-Type: image/png'); - break; - } - echo $contents; - } - } - } - - // Remove the temporary image - unlink($this->tmp_image); - $this->tmp_image = ''; - - return $status; - } - - public function crop($prop) - { - // Sanitize and normalize the properties into geometry - $this->sanitize_geometry($prop); - - // Set the IM geometry based on the properties - $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function flip($dir) - { - // Convert the direction into a GM command - $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function resize($prop) - { - switch ($prop['master']) - { - case Image::WIDTH: // Wx - $dim = escapeshellarg($prop['width'].'x'); - break; - case Image::HEIGHT: // xH - $dim = escapeshellarg('x'.$prop['height']); - break; - case Image::AUTO: // WxH - $dim = escapeshellarg($prop['width'].'x'.$prop['height']); - break; - case Image::NONE: // WxH! - $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); - break; - } - - // Use "convert" to change the width and height - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function rotate($amt) - { - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function sharpen($amount) - { - // Set the sigma, radius, and amount. The amount formula allows a nice - // spread between 1 and 100 without pixelizing the image badly. - $sigma = 0.5; - $radius = $sigma * 2; - $amount = round(($amount / 80) * 3.14, 2); - - // Convert the amount to an GM command - $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); - - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' convert').' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function composite($properties) - { - if ($error = exec(escapeshellcmd($this->dir.'gm'.$this->ext.' composite').' -geometry ' . escapeshellarg('+'.$properties['x'].'+'.$properties['y']).' -dissolve '.escapeshellarg($properties['transparency']).' '.escapeshellarg($properties['overlay_file']).' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - return TRUE; - } - - protected function properties() - { - return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); - } - -} // End Image GraphicsMagick Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Image/ImageMagick.php b/kohana/libraries/drivers/Image/ImageMagick.php deleted file mode 100644 index 4b381fd6..00000000 --- a/kohana/libraries/drivers/Image/ImageMagick.php +++ /dev/null @@ -1,222 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * ImageMagick Image Driver. - * - * $Id: ImageMagick.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Image - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Image_ImageMagick_Driver extends Image_Driver { - - // Directory that IM is installed in - protected $dir = ''; - - // Command extension (exe for windows) - protected $ext = ''; - - // Temporary image filename - protected $tmp_image; - - /** - * Attempts to detect the ImageMagick installation directory. - * - * @throws Kohana_Exception - * @param array configuration - * @return void - */ - public function __construct($config) - { - if (empty($config['directory'])) - { - // Attempt to locate IM by using "which" (only works for *nix!) - if ( ! is_file($path = exec('which convert'))) - throw new Kohana_Exception('image.imagemagick.not_found'); - - $config['directory'] = dirname($path); - } - - // Set the command extension - $this->ext = (PHP_SHLIB_SUFFIX === 'dll') ? '.exe' : ''; - - // Check to make sure the provided path is correct - if ( ! is_file(realpath($config['directory']).'/convert'.$this->ext)) - throw new Kohana_Exception('image.imagemagick.not_found', 'convert'.$this->ext); - - // Set the installation directory - $this->dir = str_replace('\\', '/', realpath($config['directory'])).'/'; - } - - /** - * Creates a temporary image and executes the given actions. By creating a - * temporary copy of the image before manipulating it, this process is atomic. - */ - public function process($image, $actions, $dir, $file, $render = FALSE) - { - // We only need the filename - $image = $image['file']; - - // Unique temporary filename - $this->tmp_image = $dir.'k2img--'.sha1(time().$dir.$file).substr($file, strrpos($file, '.')); - - // Copy the image to the temporary file - copy($image, $this->tmp_image); - - // Quality change is done last - $quality = (int) arr::remove('quality', $actions); - - // Use 95 for the default quality - empty($quality) and $quality = 95; - - // All calls to these will need to be escaped, so do it now - $this->cmd_image = escapeshellarg($this->tmp_image); - $this->new_image = ($render)? $this->cmd_image : escapeshellarg($dir.$file); - - if ($status = $this->execute($actions)) - { - // Use convert to change the image into its final version. This is - // done to allow the file type to change correctly, and to handle - // the quality conversion in the most effective way possible. - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -quality '.$quality.'% '.$this->cmd_image.' '.$this->new_image)) - { - $this->errors[] = $error; - } - else - { - // Output the image directly to the browser - if ($render !== FALSE) - { - $contents = file_get_contents($this->tmp_image); - switch (substr($file, strrpos($file, '.') + 1)) - { - case 'jpg': - case 'jpeg': - header('Content-Type: image/jpeg'); - break; - case 'gif': - header('Content-Type: image/gif'); - break; - case 'png': - header('Content-Type: image/png'); - break; - } - echo $contents; - } - } - } - - // Remove the temporary image - unlink($this->tmp_image); - $this->tmp_image = ''; - - return $status; - } - - public function crop($prop) - { - // Sanitize and normalize the properties into geometry - $this->sanitize_geometry($prop); - - // Set the IM geometry based on the properties - $geometry = escapeshellarg($prop['width'].'x'.$prop['height'].'+'.$prop['left'].'+'.$prop['top']); - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -crop '.$geometry.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function flip($dir) - { - // Convert the direction into a IM command - $dir = ($dir === Image::HORIZONTAL) ? '-flop' : '-flip'; - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' '.$dir.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function resize($prop) - { - switch ($prop['master']) - { - case Image::WIDTH: // Wx - $dim = escapeshellarg($prop['width'].'x'); - break; - case Image::HEIGHT: // xH - $dim = escapeshellarg('x'.$prop['height']); - break; - case Image::AUTO: // WxH - $dim = escapeshellarg($prop['width'].'x'.$prop['height']); - break; - case Image::NONE: // WxH! - $dim = escapeshellarg($prop['width'].'x'.$prop['height'].'!'); - break; - } - - // Use "convert" to change the width and height - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -resize '.$dim.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function rotate($amt) - { - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -rotate '.escapeshellarg($amt).' -background transparent '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function sharpen($amount) - { - // Set the sigma, radius, and amount. The amount formula allows a nice - // spread between 1 and 100 without pixelizing the image badly. - $sigma = 0.5; - $radius = $sigma * 2; - $amount = round(($amount / 80) * 3.14, 2); - - // Convert the amount to an IM command - $sharpen = escapeshellarg($radius.'x'.$sigma.'+'.$amount.'+0'); - - if ($error = exec(escapeshellcmd($this->dir.'convert'.$this->ext).' -unsharp '.$sharpen.' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - - return TRUE; - } - - public function composite($properties) - { - if ($error = exec(escapeshellcmd($this->dir.'composite'.$this->ext).' -geometry ' . escapeshellarg('+'.$properties['x'].'+'.$properties['y']).' -dissolve '.escapeshellarg($properties['transparency']).' '.escapeshellarg($properties['overlay_file']).' '.$this->cmd_image.' '.$this->cmd_image)) - { - $this->errors[] = $error; - return FALSE; - } - return TRUE; - } - - protected function properties() - { - return array_slice(getimagesize($this->tmp_image), 0, 2, FALSE); - } - -} // End Image ImageMagick Driver
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session.php b/kohana/libraries/drivers/Session.php deleted file mode 100644 index fb58c8d3..00000000 --- a/kohana/libraries/drivers/Session.php +++ /dev/null @@ -1,70 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session driver interface - * - * $Id: Session.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -interface Session_Driver { - - /** - * Opens a session. - * - * @param string save path - * @param string session name - * @return boolean - */ - public function open($path, $name); - - /** - * Closes a session. - * - * @return boolean - */ - public function close(); - - /** - * Reads a session. - * - * @param string session id - * @return string - */ - public function read($id); - - /** - * Writes a session. - * - * @param string session id - * @param string session data - * @return boolean - */ - public function write($id, $data); - - /** - * Destroys a session. - * - * @param string session id - * @return boolean - */ - public function destroy($id); - - /** - * Regenerates the session id. - * - * @return string - */ - public function regenerate(); - - /** - * Garbage collection. - * - * @param integer session expiration period - * @return boolean - */ - public function gc($maxlifetime); - -} // End Session Driver Interface
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session/Cache.php b/kohana/libraries/drivers/Session/Cache.php deleted file mode 100644 index 7221c9f2..00000000 --- a/kohana/libraries/drivers/Session/Cache.php +++ /dev/null @@ -1,105 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session cache driver. - * - * Cache library config goes in the session.storage config entry: - * $config['storage'] = array( - * 'driver' => 'apc', - * 'requests' => 10000 - * ); - * Lifetime does not need to be set as it is - * overridden by the session expiration setting. - * - * $Id: Cache.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Cache_Driver implements Session_Driver { - - protected $cache; - protected $encrypt; - - public function __construct() - { - // Load Encrypt library - if (Kohana::config('session.encryption')) - { - $this->encrypt = new Encrypt; - } - - Kohana::log('debug', 'Session Cache Driver Initialized'); - } - - public function open($path, $name) - { - $config = Kohana::config('session.storage'); - - if (empty($config)) - { - // Load the default group - $config = Kohana::config('cache.default'); - } - elseif (is_string($config)) - { - $name = $config; - - // Test the config group name - if (($config = Kohana::config('cache.'.$config)) === NULL) - throw new Kohana_Exception('cache.undefined_group', $name); - } - - $config['lifetime'] = (Kohana::config('session.expiration') == 0) ? 86400 : Kohana::config('session.expiration'); - $this->cache = new Cache($config); - - return is_object($this->cache); - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - $id = 'session_'.$id; - if ($data = $this->cache->get($id)) - { - return Kohana::config('session.encryption') ? $this->encrypt->decode($data) : $data; - } - - // Return value must be string, NOT a boolean - return ''; - } - - public function write($id, $data) - { - $id = 'session_'.$id; - $data = Kohana::config('session.encryption') ? $this->encrypt->encode($data) : $data; - - return $this->cache->set($id, $data); - } - - public function destroy($id) - { - $id = 'session_'.$id; - return $this->cache->delete($id); - } - - public function regenerate() - { - session_regenerate_id(TRUE); - - // Return new session id - return session_id(); - } - - public function gc($maxlifetime) - { - // Just return, caches are automatically cleaned up - return TRUE; - } - -} // End Session Cache Driver diff --git a/kohana/libraries/drivers/Session/Cookie.php b/kohana/libraries/drivers/Session/Cookie.php deleted file mode 100644 index 7b791064..00000000 --- a/kohana/libraries/drivers/Session/Cookie.php +++ /dev/null @@ -1,80 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session cookie driver. - * - * $Id: Cookie.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Cookie_Driver implements Session_Driver { - - protected $cookie_name; - protected $encrypt; // Library - - public function __construct() - { - $this->cookie_name = Kohana::config('session.name').'_data'; - - if (Kohana::config('session.encryption')) - { - $this->encrypt = Encrypt::instance(); - } - - Kohana::log('debug', 'Session Cookie Driver Initialized'); - } - - public function open($path, $name) - { - return TRUE; - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - $data = (string) cookie::get($this->cookie_name); - - if ($data == '') - return $data; - - return empty($this->encrypt) ? base64_decode($data) : $this->encrypt->decode($data); - } - - public function write($id, $data) - { - $data = empty($this->encrypt) ? base64_encode($data) : $this->encrypt->encode($data); - - if (strlen($data) > 4048) - { - Kohana::log('error', 'Session ('.$id.') data exceeds the 4KB limit, ignoring write.'); - return FALSE; - } - - return cookie::set($this->cookie_name, $data, Kohana::config('session.expiration')); - } - - public function destroy($id) - { - return cookie::delete($this->cookie_name); - } - - public function regenerate() - { - session_regenerate_id(TRUE); - - // Return new id - return session_id(); - } - - public function gc($maxlifetime) - { - return TRUE; - } - -} // End Session Cookie Driver Class
\ No newline at end of file diff --git a/kohana/libraries/drivers/Session/Database.php b/kohana/libraries/drivers/Session/Database.php deleted file mode 100644 index b4144ffb..00000000 --- a/kohana/libraries/drivers/Session/Database.php +++ /dev/null @@ -1,163 +0,0 @@ -<?php defined('SYSPATH') OR die('No direct access allowed.'); -/** - * Session database driver. - * - * $Id: Database.php 3769 2008-12-15 00:48:56Z zombor $ - * - * @package Core - * @author Kohana Team - * @copyright (c) 2007-2008 Kohana Team - * @license http://kohanaphp.com/license.html - */ -class Session_Database_Driver implements Session_Driver { - - /* - CREATE TABLE sessions - ( - session_id VARCHAR(127) NOT NULL, - last_activity INT(10) UNSIGNED NOT NULL, - data TEXT NOT NULL, - PRIMARY KEY (session_id) - ); - */ - - // Database settings - protected $db = 'default'; - protected $table = 'sessions'; - - // Encryption - protected $encrypt; - - // Session settings - protected $session_id; - protected $written = FALSE; - - public function __construct() - { - // Load configuration - $config = Kohana::config('session'); - - if ( ! empty($config['encryption'])) - { - // Load encryption - $this->encrypt = Encrypt::instance(); - } - - if (is_array($config['storage'])) - { - if ( ! empty($config['storage']['group'])) - { - // Set the group name - $this->db = $config['storage']['group']; - } - - if ( ! empty($config['storage']['table'])) - { - // Set the table name - $this->table = $config['storage']['table']; - } - } - - // Load database - $this->db = Database::instance($this->db); - - Kohana::log('debug', 'Session Database Driver Initialized'); - } - - public function open($path, $name) - { - return TRUE; - } - - public function close() - { - return TRUE; - } - - public function read($id) - { - // Load the session - $query = $this->db->from($this->table)->where('session_id', $id)->limit(1)->get()->result(TRUE); - - if ($query->count() === 0) - { - // No current session - $this->session_id = NULL; - - return ''; - } - - // Set the current session id - $this->session_id = $id; - - // Load the data - $data = $query->current()->data; - - return ($this->encrypt === NULL) ? base64_decode($data) : $this->encrypt->decode($data); - } - - public function write($id, $data) - { - $data = array - ( - 'session_id' => $id, - 'last_activity' => time(), - 'data' => ($this->encrypt === NULL) ? base64_encode($data) : $this->encrypt->encode($data) - ); - - if ($this->session_id === NULL) - { - // Insert a new session - $query = $this->db->insert($this->table, $data); - } - elseif ($id === $this->session_id) - { - // Do not update the session_id - unset($data['session_id']); - - // Update the existing session - $query = $this->db->update($this->table, $data, array('session_id' => $id)); - } - else - { - // Update the session and id - $query = $this->db->update($this->table, $data, array('session_id' => $this->session_id)); - - // Set the new session id - $this->session_id = $id; - } - - return (bool) $query->count(); - } - - public function destroy($id) - { - // Delete the requested session - $this->db->delete($this->table, array('session_id' => $id)); - - // Session id is no longer valid - $this->session_id = NULL; - - return TRUE; - } - - public function regenerate() - { - // Generate a new session id - session_regenerate_id(); - - // Return new session id - return session_id(); - } - - public function gc($maxlifetime) - { - // Delete all expired sessions - $query = $this->db->delete($this->table, array('last_activity <' => time() - $maxlifetime)); - - Kohana::log('debug', 'Session garbage collected: '.$query->count().' row(s) deleted.'); - - return TRUE; - } - -} // End Session Database Driver |