Updated to KH 3.3 and improved
This commit is contained in:
3
includes/kohana/modules/auth/classes/Auth.php
Normal file
3
includes/kohana/modules/auth/classes/Auth.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
abstract class Auth extends Kohana_Auth { }
|
3
includes/kohana/modules/auth/classes/Auth/File.php
Normal file
3
includes/kohana/modules/auth/classes/Auth/File.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
class Auth_File extends Kohana_Auth_File { }
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* User authorization library. Handles user login and logout, as well as secure
|
||||
* password hashing.
|
||||
*
|
||||
* @package Kohana/Auth
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
abstract class Kohana_Auth {
|
||||
@@ -23,7 +23,7 @@ abstract class Kohana_Auth {
|
||||
if ( ! isset(Auth::$_instance))
|
||||
{
|
||||
// Load the configuration for this type
|
||||
$config = Kohana::config('auth');
|
||||
$config = Kohana::$config->load('auth');
|
||||
|
||||
if ( ! $type = $config->get('driver'))
|
||||
{
|
||||
@@ -47,6 +47,7 @@ abstract class Kohana_Auth {
|
||||
/**
|
||||
* Loads Session and configuration options.
|
||||
*
|
||||
* @param array $config Config Options
|
||||
* @return void
|
||||
*/
|
||||
public function __construct($config = array())
|
||||
@@ -54,7 +55,7 @@ abstract class Kohana_Auth {
|
||||
// Save the config in the object
|
||||
$this->_config = $config;
|
||||
|
||||
$this->_session = Session::instance();
|
||||
$this->_session = Session::instance($this->_config['session_type']);
|
||||
}
|
||||
|
||||
abstract protected function _login($username, $password, $remember);
|
||||
@@ -67,6 +68,7 @@ abstract class Kohana_Auth {
|
||||
* Gets the currently logged in user from the session.
|
||||
* Returns NULL if no user is currently logged in.
|
||||
*
|
||||
* @param mixed $default Default value to return if the user is currently not logged in.
|
||||
* @return mixed
|
||||
*/
|
||||
public function get_user($default = NULL)
|
||||
@@ -77,9 +79,9 @@ abstract class Kohana_Auth {
|
||||
/**
|
||||
* Attempt to log in a user by using an ORM object and plain-text password.
|
||||
*
|
||||
* @param string username to log in
|
||||
* @param string password to check against
|
||||
* @param boolean enable autologin
|
||||
* @param string $username Username to log in
|
||||
* @param string $password Password to check against
|
||||
* @param boolean $remember Enable autologin
|
||||
* @return boolean
|
||||
*/
|
||||
public function login($username, $password, $remember = FALSE)
|
||||
@@ -87,20 +89,14 @@ abstract class Kohana_Auth {
|
||||
if (empty($password))
|
||||
return FALSE;
|
||||
|
||||
if (is_string($password))
|
||||
{
|
||||
// Create a hashed password
|
||||
$password = $this->hash($password);
|
||||
}
|
||||
|
||||
return $this->_login($username, $password, $remember);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log out a user by removing the related session variables.
|
||||
*
|
||||
* @param boolean completely destroy the session
|
||||
* @param boolean remove all tokens for user
|
||||
* @param boolean $destroy Completely destroy the session
|
||||
* @param boolean $logout_all Remove all tokens for user
|
||||
* @return boolean
|
||||
*/
|
||||
public function logout($destroy = FALSE, $logout_all = FALSE)
|
||||
@@ -127,7 +123,7 @@ abstract class Kohana_Auth {
|
||||
* Check if there is an active session. Optionally allows checking for a
|
||||
* specific role.
|
||||
*
|
||||
* @param string role name
|
||||
* @param string $role role name
|
||||
* @return mixed
|
||||
*/
|
||||
public function logged_in($role = NULL)
|
||||
@@ -140,7 +136,7 @@ abstract class Kohana_Auth {
|
||||
* method is deprecated, [Auth::hash] should be used instead.
|
||||
*
|
||||
* @deprecated
|
||||
* @param string plaintext password
|
||||
* @param string $password Plaintext password
|
||||
*/
|
||||
public function hash_password($password)
|
||||
{
|
||||
@@ -150,7 +146,7 @@ abstract class Kohana_Auth {
|
||||
/**
|
||||
* Perform a hmac hash, using the configured method.
|
||||
*
|
||||
* @param string string to hash
|
||||
* @param string $str string to hash
|
||||
* @return string
|
||||
*/
|
||||
public function hash($str)
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
/**
|
||||
* File Auth driver.
|
||||
* [!!] this Auth driver does not support roles nor autologin.
|
||||
*
|
||||
* @package Kohana/Auth
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2007-2010 Kohana Team
|
||||
* @copyright (c) 2007-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Auth_File extends Auth {
|
||||
@@ -27,13 +27,19 @@ class Kohana_Auth_File extends Auth {
|
||||
/**
|
||||
* Logs a user in.
|
||||
*
|
||||
* @param string username
|
||||
* @param string password
|
||||
* @param boolean enable autologin (not supported)
|
||||
* @param string $username Username
|
||||
* @param string $password Password
|
||||
* @param boolean $remember Enable autologin (not supported)
|
||||
* @return boolean
|
||||
*/
|
||||
protected function _login($username, $password, $remember)
|
||||
{
|
||||
if (is_string($password))
|
||||
{
|
||||
// Create a hashed password
|
||||
$password = $this->hash($password);
|
||||
}
|
||||
|
||||
if (isset($this->_users[$username]) AND $this->_users[$username] === $password)
|
||||
{
|
||||
// Complete the login
|
||||
@@ -47,7 +53,7 @@ class Kohana_Auth_File extends Auth {
|
||||
/**
|
||||
* Forces a user to be logged in, without specifying a password.
|
||||
*
|
||||
* @param mixed username
|
||||
* @param mixed $username Username
|
||||
* @return boolean
|
||||
*/
|
||||
public function force_login($username)
|
||||
@@ -59,7 +65,7 @@ class Kohana_Auth_File extends Auth {
|
||||
/**
|
||||
* Get the stored password for a username.
|
||||
*
|
||||
* @param mixed username
|
||||
* @param mixed $username Username
|
||||
* @return string
|
||||
*/
|
||||
public function password($username)
|
||||
@@ -70,7 +76,7 @@ class Kohana_Auth_File extends Auth {
|
||||
/**
|
||||
* Compare password with original (plain text). Works for current (logged in) user
|
||||
*
|
||||
* @param string $password
|
||||
* @param string $password Password
|
||||
* @return boolean
|
||||
*/
|
||||
public function check_password($password)
|
||||
@@ -85,4 +91,4 @@ class Kohana_Auth_File extends Auth {
|
||||
return ($password === $this->password($username));
|
||||
}
|
||||
|
||||
} // End Auth File
|
||||
} // End Auth File
|
@@ -1,3 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
abstract class Auth extends Kohana_Auth { }
|
@@ -1,3 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
|
||||
class Auth_File extends Kohana_Auth_File { }
|
@@ -1,11 +1,12 @@
|
||||
<?php defined('SYSPATH') or die('No direct access allowed.');
|
||||
<?php defined('SYSPATH') OR die('No direct access allowed.');
|
||||
|
||||
return array(
|
||||
|
||||
'driver' => 'file',
|
||||
'driver' => 'File',
|
||||
'hash_method' => 'sha256',
|
||||
'hash_key' => NULL,
|
||||
'lifetime' => 1209600,
|
||||
'session_type' => Session::$default,
|
||||
'session_key' => 'auth_user',
|
||||
|
||||
// Username/password combinations for the Auth File driver
|
||||
|
23
includes/kohana/modules/auth/config/userguide.php
Normal file
23
includes/kohana/modules/auth/config/userguide.php
Normal file
@@ -0,0 +1,23 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
return array(
|
||||
// Leave this alone
|
||||
'modules' => array(
|
||||
|
||||
// This should be the path to this modules userguide pages, without the 'guide/'. Ex: '/guide/modulename/' would be 'modulename'
|
||||
'auth' => array(
|
||||
|
||||
// Whether this modules userguide pages should be shown
|
||||
'enabled' => TRUE,
|
||||
|
||||
// The name that should show up on the userguide index page
|
||||
'name' => 'Auth',
|
||||
|
||||
// A short description of this module, shown on the index page
|
||||
'description' => 'User authentication and authorization.',
|
||||
|
||||
// Copyright message, shown in the footer for this module
|
||||
'copyright' => '© 2008–2012 Kohana Team',
|
||||
)
|
||||
)
|
||||
);
|
@@ -0,0 +1,13 @@
|
||||
# Configuration
|
||||
|
||||
The default configuration file is located in `MODPATH/auth/config/auth.php`. You should copy this file to `APPPATH/config/auth.php` and make changes there, in keeping with the [cascading filesystem](../kohana/files).
|
||||
|
||||
[Config merging](../kohana/config#config-merging) allows these default configuration settings to apply if you don't overwrite them in your application configuration file.
|
||||
|
||||
Name | Type | Default | Description
|
||||
-----|------|---------|------------
|
||||
driver | `string` | file | The name of the auth driver to use.
|
||||
hash_method | `string` | sha256 | The hashing function to use on the passwords.
|
||||
hash_key | `string` | NULL | The key to use when hashing the password.
|
||||
session_type | `string` | [Session::$default] | The type of session to use when storing the auth user.
|
||||
session_key | `string` | auth_user | The name of the session variable used to save the user.
|
||||
|
79
includes/kohana/modules/auth/guide/auth/driver/develop.md
Normal file
79
includes/kohana/modules/auth/guide/auth/driver/develop.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Developing Drivers
|
||||
|
||||
## Real World Example
|
||||
|
||||
Sometimes the best way to learn is to jump right in and read the code from another module. The [ORM](https://github.com/kohana/orm/blob/3.2/develop/classes/kohana/auth/orm.php) module comes with an auth driver you can learn from.
|
||||
|
||||
[!!] We will be developing an `example` driver. In your own driver you will substitute `example` with your driver name.
|
||||
|
||||
This example file would be saved at `APPPATH/classes/auth/example.php` (or `MODPATH` if you are creating a module).
|
||||
|
||||
---
|
||||
|
||||
## Quick Example
|
||||
|
||||
First we will show you a quick example and then break down what is going on.
|
||||
|
||||
~~~
|
||||
class Auth_Example extends Auth
|
||||
{
|
||||
protected function _login($username, $password, $remember)
|
||||
{
|
||||
// Do username/password check here
|
||||
}
|
||||
|
||||
public function password($username)
|
||||
{
|
||||
// Return the password for the username
|
||||
}
|
||||
|
||||
public function check_password($password)
|
||||
{
|
||||
// Check to see if the logged in user has the given password
|
||||
}
|
||||
|
||||
public function logged_in($role = NULL)
|
||||
{
|
||||
// Check to see if the user is logged in, and if $role is set, has all roles
|
||||
}
|
||||
|
||||
public function get_user($default = NULL)
|
||||
{
|
||||
// Get the logged in user, or return the $default if a user is not found
|
||||
}
|
||||
}
|
||||
~~~
|
||||
|
||||
## Extending Auth
|
||||
|
||||
All drivers must extend the [Auth] class.
|
||||
|
||||
class Auth_Example extends Auth
|
||||
|
||||
## Abstract Methods
|
||||
|
||||
The `Auth` class has 3 abstract methods that must be defined in your new driver.
|
||||
|
||||
~~~
|
||||
abstract protected function _login($username, $password, $remember);
|
||||
|
||||
abstract public function password($username);
|
||||
|
||||
abstract public function check_password($user);
|
||||
~~~
|
||||
|
||||
## Extending Functionality
|
||||
|
||||
Given that every auth system is going to check if users exist and if they have roles or not you will more than likely have to change some default functionality.
|
||||
|
||||
Here are a few functions that you should pay attention to.
|
||||
|
||||
~~~
|
||||
public function logged_in($role = NULL)
|
||||
|
||||
public function get_user($default = NULL)
|
||||
~~~
|
||||
|
||||
## Activating the Driver
|
||||
|
||||
After you create your driver you will want to use it. It is a easy as setting the `driver` [configuration](config) option to the name of your driver (in our case `example`).
|
19
includes/kohana/modules/auth/guide/auth/driver/file.md
Normal file
19
includes/kohana/modules/auth/guide/auth/driver/file.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# File Driver
|
||||
|
||||
The [Auth::File] driver is included with the auth module.
|
||||
|
||||
Below are additional configuration options that can be set for this driver.
|
||||
|
||||
Name | Type | Default | Description
|
||||
-----|------|---------|-------------
|
||||
users | `array` | array() | A user => password (_hashed_) array of all the users in your application
|
||||
|
||||
## Forcing Login
|
||||
|
||||
[Auth_File::force_login] allows you to force a user login without a password.
|
||||
|
||||
~~~
|
||||
// Force the user with a username of admin to be logged into your application
|
||||
Auth::instance()->force_login('admin');
|
||||
$user = Auth::instance()->get_user();
|
||||
~~~
|
@@ -0,0 +1,19 @@
|
||||
# Auth
|
||||
|
||||
User authentication and authorization is provided by the auth module.
|
||||
|
||||
The auth module is included with Kohana, but needs to be enabled before you can use it. To enable, open your `application/bootstrap.php` file and modify the call to [Kohana::modules] by including the auth module like so:
|
||||
|
||||
~~~
|
||||
Kohana::modules(array(
|
||||
...
|
||||
'auth' => MODPATH.'auth',
|
||||
...
|
||||
));
|
||||
~~~
|
||||
|
||||
Next, you will then need to [configure](config) the auth module.
|
||||
|
||||
The auth module provides the [Auth::File] driver for you. There is also an auth driver included with the ORM module.
|
||||
|
||||
As your application needs change you may need to find another driver or [develop](driver/develop) your own.
|
||||
|
@@ -0,0 +1,62 @@
|
||||
# Log in and out
|
||||
|
||||
The auth module provides methods to help you log users in and out of your application.
|
||||
|
||||
## Log in
|
||||
|
||||
The [Auth::login] method handles the login.
|
||||
|
||||
~~~
|
||||
// Handled from a form with inputs with names email / password
|
||||
$post = $this->request->post();
|
||||
$success = Auth::instance()->login($post['email'], $post['password']);
|
||||
|
||||
if ($success)
|
||||
{
|
||||
// Login successful, send to app
|
||||
}
|
||||
else
|
||||
{
|
||||
// Login failed, send back to form with error message
|
||||
}
|
||||
~~~
|
||||
|
||||
## Logged in User
|
||||
|
||||
There are two ways to check if a user is logged in. If you just need to check if the user is logged in use [Auth::logged_in].
|
||||
|
||||
~~~
|
||||
if (Auth::instance()->logged_in())
|
||||
{
|
||||
// User is logged in, continue on
|
||||
}
|
||||
else
|
||||
{
|
||||
// User isn't logged in, redirect to the login form.
|
||||
}
|
||||
~~~
|
||||
|
||||
You can also get the logged in user object by using [Auth::get_user]. If the user is null, then no user was found.
|
||||
|
||||
~~~
|
||||
$user = Auth::instance()->get_user();
|
||||
|
||||
// Check for a user (NULL if not user is found)
|
||||
if ($user !== null)
|
||||
{
|
||||
// User is found, continue on
|
||||
}
|
||||
else
|
||||
{
|
||||
// User was not found, redirect to the login form
|
||||
}
|
||||
~~~
|
||||
|
||||
## Log out
|
||||
|
||||
The [Auth::logout] method will take care of logging out a user.
|
||||
|
||||
~~~
|
||||
Auth::instance()->logout();
|
||||
// Redirect the user back to login page
|
||||
~~~
|
||||
|
@@ -1,7 +1,6 @@
|
||||
## [Auth]()
|
||||
- [Config](config)
|
||||
- [User Model](user)
|
||||
- [Register Users](register)
|
||||
- [Configuration](config)
|
||||
- [Log in and out](login)
|
||||
- [Edit User](edit)
|
||||
- [Using Roles](roles)
|
||||
- Drivers
|
||||
- [File](driver/file)
|
||||
- [Developing](driver/develop)
|
||||
|
12
includes/kohana/modules/cache/README.md
vendored
12
includes/kohana/modules/cache/README.md
vendored
@@ -9,13 +9,11 @@ Supported cache solutions
|
||||
Currently this module supports the following cache methods.
|
||||
|
||||
1. APC
|
||||
2. eAccelerator
|
||||
3. Memcache
|
||||
4. Memcached-tags (Supports tags)
|
||||
5. SQLite (Supports tags)
|
||||
6. File
|
||||
7. Xcache
|
||||
8. Wincache
|
||||
2. Memcache
|
||||
3. Memcached-tags (Supports tags)
|
||||
4. SQLite (Supports tags)
|
||||
5. File
|
||||
6. Wincache
|
||||
|
||||
Planned support
|
||||
---------------
|
||||
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Cache_Eaccelerator extends Kohana_Cache_Eaccelerator {}
|
||||
interface Cache_Arithmetic extends Kohana_Cache_Arithmetic {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Database_PDO extends Kohana_Database_PDO {}
|
||||
class Cache_Exception extends Kohana_Cache_Exception {}
|
3
includes/kohana/modules/cache/classes/Cache/GarbageCollect.php
vendored
Normal file
3
includes/kohana/modules/cache/classes/Cache/GarbageCollect.php
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
interface Cache_GarbageCollect extends Kohana_Cache_GarbageCollect {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
abstract class Database extends Kohana_Database {}
|
||||
interface Cache_Tagging extends Kohana_Cache_Tagging {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Image_GD extends Kohana_Image_GD {}
|
||||
class HTTP_Cache extends Kohana_HTTP_Cache {}
|
@@ -1,11 +1,11 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana Cache provides a common interface to a variety of caching engines. Tags are
|
||||
* supported where available natively to the cache system. Kohana Cache supports multiple
|
||||
* supported where available natively to the cache system. Kohana Cache supports multiple
|
||||
* instances of cache engines through a grouped singleton pattern.
|
||||
*
|
||||
*
|
||||
* ### Supported cache engines
|
||||
*
|
||||
*
|
||||
* * [APC](http://php.net/manual/en/book.apc.php)
|
||||
* * [eAccelerator](http://eaccelerator.net/)
|
||||
* * File
|
||||
@@ -13,28 +13,28 @@
|
||||
* * [Memcached-tags](http://code.google.com/p/memcached-tags/)
|
||||
* * [SQLite](http://www.sqlite.org/)
|
||||
* * [Xcache](http://xcache.lighttpd.net/)
|
||||
*
|
||||
*
|
||||
* ### Introduction to caching
|
||||
*
|
||||
*
|
||||
* Caching should be implemented with consideration. Generally, caching the result of resources
|
||||
* is faster than reprocessing them. Choosing what, how and when to cache is vital. PHP APC is
|
||||
* presently one of the fastest caching systems available, closely followed by Memcache. SQLite
|
||||
* and File caching are two of the slowest cache methods, however usually faster than reprocessing
|
||||
* a complex set of instructions.
|
||||
*
|
||||
*
|
||||
* Caching engines that use memory are considerably faster than the file based alternatives. But
|
||||
* memory is limited whereas disk space is plentiful. If caching large datasets it is best to use
|
||||
* file caching.
|
||||
*
|
||||
*
|
||||
* ### Configuration settings
|
||||
*
|
||||
*
|
||||
* Kohana Cache uses configuration groups to create cache instances. A configuration group can
|
||||
* use any supported driver, with successive groups using the same driver type if required.
|
||||
*
|
||||
*
|
||||
* #### Configuration example
|
||||
*
|
||||
*
|
||||
* Below is an example of a _memcache_ server configuration.
|
||||
*
|
||||
*
|
||||
* return array(
|
||||
* 'default' => array( // Default group
|
||||
* 'driver' => 'memcache', // using Memcache driver
|
||||
@@ -48,30 +48,30 @@
|
||||
* 'compression' => FALSE, // Use compression?
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
*
|
||||
*
|
||||
* Details of the settings specific to each driver are available within the drivers documentation.
|
||||
*
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @version 2.0
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Kohana_Cache {
|
||||
@@ -91,19 +91,19 @@ abstract class Kohana_Cache {
|
||||
/**
|
||||
* Creates a singleton of a Kohana Cache group. If no group is supplied
|
||||
* the __default__ cache group is used.
|
||||
*
|
||||
*
|
||||
* // Create an instance of the default group
|
||||
* $default_group = Cache::instance();
|
||||
*
|
||||
*
|
||||
* // Create an instance of a group
|
||||
* $foo_group = Cache::instance('foo');
|
||||
*
|
||||
*
|
||||
* // Access an instantiated group directly
|
||||
* $foo_group = Cache::$instances['default'];
|
||||
*
|
||||
* @param string the name of the cache group to use [Optional]
|
||||
* @return Kohana_Cache
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param string $group the name of the cache group to use [Optional]
|
||||
* @return Cache
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public static function instance($group = NULL)
|
||||
{
|
||||
@@ -120,11 +120,14 @@ abstract class Kohana_Cache {
|
||||
return Cache::$instances[$group];
|
||||
}
|
||||
|
||||
$config = Kohana::config('cache');
|
||||
$config = Kohana::$config->load('cache');
|
||||
|
||||
if ( ! $config->offsetExists($group))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Failed to load Kohana Cache group: :group', array(':group' => $group));
|
||||
throw new Cache_Exception(
|
||||
'Failed to load Kohana Cache group: :group',
|
||||
array(':group' => $group)
|
||||
);
|
||||
}
|
||||
|
||||
$config = $config->get($group);
|
||||
@@ -140,59 +143,100 @@ abstract class Kohana_Cache {
|
||||
/**
|
||||
* @var Config
|
||||
*/
|
||||
protected $_config;
|
||||
protected $_config = array();
|
||||
|
||||
/**
|
||||
* Ensures singleton pattern is observed, loads the default expiry
|
||||
*
|
||||
* @param array configuration
|
||||
*
|
||||
* @param array $config configuration
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
$this->_config = $config;
|
||||
$this->config($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter and setter for the configuration. If no argument provided, the
|
||||
* current configuration is returned. Otherwise the configuration is set
|
||||
* to this class.
|
||||
*
|
||||
* // Overwrite all configuration
|
||||
* $cache->config(array('driver' => 'memcache', '...'));
|
||||
*
|
||||
* // Set a new configuration setting
|
||||
* $cache->config('servers', array(
|
||||
* 'foo' => 'bar',
|
||||
* '...'
|
||||
* ));
|
||||
*
|
||||
* // Get a configuration setting
|
||||
* $servers = $cache->config('servers);
|
||||
*
|
||||
* @param mixed key to set to array, either array or config path
|
||||
* @param mixed value to associate with key
|
||||
* @return mixed
|
||||
*/
|
||||
public function config($key = NULL, $value = NULL)
|
||||
{
|
||||
if ($key === NULL)
|
||||
return $this->_config;
|
||||
|
||||
if (is_array($key))
|
||||
{
|
||||
$this->_config = $key;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($value === NULL)
|
||||
return Arr::get($this->_config, $key);
|
||||
|
||||
$this->_config[$key] = $value;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overload the __clone() method to prevent cloning
|
||||
*
|
||||
* @return void
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function __clone()
|
||||
final public function __clone()
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Cloning of Kohana_Cache objects is forbidden');
|
||||
throw new Cache_Exception('Cloning of Kohana_Cache objects is forbidden');
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from default group
|
||||
* $data = Cache::instance()->get('foo');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from default group and return 'bar' if miss
|
||||
* $data = Cache::instance()->get('foo', 'bar');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from memcache group
|
||||
* $data = Cache::instance('memcache')->get('foo');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
abstract public function get($id, $default = NULL);
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in default group, using default expiry
|
||||
* Cache::instance()->set('foo', $data);
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in default group for 30 seconds
|
||||
* Cache::instance()->set('foo', $data, 30);
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in memcache group for 10 minutes
|
||||
* if (Cache::instance('memcache')->set('foo', $data, 600))
|
||||
* {
|
||||
@@ -200,37 +244,37 @@ abstract class Kohana_Cache {
|
||||
* return
|
||||
* }
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param string data to set to cache
|
||||
* @param integer lifetime in seconds
|
||||
* @param string $id id of cache entry
|
||||
* @param string $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function set($id, $data, $lifetime = 3600);
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
*
|
||||
* // Delete 'foo' entry from the default group
|
||||
* Cache::instance()->delete('foo');
|
||||
*
|
||||
*
|
||||
* // Delete 'foo' entry from the memcache group
|
||||
* Cache::instance('memcache')->delete('foo')
|
||||
*
|
||||
* @param string id to remove from cache
|
||||
* @param string $id id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
abstract public function delete($id);
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the default group
|
||||
* Cache::instance()->delete_all();
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the memcache group
|
||||
* Cache::instance('memcache')->delete_all();
|
||||
*
|
||||
@@ -243,8 +287,8 @@ abstract class Kohana_Cache {
|
||||
*
|
||||
* // Sanitize a cache id
|
||||
* $id = $this->_sanitize_id($id);
|
||||
*
|
||||
* @param string id of cache to sanitize
|
||||
*
|
||||
* @param string $id id of cache to sanitize
|
||||
* @return string
|
||||
*/
|
||||
protected function _sanitize_id($id)
|
@@ -2,54 +2,54 @@
|
||||
/**
|
||||
* [Kohana Cache](api/Kohana_Cache) APC driver. Provides an opcode based
|
||||
* driver for the Kohana Cache library.
|
||||
*
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
*
|
||||
* Below is an example of an _apc_ server configuration.
|
||||
*
|
||||
*
|
||||
* return array(
|
||||
* 'apc' => array( // Driver group
|
||||
* 'driver' => 'apc', // using APC driver
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
*
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
* * APC PHP extension
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Apc extends Cache {
|
||||
class Kohana_Cache_Apc extends Cache implements Cache_Arithmetic {
|
||||
|
||||
/**
|
||||
* Check for existence of the APC extension This method cannot be invoked externally. The driver must
|
||||
* be instantiated using the `Cache::instance()` method.
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
if ( ! extension_loaded('apc'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('PHP APC extension is not available.');
|
||||
throw new Cache_Exception('PHP APC extension is not available.');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
@@ -57,17 +57,17 @@ class Kohana_Cache_Apc extends Cache {
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from apc group
|
||||
* $data = Cache::instance('apc')->get('foo');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from apc group and return 'bar' if miss
|
||||
* $data = Cache::instance('apc')->get('foo', 'bar');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
@@ -78,18 +78,18 @@ class Kohana_Cache_Apc extends Cache {
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in apc group, using default expiry
|
||||
* Cache::instance('apc')->set('foo', $data);
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in apc group for 30 seconds
|
||||
* Cache::instance('apc')->set('foo', $data, 30);
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param string data to set to cache
|
||||
* @param integer lifetime in seconds
|
||||
* @param string $id id of cache entry
|
||||
* @param string $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
@@ -104,11 +104,11 @@ class Kohana_Cache_Apc extends Cache {
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
*
|
||||
* // Delete 'foo' entry from the apc group
|
||||
* Cache::instance('apc')->delete('foo');
|
||||
*
|
||||
* @param string id to remove from cache
|
||||
* @param string $id id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
@@ -118,11 +118,11 @@ class Kohana_Cache_Apc extends Cache {
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the apc group
|
||||
* Cache::instance('apc')->delete_all();
|
||||
*
|
||||
@@ -132,4 +132,35 @@ class Kohana_Cache_Apc extends Cache {
|
||||
{
|
||||
return apc_clear_cache('user');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to increment
|
||||
* @param int step value to increment by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($id, $step = 1)
|
||||
{
|
||||
return apc_inc($id, $step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to decrement
|
||||
* @param int step value to decrement by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($id, $step = 1)
|
||||
{
|
||||
return apc_dec($id, $step);
|
||||
}
|
||||
|
||||
} // End Kohana_Cache_Apc
|
39
includes/kohana/modules/cache/classes/Kohana/Cache/Arithmetic.php
vendored
Normal file
39
includes/kohana/modules/cache/classes/Kohana/Cache/Arithmetic.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana Cache Arithmetic Interface, for basic cache integer based
|
||||
* arithmetic, addition and subtraction
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @since 3.2.0
|
||||
*/
|
||||
interface Kohana_Cache_Arithmetic {
|
||||
|
||||
/**
|
||||
* Increments a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to increment
|
||||
* @param int step value to increment by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($id, $step = 1);
|
||||
|
||||
/**
|
||||
* Decrements a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to decrement
|
||||
* @param int step value to decrement by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($id, $step = 1);
|
||||
|
||||
} // End Kohana_Cache_Arithmetic
|
@@ -5,7 +5,7 @@
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Exception extends Kohana_Exception {}
|
@@ -3,56 +3,56 @@
|
||||
* [Kohana Cache](api/Kohana_Cache) File driver. Provides a file based
|
||||
* driver for the Kohana Cache library. This is one of the slowest
|
||||
* caching methods.
|
||||
*
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
*
|
||||
* Below is an example of a _file_ server configuration.
|
||||
*
|
||||
*
|
||||
* return array(
|
||||
* 'file' => array( // File driver group
|
||||
* 'driver' => 'file', // using File driver
|
||||
* 'cache_dir' => APPPATH.'cache/.kohana_cache', // Cache location
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
* cache_dir | __NO__ | (_string_) The cache directory to use for this cache instance
|
||||
*
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
class Kohana_Cache_File extends Cache implements Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Creates a hashed filename based on the string. This is used
|
||||
* to create shorter unique IDs for each cache filename.
|
||||
*
|
||||
*
|
||||
* // Create the cache filename
|
||||
* $filename = Cache_File::filename($this->_sanitize_id($id));
|
||||
*
|
||||
* @param string string to hash into filename
|
||||
* @param string $string string to hash into filename
|
||||
* @return string
|
||||
*/
|
||||
protected static function filename($string)
|
||||
{
|
||||
return sha1($string).'.json';
|
||||
return sha1($string).'.cache';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -64,8 +64,8 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
* Constructs the file cache driver. This method cannot be invoked externally. The file cache driver must
|
||||
* be instantiated using the `Cache::instance()` method.
|
||||
*
|
||||
* @param array config
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config config
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
@@ -91,35 +91,35 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
// If the defined directory is a file, get outta here
|
||||
if ($this->_cache_dir->isFile())
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Unable to create cache directory as a file already exists : :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
throw new Cache_Exception('Unable to create cache directory as a file already exists : :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
}
|
||||
|
||||
// Check the read status of the directory
|
||||
if ( ! $this->_cache_dir->isReadable())
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Unable to read from the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
throw new Cache_Exception('Unable to read from the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
}
|
||||
|
||||
// Check the write status of the directory
|
||||
if ( ! $this->_cache_dir->isWritable())
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Unable to write to the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
throw new Cache_Exception('Unable to write to the cache directory :resource', array(':resource' => $this->_cache_dir->getRealPath()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from file group
|
||||
* $data = Cache::instance('file')->get('foo');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from file group and return 'bar' if miss
|
||||
* $data = Cache::instance('file')->get('foo', 'bar');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
@@ -140,34 +140,44 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
}
|
||||
else
|
||||
{
|
||||
// Open the file and extract the json
|
||||
$json = $file->openFile()->current();
|
||||
// Open the file and parse data
|
||||
$created = $file->getMTime();
|
||||
$data = $file->openFile();
|
||||
$lifetime = $data->fgets();
|
||||
|
||||
// Decode the json into PHP object
|
||||
$data = json_decode($json);
|
||||
// If we're at the EOF at this point, corrupted!
|
||||
if ($data->eof())
|
||||
{
|
||||
throw new Cache_Exception(__METHOD__.' corrupted cache file!');
|
||||
}
|
||||
|
||||
$cache = '';
|
||||
|
||||
while ($data->eof() === FALSE)
|
||||
{
|
||||
$cache .= $data->fgets();
|
||||
}
|
||||
|
||||
// Test the expiry
|
||||
if ($data->expiry < time())
|
||||
if (($created + (int) $lifetime) < time())
|
||||
{
|
||||
// Delete the file
|
||||
$this->_delete_file($file, NULL, TRUE);
|
||||
|
||||
// Return default value
|
||||
return $default;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ($data->type === 'string') ? $data->payload : unserialize($data->payload);
|
||||
return unserialize($cache);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
// Handle ErrorException caused by failed unserialization
|
||||
if ($e->getCode() === E_NOTICE)
|
||||
{
|
||||
throw new Kohana_Cache_Exception(__METHOD__.' failed to unserialize cached object with message : '.$e->getMessage());
|
||||
throw new Cache_Exception(__METHOD__.' failed to unserialize cached object with message : '.$e->getMessage());
|
||||
}
|
||||
|
||||
// Otherwise throw the exception
|
||||
@@ -177,18 +187,18 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in file group, using default expiry
|
||||
* Cache::instance('file')->set('foo', $data);
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in file group for 30 seconds
|
||||
* Cache::instance('file')->set('foo', $data, 30);
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param string data to set to cache
|
||||
* @param integer lifetime in seconds
|
||||
* @param string $id id of cache entry
|
||||
* @param string $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
@@ -209,10 +219,10 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
// If the directory path is not a directory
|
||||
if ( ! $dir->isDir())
|
||||
{
|
||||
// Create the directory
|
||||
// Create the directory
|
||||
if ( ! mkdir($directory, 0777, TRUE))
|
||||
{
|
||||
throw new Kohana_Cache_Exception(__METHOD__.' unable to create directory : :directory', array(':directory' => $directory));
|
||||
throw new Cache_Exception(__METHOD__.' unable to create directory : :directory', array(':directory' => $directory));
|
||||
}
|
||||
|
||||
// chmod to solve potential umask issues
|
||||
@@ -225,16 +235,9 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
|
||||
try
|
||||
{
|
||||
$type = gettype($data);
|
||||
|
||||
// Serialize the data
|
||||
$data = json_encode( (object) array(
|
||||
'payload' => ($type === 'string') ? $data : serialize($data),
|
||||
'expiry' => time() + $lifetime,
|
||||
'type' => $type
|
||||
));
|
||||
|
||||
$size = strlen($data);
|
||||
$data = $lifetime."\n".serialize($data);
|
||||
$file->fwrite($data, strlen($data));
|
||||
return (bool) $file->fflush();
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
@@ -242,31 +245,21 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
if ($e->getCode() === E_NOTICE)
|
||||
{
|
||||
// Throw a caching error
|
||||
throw new Kohana_Cache_Exception(__METHOD__.' failed to serialize data for caching with message : '.$e->getMessage());
|
||||
throw new Cache_Exception(__METHOD__.' failed to serialize data for caching with message : '.$e->getMessage());
|
||||
}
|
||||
|
||||
// Else rethrow the error exception
|
||||
throw $e;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$file->fwrite($data, $size);
|
||||
return (bool) $file->fflush();
|
||||
}
|
||||
catch (Exception $e)
|
||||
{
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
*
|
||||
* // Delete 'foo' entry from the file group
|
||||
* Cache::instance('file')->delete('foo');
|
||||
*
|
||||
* @param string id to remove from cache
|
||||
* @param string $id id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
@@ -279,11 +272,11 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the file group
|
||||
* Cache::instance('file')->delete_all();
|
||||
*
|
||||
@@ -308,16 +301,16 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Deletes files recursively and returns FALSE on any errors
|
||||
*
|
||||
*
|
||||
* // Delete a file or folder whilst retaining parent directory and ignore all errors
|
||||
* $this->_delete_file($folder, TRUE, TRUE);
|
||||
*
|
||||
* @param SplFileInfo file
|
||||
* @param boolean retain the parent directory
|
||||
* @param boolean ignore_errors to prevent all exceptions interrupting exec
|
||||
* @param boolean only expired files
|
||||
* @param SplFileInfo $file file
|
||||
* @param boolean $retain_parent_directory retain the parent directory
|
||||
* @param boolean $ignore_errors ignore_errors to prevent all exceptions interrupting exec
|
||||
* @param boolean $only_expired only expired files
|
||||
* @return boolean
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function _delete_file(SplFileInfo $file, $retain_parent_directory = FALSE, $ignore_errors = FALSE, $only_expired = FALSE)
|
||||
{
|
||||
@@ -329,8 +322,13 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
{
|
||||
try
|
||||
{
|
||||
// Handle ignore files
|
||||
if (in_array($file->getFilename(), $this->config('ignore_on_delete')))
|
||||
{
|
||||
$delete = FALSE;
|
||||
}
|
||||
// If only expired is not set
|
||||
if ($only_expired === FALSE)
|
||||
elseif ($only_expired === FALSE)
|
||||
{
|
||||
// We want to delete the file
|
||||
$delete = TRUE;
|
||||
@@ -344,19 +342,18 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
$delete = $data->expiry < time();
|
||||
}
|
||||
|
||||
// If the delete flag is set
|
||||
// If the delete flag is set delete file
|
||||
if ($delete === TRUE)
|
||||
{
|
||||
// Try to delete
|
||||
unlink($file->getRealPath());
|
||||
}
|
||||
return unlink($file->getRealPath());
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
catch (ErrorException $e)
|
||||
{
|
||||
// Catch any delete file warnings
|
||||
if ($e->getCode() === E_WARNING)
|
||||
{
|
||||
throw new Kohana_Cache_Exception(__METHOD__.' failed to delete file : :file', array(':file' => $file->getRealPath()));
|
||||
throw new Cache_Exception(__METHOD__.' failed to delete file : :file', array(':file' => $file->getRealPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -373,7 +370,7 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
$name = $files->getFilename();
|
||||
|
||||
// If the name is not a dot
|
||||
if ($name != '.' AND $name != '..' AND substr($file->getFilename(), 0, 1) == '.')
|
||||
if ($name != '.' AND $name != '..')
|
||||
{
|
||||
// Create new file resource
|
||||
$fp = new SplFileInfo($files->getRealPath());
|
||||
@@ -405,10 +402,16 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
// Catch any delete directory warnings
|
||||
if ($e->getCode() === E_WARNING)
|
||||
{
|
||||
throw new Kohana_Cache_Exception(__METHOD__.' failed to delete directory : :directory', array(':directory' => $file->getRealPath()));
|
||||
throw new Cache_Exception(__METHOD__.' failed to delete directory : :directory', array(':directory' => $file->getRealPath()));
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We get here if a file has already been deleted
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
// Catch all exceptions
|
||||
catch (Exception $e)
|
||||
@@ -426,11 +429,11 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Resolves the cache directory real path from the filename
|
||||
*
|
||||
*
|
||||
* // Get the realpath of the cache folder
|
||||
* $realpath = $this->_resolve_directory($filename);
|
||||
*
|
||||
* @param string filename to resolve
|
||||
* @param string $filename filename to resolve
|
||||
* @return string
|
||||
*/
|
||||
protected function _resolve_directory($filename)
|
||||
@@ -442,22 +445,22 @@ class Kohana_Cache_File extends Cache implements Kohana_Cache_GarbageCollect {
|
||||
* Makes the cache directory if it doesn't exist. Simply a wrapper for
|
||||
* `mkdir` to ensure DRY principles
|
||||
*
|
||||
* @see http://php.net/manual/en/function.mkdir.php
|
||||
* @param string directory
|
||||
* @param string mode
|
||||
* @param string recursive
|
||||
* @param string context
|
||||
* @link http://php.net/manual/en/function.mkdir.php
|
||||
* @param string $directory
|
||||
* @param integer $mode
|
||||
* @param boolean $recursive
|
||||
* @param resource $context
|
||||
* @return SplFileInfo
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function _make_directory($directory, $mode = 0777, $recursive = FALSE, $context = NULL)
|
||||
{
|
||||
if ( ! mkdir($directory, $mode, $recursive, $context))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
|
||||
throw new Cache_Exception('Failed to create the defined cache directory : :directory', array(':directory' => $directory));
|
||||
}
|
||||
chmod($directory, $mode);
|
||||
|
||||
return new SplFileInfo($directory);;
|
||||
return new SplFileInfo($directory);
|
||||
}
|
||||
}
|
@@ -8,7 +8,7 @@
|
||||
* @category Base
|
||||
* @version 2.0
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
* @since 3.0.8
|
||||
*/
|
@@ -1,16 +1,16 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* [Kohana Cache](api/Kohana_Cache) Memcache driver,
|
||||
*
|
||||
*
|
||||
* ### Supported cache engines
|
||||
*
|
||||
*
|
||||
* * [Memcache](http://www.php.net/manual/en/book.memcache.php)
|
||||
* * [Memcached-tags](http://code.google.com/p/memcached-tags/)
|
||||
*
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
*
|
||||
* Below is an example of a _memcache_ server configuration.
|
||||
*
|
||||
*
|
||||
* return array(
|
||||
* 'default' => array( // Default group
|
||||
* 'driver' => 'memcache', // using Memcache driver
|
||||
@@ -37,24 +37,24 @@
|
||||
* 'compression' => FALSE, // Use compression?
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
* servers | __YES__ | (_array_) Associative array of server details, must include a __host__ key. (see _Memcache server configuration_ below)
|
||||
* compression | __NO__ | (_boolean_) Use data compression when caching
|
||||
*
|
||||
*
|
||||
* #### Memcache server configuration
|
||||
*
|
||||
*
|
||||
* The following settings should be used when defining each memcache server
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* ---------------- | -------- | ---------------------------------------------------------------
|
||||
* host | __YES__ | (_string_) The host of the memcache server, i.e. __localhost__; or __127.0.0.1__; or __memcache.domain.tld__
|
||||
@@ -65,22 +65,22 @@
|
||||
* retry_interval | __NO__ | (_integer_) Controls how often a failed server will be retried, the default value is 15 seconds. Setting this parameter to -1 disables automatic retry. Default __15__
|
||||
* status | __NO__ | (_boolean_) Controls if the server should be flagged as online. Default __TRUE__
|
||||
* failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language.pseudo-types.php#language.types.callback)_) Allows the user to specify a callback function to run upon encountering an error. The callback is run before failover is attempted. The function takes two parameters, the hostname and port of the failed server. Default __NULL__
|
||||
*
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
* * Memcache (plus Memcached-tags for native tagging support)
|
||||
* * Zlib
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @version 2.0
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Memcache extends Cache {
|
||||
class Kohana_Cache_Memcache extends Cache implements Cache_Arithmetic {
|
||||
|
||||
// Memcache has a maximum cache lifetime of 30 days
|
||||
const CACHE_CEILING = 2592000;
|
||||
@@ -109,15 +109,15 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
/**
|
||||
* Constructs the memcache Kohana_Cache object
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
// Check for the memcache extention
|
||||
if ( ! extension_loaded('memcache'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Memcache PHP extention not loaded');
|
||||
throw new Cache_Exception('Memcache PHP extention not loaded');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
@@ -131,7 +131,7 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
if ( ! $servers)
|
||||
{
|
||||
// Throw an exception if no server found
|
||||
throw new Kohana_Cache_Exception('No Memcache servers defined in configuration');
|
||||
throw new Cache_Exception('No Memcache servers defined in configuration');
|
||||
}
|
||||
|
||||
// Setup default server configuration
|
||||
@@ -155,7 +155,7 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
|
||||
if ( ! $this->_memcache->addServer($server['host'], $server['port'], $server['persistent'], $server['weight'], $server['timeout'], $server['retry_interval'], $server['status'], $server['failure_callback']))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Memcache could not connect to host \':host\' using port \':port\'', array(':host' => $server['host'], ':port' => $server['port']));
|
||||
throw new Cache_Exception('Memcache could not connect to host \':host\' using port \':port\'', array(':host' => $server['host'], ':port' => $server['port']));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,17 +165,17 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from memcache group
|
||||
* $data = Cache::instance('memcache')->get('foo');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from memcache group and return 'bar' if miss
|
||||
* $data = Cache::instance('memcache')->get('foo', 'bar');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
@@ -194,9 +194,9 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in memcache group for 10 minutes
|
||||
* if (Cache::instance('memcache')->set('foo', $data, 600))
|
||||
* {
|
||||
@@ -204,9 +204,9 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
* return
|
||||
* }
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param mixed data to set to cache
|
||||
* @param integer lifetime in seconds, maximum value 2592000
|
||||
* @param string $id id of cache entry
|
||||
* @param mixed $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds, maximum value 2592000
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = 3600)
|
||||
@@ -235,15 +235,15 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
*
|
||||
* // Delete the 'foo' cache entry immediately
|
||||
* Cache::instance('memcache')->delete('foo');
|
||||
*
|
||||
*
|
||||
* // Delete the 'bar' cache entry after 30 seconds
|
||||
* Cache::instance('memcache')->delete('bar', 30);
|
||||
*
|
||||
* @param string id of entry to delete
|
||||
* @param integer timeout of entry, if zero item is deleted immediately, otherwise the item will delete after the specified value in seconds
|
||||
* @param string $id id of entry to delete
|
||||
* @param integer $timeout timeout of entry, if zero item is deleted immediately, otherwise the item will delete after the specified value in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id, $timeout = 0)
|
||||
@@ -254,11 +254,11 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the default group
|
||||
* Cache::instance('memcache')->delete_all();
|
||||
*
|
||||
@@ -280,15 +280,15 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
* on a particular server fails. This method switches off that instance of the
|
||||
* server if the configuration setting `instant_death` is set to `TRUE`.
|
||||
*
|
||||
* @param string hostname
|
||||
* @param integer port
|
||||
* @param string $hostname
|
||||
* @param integer $port
|
||||
* @return void|boolean
|
||||
* @since 3.0.8
|
||||
*/
|
||||
public function _failed_request($hostname, $port)
|
||||
{
|
||||
if ( ! $this->_config['instant_death'])
|
||||
return;
|
||||
return;
|
||||
|
||||
// Setup non-existent host
|
||||
$host = FALSE;
|
||||
@@ -321,4 +321,34 @@ class Kohana_Cache_Memcache extends Cache {
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Increments a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to increment
|
||||
* @param int step value to increment by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function increment($id, $step = 1)
|
||||
{
|
||||
return $this->_memcache->increment($id, $step);
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrements a given value by the step value supplied.
|
||||
* Useful for shared counters and other persistent integer based
|
||||
* tracking.
|
||||
*
|
||||
* @param string id of cache entry to decrement
|
||||
* @param int step value to decrement by
|
||||
* @return integer
|
||||
* @return boolean
|
||||
*/
|
||||
public function decrement($id, $step = 1)
|
||||
{
|
||||
return $this->_memcache->decrement($id, $step);
|
||||
}
|
||||
}
|
@@ -1,21 +1,21 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* See [Kohana_Cache_Memcache]
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @version 2.0
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Tagging {
|
||||
class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Cache_Tagging {
|
||||
|
||||
/**
|
||||
/**
|
||||
* Constructs the memcache object
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
@@ -23,21 +23,23 @@ class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Ta
|
||||
|
||||
if ( ! method_exists($this->_memcache, 'tag_add'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Memcached-tags PHP plugin not present. Please see http://code.google.com/p/memcached-tags/ for more information');
|
||||
throw new Cache_Exception('Memcached-tags PHP plugin not present. Please see http://code.google.com/p/memcached-tags/ for more information');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value based on an id with tags
|
||||
*
|
||||
* @param string id
|
||||
* @param mixed data
|
||||
* @param integer lifetime [Optional]
|
||||
* @param array tags [Optional]
|
||||
*
|
||||
* @param string $id id
|
||||
* @param mixed $data data
|
||||
* @param integer $lifetime lifetime [Optional]
|
||||
* @param array $tags tags [Optional]
|
||||
* @return boolean
|
||||
*/
|
||||
public function set_with_tags($id, $data, $lifetime = NULL, array $tags = NULL)
|
||||
{
|
||||
$id = $this->_sanitize_id($id);
|
||||
|
||||
$result = $this->set($id, $data, $lifetime);
|
||||
|
||||
if ($result and $tags)
|
||||
@@ -54,7 +56,7 @@ class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Ta
|
||||
/**
|
||||
* Delete cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param string $tag tag
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete_tag($tag)
|
||||
@@ -65,12 +67,12 @@ class Kohana_Cache_MemcacheTag extends Cache_Memcache implements Kohana_Cache_Ta
|
||||
/**
|
||||
* Find cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param string $tag tag
|
||||
* @return void
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function find($tag)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Memcached-tags does not support finding by tag');
|
||||
}
|
||||
throw new Cache_Exception('Memcached-tags does not support finding by tag');
|
||||
}
|
||||
}
|
@@ -1,16 +1,16 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana Cache Sqlite Driver
|
||||
*
|
||||
*
|
||||
* Requires SQLite3 and PDO
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_Cache_GarbageCollect {
|
||||
class Kohana_Cache_Sqlite extends Cache implements Cache_Tagging, Cache_GarbageCollect {
|
||||
|
||||
/**
|
||||
* Database resource
|
||||
@@ -23,8 +23,8 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
* Sets up the PDO SQLite table and
|
||||
* initialises the PDO connection
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
@@ -34,7 +34,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
|
||||
if ($database === NULL)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Database path not available in Kohana Cache configuration');
|
||||
throw new Cache_Exception('Database path not available in Kohana Cache configuration');
|
||||
}
|
||||
|
||||
// Load new Sqlite DB
|
||||
@@ -50,7 +50,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
|
||||
if ($database_schema === NULL)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Database schema not found in Kohana Cache configuration');
|
||||
throw new Cache_Exception('Database schema not found in Kohana Cache configuration');
|
||||
}
|
||||
|
||||
try
|
||||
@@ -60,7 +60,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('Failed to create new SQLite caches table with the following error : :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('Failed to create new SQLite caches table with the following error : :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -68,10 +68,10 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
/**
|
||||
* Retrieve a value based on an id
|
||||
*
|
||||
* @param string id
|
||||
* @param string default [Optional] Default value to return if id not found
|
||||
* @param string $id id
|
||||
* @param string $default default [Optional] Default value to return if id not found
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
@@ -85,7 +85,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
if ( ! $result = $statement->fetch(PDO::FETCH_OBJ))
|
||||
@@ -105,7 +105,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
{
|
||||
// Disable notices for unserializing
|
||||
$ER = error_reporting(~E_NOTICE);
|
||||
|
||||
|
||||
// Return the valid cache data
|
||||
$data = unserialize($result->cache);
|
||||
|
||||
@@ -120,9 +120,9 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
/**
|
||||
* Set a value based on an id. Optionally add tags.
|
||||
*
|
||||
* @param string id
|
||||
* @param mixed data
|
||||
* @param integer lifetime [Optional]
|
||||
* @param string $id id
|
||||
* @param mixed $data data
|
||||
* @param integer $lifetime lifetime [Optional]
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
@@ -133,10 +133,9 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
* @param string id
|
||||
* @param integer timeout [Optional]
|
||||
* @param string $id id
|
||||
* @return boolean
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
@@ -150,7 +149,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
return (bool) $statement->rowCount();
|
||||
@@ -181,13 +180,13 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
|
||||
/**
|
||||
* Set a value based on an id. Optionally add tags.
|
||||
*
|
||||
* @param string id
|
||||
* @param mixed data
|
||||
* @param integer lifetime [Optional]
|
||||
* @param array tags [Optional]
|
||||
*
|
||||
* @param string $id id
|
||||
* @param mixed $data data
|
||||
* @param integer $lifetime lifetime [Optional]
|
||||
* @param array $tags tags [Optional]
|
||||
* @return boolean
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function set_with_tags($id, $data, $lifetime = NULL, array $tags = NULL)
|
||||
{
|
||||
@@ -200,7 +199,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
// Setup lifetime
|
||||
if ($lifetime === NULL)
|
||||
{
|
||||
$lifetime = (0 === Arr::get('default_expire', NULL)) ? 0 : (Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE) + time());
|
||||
$lifetime = (0 === Arr::get($this->_config, 'default_expire', NULL)) ? 0 : (Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE) + time());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -208,7 +207,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
|
||||
// Prepare statement
|
||||
// $this->exists() may throw Kohana_Cache_Exception, no need to catch/rethrow
|
||||
// $this->exists() may throw Cache_Exception, no need to catch/rethrow
|
||||
$statement = $this->exists($id) ? $this->_db->prepare('UPDATE caches SET expiration = :expiration, cache = :cache, tags = :tags WHERE id = :id') : $this->_db->prepare('INSERT INTO caches (id, cache, expiration, tags) VALUES (:id, :cache, :expiration, :tags)');
|
||||
|
||||
// Try to insert
|
||||
@@ -218,7 +217,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
return (bool) $statement->rowCount();
|
||||
@@ -227,10 +226,9 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
/**
|
||||
* Delete cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param integer timeout [Optional]
|
||||
* @param string $tag tag
|
||||
* @return boolean
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function delete_tag($tag)
|
||||
{
|
||||
@@ -253,9 +251,9 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
/**
|
||||
* Find cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param string $tag tag
|
||||
* @return array
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function find($tag)
|
||||
{
|
||||
@@ -272,7 +270,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
$result = array();
|
||||
@@ -308,16 +306,16 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOException $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether an id exists or not
|
||||
*
|
||||
* @param string id
|
||||
* @param string $id id
|
||||
* @return boolean
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function exists($id)
|
||||
{
|
||||
@@ -328,7 +326,7 @@ class Kohana_Cache_Sqlite extends Cache implements Kohana_Cache_Tagging, Kohana_
|
||||
}
|
||||
catch (PDOExeption $e)
|
||||
{
|
||||
throw new Kohana_Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
throw new Cache_Exception('There was a problem querying the local SQLite3 cache. :error', array(':error' => $e->getMessage()));
|
||||
}
|
||||
|
||||
return (bool) $statement->fetchAll();
|
@@ -1,25 +1,25 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana Cache Tagging Interface
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
interface Kohana_Cache_Tagging {
|
||||
|
||||
/**
|
||||
* Set a value based on an id. Optionally add tags.
|
||||
*
|
||||
*
|
||||
* Note : Some caching engines do not support
|
||||
* tagging
|
||||
*
|
||||
* @param string id
|
||||
* @param mixed data
|
||||
* @param integer lifetime [Optional]
|
||||
* @param array tags [Optional]
|
||||
* @param string $id id
|
||||
* @param mixed $data data
|
||||
* @param integer $lifetime lifetime [Optional]
|
||||
* @param array $tags tags [Optional]
|
||||
* @return boolean
|
||||
*/
|
||||
public function set_with_tags($id, $data, $lifetime = NULL, array $tags = NULL);
|
||||
@@ -27,15 +27,14 @@ interface Kohana_Cache_Tagging {
|
||||
/**
|
||||
* Delete cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param integer timeout [Optional]
|
||||
* @param string $tag tag
|
||||
*/
|
||||
public function delete_tag($tag);
|
||||
|
||||
/**
|
||||
* Find cache entries based on a tag
|
||||
*
|
||||
* @param string tag
|
||||
* @param string $tag tag
|
||||
* @return array
|
||||
*/
|
||||
public function find($tag);
|
@@ -2,30 +2,30 @@
|
||||
/**
|
||||
* [Kohana Cache](api/Kohana_Cache) Wincache driver. Provides an opcode based
|
||||
* driver for the Kohana Cache library.
|
||||
*
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
*
|
||||
* Below is an example of an _wincache_ server configuration.
|
||||
*
|
||||
*
|
||||
* return array(
|
||||
* 'wincache' => array( // Driver group
|
||||
* 'driver' => 'wincache', // using wincache driver
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
*
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
*
|
||||
* * Windows XP SP3 with IIS 5.1 and » FastCGI Extension
|
||||
* * Windows Server 2003 with IIS 6.0 and » FastCGI Extension
|
||||
* * Windows Vista SP1 with IIS 7.0 and FastCGI Module
|
||||
@@ -34,11 +34,11 @@
|
||||
* * Windows Server 2008 R2 with IIS 7.5 and FastCGI Module
|
||||
* * PHP 5.2.X, Non-thread-safe build
|
||||
* * PHP 5.3 X86, Non-thread-safe VC9 build
|
||||
*
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Wincache extends Cache {
|
||||
@@ -47,14 +47,14 @@ class Kohana_Cache_Wincache extends Cache {
|
||||
* Check for existence of the wincache extension This method cannot be invoked externally. The driver must
|
||||
* be instantiated using the `Cache::instance()` method.
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @param array $config configuration
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
if ( ! extension_loaded('wincache'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('PHP wincache extension is not available.');
|
||||
throw new Cache_Exception('PHP wincache extension is not available.');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
@@ -62,17 +62,17 @@ class Kohana_Cache_Wincache extends Cache {
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from wincache group
|
||||
* $data = Cache::instance('wincache')->get('foo');
|
||||
*
|
||||
*
|
||||
* // Retrieve cache entry from wincache group and return 'bar' if miss
|
||||
* $data = Cache::instance('wincache')->get('foo', 'bar');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @param string $id id of cache to entry
|
||||
* @param string $default default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
* @throws Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
@@ -83,18 +83,18 @@ class Kohana_Cache_Wincache extends Cache {
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in wincache group, using default expiry
|
||||
* Cache::instance('wincache')->set('foo', $data);
|
||||
*
|
||||
*
|
||||
* // Set 'bar' to 'foo' in wincache group for 30 seconds
|
||||
* Cache::instance('wincache')->set('foo', $data, 30);
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param string data to set to cache
|
||||
* @param integer lifetime in seconds
|
||||
* @param string $id id of cache entry
|
||||
* @param string $data data to set to cache
|
||||
* @param integer $lifetime lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
@@ -109,11 +109,11 @@ class Kohana_Cache_Wincache extends Cache {
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
*
|
||||
* // Delete 'foo' entry from the wincache group
|
||||
* Cache::instance('wincache')->delete('foo');
|
||||
*
|
||||
* @param string id to remove from cache
|
||||
* @param string $id id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
@@ -123,11 +123,11 @@ class Kohana_Cache_Wincache extends Cache {
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
*
|
||||
* // Delete all cache entries in the wincache group
|
||||
* Cache::instance('wincache')->delete_all();
|
||||
*
|
503
includes/kohana/modules/cache/classes/Kohana/HTTP/Cache.php
vendored
Normal file
503
includes/kohana/modules/cache/classes/Kohana/HTTP/Cache.php
vendored
Normal file
@@ -0,0 +1,503 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* HTTT Caching adaptor class that provides caching services to the
|
||||
* [Request_Client] class, using HTTP cache control logic as defined in
|
||||
* RFC 2616.
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
* @since 3.2.0
|
||||
*/
|
||||
class Kohana_HTTP_Cache {
|
||||
|
||||
const CACHE_STATUS_KEY = 'x-cache-status';
|
||||
const CACHE_STATUS_SAVED = 'SAVED';
|
||||
const CACHE_STATUS_HIT = 'HIT';
|
||||
const CACHE_STATUS_MISS = 'MISS';
|
||||
const CACHE_HIT_KEY = 'x-cache-hits';
|
||||
|
||||
/**
|
||||
* Factory method for HTTP_Cache that provides a convenient dependency
|
||||
* injector for the Cache library.
|
||||
*
|
||||
* // Create HTTP_Cache with named cache engine
|
||||
* $http_cache = HTTP_Cache::factory('memcache', array(
|
||||
* 'allow_private_cache' => FALSE
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* // Create HTTP_Cache with supplied cache engine
|
||||
* $http_cache = HTTP_Cache::factory(Cache::instance('memcache'),
|
||||
* array(
|
||||
* 'allow_private_cache' => FALSE
|
||||
* )
|
||||
* );
|
||||
*
|
||||
* @uses [Cache]
|
||||
* @param mixed $cache cache engine to use
|
||||
* @param array $options options to set to this class
|
||||
* @return HTTP_Cache
|
||||
*/
|
||||
public static function factory($cache, array $options = array())
|
||||
{
|
||||
if ( ! $cache instanceof Cache)
|
||||
{
|
||||
$cache = Cache::instance($cache);
|
||||
}
|
||||
|
||||
$options['cache'] = $cache;
|
||||
|
||||
return new HTTP_Cache($options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Basic cache key generator that hashes the entire request and returns
|
||||
* it. This is fine for static content, or dynamic content where user
|
||||
* specific information is encoded into the request.
|
||||
*
|
||||
* // Generate cache key
|
||||
* $cache_key = HTTP_Cache::basic_cache_key_generator($request);
|
||||
*
|
||||
* @param Request $request
|
||||
* @return string
|
||||
*/
|
||||
public static function basic_cache_key_generator(Request $request)
|
||||
{
|
||||
$uri = $request->uri();
|
||||
$query = $request->query();
|
||||
$headers = $request->headers()->getArrayCopy();
|
||||
$body = $request->body();
|
||||
|
||||
return sha1($uri.'?'.http_build_query($query, NULL, '&').'~'.implode('~', $headers).'~'.$body);
|
||||
}
|
||||
|
||||
/**
|
||||
* @var Cache cache driver to use for HTTP caching
|
||||
*/
|
||||
protected $_cache;
|
||||
|
||||
/**
|
||||
* @var callback Cache key generator callback
|
||||
*/
|
||||
protected $_cache_key_callback;
|
||||
|
||||
/**
|
||||
* @var boolean Defines whether this client should cache `private` cache directives
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
||||
*/
|
||||
protected $_allow_private_cache = FALSE;
|
||||
|
||||
/**
|
||||
* @var int The timestamp of the request
|
||||
*/
|
||||
protected $_request_time;
|
||||
|
||||
/**
|
||||
* @var int The timestamp of the response
|
||||
*/
|
||||
protected $_response_time;
|
||||
|
||||
/**
|
||||
* Constructor method for this class. Allows dependency injection of the
|
||||
* required components such as `Cache` and the cache key generator.
|
||||
*
|
||||
* @param array $options
|
||||
*/
|
||||
public function __construct(array $options = array())
|
||||
{
|
||||
foreach ($options as $key => $value)
|
||||
{
|
||||
if (method_exists($this, $key))
|
||||
{
|
||||
$this->$key($value);
|
||||
}
|
||||
}
|
||||
|
||||
if ($this->_cache_key_callback === NULL)
|
||||
{
|
||||
$this->cache_key_callback('HTTP_Cache::basic_cache_key_generator');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the supplied [Request] with the supplied [Request_Client].
|
||||
* Before execution, the HTTP_Cache adapter checks the request type,
|
||||
* destructive requests such as `POST`, `PUT` and `DELETE` will bypass
|
||||
* cache completely and ensure the response is not cached. All other
|
||||
* Request methods will allow caching, if the rules are met.
|
||||
*
|
||||
* @param Request_Client $client client to execute with Cache-Control
|
||||
* @param Request $request request to execute with client
|
||||
* @return [Response]
|
||||
*/
|
||||
public function execute(Request_Client $client, Request $request, Response $response)
|
||||
{
|
||||
if ( ! $this->_cache instanceof Cache)
|
||||
return $client->execute_request($request, $response);
|
||||
|
||||
// If this is a destructive request, by-pass cache completely
|
||||
if (in_array($request->method(), array(
|
||||
HTTP_Request::POST,
|
||||
HTTP_Request::PUT,
|
||||
HTTP_Request::DELETE)))
|
||||
{
|
||||
// Kill existing caches for this request
|
||||
$this->invalidate_cache($request);
|
||||
|
||||
$response = $client->execute_request($request, $response);
|
||||
|
||||
$cache_control = HTTP_Header::create_cache_control(array(
|
||||
'no-cache',
|
||||
'must-revalidate'
|
||||
));
|
||||
|
||||
// Ensure client respects destructive action
|
||||
return $response->headers('cache-control', $cache_control);
|
||||
}
|
||||
|
||||
// Create the cache key
|
||||
$cache_key = $this->create_cache_key($request, $this->_cache_key_callback);
|
||||
|
||||
// Try and return cached version
|
||||
if (($cached_response = $this->cache_response($cache_key, $request)) instanceof Response)
|
||||
return $cached_response;
|
||||
|
||||
// Start request time
|
||||
$this->_request_time = time();
|
||||
|
||||
// Execute the request with the Request client
|
||||
$response = $client->execute_request($request, $response);
|
||||
|
||||
// Stop response time
|
||||
$this->_response_time = (time() - $this->_request_time);
|
||||
|
||||
// Cache the response
|
||||
$this->cache_response($cache_key, $request, $response);
|
||||
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY,
|
||||
HTTP_Cache::CACHE_STATUS_MISS);
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate a cached response for the [Request] supplied.
|
||||
* This has the effect of deleting the response from the
|
||||
* [Cache] entry.
|
||||
*
|
||||
* @param Request $request Response to remove from cache
|
||||
* @return void
|
||||
*/
|
||||
public function invalidate_cache(Request $request)
|
||||
{
|
||||
if (($cache = $this->cache()) instanceof Cache)
|
||||
{
|
||||
$cache->delete($this->create_cache_key($request, $this->_cache_key_callback));
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Getter and setter for the internal caching engine,
|
||||
* used to cache responses if available and valid.
|
||||
*
|
||||
* @param Kohana_Cache $cache engine to use for caching
|
||||
* @return Kohana_Cache
|
||||
* @return Kohana_Request_Client
|
||||
*/
|
||||
public function cache(Cache $cache = NULL)
|
||||
{
|
||||
if ($cache === NULL)
|
||||
return $this->_cache;
|
||||
|
||||
$this->_cache = $cache;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets or sets the [Request_Client::allow_private_cache] setting.
|
||||
* If set to `TRUE`, the client will also cache cache-control directives
|
||||
* that have the `private` setting.
|
||||
*
|
||||
* @link http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
||||
* @param boolean $setting allow caching of privately marked responses
|
||||
* @return boolean
|
||||
* @return [Request_Client]
|
||||
*/
|
||||
public function allow_private_cache($setting = NULL)
|
||||
{
|
||||
if ($setting === NULL)
|
||||
return $this->_allow_private_cache;
|
||||
|
||||
$this->_allow_private_cache = (bool) $setting;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets or gets the cache key generator callback for this caching
|
||||
* class. The cache key generator provides a unique hash based on the
|
||||
* `Request` object passed to it.
|
||||
*
|
||||
* The default generator is [HTTP_Cache::basic_cache_key_generator()], which
|
||||
* serializes the entire `HTTP_Request` into a unique sha1 hash. This will
|
||||
* provide basic caching for static and simple dynamic pages. More complex
|
||||
* algorithms can be defined and then passed into `HTTP_Cache` using this
|
||||
* method.
|
||||
*
|
||||
* // Get the cache key callback
|
||||
* $callback = $http_cache->cache_key_callback();
|
||||
*
|
||||
* // Set the cache key callback
|
||||
* $http_cache->cache_key_callback('Foo::cache_key');
|
||||
*
|
||||
* // Alternatively, in PHP 5.3 use a closure
|
||||
* $http_cache->cache_key_callback(function (Request $request) {
|
||||
* return sha1($request->render());
|
||||
* });
|
||||
*
|
||||
* @param callback $callback
|
||||
* @return mixed
|
||||
* @throws HTTP_Exception
|
||||
*/
|
||||
public function cache_key_callback($callback = NULL)
|
||||
{
|
||||
if ($callback === NULL)
|
||||
return $this->_cache_key_callback;
|
||||
|
||||
if ( ! is_callable($callback))
|
||||
throw new Kohana_Exception('cache_key_callback must be callable!');
|
||||
|
||||
$this->_cache_key_callback = $callback;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a cache key for the request to use for caching
|
||||
* [Kohana_Response] returned by [Request::execute].
|
||||
*
|
||||
* This is the default cache key generating logic, but can be overridden
|
||||
* by setting [HTTP_Cache::cache_key_callback()].
|
||||
*
|
||||
* @param Request $request request to create key for
|
||||
* @param callback $callback optional callback to use instead of built-in method
|
||||
* @return string
|
||||
*/
|
||||
public function create_cache_key(Request $request, $callback = FALSE)
|
||||
{
|
||||
if (is_callable($callback))
|
||||
return call_user_func($callback, $request);
|
||||
else
|
||||
return HTTP_Cache::basic_cache_key_generator($request);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controls whether the response can be cached. Uses HTTP
|
||||
* protocol to determine whether the response can be cached.
|
||||
*
|
||||
* @link RFC 2616 http://www.w3.org/Protocols/rfc2616/
|
||||
* @param Response $response The Response
|
||||
* @return boolean
|
||||
*/
|
||||
public function set_cache(Response $response)
|
||||
{
|
||||
$headers = $response->headers()->getArrayCopy();
|
||||
|
||||
if ($cache_control = Arr::get($headers, 'cache-control'))
|
||||
{
|
||||
// Parse the cache control
|
||||
$cache_control = HTTP_Header::parse_cache_control($cache_control);
|
||||
|
||||
// If the no-cache or no-store directive is set, return
|
||||
if (array_intersect($cache_control, array('no-cache', 'no-store')))
|
||||
return FALSE;
|
||||
|
||||
// Check for private cache and get out of here if invalid
|
||||
if ( ! $this->_allow_private_cache AND in_array('private', $cache_control))
|
||||
{
|
||||
if ( ! isset($cache_control['s-maxage']))
|
||||
return FALSE;
|
||||
|
||||
// If there is a s-maxage directive we can use that
|
||||
$cache_control['max-age'] = $cache_control['s-maxage'];
|
||||
}
|
||||
|
||||
// Check that max-age has been set and if it is valid for caching
|
||||
if (isset($cache_control['max-age']) AND $cache_control['max-age'] < 1)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if ($expires = Arr::get($headers, 'expires') AND ! isset($cache_control['max-age']))
|
||||
{
|
||||
// Can't cache things that have expired already
|
||||
if (strtotime($expires) <= time())
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches a [Response] using the supplied [Cache]
|
||||
* and the key generated by [Request_Client::_create_cache_key].
|
||||
*
|
||||
* If not response is supplied, the cache will be checked for an existing
|
||||
* one that is available.
|
||||
*
|
||||
* @param string $key the cache key to use
|
||||
* @param Request $request the HTTP Request
|
||||
* @param Response $response the HTTP Response
|
||||
* @return mixed
|
||||
*/
|
||||
public function cache_response($key, Request $request, Response $response = NULL)
|
||||
{
|
||||
if ( ! $this->_cache instanceof Cache)
|
||||
return FALSE;
|
||||
|
||||
// Check for Pragma: no-cache
|
||||
if ($pragma = $request->headers('pragma'))
|
||||
{
|
||||
if ($pragma == 'no-cache')
|
||||
return FALSE;
|
||||
elseif (is_array($pragma) AND in_array('no-cache', $pragma))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// If there is no response, lookup an existing cached response
|
||||
if ($response === NULL)
|
||||
{
|
||||
$response = $this->_cache->get($key);
|
||||
|
||||
if ( ! $response instanceof Response)
|
||||
return FALSE;
|
||||
|
||||
// Do cache hit arithmetic, using fast arithmetic if available
|
||||
if ($this->_cache instanceof Cache_Arithmetic)
|
||||
{
|
||||
$hit_count = $this->_cache->increment(HTTP_Cache::CACHE_HIT_KEY.$key);
|
||||
}
|
||||
else
|
||||
{
|
||||
$hit_count = $this->_cache->get(HTTP_Cache::CACHE_HIT_KEY.$key);
|
||||
$this->_cache->set(HTTP_Cache::CACHE_HIT_KEY.$key, ++$hit_count);
|
||||
}
|
||||
|
||||
// Update the header to have correct HIT status and count
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY,
|
||||
HTTP_Cache::CACHE_STATUS_HIT)
|
||||
->headers(HTTP_Cache::CACHE_HIT_KEY, $hit_count);
|
||||
|
||||
return $response;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (($ttl = $this->cache_lifetime($response)) === FALSE)
|
||||
return FALSE;
|
||||
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY,
|
||||
HTTP_Cache::CACHE_STATUS_SAVED);
|
||||
|
||||
// Set the hit count to zero
|
||||
$this->_cache->set(HTTP_Cache::CACHE_HIT_KEY.$key, 0);
|
||||
|
||||
return $this->_cache->set($key, $response, $ttl);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total Time To Live based on the specification
|
||||
* RFC 2616 cache lifetime rules.
|
||||
*
|
||||
* @param Response $response Response to evaluate
|
||||
* @return mixed TTL value or false if the response should not be cached
|
||||
*/
|
||||
public function cache_lifetime(Response $response)
|
||||
{
|
||||
// Get out of here if this cannot be cached
|
||||
if ( ! $this->set_cache($response))
|
||||
return FALSE;
|
||||
|
||||
// Calculate apparent age
|
||||
if ($date = $response->headers('date'))
|
||||
{
|
||||
$apparent_age = max(0, $this->_response_time - strtotime($date));
|
||||
}
|
||||
else
|
||||
{
|
||||
$apparent_age = max(0, $this->_response_time);
|
||||
}
|
||||
|
||||
// Calculate corrected received age
|
||||
if ($age = $response->headers('age'))
|
||||
{
|
||||
$corrected_received_age = max($apparent_age, intval($age));
|
||||
}
|
||||
else
|
||||
{
|
||||
$corrected_received_age = $apparent_age;
|
||||
}
|
||||
|
||||
// Corrected initial age
|
||||
$corrected_initial_age = $corrected_received_age + $this->request_execution_time();
|
||||
|
||||
// Resident time
|
||||
$resident_time = time() - $this->_response_time;
|
||||
|
||||
// Current age
|
||||
$current_age = $corrected_initial_age + $resident_time;
|
||||
|
||||
// Prepare the cache freshness lifetime
|
||||
$ttl = NULL;
|
||||
|
||||
// Cache control overrides
|
||||
if ($cache_control = $response->headers('cache-control'))
|
||||
{
|
||||
// Parse the cache control header
|
||||
$cache_control = HTTP_Header::parse_cache_control($cache_control);
|
||||
|
||||
if (isset($cache_control['max-age']))
|
||||
{
|
||||
$ttl = $cache_control['max-age'];
|
||||
}
|
||||
|
||||
if (isset($cache_control['s-maxage']) AND isset($cache_control['private']) AND $this->_allow_private_cache)
|
||||
{
|
||||
$ttl = $cache_control['s-maxage'];
|
||||
}
|
||||
|
||||
if (isset($cache_control['max-stale']) AND ! isset($cache_control['must-revalidate']))
|
||||
{
|
||||
$ttl = $current_age + $cache_control['max-stale'];
|
||||
}
|
||||
}
|
||||
|
||||
// If we have a TTL at this point, return
|
||||
if ($ttl !== NULL)
|
||||
return $ttl;
|
||||
|
||||
if ($expires = $response->headers('expires'))
|
||||
return strtotime($expires) - $current_age;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration of the last request execution.
|
||||
* Either returns the time of completed requests or
|
||||
* `FALSE` if the request hasn't finished executing, or
|
||||
* is yet to be run.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function request_execution_time()
|
||||
{
|
||||
if ($this->_request_time === NULL OR $this->_response_time === NULL)
|
||||
return FALSE;
|
||||
|
||||
return $this->_response_time - $this->_request_time;
|
||||
}
|
||||
|
||||
} // End Kohana_HTTP_Cache
|
@@ -1,3 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
|
||||
class Cache_Xcache extends Kohana_Cache_Xcache {}
|
@@ -1,133 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* [Kohana Cache](api/Kohana_Cache) Eaccelerator driver. Provides an opcode based
|
||||
* driver for the Kohana Cache library.
|
||||
*
|
||||
* ### Configuration example
|
||||
*
|
||||
* Below is an example of an _eaccelerator_ server configuration.
|
||||
*
|
||||
* return array(
|
||||
* 'eaccelerator' => array( // Driver group
|
||||
* 'driver' => 'eaccelerator', // using Eaccelerator driver
|
||||
* ),
|
||||
* )
|
||||
*
|
||||
* In cases where only one cache group is required, if the group is named `default` there is
|
||||
* no need to pass the group name when instantiating a cache instance.
|
||||
*
|
||||
* #### General cache group configuration settings
|
||||
*
|
||||
* Below are the settings available to all types of cache driver.
|
||||
*
|
||||
* Name | Required | Description
|
||||
* -------------- | -------- | ---------------------------------------------------------------
|
||||
* driver | __YES__ | (_string_) The driver type to use
|
||||
*
|
||||
* ### System requirements
|
||||
*
|
||||
* * Kohana 3.0.x
|
||||
* * PHP 5.2.4 or greater
|
||||
* * Eaccelerator PHP extension
|
||||
*
|
||||
* @package Kohana/Cache
|
||||
* @category Base
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Eaccelerator extends Cache {
|
||||
|
||||
/**
|
||||
* Check for existence of the eAccelerator extension This method cannot be invoked externally. The driver must
|
||||
* be instantiated using the `Cache::instance()` method.
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
if ( ! extension_loaded('eaccelerator'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('PHP eAccelerator extension is not available.');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a cached value entry by id.
|
||||
*
|
||||
* // Retrieve cache entry from eaccelerator group
|
||||
* $data = Cache::instance('eaccelerator')->get('foo');
|
||||
*
|
||||
* // Retrieve cache entry from eaccelerator group and return 'bar' if miss
|
||||
* $data = Cache::instance('eaccelerator')->get('foo', 'bar');
|
||||
*
|
||||
* @param string id of cache to entry
|
||||
* @param string default value to return if cache miss
|
||||
* @return mixed
|
||||
* @throws Kohana_Cache_Exception
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
return (($data = eaccelerator_get($this->_sanitize_id($id))) === FALSE) ? $default : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value to cache with id and lifetime
|
||||
*
|
||||
* $data = 'bar';
|
||||
*
|
||||
* // Set 'bar' to 'foo' in eaccelerator group, using default expiry
|
||||
* Cache::instance('eaccelerator')->set('foo', $data);
|
||||
*
|
||||
* // Set 'bar' to 'foo' in eaccelerator group for 30 seconds
|
||||
* Cache::instance('eaccelerator')->set('foo', $data, 30);
|
||||
*
|
||||
* @param string id of cache entry
|
||||
* @param string data to set to cache
|
||||
* @param integer lifetime in seconds
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
{
|
||||
if ($lifetime === NULL)
|
||||
{
|
||||
$lifetime = time() + Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
return eaccelerator_put($this->_sanitize_id($id), $data, $lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
* // Delete 'foo' entry from the eaccelerator group
|
||||
* Cache::instance('eaccelerator')->delete('foo');
|
||||
*
|
||||
* @param string id to remove from cache
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return eaccelerator_rm($this->_sanitize_id($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all cache entries.
|
||||
*
|
||||
* Beware of using this method when
|
||||
* using shared memory cache systems, as it will wipe every
|
||||
* entry within the system for all clients.
|
||||
*
|
||||
* // Delete all cache entries in the eaccelerator group
|
||||
* Cache::instance('eaccelerator')->delete_all();
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete_all()
|
||||
{
|
||||
return eaccelerator_clean();
|
||||
}
|
||||
}
|
@@ -1,84 +0,0 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
/**
|
||||
* Kohana Cache Xcache Driver
|
||||
*
|
||||
* Requires Xcache
|
||||
* http://xcache.lighttpd.net/
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Cache
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2010 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_Xcache extends Cache {
|
||||
|
||||
/**
|
||||
* Check for existence of the APC extension
|
||||
*
|
||||
* @param array configuration
|
||||
* @throws Kohana_Cache_Exception
|
||||
*/
|
||||
protected function __construct(array $config)
|
||||
{
|
||||
if ( ! extension_loaded('xcache'))
|
||||
{
|
||||
throw new Kohana_Cache_Exception('PHP Xcache extension is not available.');
|
||||
}
|
||||
|
||||
parent::__construct($config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a value based on an id
|
||||
*
|
||||
* @param string id
|
||||
* @param string default [Optional] Default value to return if id not found
|
||||
* @return mixed
|
||||
*/
|
||||
public function get($id, $default = NULL)
|
||||
{
|
||||
return (($data = xcache_get($this->_sanitize_id($id))) === NULL) ? $default : $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a value based on an id. Optionally add tags.
|
||||
*
|
||||
* @param string id
|
||||
* @param string data
|
||||
* @param integer lifetime [Optional]
|
||||
* @return boolean
|
||||
*/
|
||||
public function set($id, $data, $lifetime = NULL)
|
||||
{
|
||||
if (NULL === $lifetime)
|
||||
{
|
||||
$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE);
|
||||
}
|
||||
|
||||
return xcache_set($this->_sanitize_id($id), $data, $lifetime);
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a cache entry based on id
|
||||
*
|
||||
* @param string id
|
||||
* @param integer timeout [Optional]
|
||||
* @return boolean
|
||||
*/
|
||||
public function delete($id)
|
||||
{
|
||||
return xcache_unset($this->_sanitize_id($id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all cache entries
|
||||
* To use this method xcache.admin.enable_auth has to be Off in xcache.ini
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete_all()
|
||||
{
|
||||
xcache_clear_cache(XC_TYPE_PHP, 0);
|
||||
}
|
||||
}
|
44
includes/kohana/modules/cache/config/cache.php
vendored
44
includes/kohana/modules/cache/config/cache.php
vendored
@@ -1,15 +1,12 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
return array
|
||||
(
|
||||
'memcache' => array
|
||||
(
|
||||
/* 'memcache' => array(
|
||||
'driver' => 'memcache',
|
||||
'default_expire' => 3600,
|
||||
'compression' => FALSE, // Use Zlib compression (can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
array
|
||||
(
|
||||
'servers' => array(
|
||||
'local' => array(
|
||||
'host' => 'localhost', // Memcache Server
|
||||
'port' => 11211, // Memcache port number
|
||||
'persistent' => FALSE, // Persistent connection
|
||||
@@ -21,15 +18,12 @@ return array
|
||||
),
|
||||
'instant_death' => TRUE, // Take server offline immediately on first fail (no retry)
|
||||
),
|
||||
'memcachetag' => array
|
||||
(
|
||||
'memcachetag' => array(
|
||||
'driver' => 'memcachetag',
|
||||
'default_expire' => 3600,
|
||||
'compression' => FALSE, // Use Zlib compression (can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
array
|
||||
(
|
||||
'servers' => array(
|
||||
'local' => array(
|
||||
'host' => 'localhost', // Memcache Server
|
||||
'port' => 11211, // Memcache port number
|
||||
'persistent' => FALSE, // Persistent connection
|
||||
@@ -41,36 +35,36 @@ return array
|
||||
),
|
||||
'instant_death' => TRUE,
|
||||
),
|
||||
'apc' => array
|
||||
(
|
||||
'apc' => array(
|
||||
'driver' => 'apc',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
'wincache' => array
|
||||
(
|
||||
'wincache' => array(
|
||||
'driver' => 'wincache',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
'sqlite' => array
|
||||
(
|
||||
'sqlite' => array(
|
||||
'driver' => 'sqlite',
|
||||
'default_expire' => 3600,
|
||||
'database' => APPPATH.'cache/kohana-cache.sql3',
|
||||
'schema' => 'CREATE TABLE caches(id VARCHAR(127) PRIMARY KEY, tags VARCHAR(255), expiration INTEGER, cache TEXT)',
|
||||
),
|
||||
'eaccelerator' => array
|
||||
(
|
||||
'eaccelerator' => array(
|
||||
'driver' => 'eaccelerator',
|
||||
),
|
||||
'xcache' => array
|
||||
(
|
||||
'xcache' => array(
|
||||
'driver' => 'xcache',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
'file' => array
|
||||
(
|
||||
'file' => array(
|
||||
'driver' => 'file',
|
||||
'cache_dir' => APPPATH.'cache',
|
||||
'default_expire' => 3600,
|
||||
'ignore_on_delete' => array(
|
||||
'.gitignore',
|
||||
'.git',
|
||||
'.svn'
|
||||
)
|
||||
)
|
||||
);
|
||||
*/
|
||||
);
|
||||
|
@@ -17,7 +17,7 @@ return array(
|
||||
'description' => 'Common interface for caching engines.',
|
||||
|
||||
// Copyright message, shown in the footer for this module
|
||||
'copyright' => '© 2008–2010 Kohana Team',
|
||||
'copyright' => '© 2008–2012 Kohana Team',
|
||||
)
|
||||
)
|
||||
);
|
@@ -67,7 +67,7 @@ Certain cache drivers support setting values with tags. To set a value to cache
|
||||
$memcache = Cache::instance('memcachetag');
|
||||
|
||||
// Test for tagging interface
|
||||
if ($memcache instanceof Kohana_Cache_Tagging)
|
||||
if ($memcache instanceof Cache_Tagging)
|
||||
{
|
||||
// Set a value with some tags for 30 seconds
|
||||
$memcache->set('foo', $object, 30, array('snafu', 'stfu', 'fubar'));
|
||||
@@ -79,7 +79,7 @@ Certain cache drivers support setting values with tags. To set a value to cache
|
||||
$memcache->set('foo', $object, 30);
|
||||
}
|
||||
|
||||
It is possible to implement custom tagging solutions onto existing or new cache drivers by implementing the [Kohana_Cache_Tagging] interface. Kohana_Cache only applies the interface to drivers that support tagging natively as standard.
|
||||
It is possible to implement custom tagging solutions onto existing or new cache drivers by implementing the [Cache_Tagging] interface. Kohana_Cache only applies the interface to drivers that support tagging natively as standard.
|
||||
|
||||
### Getting a value from cache
|
||||
|
||||
@@ -115,7 +115,7 @@ It is possible to retrieve values from cache grouped by tag, using the [Cache::f
|
||||
// Find values based on tag
|
||||
return $cache->find('snafu');
|
||||
}
|
||||
catch (Kohana_Cache_Exception $e)
|
||||
catch (Cache_Exception $e)
|
||||
{
|
||||
// Handle gracefully
|
||||
return FALSE;
|
||||
@@ -170,7 +170,7 @@ Some of the caching drivers support deleting by tag. This will remove all the ca
|
||||
$cache = Cache::instance();
|
||||
|
||||
// Check for tagging interface
|
||||
if ($cache instanceof Kohana_Cache_Tagging)
|
||||
if ($cache instanceof Cache_Tagging)
|
||||
{
|
||||
// Delete all entries by the tag 'snafu'
|
||||
$cache->delete_tag('snafu');
|
||||
@@ -189,7 +189,7 @@ When not automated, garbage collection is the responsibility of the developer. I
|
||||
$gc = 10;
|
||||
|
||||
// If the GC probability is a hit
|
||||
if (rand(0,99) <= $gc and $cache_file instanceof Kohana_Cache_GarbageCollect)
|
||||
if (rand(0,99) <= $gc and $cache_file instanceof Cache_GarbageCollect)
|
||||
{
|
||||
// Garbage Collect
|
||||
$cache_file->garbage_collect();
|
||||
@@ -199,10 +199,10 @@ When not automated, garbage collection is the responsibility of the developer. I
|
||||
|
||||
Kohana Cache comes with two interfaces that are implemented where the drivers support them:
|
||||
|
||||
- __[Kohana_Cache_Tagging] for tagging support on cache entries__
|
||||
- __[Cache_Tagging] for tagging support on cache entries__
|
||||
- [Cache_MemcacheTag]
|
||||
- [Cache_Sqlite]
|
||||
- __[Kohana_Cache_GarbageCollect] for garbage collection with drivers without native support__
|
||||
- __[Cache_GarbageCollect] for garbage collection with drivers without native support__
|
||||
- [Cache_File]
|
||||
- [Cache_Sqlite]
|
||||
|
||||
@@ -212,7 +212,7 @@ When using interface specific caching features, ensure that code checks for the
|
||||
$cache = Cache::instance();
|
||||
|
||||
// Test for Garbage Collection
|
||||
if ($cache instanceof Kohana_Cache_GarbageCollect)
|
||||
if ($cache instanceof Cache_GarbageCollect)
|
||||
{
|
||||
// Collect garbage
|
||||
$cache->garbage_collect();
|
||||
|
@@ -58,7 +58,7 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
(can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
array
|
||||
'local' => array
|
||||
(
|
||||
'host' => 'localhost', // Memcache Server
|
||||
'port' => 11211, // Memcache port number
|
||||
@@ -74,7 +74,7 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
(can cause issues with integers)
|
||||
'servers' => array
|
||||
(
|
||||
array
|
||||
'local' => array
|
||||
(
|
||||
'host' => 'localhost', // Memcache Server
|
||||
'port' => 11211, // Memcache port number
|
||||
@@ -102,21 +102,6 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
tags VARCHAR(255), expiration INTEGER, cache TEXT)',
|
||||
),
|
||||
|
||||
## Eaccelerator settings
|
||||
|
||||
'eaccelerator' array
|
||||
(
|
||||
'driver' => 'eaccelerator',
|
||||
),
|
||||
|
||||
## Xcache settings
|
||||
|
||||
'xcache' => array
|
||||
(
|
||||
'driver' => 'xcache',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
|
||||
## File settings
|
||||
|
||||
'file' => array
|
||||
@@ -126,6 +111,15 @@ failure_callback | __NO__ | (_[callback](http://www.php.net/manual/en/language
|
||||
'default_expire' => 3600,
|
||||
)
|
||||
|
||||
## Wincache settings
|
||||
|
||||
'wincache' => array
|
||||
(
|
||||
'driver' => 'wincache',
|
||||
'default_expire' => 3600,
|
||||
),
|
||||
|
||||
|
||||
## Override existing configuration group
|
||||
|
||||
The following example demonstrates how to override an existing configuration setting, using the config file in `/application/config/cache.php`.
|
||||
@@ -165,4 +159,4 @@ The following example demonstrates how to add a new configuration setting, using
|
||||
'driver' => 'apc', // Use Memcached as the default driver
|
||||
'default_expire' => 1000, // Overide default expiry
|
||||
)
|
||||
);
|
||||
);
|
||||
|
@@ -1,18 +1,17 @@
|
||||
# About Kohana Cache
|
||||
|
||||
[Kohana_Cache] provides a common interface to a variety of caching engines. [Kohana_Cache_Tagging] is
|
||||
[Kohana_Cache] provides a common interface to a variety of caching engines. [Cache_Tagging] is
|
||||
supported where available natively to the cache system. Kohana Cache supports multiple
|
||||
instances of cache engines through a grouped singleton pattern.
|
||||
|
||||
## Supported cache engines
|
||||
|
||||
* APC ([Cache_Apc])
|
||||
* eAccelerator ([Cache_Eaccelerator])
|
||||
* File ([Cache_File])
|
||||
* Memcached ([Cache_Memcache])
|
||||
* Memcached-tags ([Cache_Memcachetag])
|
||||
* SQLite ([Cache_Sqlite])
|
||||
* Xcache ([Cache_Xcache])
|
||||
* Wincache
|
||||
|
||||
## Introduction to caching
|
||||
|
||||
@@ -45,13 +44,12 @@ Getting and setting values to cache is very simple when using the _Kohana Cache_
|
||||
Driver | Storage | Speed | Tags | Distributed | Automatic Garbage Collection | Notes
|
||||
---------------- | ------------ | --------- | -------- | ----------- | ---------------------------- | -----------------------
|
||||
APC | __Memory__ | Excellent | No | No | Yes | Widely available PHP opcode caching solution, improves php execution performance
|
||||
eAccelerator | __Memory__ | Excellent | No | No | Yes | Limited support and no longer developed. Included for legacy systems
|
||||
Wincache | __Memory__ | Excellent | No | No | Yes | Windows variant of APC
|
||||
File | __Disk__ | Poor | No | No | No | Marginally faster than execution
|
||||
Memcache (tag) | __Memory__ | Good | No (yes) | Yes | Yes | Generally fast distributed solution, but has a speed hit due to variable network latency
|
||||
Memcache (tag) | __Memory__ | Good | No (yes) | Yes | Yes | Generally fast distributed solution, but has a speed hit due to variable network latency and serialization
|
||||
Sqlite | __Disk__ | Poor | Yes | No | No | Marginally faster than execution
|
||||
Xcache | __Memory__ | Excellent | Yes | No | Yes | Very fast memory solution and alternative to APC
|
||||
|
||||
It is possible to have hybrid cache solutions that use a combination of the engines above in different contexts. This is supported with _Kohana Cache_ as well.
|
||||
It is possible to have hybrid cache solutions that use a combination of the engines above in different contexts. This is supported with _Kohana Cache_ as well
|
||||
|
||||
## Minimum requirements
|
||||
|
||||
|
@@ -67,7 +67,7 @@ Certain cache drivers support setting values with tags. To set a value to cache
|
||||
$memcache = Cache::instance('memcachetag');
|
||||
|
||||
// Test for tagging interface
|
||||
if ($memcache instanceof Kohana_Cache_Tagging)
|
||||
if ($memcache instanceof Cache_Tagging)
|
||||
{
|
||||
// Set a value with some tags for 30 seconds
|
||||
$memcache->set('foo', $object, 30, array('snafu', 'stfu', 'fubar'));
|
||||
@@ -79,7 +79,7 @@ Certain cache drivers support setting values with tags. To set a value to cache
|
||||
$memcache->set('foo', $object, 30);
|
||||
}
|
||||
|
||||
It is possible to implement custom tagging solutions onto existing or new cache drivers by implementing the [Kohana_Cache_Tagging] interface. Kohana_Cache only applies the interface to drivers that support tagging natively as standard.
|
||||
It is possible to implement custom tagging solutions onto existing or new cache drivers by implementing the [Cache_Tagging] interface. Kohana_Cache only applies the interface to drivers that support tagging natively as standard.
|
||||
|
||||
### Getting a value from cache
|
||||
|
||||
@@ -115,7 +115,7 @@ It is possible to retrieve values from cache grouped by tag, using the [Cache::f
|
||||
// Find values based on tag
|
||||
return $cache->find('snafu');
|
||||
}
|
||||
catch (Kohana_Cache_Exception $e)
|
||||
catch (Cache_Exception $e)
|
||||
{
|
||||
// Handle gracefully
|
||||
return FALSE;
|
||||
@@ -170,7 +170,7 @@ Some of the caching drivers support deleting by tag. This will remove all the ca
|
||||
$cache = Cache::instance();
|
||||
|
||||
// Check for tagging interface
|
||||
if ($cache instanceof Kohana_Cache_Tagging)
|
||||
if ($cache instanceof Cache_Tagging)
|
||||
{
|
||||
// Delete all entries by the tag 'snafu'
|
||||
$cache->delete_tag('snafu');
|
||||
@@ -189,7 +189,7 @@ When not automated, garbage collection is the responsibility of the developer. I
|
||||
$gc = 10;
|
||||
|
||||
// If the GC probability is a hit
|
||||
if (rand(0,99) <= $gc and $cache_file instanceof Kohana_Cache_GarbageCollect)
|
||||
if (rand(0,99) <= $gc and $cache_file instanceof Cache_GarbageCollect)
|
||||
{
|
||||
// Garbage Collect
|
||||
$cache_file->garbage_collect();
|
||||
@@ -199,10 +199,10 @@ When not automated, garbage collection is the responsibility of the developer. I
|
||||
|
||||
Kohana Cache comes with two interfaces that are implemented where the drivers support them:
|
||||
|
||||
- __[Kohana_Cache_Tagging] for tagging support on cache entries__
|
||||
- __[Cache_Tagging] for tagging support on cache entries__
|
||||
- [Cache_MemcacheTag]
|
||||
- [Cache_Sqlite]
|
||||
- __[Kohana_Cache_GarbageCollect] for garbage collection with drivers without native support__
|
||||
- __[Cache_GarbageCollect] for garbage collection with drivers without native support__
|
||||
- [Cache_File]
|
||||
- [Cache_Sqlite]
|
||||
|
||||
@@ -212,7 +212,7 @@ When using interface specific caching features, ensure that code checks for the
|
||||
$cache = Cache::instance();
|
||||
|
||||
// Test for Garbage Collection
|
||||
if ($cache instanceof Kohana_Cache_GarbageCollect)
|
||||
if ($cache instanceof Cache_GarbageCollect)
|
||||
{
|
||||
// Collect garbage
|
||||
$cache->garbage_collect();
|
||||
|
299
includes/kohana/modules/cache/tests/cache/CacheBasicMethodsTest.php
vendored
Normal file
299
includes/kohana/modules/cache/tests/cache/CacheBasicMethodsTest.php
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Kohana_CacheBasicMethodsTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
/**
|
||||
* @var Cache driver for this test
|
||||
*/
|
||||
protected $_cache_driver;
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Accessor method to `$_cache_driver`.
|
||||
*
|
||||
* @return Cache
|
||||
* @return self
|
||||
*/
|
||||
public function cache(Cache $cache = NULL)
|
||||
{
|
||||
if ($cache === NULL)
|
||||
return $this->_cache_driver;
|
||||
|
||||
$this->_cache_driver = $cache;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_set_get()
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_set_get()
|
||||
{
|
||||
$object = new StdClass;
|
||||
$object->foo = 'foo';
|
||||
$object->bar = 'bar';
|
||||
|
||||
$html_text = <<<TESTTEXT
|
||||
<!doctype html>
|
||||
<head>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
TESTTEXT;
|
||||
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'id' => 'string', // Key to set to cache
|
||||
'value' => 'foobar', // Value to set to key
|
||||
'ttl' => 0, // Time to live
|
||||
'wait' => FALSE, // Test wait time to let cache expire
|
||||
'type' => 'string', // Type test
|
||||
'default' => NULL // Default value get should return
|
||||
),
|
||||
'foobar'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'integer',
|
||||
'value' => 101010,
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'integer',
|
||||
'default' => NULL
|
||||
),
|
||||
101010
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'float',
|
||||
'value' => 10.00,
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'float',
|
||||
'default' => NULL
|
||||
),
|
||||
10.00
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'array',
|
||||
'value' => array(
|
||||
'key' => 'foo',
|
||||
'value' => 'bar'
|
||||
),
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'array',
|
||||
'default' => NULL
|
||||
),
|
||||
array(
|
||||
'key' => 'foo',
|
||||
'value' => 'bar'
|
||||
)
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'boolean',
|
||||
'value' => TRUE,
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'boolean',
|
||||
'default' => NULL
|
||||
),
|
||||
TRUE
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'null',
|
||||
'value' => NULL,
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'null',
|
||||
'default' => NULL
|
||||
),
|
||||
NULL
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'object',
|
||||
'value' => $object,
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'object',
|
||||
'default' => NULL
|
||||
),
|
||||
$object
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'bar\\ with / troublesome key',
|
||||
'value' => 'foo bar snafu',
|
||||
'ttl' => 0,
|
||||
'wait' => FALSE,
|
||||
'type' => 'string',
|
||||
'default' => NULL
|
||||
),
|
||||
'foo bar snafu'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'bar',
|
||||
'value' => 'foo',
|
||||
'ttl' => 3,
|
||||
'wait' => 5,
|
||||
'type' => 'null',
|
||||
'default' => NULL
|
||||
),
|
||||
NULL
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'snafu',
|
||||
'value' => 'fubar',
|
||||
'ttl' => 3,
|
||||
'wait' => 5,
|
||||
'type' => 'string',
|
||||
'default' => 'something completely different!'
|
||||
),
|
||||
'something completely different!'
|
||||
),
|
||||
array(
|
||||
array(
|
||||
'id' => 'new line test with HTML',
|
||||
'value' => $html_text,
|
||||
'ttl' => 10,
|
||||
'wait' => FALSE,
|
||||
'type' => 'string',
|
||||
'default' => NULL,
|
||||
),
|
||||
$html_text
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::set()] method, testing;
|
||||
*
|
||||
* - The value is cached
|
||||
* - The lifetime is respected
|
||||
* - The returned value type is as expected
|
||||
* - The default not-found value is respected
|
||||
*
|
||||
* @dataProvider provider_set_get
|
||||
*
|
||||
* @param array data
|
||||
* @param mixed expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_set_get(array $data, $expected)
|
||||
{
|
||||
$cache = $this->cache();
|
||||
extract($data);
|
||||
|
||||
$this->assertTrue($cache->set($id, $value, $ttl));
|
||||
|
||||
if ($wait !== FALSE)
|
||||
{
|
||||
// Lets let the cache expire
|
||||
sleep($wait);
|
||||
}
|
||||
|
||||
$result = $cache->get($id, $default);
|
||||
$this->assertEquals($expected, $result);
|
||||
$this->assertInternalType($type, $result);
|
||||
|
||||
unset($id, $value, $ttl, $wait, $type, $default);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::delete()] method, testing;
|
||||
*
|
||||
* - The a cached value is deleted from cache
|
||||
* - The cache returns a TRUE value upon deletion
|
||||
* - The cache returns a FALSE value if no value exists to delete
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_delete()
|
||||
{
|
||||
// Init
|
||||
$cache = $this->cache();
|
||||
$cache->delete_all();
|
||||
|
||||
// Test deletion if real cached value
|
||||
if ( ! $cache->set('test_delete_1', 'This should not be here!', 0))
|
||||
{
|
||||
$this->fail('Unable to set cache value to delete!');
|
||||
}
|
||||
|
||||
// Test delete returns TRUE and check the value is gone
|
||||
$this->assertTrue($cache->delete('test_delete_1'));
|
||||
$this->assertNull($cache->get('test_delete_1'));
|
||||
|
||||
// Test non-existant cache value returns FALSE if no error
|
||||
$this->assertFalse($cache->delete('test_delete_1'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests [Cache::delete_all()] works as specified
|
||||
*
|
||||
* @return void
|
||||
* @uses Kohana_CacheBasicMethodsTest::provider_set_get()
|
||||
*/
|
||||
public function test_delete_all()
|
||||
{
|
||||
// Init
|
||||
$cache = $this->cache();
|
||||
$data = $this->provider_set_get();
|
||||
|
||||
foreach ($data as $key => $values)
|
||||
{
|
||||
extract($values[0]);
|
||||
if ( ! $cache->set($id, $value))
|
||||
{
|
||||
$this->fail('Unable to set: '.$key.' => '.$value.' to cache');
|
||||
}
|
||||
unset($id, $value, $ttl, $wait, $type, $default);
|
||||
}
|
||||
|
||||
// Test delete_all is successful
|
||||
$this->assertTrue($cache->delete_all());
|
||||
|
||||
foreach ($data as $key => $values)
|
||||
{
|
||||
// Verify data has been purged
|
||||
$this->assertSame('Cache Deleted!', $cache->get($values[0]['id'],
|
||||
'Cache Deleted!'));
|
||||
}
|
||||
}
|
||||
|
||||
} // End Kohana_CacheBasicMethodsTest
|
242
includes/kohana/modules/cache/tests/cache/CacheTest.php
vendored
Normal file
242
includes/kohana/modules/cache/tests/cache/CacheTest.php
vendored
Normal file
@@ -0,0 +1,242 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_CacheTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
const BAD_GROUP_DEFINITION = 1010;
|
||||
const EXPECT_SELF = 1001;
|
||||
|
||||
/**
|
||||
* Data provider for test_instance
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_instance()
|
||||
{
|
||||
$tmp = realpath(sys_get_temp_dir());
|
||||
|
||||
$base = array();
|
||||
|
||||
if (Kohana::$config->load('cache.file'))
|
||||
{
|
||||
$base = array(
|
||||
// Test default group
|
||||
array(
|
||||
NULL,
|
||||
Cache::instance('file')
|
||||
),
|
||||
// Test defined group
|
||||
array(
|
||||
'file',
|
||||
Cache::instance('file')
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
return array(
|
||||
// Test bad group definition
|
||||
$base+array(
|
||||
Kohana_CacheTest::BAD_GROUP_DEFINITION,
|
||||
'Failed to load Kohana Cache group: 1010'
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::factory()] method behaves as expected
|
||||
*
|
||||
* @dataProvider provider_instance
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_instance($group, $expected)
|
||||
{
|
||||
if (in_array($group, array(
|
||||
Kohana_CacheTest::BAD_GROUP_DEFINITION,
|
||||
)
|
||||
))
|
||||
{
|
||||
$this->setExpectedException('Cache_Exception');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$cache = Cache::instance($group);
|
||||
}
|
||||
catch (Cache_Exception $e)
|
||||
{
|
||||
$this->assertSame($expected, $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->assertInstanceOf(get_class($expected), $cache);
|
||||
$this->assertSame($expected->config(), $cache->config());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that `clone($cache)` will be prevented to maintain singleton
|
||||
*
|
||||
* @return void
|
||||
* @expectedException Cache_Exception
|
||||
*/
|
||||
public function test_cloning_fails()
|
||||
{
|
||||
if ( ! Kohana::$config->load('cache.file'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load File configuration');
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$cache_clone = clone(Cache::instance('file'));
|
||||
}
|
||||
catch (Cache_Exception $e)
|
||||
{
|
||||
$this->assertSame('Cloning of Kohana_Cache objects is forbidden',
|
||||
$e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_config
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_config()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
array(
|
||||
'server' => 'otherhost',
|
||||
'port' => 5555,
|
||||
'persistent' => TRUE,
|
||||
),
|
||||
NULL,
|
||||
Kohana_CacheTest::EXPECT_SELF,
|
||||
array(
|
||||
'server' => 'otherhost',
|
||||
'port' => 5555,
|
||||
'persistent' => TRUE,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'foo',
|
||||
'bar',
|
||||
Kohana_CacheTest::EXPECT_SELF,
|
||||
array(
|
||||
'foo' => 'bar'
|
||||
)
|
||||
),
|
||||
array(
|
||||
'server',
|
||||
NULL,
|
||||
NULL,
|
||||
array()
|
||||
),
|
||||
array(
|
||||
NULL,
|
||||
NULL,
|
||||
array(),
|
||||
array()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the config method behaviour
|
||||
*
|
||||
* @dataProvider provider_config
|
||||
*
|
||||
* @param mixed key value to set or get
|
||||
* @param mixed value to set to key
|
||||
* @param mixed expected result from [Cache::config()]
|
||||
* @param array expected config within cache
|
||||
* @return void
|
||||
*/
|
||||
public function test_config($key, $value, $expected_result, array $expected_config)
|
||||
{
|
||||
$cache = $this->getMock('Cache_File', NULL, array(), '', FALSE);
|
||||
|
||||
if ($expected_result === Kohana_CacheTest::EXPECT_SELF)
|
||||
{
|
||||
$expected_result = $cache;
|
||||
}
|
||||
|
||||
$this->assertSame($expected_result, $cache->config($key, $value));
|
||||
$this->assertSame($expected_config, $cache->config());
|
||||
}
|
||||
|
||||
/**
|
||||
* Data provider for test_sanitize_id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_sanitize_id()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'foo',
|
||||
'foo'
|
||||
),
|
||||
array(
|
||||
'foo+-!@',
|
||||
'foo+-!@'
|
||||
),
|
||||
array(
|
||||
'foo/bar',
|
||||
'foo_bar',
|
||||
),
|
||||
array(
|
||||
'foo\\bar',
|
||||
'foo_bar'
|
||||
),
|
||||
array(
|
||||
'foo bar',
|
||||
'foo_bar'
|
||||
),
|
||||
array(
|
||||
'foo\\bar snafu/stfu',
|
||||
'foo_bar_snafu_stfu'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::_sanitize_id()] method works as expected.
|
||||
* This uses some nasty reflection techniques to access a protected
|
||||
* method.
|
||||
*
|
||||
* @dataProvider provider_sanitize_id
|
||||
*
|
||||
* @param string id
|
||||
* @param string expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_sanitize_id($id, $expected)
|
||||
{
|
||||
$cache = $this->getMock('Cache', array(
|
||||
'get',
|
||||
'set',
|
||||
'delete',
|
||||
'delete_all'
|
||||
), array(array()),
|
||||
'', FALSE
|
||||
);
|
||||
|
||||
$cache_reflection = new ReflectionClass($cache);
|
||||
$sanitize_id = $cache_reflection->getMethod('_sanitize_id');
|
||||
$sanitize_id->setAccessible(TRUE);
|
||||
|
||||
$this->assertSame($expected, $sanitize_id->invoke($cache, $id));
|
||||
}
|
||||
} // End Kohana_CacheTest
|
98
includes/kohana/modules/cache/tests/cache/FileTest.php
vendored
Normal file
98
includes/kohana/modules/cache/tests/cache/FileTest.php
vendored
Normal file
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_Cache_FileTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! Kohana::$config->load('cache.file'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load File configuration');
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('file'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that ignored files are not removed from file cache
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_ignore_delete_file()
|
||||
{
|
||||
$cache = $this->cache();
|
||||
$config = Kohana::$config->load('cache')->file;
|
||||
$file = $config['cache_dir'].'/.gitignore';
|
||||
|
||||
// Lets pollute the cache folder
|
||||
file_put_contents($file, 'foobar');
|
||||
|
||||
$this->assertTrue($cache->delete_all());
|
||||
$this->assertTrue(file_exists($file));
|
||||
$this->assertEquals('foobar', file_get_contents($file));
|
||||
|
||||
unlink($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_utf8
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_utf8()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
'This is â ütf-8 Ӝ☃ string',
|
||||
'This is â ütf-8 Ӝ☃ string'
|
||||
),
|
||||
array(
|
||||
'㆓㆕㆙㆛',
|
||||
'㆓㆕㆙㆛'
|
||||
),
|
||||
array(
|
||||
'அஆஇஈஊ',
|
||||
'அஆஇஈஊ'
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the file driver supports utf-8 strings
|
||||
*
|
||||
* @dataProvider provider_utf8
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_utf8($input, $expected)
|
||||
{
|
||||
$cache = $this->cache();
|
||||
$cache->set('utf8', $input);
|
||||
|
||||
$this->assertSame($expected, $cache->get('utf8'));
|
||||
}
|
||||
|
||||
} // End Kohana_SqliteTest
|
@@ -1,91 +0,0 @@
|
||||
<?php
|
||||
|
||||
class KohanaCacheTest extends PHPUnit_Framework_TestCase {
|
||||
|
||||
static protected $test_instance;
|
||||
|
||||
public function setUp()
|
||||
{
|
||||
self::$test_instance = Cache::instance('file');
|
||||
self::$test_instance->delete_all();
|
||||
|
||||
self::$test_instance->set('testGet1', 'foo', 3600);
|
||||
}
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
self::$test_instance->delete_all();
|
||||
self::$test_instance = NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the cache static instance method
|
||||
*/
|
||||
public function testInstance()
|
||||
{
|
||||
$file_instance = Cache::instance('file');
|
||||
$file_instance2 = Cache::instance('file');
|
||||
|
||||
// Try and load a Cache instance
|
||||
$this->assertType('Kohana_Cache', Cache::instance());
|
||||
$this->assertType('Kohana_Cache_File', $file_instance);
|
||||
|
||||
// Test instances are only initialised once
|
||||
$this->assertTrue(spl_object_hash($file_instance) == spl_object_hash($file_instance2));
|
||||
|
||||
// Test the publically accessible Cache instance store
|
||||
$this->assertTrue(spl_object_hash(Cache::$instances['file']) == spl_object_hash($file_instance));
|
||||
|
||||
// Get the constructor method
|
||||
$constructorMethod = new ReflectionMethod($file_instance, '__construct');
|
||||
|
||||
// Test the constructor for hidden visibility
|
||||
$this->assertTrue($constructorMethod->isProtected(), '__construct is does not have protected visibility');
|
||||
}
|
||||
|
||||
public function testGet()
|
||||
{
|
||||
// Try and get a non property
|
||||
$this->assertNull(self::$test_instance->get('testGet0'));
|
||||
|
||||
// Try and get a non property with default return value
|
||||
$this->assertEquals('bar', self::$test_instance->get('testGet0', 'bar'));
|
||||
|
||||
// Try and get a real cached property
|
||||
$this->assertEquals('foo', self::$test_instance->get('testGet1'));
|
||||
}
|
||||
|
||||
public function testSet()
|
||||
{
|
||||
$value = 'foobar';
|
||||
$value2 = 'snafu';
|
||||
|
||||
// Set a new property
|
||||
$this->assertTrue(self::$test_instance->set('testSet1', $value));
|
||||
|
||||
// Test the property exists
|
||||
$this->assertEquals(self::$test_instance->get('testSet1'), $value);
|
||||
|
||||
// Test short set
|
||||
$this->assertTrue(self::$test_instance->set('testSet2', $value2, 3));
|
||||
|
||||
// Test the property exists
|
||||
$this->assertEquals(self::$test_instance->get('testSet2'), $value2);
|
||||
|
||||
// Allow test2 to expire
|
||||
sleep(4);
|
||||
|
||||
// Test the property has expired
|
||||
$this->assertNull(self::$test_instance->get('testSet2'));
|
||||
}
|
||||
|
||||
public function testDelete()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public function testDeleteAll()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
44
includes/kohana/modules/cache/tests/cache/SqliteTest.php
vendored
Normal file
44
includes/kohana/modules/cache/tests/cache/SqliteTest.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_SqliteTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('pdo_sqlite'))
|
||||
{
|
||||
$this->markTestSkipped('SQLite PDO PHP Extension is not available');
|
||||
}
|
||||
|
||||
if ( ! Kohana::$config->load('cache.sqlite'))
|
||||
{
|
||||
$this->markTestIncomplete('Unable to load sqlite configuration');
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('sqlite'));
|
||||
}
|
||||
|
||||
} // End Kohana_SqliteTest
|
39
includes/kohana/modules/cache/tests/cache/WincacheTest.php
vendored
Normal file
39
includes/kohana/modules/cache/tests/cache/WincacheTest.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_WincacheTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('wincache'))
|
||||
{
|
||||
$this->markTestSkipped('Wincache PHP Extension is not available');
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('wincache'));
|
||||
}
|
||||
|
||||
} // End Kohana_WincacheTest
|
75
includes/kohana/modules/cache/tests/cache/arithmetic/ApcTest.php
vendored
Normal file
75
includes/kohana/modules/cache/tests/cache/arithmetic/ApcTest.php
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache/arithmetic', 'CacheArithmeticMethods'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_ApcTest extends Kohana_CacheArithmeticMethodsTest {
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('apc'))
|
||||
{
|
||||
$this->markTestSkipped('APC PHP Extension is not available');
|
||||
}
|
||||
|
||||
if (ini_get('apc.enable_cli') != '1')
|
||||
{
|
||||
$this->markTestSkipped('Unable to test APC in CLI mode. To fix '.
|
||||
'place "apc.enable_cli=1" in your php.ini file');
|
||||
}
|
||||
|
||||
$this->cache(Cache::instance('apc'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the [Cache::set()] method, testing;
|
||||
*
|
||||
* - The value is cached
|
||||
* - The lifetime is respected
|
||||
* - The returned value type is as expected
|
||||
* - The default not-found value is respected
|
||||
*
|
||||
* This test doesn't test the TTL as there is a known bug/feature
|
||||
* in APC that prevents the same request from killing cache on timeout.
|
||||
*
|
||||
* @link http://pecl.php.net/bugs/bug.php?id=16814
|
||||
*
|
||||
* @dataProvider provider_set_get
|
||||
*
|
||||
* @param array data
|
||||
* @param mixed expected
|
||||
* @return void
|
||||
*/
|
||||
public function test_set_get(array $data, $expected)
|
||||
{
|
||||
if ($data['wait'] !== FALSE)
|
||||
{
|
||||
$this->markTestSkipped('Unable to perform TTL test in CLI, see: '.
|
||||
'http://pecl.php.net/bugs/bug.php?id=16814 for more info!');
|
||||
}
|
||||
|
||||
parent::test_set_get($data, $expected);
|
||||
}
|
||||
|
||||
} // End Kohana_ApcTest
|
173
includes/kohana/modules/cache/tests/cache/arithmetic/CacheArithmeticMethods.php
vendored
Normal file
173
includes/kohana/modules/cache/tests/cache/arithmetic/CacheArithmeticMethods.php
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache', 'CacheBasicMethodsTest'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache/Memcache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
abstract class Kohana_CacheArithmeticMethodsTest extends Kohana_CacheBasicMethodsTest {
|
||||
|
||||
public function tearDown()
|
||||
{
|
||||
parent::tearDown();
|
||||
|
||||
// Cleanup
|
||||
$cache = $this->cache();
|
||||
|
||||
if ($cache instanceof Cache)
|
||||
{
|
||||
$cache->delete_all();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_increment
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_increment()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
0,
|
||||
array(
|
||||
'id' => 'increment_test_1',
|
||||
'step' => 1
|
||||
),
|
||||
1
|
||||
),
|
||||
array(
|
||||
1,
|
||||
array(
|
||||
'id' => 'increment_test_2',
|
||||
'step' => 1
|
||||
),
|
||||
2
|
||||
),
|
||||
array(
|
||||
5,
|
||||
array(
|
||||
'id' => 'increment_test_3',
|
||||
'step' => 5
|
||||
),
|
||||
10
|
||||
),
|
||||
array(
|
||||
NULL,
|
||||
array(
|
||||
'id' => 'increment_test_4',
|
||||
'step' => 1
|
||||
),
|
||||
FALSE
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test for [Cache_Arithmetic::increment()]
|
||||
*
|
||||
* @dataProvider provider_increment
|
||||
*
|
||||
* @param integer start state
|
||||
* @param array increment arguments
|
||||
* @return void
|
||||
*/
|
||||
public function test_increment(
|
||||
$start_state = NULL,
|
||||
array $inc_args,
|
||||
$expected)
|
||||
{
|
||||
$cache = $this->cache();
|
||||
|
||||
if ($start_state !== NULL)
|
||||
{
|
||||
$cache->set($inc_args['id'], $start_state, 0);
|
||||
}
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$cache->increment(
|
||||
$inc_args['id'],
|
||||
$inc_args['step']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Provider for test_decrement
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_decrement()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
10,
|
||||
array(
|
||||
'id' => 'decrement_test_1',
|
||||
'step' => 1
|
||||
),
|
||||
9
|
||||
),
|
||||
array(
|
||||
10,
|
||||
array(
|
||||
'id' => 'decrement_test_2',
|
||||
'step' => 2
|
||||
),
|
||||
8
|
||||
),
|
||||
array(
|
||||
50,
|
||||
array(
|
||||
'id' => 'decrement_test_3',
|
||||
'step' => 5
|
||||
),
|
||||
45
|
||||
),
|
||||
array(
|
||||
NULL,
|
||||
array(
|
||||
'id' => 'decrement_test_4',
|
||||
'step' => 1
|
||||
),
|
||||
FALSE
|
||||
),
|
||||
); }
|
||||
|
||||
/**
|
||||
* Test for [Cache_Arithmetic::decrement()]
|
||||
*
|
||||
* @dataProvider provider_decrement
|
||||
*
|
||||
* @param integer start state
|
||||
* @param array decrement arguments
|
||||
* @return void
|
||||
*/
|
||||
public function test_decrement(
|
||||
$start_state = NULL,
|
||||
array $dec_args,
|
||||
$expected)
|
||||
{
|
||||
$cache = $this->cache();
|
||||
|
||||
if ($start_state !== NULL)
|
||||
{
|
||||
$cache->set($dec_args['id'], $start_state, 0);
|
||||
}
|
||||
|
||||
$this->assertSame(
|
||||
$expected,
|
||||
$cache->decrement(
|
||||
$dec_args['id'],
|
||||
$dec_args['step']
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
} // End Kohana_CacheArithmeticMethodsTest
|
103
includes/kohana/modules/cache/tests/cache/arithmetic/MemcacheTest.php
vendored
Normal file
103
includes/kohana/modules/cache/tests/cache/arithmetic/MemcacheTest.php
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
include_once(Kohana::find_file('tests/cache/arithmetic', 'CacheArithmeticMethods'));
|
||||
|
||||
/**
|
||||
* @package Kohana/Cache/Memcache
|
||||
* @group kohana
|
||||
* @group kohana.cache
|
||||
* @category Test
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2009-2012 Kohana Team
|
||||
* @license http://kohanaphp.com/license
|
||||
*/
|
||||
class Kohana_CacheArithmeticMemcacheTest extends Kohana_CacheArithmeticMethodsTest {
|
||||
|
||||
|
||||
/**
|
||||
* This method MUST be implemented by each driver to setup the `Cache`
|
||||
* instance for each test.
|
||||
*
|
||||
* This method should do the following tasks for each driver test:
|
||||
*
|
||||
* - Test the Cache instance driver is available, skip test otherwise
|
||||
* - Setup the Cache instance
|
||||
* - Call the parent setup method, `parent::setUp()`
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
parent::setUp();
|
||||
|
||||
if ( ! extension_loaded('memcache'))
|
||||
{
|
||||
$this->markTestSkipped('Memcache PHP Extension is not available');
|
||||
}
|
||||
if ( ! $config = Kohana::$config->load('cache.memcache'))
|
||||
{
|
||||
$this->markTestSkipped('Unable to load Memcache configuration');
|
||||
}
|
||||
|
||||
$memcache = new Memcache;
|
||||
if ( ! $memcache->connect($config['servers']['local']['host'],
|
||||
$config['servers']['local']['port']))
|
||||
{
|
||||
$this->markTestSkipped('Unable to connect to memcache server @ '.
|
||||
$config['servers']['local']['host'].':'.
|
||||
$config['servers']['local']['port']);
|
||||
}
|
||||
|
||||
if ($memcache->getVersion() === FALSE)
|
||||
{
|
||||
$this->markTestSkipped('Memcache server @ '.
|
||||
$config['servers']['local']['host'].':'.
|
||||
$config['servers']['local']['port'].
|
||||
' not responding!');
|
||||
}
|
||||
|
||||
unset($memcache);
|
||||
|
||||
$this->cache(Cache::instance('memcache'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that multiple values set with Memcache do not cause unexpected
|
||||
* results. For accurate results, this should be run with a memcache
|
||||
* configuration that includes multiple servers.
|
||||
*
|
||||
* This is to test #4110
|
||||
*
|
||||
* @link http://dev.kohanaframework.org/issues/4110
|
||||
* @return void
|
||||
*/
|
||||
public function test_multiple_set()
|
||||
{
|
||||
$cache = $this->cache();
|
||||
$id_set = 'set_id';
|
||||
$ttl = 300;
|
||||
|
||||
$data = array(
|
||||
'foobar',
|
||||
0,
|
||||
1.0,
|
||||
new stdClass,
|
||||
array('foo', 'bar' => 1),
|
||||
TRUE,
|
||||
NULL,
|
||||
FALSE
|
||||
);
|
||||
|
||||
$previous_set = $cache->get($id_set, NULL);
|
||||
|
||||
foreach ($data as $value)
|
||||
{
|
||||
// Use Equals over Sames as Objects will not be equal
|
||||
$this->assertEquals($previous_set, $cache->get($id_set, NULL));
|
||||
$cache->set($id_set, $value, $ttl);
|
||||
|
||||
$previous_set = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // End Kohana_CacheArithmeticMemcacheTest
|
265
includes/kohana/modules/cache/tests/cache/request/client/CacheTest.php
vendored
Normal file
265
includes/kohana/modules/cache/tests/cache/request/client/CacheTest.php
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
<?php defined('SYSPATH') OR die('Kohana bootstrap needs to be included before tests run');
|
||||
/**
|
||||
* Unit tests for request client cache logic
|
||||
*
|
||||
* @group kohana
|
||||
* @group kohana.request
|
||||
* @group kohana.request.client
|
||||
* @group kohana.request.client.cache
|
||||
*
|
||||
* @package Kohana
|
||||
* @category Tests
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2008-2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Kohana_Request_Client_CacheTest extends Unittest_TestCase {
|
||||
|
||||
/**
|
||||
* Sets up a test route for caching
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function setUp()
|
||||
{
|
||||
Route::set('welcome', 'welcome/index')
|
||||
->defaults(array(
|
||||
'controller' => 'welcome',
|
||||
'action' => 'index'
|
||||
));
|
||||
|
||||
parent::setUp();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the Client does not attempt to load cache if no Cache library
|
||||
* is present
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_cache_not_called_with_no_cache()
|
||||
{
|
||||
$request = new Request('welcome/index');
|
||||
$response = new Response;
|
||||
|
||||
$client_mock = $this->getMock('Request_Client_Internal');
|
||||
|
||||
$request->client($client_mock);
|
||||
$client_mock->expects($this->exactly(0))
|
||||
->method('execute_request');
|
||||
$client_mock->expects($this->once())
|
||||
->method('execute')
|
||||
->will($this->returnValue($response));
|
||||
|
||||
$this->assertSame($response, $request->execute());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the client attempts to load a cached response from the
|
||||
* cache library, but fails.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_cache_miss()
|
||||
{
|
||||
$route = new Route('welcome/index');
|
||||
$route->defaults(array(
|
||||
'controller' => 'Kohana_Request_CacheTest_Dummy',
|
||||
'action' => 'index',
|
||||
));
|
||||
|
||||
$request = new Request('welcome/index', NULL, array($route));
|
||||
$cache_mock = $this->_get_cache_mock();
|
||||
|
||||
$request->client()->cache(HTTP_Cache::factory($cache_mock));
|
||||
|
||||
$cache_mock->expects($this->once())
|
||||
->method('get')
|
||||
->with($request->client()->cache()->create_cache_key($request))
|
||||
->will($this->returnValue(FALSE));
|
||||
|
||||
$response = $request->client()->execute($request);
|
||||
|
||||
$this->assertSame(HTTP_Cache::CACHE_STATUS_MISS,
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the client saves a response if the correct headers are set
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_cache_save()
|
||||
{
|
||||
$lifetime = 800;
|
||||
$request = new Request('welcome/index');
|
||||
$cache_mock = $this->_get_cache_mock();
|
||||
$response = Response::factory();
|
||||
|
||||
$request->client()->cache(new HTTP_Cache(array(
|
||||
'cache' => $cache_mock
|
||||
)
|
||||
));
|
||||
|
||||
$response->headers('cache-control', 'max-age='.$lifetime);
|
||||
|
||||
$key = $request->client()->cache()->create_cache_key($request);
|
||||
|
||||
$cache_mock->expects($this->at(0))
|
||||
->method('set')
|
||||
->with($this->stringEndsWith($key), $this->identicalTo(0));
|
||||
|
||||
$cache_mock->expects($this->at(1))
|
||||
->method('set')
|
||||
->with($this->identicalTo($key), $this->anything(), $this->identicalTo($lifetime))
|
||||
->will($this->returnValue(TRUE));
|
||||
|
||||
$this->assertTrue(
|
||||
$request->client()->cache()
|
||||
->cache_response($key, $request, $response)
|
||||
);
|
||||
|
||||
$this->assertSame(HTTP_Cache::CACHE_STATUS_SAVED,
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the client handles a cache HIT event correctly
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function test_cache_hit()
|
||||
{
|
||||
$lifetime = 800;
|
||||
$request = new Request('welcome/index');
|
||||
$cache_mock = $this->_get_cache_mock();
|
||||
|
||||
$request->client()->cache(new HTTP_Cache(array(
|
||||
'cache' => $cache_mock
|
||||
)
|
||||
));
|
||||
|
||||
$response = Response::factory();
|
||||
|
||||
$response->headers(array(
|
||||
'cache-control' => 'max-age='.$lifetime,
|
||||
HTTP_Cache::CACHE_STATUS_KEY =>
|
||||
HTTP_Cache::CACHE_STATUS_HIT
|
||||
));
|
||||
|
||||
$key = $request->client()->cache()->create_cache_key($request);
|
||||
|
||||
$cache_mock->expects($this->exactly(2))
|
||||
->method('get')
|
||||
->with($this->stringContains($key))
|
||||
->will($this->returnValue($response));
|
||||
|
||||
$request->client()->cache()->cache_response($key, $request);
|
||||
|
||||
$this->assertSame(HTTP_Cache::CACHE_STATUS_HIT,
|
||||
$response->headers(HTTP_Cache::CACHE_STATUS_KEY));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Data provider for test_set_cache
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function provider_set_cache()
|
||||
{
|
||||
return array(
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'no-cache')),
|
||||
array('no-cache' => NULL),
|
||||
FALSE,
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'no-store')),
|
||||
array('no-store' => NULL),
|
||||
FALSE,
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'max-age=100')),
|
||||
array('max-age' => '100'),
|
||||
TRUE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'private')),
|
||||
array('private' => NULL),
|
||||
FALSE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'private, max-age=100')),
|
||||
array('private' => NULL, 'max-age' => '100'),
|
||||
FALSE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array('cache-control' => 'private, s-maxage=100')),
|
||||
array('private' => NULL, 's-maxage' => '100'),
|
||||
TRUE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array(
|
||||
'expires' => date('m/d/Y', strtotime('-1 day')),
|
||||
)),
|
||||
array(),
|
||||
FALSE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array(
|
||||
'expires' => date('m/d/Y', strtotime('+1 day')),
|
||||
)),
|
||||
array(),
|
||||
TRUE
|
||||
),
|
||||
array(
|
||||
new HTTP_Header(array()),
|
||||
array(),
|
||||
TRUE
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the set_cache() method
|
||||
*
|
||||
* @test
|
||||
* @dataProvider provider_set_cache
|
||||
*
|
||||
* @return null
|
||||
*/
|
||||
public function test_set_cache($headers, $cache_control, $expected)
|
||||
{
|
||||
/**
|
||||
* Set up a mock response object to test with
|
||||
*/
|
||||
$response = $this->getMock('Response');
|
||||
|
||||
$response->expects($this->any())
|
||||
->method('headers')
|
||||
->will($this->returnValue($headers));
|
||||
|
||||
$request = new Request_Client_Internal;
|
||||
$request->cache(new HTTP_Cache);
|
||||
$this->assertEquals($request->cache()->set_cache($response), $expected);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mock object for Cache
|
||||
*
|
||||
* @return Cache
|
||||
*/
|
||||
protected function _get_cache_mock()
|
||||
{
|
||||
return $this->getMock('Cache_File', array(), array(), '', FALSE);
|
||||
}
|
||||
} // End Kohana_Request_Client_CacheTest
|
||||
|
||||
class Controller_Kohana_Request_CacheTest_Dummy extends Controller
|
||||
{
|
||||
public function action_index()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
@@ -7,7 +7,10 @@
|
||||
|
||||
Any options you specify when calling phpunit will override the ones in here
|
||||
-->
|
||||
<phpunit colors="true" bootstrap="../../../articles/public/index.php">
|
||||
<php>
|
||||
<includePath>./cache</includePath>
|
||||
</php>
|
||||
<phpunit colors="true" bootstrap="/path/to/your/unittest/bootstrap.php">
|
||||
<testsuites>
|
||||
<testsuite name="Kohana Cache Tests">
|
||||
<directory suffix=".php">cache/</directory>
|
||||
|
@@ -13,12 +13,14 @@ class Controller_Codebench extends Kohana_Controller_Template {
|
||||
// The codebench view
|
||||
public $template = 'codebench';
|
||||
|
||||
public function action_index($class)
|
||||
public function action_index()
|
||||
{
|
||||
$class = $this->request->param('class');
|
||||
|
||||
// Convert submitted class name to URI segment
|
||||
if (isset($_POST['class']))
|
||||
{
|
||||
$this->request->redirect('codebench/'.trim($_POST['class']));
|
||||
throw HTTP_Exception::factory(302)->location('codebench/'.trim($_POST['class']));
|
||||
}
|
||||
|
||||
// Pass the class name on to the view
|
@@ -47,7 +47,7 @@ abstract class Kohana_Codebench {
|
||||
public function __construct()
|
||||
{
|
||||
// Set the maximum execution time
|
||||
set_time_limit(Kohana::config('codebench')->max_execution_time);
|
||||
set_time_limit(Kohana::$config->load('codebench')->max_execution_time);
|
||||
}
|
||||
|
||||
/**
|
@@ -17,7 +17,7 @@ return array(
|
||||
'description' => 'Code benchmarking tool.',
|
||||
|
||||
// Copyright message, shown in the footer for this module
|
||||
'copyright' => '© 2008–2010 Kohana Team',
|
||||
'copyright' => '© 2008–2012 Kohana Team',
|
||||
)
|
||||
)
|
||||
);
|
@@ -3,6 +3,6 @@
|
||||
// Catch-all route for Codebench classes to run
|
||||
Route::set('codebench', 'codebench(/<class>)')
|
||||
->defaults(array(
|
||||
'controller' => 'codebench',
|
||||
'controller' => 'Codebench',
|
||||
'action' => 'index',
|
||||
'class' => NULL));
|
||||
|
@@ -111,7 +111,7 @@
|
||||
}
|
||||
});
|
||||
|
||||
<?php if (Kohana::config('codebench')->expand_all) { ?>
|
||||
<?php if (Kohana::$config->load('codebench')->expand_all) { ?>
|
||||
// Expand all benchmark details by default
|
||||
$toggle_all.click();
|
||||
<?php } ?>
|
||||
@@ -245,7 +245,7 @@
|
||||
<?php echo Text::auto_p(Text::auto_link($codebench['description']), FALSE) ?>
|
||||
<?php } ?>
|
||||
|
||||
<?php // echo '<h2>Raw output:</h2>', Kohana::debug($codebench) ?>
|
||||
<?php // echo '<h2>Raw output:</h2>', Debug::vars($codebench) ?>
|
||||
|
||||
<?php } ?>
|
||||
|
||||
|
12
includes/kohana/modules/database/classes/Config/Database.php
Normal file
12
includes/kohana/modules/database/classes/Config/Database.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Transparent extension for the Kohana_Config_Database class
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Config_Database extends Kohana_Config_Database {}
|
@@ -0,0 +1,15 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Transparent extension of the Kohana_Config_Database_Reader class
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Config_Database_Reader extends Kohana_Config_Database_Reader
|
||||
{
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
/**
|
||||
* Transparent extension for the Kohana_Config_Database_Writer class
|
||||
*
|
||||
* @package Kohana/Database
|
||||
* @category Configuration
|
||||
* @author Kohana Team
|
||||
* @copyright (c) 2012 Kohana Team
|
||||
* @license http://kohanaframework.org/license
|
||||
*/
|
||||
class Config_Database_Writer extends Kohana_Config_Database_Writer
|
||||
{
|
||||
|
||||
}
|
3
includes/kohana/modules/database/classes/DB.php
Normal file
3
includes/kohana/modules/database/classes/DB.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class DB extends Kohana_DB {}
|
3
includes/kohana/modules/database/classes/Database.php
Normal file
3
includes/kohana/modules/database/classes/Database.php
Normal file
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
abstract class Database extends Kohana_Database {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Exception extends Kohana_Database_Exception {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Expression extends Kohana_Database_Expression {}
|
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_MySQL extends Kohana_Database_MySQL {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_MySQL_Result extends Kohana_Database_MySQL_Result {}
|
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_PDO extends Kohana_Database_PDO {}
|
@@ -0,0 +1,3 @@
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Query extends Kohana_Database_Query {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
abstract class Database_Query_Builder extends Kohana_Database_Query_Builder {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Query_Builder_Delete extends Kohana_Database_Query_Builder_Delete {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Query_Builder_Insert extends Kohana_Database_Query_Builder_Insert {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Query_Builder_Join extends Kohana_Database_Query_Builder_Join {}
|
@@ -1,3 +1,3 @@
|
||||
<?php defined('SYSPATH') or die('No direct script access.');
|
||||
<?php defined('SYSPATH') OR die('No direct script access.');
|
||||
|
||||
class Database_Query_Builder_Select extends Kohana_Database_Query_Builder_Select {}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user