@@ -0,0 +1,3 @@ | |||
service_name: travis-ci | |||
coverage_clover: build/logs/clover.xml | |||
json_path: build/logs/coveralls-upload.json |
@@ -0,0 +1,17 @@ | |||
# Project files | |||
.idea | |||
nbproject | |||
*.iml | |||
out | |||
gen | |||
# Kohana template | |||
application/cache/* | |||
application/logs/* | |||
# Composer | |||
/vendor/ | |||
composer.lock | |||
# Coverage reports | |||
/build/logs/ |
@@ -0,0 +1,19 @@ | |||
dist: trusty | |||
language: php | |||
php: | |||
- 7.0 | |||
- 7.1 | |||
- 7.2 | |||
before_script: | |||
- composer install | |||
script: | |||
- vendor/bin/phpunit | |||
after_success: | |||
- travis_retry vendor/bin/php-coveralls | |||
notifications: | |||
email: false |
@@ -0,0 +1,175 @@ | |||
<?php | |||
// -- Environment setup -------------------------------------------------------- | |||
// Load the core Kohana class | |||
require SYSPATH.'classes/Kohana/Core'.EXT; | |||
if (is_file(APPPATH.'classes/Kohana'.EXT)) | |||
{ | |||
// Application extends the core | |||
require APPPATH.'classes/Kohana'.EXT; | |||
} | |||
else | |||
{ | |||
// Load empty core extension | |||
require SYSPATH.'classes/Kohana'.EXT; | |||
} | |||
/** | |||
* Set the default time zone. | |||
* | |||
* @link http://kohanaframework.org/guide/using.configuration | |||
* @link http://www.php.net/manual/timezones | |||
*/ | |||
date_default_timezone_set('America/Chicago'); | |||
/** | |||
* Set the default locale. | |||
* | |||
* @link http://kohanaframework.org/guide/using.configuration | |||
* @link http://www.php.net/manual/function.setlocale | |||
*/ | |||
setlocale(LC_ALL, 'en_US.utf-8'); | |||
/** | |||
* Enable the Kohana auto-loader. | |||
* | |||
* @link http://kohanaframework.org/guide/using.autoloading | |||
* @link http://www.php.net/manual/function.spl-autoload-register | |||
*/ | |||
spl_autoload_register(['Kohana', 'auto_load']); | |||
/** | |||
* Optionally, you can enable a compatibility auto-loader for use with | |||
* older modules that have not been updated for PSR-0. | |||
* | |||
* It is recommended to not enable this unless absolutely necessary. | |||
*/ | |||
//spl_autoload_register(array('Kohana', 'auto_load_lowercase')); | |||
/** | |||
* Enable the Kohana auto-loader for unserialization. | |||
* | |||
* @link http://www.php.net/manual/function.spl-autoload-call | |||
* @link http://www.php.net/manual/var.configuration#unserialize-callback-func | |||
*/ | |||
ini_set('unserialize_callback_func', 'spl_autoload_call'); | |||
/** | |||
* Enable composer autoload libraries | |||
*/ | |||
if (is_file(DOCROOT.'/vendor/autoload.php')) | |||
{ | |||
require DOCROOT.'/vendor/autoload.php'; | |||
} | |||
/** | |||
* Set the mb_substitute_character to "none" | |||
* | |||
* @link http://www.php.net/manual/function.mb-substitute-character.php | |||
*/ | |||
mb_substitute_character('none'); | |||
// -- Configuration and initialization ----------------------------------------- | |||
/** | |||
* Set the default language | |||
*/ | |||
I18n::lang('en-us'); | |||
if (isset($_SERVER['SERVER_PROTOCOL'])) | |||
{ | |||
// Replace the default protocol. | |||
HTTP::$protocol = $_SERVER['SERVER_PROTOCOL']; | |||
} | |||
/** | |||
* Set Kohana::$environment if a 'KOHANA_ENV' environment variable has been supplied. | |||
* | |||
* Note: If you supply an invalid environment name, a PHP warning will be thrown | |||
* saying "Couldn't find constant Kohana::<INVALID_ENV_NAME>" | |||
*/ | |||
if (isset($_SERVER['KOHANA_ENV'])) | |||
{ | |||
Kohana::$environment = constant('Kohana::'.strtoupper($_SERVER['KOHANA_ENV'])); | |||
} | |||
/** | |||
* Initialize Kohana, setting the default options. | |||
* | |||
* The following options are available: | |||
* | |||
* - string base_url path, and optionally domain, of your application NULL | |||
* - string index_file name of your index file, usually "index.php", if set to FALSE uses clean URLS index.php | |||
* - string charset internal character set used for input and output utf-8 | |||
* - string cache_dir set the internal cache directory APPPATH/cache | |||
* - integer cache_life lifetime, in seconds, of items cached 60 | |||
* - boolean errors enable or disable error handling TRUE | |||
* - boolean profile enable or disable internal profiling TRUE | |||
* - boolean caching enable or disable internal caching FALSE | |||
* - boolean expose set the X-Powered-By header FALSE | |||
*/ | |||
Kohana::init([ | |||
'base_url' => '/', | |||
]); | |||
/** | |||
* Attach the file write to logging. Multiple writers are supported. | |||
*/ | |||
Kohana::$log->attach(new Log_File(APPPATH.'logs')); | |||
/** | |||
* Attach a file reader to config. Multiple readers are supported. | |||
*/ | |||
Kohana::$config->attach(new Config_File); | |||
/** | |||
* Enable modules. Modules are referenced by a relative or absolute path. | |||
*/ | |||
Kohana::modules([ | |||
// 'encrypt' => MODPATH.'encrypt', // Encryption supprt | |||
// 'auth' => MODPATH.'auth', // Basic authentication | |||
// 'cache' => MODPATH.'cache', // Caching with multiple backends | |||
// 'codebench' => MODPATH.'codebench', // Benchmarking tool | |||
'database' => MODPATH.'database', // Database access | |||
// 'image' => MODPATH.'image', // Image manipulation | |||
// 'minion' => MODPATH.'minion', // CLI Tasks | |||
// 'orm' => MODPATH.'orm', // Object Relationship Mapping | |||
// 'pagination' => MODPATH.'pagination', // Pagination | |||
// 'unittest' => MODPATH.'unittest', // Unit testing | |||
// 'userguide' => MODPATH.'userguide', // User guide and API documentation | |||
'twig' => MODPATH.'twig', // Twig templating engine | |||
]); | |||
/** | |||
* Cookie Salt | |||
* @see http://kohanaframework.org/3.3/guide/kohana/cookies | |||
* | |||
* If you have not defined a cookie salt in your Cookie class then | |||
* uncomment the line below and define a preferrably long salt. | |||
*/ | |||
// Cookie::$salt = NULL; | |||
/** | |||
* Cookie HttpOnly directive | |||
* If set to true, disallows cookies to be accessed from JavaScript | |||
* @see https://en.wikipedia.org/wiki/Session_hijacking | |||
*/ | |||
// Cookie::$httponly = TRUE; | |||
/** | |||
* If website runs on secure protocol HTTPS, allows cookies only to be transmitted | |||
* via HTTPS. | |||
* Warning: HSTS must also be enabled in .htaccess, otherwise first request | |||
* to http://www.example.com will still reveal this cookie | |||
*/ | |||
// Cookie::$secure = isset($_SERVER['HTTPS']) AND $_SERVER['HTTPS'] == 'on' ? TRUE : FALSE; | |||
/** | |||
* Set the routes. Each route must have a minimum of a name, a URI and a set of | |||
* defaults for the URI. | |||
*/ | |||
Route::set('default', '(<controller>(/<action>(/<id>)))') | |||
->defaults([ | |||
'controller' => 'welcome', | |||
'action' => 'index', | |||
]); |
@@ -0,0 +1 @@ | |||
[^.]* |
@@ -0,0 +1,29 @@ | |||
<?php | |||
class Controller_Welcome extends Controller_Twig { | |||
public function action_index() | |||
{ | |||
// $this->context = DB::select(DB::expr('id,name,url,login,pwd,sale_page')) | |||
// ->from('hosts') | |||
// ->where('sale_page', 'in', ['avs', 'avs5']) | |||
// ->as_object()->execute(); | |||
$this->template_name = 'index'; | |||
// $this->context->message= "hello world"; | |||
$this->context->hosts = DB::select(DB::expr('id,name,url,login,pwd,sale_page')) | |||
->from('hosts') | |||
->where('sale_page', 'in', ['avs', 'avs5']) | |||
->as_object()->execute(); | |||
// $this->response->body('hello, world!НАКОНЕЦ-ТААААААААААААААААААААААААААААААААААААААААААААААААААААААА'); | |||
} | |||
} // End Welcome |
@@ -0,0 +1 @@ | |||
@@ -0,0 +1,21 @@ | |||
<?php defined('SYSPATH') or die('No direct script access.'); | |||
/** | |||
* Its a test task class | |||
* | |||
* @author biakaveron | |||
*/ | |||
class Task_Welcome extends Minion_Task { | |||
/** | |||
* Test action | |||
* | |||
* @param array $params | |||
* @return void | |||
*/ | |||
protected function _execute(array $params) | |||
{ | |||
Minion_CLI::write('hello world!'); | |||
} | |||
} |
@@ -0,0 +1 @@ | |||
@@ -0,0 +1,41 @@ | |||
<?php defined('SYSPATH') OR die('No direct access allowed.'); | |||
return [ | |||
'data_source' => [ | |||
'type' => 'avs', // Тип источника данных avs/avs5/csv | |||
'host' => 'http://webapp.avtovokzal.ru/avs4test/', // URL для AVServer | |||
'username' => 'web_www', // Логин для AVServer | |||
'password' => 'etraffic2008', // Пароль для AVServer | |||
], | |||
// 'data_source' => [ | |||
// 'type'=>'csv', | |||
// 'file'=>DOCROOT.'var/data/mosobl_rasp.csv', | |||
// ], | |||
'home_station_id' => 6, // ID станции отправления по умолчанию | |||
'refresh_timeout' => 30, // Период обновления данных в секундах | |||
'row_limit' => 20, // Кол-во отображаемых на экране рейсов | |||
'timezone' => 'Asia/Krasnoyarsk', // Временная зона сервера | |||
// 'scroll_row_limit' => 2, // Кол-во рейсов, отображаемых на экране в режиме скроллинга | |||
// 'scroll_page_count' => 3, // Максимальное кол-во страниц, отображаемое в режиме скроллинга | |||
'running_line' => false, // нужно ли использовать бегущую строку | |||
// 'running_line' => '/var/data/ticker.html', // нужно ли использовать бегущую строку | |||
// 'template_main' => 'index', | |||
'template_main' => 'index-schelk', // Имя шаблона, используемого для отображения страницы загрузки | |||
// 'template_main' => 'index0', | |||
'template_dispatch' => 'dispatch_2', // Имя шаблона, используемого для отображения отправляющихся рейсов | |||
// 'template_dispatch' => 'dispatch', | |||
// 'template_dispatch' => 'dispatch-schelk', | |||
// 'depots' => [ | |||
// 1 => [ | |||
// 'template_main' => 'index', | |||
// 'template_dispatch' => 'dispatch', | |||
// ], | |||
// 1099 => [ | |||
// 'template_main' => 'index', | |||
// 'template_dispatch' => 'dispatch_2', | |||
// ] | |||
// ] | |||
]; | |||
@@ -0,0 +1,5 @@ | |||
<?php defined('SYSPATH') or die('No direct script access.'); | |||
return array( | |||
'trusted_hosts' => ['localhost:8000', 'timetable.local', 'monitor.local', 'timetable.e-traffic.ru'] | |||
); |
@@ -0,0 +1 @@ | |||
@@ -0,0 +1 @@ | |||
[^.]* |
@@ -0,0 +1 @@ | |||
@@ -0,0 +1,25 @@ | |||
<!doctype html> | |||
<html lang="en"> | |||
<head> | |||
<meta charset="UTF-8"> | |||
<meta name="viewport" | |||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> | |||
<meta http-equiv="X-UA-Compatible" content="ie=edge"> | |||
<title>Document</title> | |||
</head> | |||
<body> | |||
{% for host in hosts %} | |||
{{ host.name }} | |||
{{ host.id }} | |||
{{ host.url }} | |||
{{ host.login }} | |||
{{ host.pwd }} | |||
{{ host.sale_page }} | |||
{% endfor %} | |||
</body> | |||
</html> |
@@ -0,0 +1,55 @@ | |||
{ | |||
"name": "koseven/koseven", | |||
"description": "Koseven Framework - PHP-7 compatible replacement for Kohana", | |||
"license": "BSD-3-Clause", | |||
"keywords": [ | |||
"kohana", | |||
"kohana-php7", | |||
"koseven" | |||
], | |||
"homepage": "https://koseven.ga/", | |||
"authors": [ | |||
{ | |||
"name": "Koseven Team", | |||
"homepage": "https://koseven.ga/", | |||
"role": "developer" | |||
}, | |||
{ | |||
"name": "Kohana Team", | |||
"email": "team@kohanaframework.org", | |||
"homepage": "http://kohanaframework.org/team", | |||
"role": "developer" | |||
} | |||
], | |||
"support": { | |||
"forum": "https://telegram.me/koseven", | |||
"issues": "https://github.com/koseven/koseven/issues" | |||
}, | |||
"require": { | |||
"php": ">=7.0", | |||
"twig/twig": "~2.6" | |||
}, | |||
"conflict": { | |||
"kohana/core": "3.3.*" | |||
}, | |||
"replace": { | |||
"kohana/core": "3.3.*" | |||
}, | |||
"scripts": { | |||
"post-autoload-dump": [ | |||
"@createVar" | |||
], | |||
"createVar" : [ | |||
"mkdir -p var/", | |||
"mkdir -p var/cache/", | |||
"mkdir -p var/logs/", | |||
"mkdir -p var/twig/", | |||
"chmod 777 var/cache/", | |||
"chmod 777 var/logs/", | |||
"chmod 777 var/twig/" | |||
], | |||
"clearCache": "rm -rf var/cache/*", | |||
"clearTwig": "find var/twig -type f -name '*.php' -delete" | |||
} | |||
} |
@@ -0,0 +1,13 @@ | |||
Kohana auth module | |||
--- | |||
I've forked the main Auth module because there were some fundamental flaws with it: | |||
1. It's trivial to [bruteforce](http://dev.kohanaframework.org/issues/3163) publicly hidden salt hashes. | |||
- I've fixed this by switching the password hashing algorithm to the more secure secret-key based hash_hmac method. | |||
2. ORM drivers were included. | |||
- I've fixed this by simply removing them. They cause confusion with new users because they think that Auth requires ORM. The only driver currently provided by default is the file driver. | |||
3. Auth::get_user()'s api is inconsistent because it returns different data types. | |||
- I've fixed this by returning an empty user model by default. You can override what gets returned (if you've changed your user model class name for instance) by overloading the get_user() method in your application. | |||
These changes should be merged into the mainline branch eventually, but they completely break the API, so likely won't be done until 3.1. |
@@ -0,0 +1,3 @@ | |||
<?php | |||
abstract class Auth extends Kohana_Auth {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Auth_File extends Kohana_Auth_File {} |
@@ -0,0 +1,171 @@ | |||
<?php | |||
/** | |||
* User authorization library. Handles user login and logout, as well as secure | |||
* password hashing. | |||
* | |||
* @package Kohana/Auth | |||
* @author Kohana Team | |||
* @copyright (c) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
abstract class Kohana_Auth { | |||
// Auth instances | |||
protected static $_instance; | |||
/** | |||
* Singleton pattern | |||
* | |||
* @return Auth | |||
*/ | |||
public static function instance() | |||
{ | |||
if ( ! isset(Auth::$_instance)) | |||
{ | |||
// Load the configuration for this type | |||
$config = Kohana::$config->load('auth'); | |||
if ( ! $type = $config->get('driver')) | |||
{ | |||
$type = 'file'; | |||
} | |||
// Set the session class name | |||
$class = 'Auth_'.ucfirst($type); | |||
// Create a new session instance | |||
Auth::$_instance = new $class($config); | |||
} | |||
return Auth::$_instance; | |||
} | |||
protected $_session; | |||
protected $_config; | |||
/** | |||
* Loads Session and configuration options. | |||
* | |||
* @param array $config Config Options | |||
* @return void | |||
*/ | |||
public function __construct($config = []) | |||
{ | |||
// Save the config in the object | |||
$this->_config = $config; | |||
$this->_session = Session::instance($this->_config['session_type']); | |||
} | |||
abstract protected function _login($username, $password, $remember); | |||
abstract public function password($username); | |||
abstract public function check_password($password); | |||
/** | |||
* 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) | |||
{ | |||
return $this->_session->get($this->_config['session_key'], $default); | |||
} | |||
/** | |||
* Attempt to log in a user by using an ORM object and plain-text password. | |||
* | |||
* @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) | |||
{ | |||
if (empty($password)) | |||
return FALSE; | |||
return $this->_login($username, $password, $remember); | |||
} | |||
/** | |||
* Log out a user by removing the related session variables. | |||
* | |||
* @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) | |||
{ | |||
if ($destroy === TRUE) | |||
{ | |||
// Destroy the session completely | |||
$this->_session->destroy(); | |||
} | |||
else | |||
{ | |||
// Remove the user from the session | |||
$this->_session->delete($this->_config['session_key']); | |||
// Regenerate session_id | |||
$this->_session->regenerate(); | |||
} | |||
// Double check | |||
return ! $this->logged_in(); | |||
} | |||
/** | |||
* Check if there is an active session. Optionally allows checking for a | |||
* specific role. | |||
* | |||
* @param string $role role name | |||
* @return mixed | |||
*/ | |||
public function logged_in($role = NULL) | |||
{ | |||
return ($this->get_user() !== NULL); | |||
} | |||
/** | |||
* Creates a hashed hmac password from a plaintext password. This | |||
* method is deprecated, [Auth::hash] should be used instead. | |||
* | |||
* @deprecated | |||
* @param string $password Plaintext password | |||
*/ | |||
public function hash_password($password) | |||
{ | |||
return $this->hash($password); | |||
} | |||
/** | |||
* Perform a hmac hash, using the configured method. | |||
* | |||
* @param string $str string to hash | |||
* @return string | |||
*/ | |||
public function hash($str) | |||
{ | |||
if ( ! $this->_config['hash_key']) | |||
throw new Kohana_Exception('A valid hash key must be set in your auth config.'); | |||
return hash_hmac($this->_config['hash_method'], $str, $this->_config['hash_key']); | |||
} | |||
protected function complete_login($user) | |||
{ | |||
// Regenerate session_id | |||
$this->_session->regenerate(); | |||
// Store username in session | |||
$this->_session->set($this->_config['session_key'], $user); | |||
return TRUE; | |||
} | |||
} |
@@ -0,0 +1,97 @@ | |||
<?php | |||
/** | |||
* File Auth driver. | |||
* [!!] this Auth driver does not support roles nor autologin. | |||
* | |||
* @package Kohana/Auth | |||
* @author Kohana Team | |||
* @copyright (c) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
class Kohana_Auth_File extends Auth { | |||
// User list | |||
protected $_users; | |||
/** | |||
* Constructor loads the user list into the class. | |||
*/ | |||
public function __construct($config = []) | |||
{ | |||
parent::__construct($config); | |||
// Load user list | |||
$this->_users = Arr::get($config, 'users', []); | |||
} | |||
/** | |||
* Logs a user in. | |||
* | |||
* @param string $username Username | |||
* @param string $password Password | |||
* @param boolean $remember Enable autologin (not supported) | |||
* @return boolean | |||
*/ | |||
protected function _login($username, $password, $remember) | |||
{ | |||
if ($remember) | |||
{ | |||
throw new Kohana_Exception('File based auth does not support 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 | |||
return $this->complete_login($username); | |||
} | |||
// Login failed | |||
return FALSE; | |||
} | |||
/** | |||
* Forces a user to be logged in, without specifying a password. | |||
* | |||
* @param mixed $username Username | |||
* @return boolean | |||
*/ | |||
public function force_login($username) | |||
{ | |||
// Complete the login | |||
return $this->complete_login($username); | |||
} | |||
/** | |||
* Get the stored password for a username. | |||
* | |||
* @param mixed $username Username | |||
* @return string | |||
*/ | |||
public function password($username) | |||
{ | |||
return Arr::get($this->_users, $username, FALSE); | |||
} | |||
/** | |||
* Compare password with original (plain text). Works for current (logged in) user | |||
* | |||
* @param string $password Password | |||
* @return boolean | |||
*/ | |||
public function check_password($password) | |||
{ | |||
$username = $this->get_user(); | |||
if ($username === FALSE) | |||
return FALSE; | |||
return ($password === $this->password($username)); | |||
} | |||
} |
@@ -0,0 +1,19 @@ | |||
<?php | |||
return [ | |||
'driver' => 'File', | |||
'hash_method' => 'sha256', | |||
'hash_key' => NULL, | |||
'lifetime' => 1209600, | |||
'session_type' => Session::$default, | |||
'session_key' => 'auth_user', | |||
// For Auth_Bcrypt | |||
'cost' => 10, | |||
// Username/password combinations for the Auth File driver | |||
'users' => [ | |||
// 'admin' => 'b3154acf3a344170077d11bdb5fff31532f679a1919e716a02', | |||
], | |||
]; |
@@ -0,0 +1,25 @@ | |||
<?php | |||
return [ | |||
// Leave this alone | |||
'modules' => [ | |||
// This should be the path to this modules userguide pages, without the 'guide/'. Ex: '/guide/modulename/' would be 'modulename' | |||
'auth' => [ | |||
// 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–2016 Kohana Team - 2016-2018 Koseven Team - https://github.com/orgs/koseven/people', | |||
] | |||
] | |||
]; |
@@ -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. |
@@ -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`). |
@@ -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 | |||
~~~ |
@@ -0,0 +1,6 @@ | |||
## [Auth]() | |||
- [Configuration](config) | |||
- [Log in and out](login) | |||
- Drivers | |||
- [File](driver/file) | |||
- [Developing](driver/develop) |
@@ -0,0 +1,59 @@ | |||
Kohana Cache library | |||
==================== | |||
The cache library for Kohana 3 provides a simple interface to the most common cache solutions. Developers are free to add their own caching solutions that follow the cache design pattern defined within this module. | |||
Supported cache solutions | |||
------------------------- | |||
Currently this module supports the following cache methods. | |||
1. APC | |||
2. Memcache | |||
3. Memcached-tags (Supports tags) | |||
4. SQLite (Supports tags) | |||
5. File | |||
6. Wincache | |||
Planned support | |||
--------------- | |||
In the near future, additional support for the following methods will be included. | |||
1. Memcached | |||
Introduction to caching | |||
----------------------- | |||
To use caching to the maximum potential, your application should be designed with caching in mind from the outset. In general, the most effective caches contain lots of small collections of data that are the result of expensive computational operations, such as searching through a large data set. | |||
There are many different caching methods available for PHP, from the very basic file based caching to opcode caching in eAccelerator and APC. Caching engines that use physical memory over disk based storage are always faster, however many do not support more advanced features such as tagging. | |||
Using Cache | |||
----------- | |||
To use Kohana Cache, download and extract the latest stable release of Kohana Cache from [Github](http://github.com/samsoir/kohana-cache). Place the module into your Kohana instances modules folder. Finally enable the module within the application bootstrap within the section entitled _modules_. | |||
Quick example | |||
------------- | |||
The following is a quick example of how to use Kohana Cache. The example is using the SQLite driver. | |||
<?php | |||
// Get a Sqlite Cache instance | |||
$mycache = Cache::instance('sqlite'); | |||
// Create some data | |||
$data = array('foo' => 'bar', 'apples' => 'pear', 'BDFL' => 'Shadowhand'); | |||
// Save the data to cache, with an id of test_id and a lifetime of 10 minutes | |||
$mycache->set('test_id', $data, 600); | |||
// Retrieve the data from cache | |||
$retrieved_data = $mycache->get('test_id'); | |||
// Remove the cache item | |||
$mycache->delete('test_id'); | |||
// Clear the cache of all stored items | |||
$mycache->delete_all(); |
@@ -0,0 +1,3 @@ | |||
<?php | |||
abstract class Cache extends Kohana_Cache {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Apc extends Kohana_Cache_Apc {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Apcu extends Kohana_Cache_Apcu {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
interface Cache_Arithmetic extends Kohana_Cache_Arithmetic {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Exception extends Kohana_Cache_Exception {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_File extends Kohana_Cache_File {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
interface Cache_GarbageCollect extends Kohana_Cache_GarbageCollect {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Memcache extends Kohana_Cache_Memcache {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_MemcacheTag extends Kohana_Cache_MemcacheTag {} |
@@ -0,0 +1,25 @@ | |||
<?php | |||
/** | |||
* Cache_Memcached class | |||
* | |||
* LICENSE: THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS | |||
* CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED | |||
* BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS | |||
* AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. | |||
* | |||
* BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO | |||
* BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE | |||
* CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE | |||
* IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. | |||
* | |||
* @package Kohana/Cache | |||
* @author gimpe <gimpehub@intljaywalkers.com> | |||
* @copyright 2011 International Jaywalkers | |||
* @copyright (c) 2018 Koseven Team | |||
* @license http://creativecommons.org/licenses/by/3.0/ CC BY 3.0 | |||
* @link http://github.com/gimpe/kohana-memcached | |||
*/ | |||
class Cache_Memcached extends Kohana_Cache_Memcached | |||
{ | |||
} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Sqlite extends Kohana_Cache_Sqlite {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
interface Cache_Tagging extends Kohana_Cache_Tagging {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class Cache_Wincache extends Kohana_Cache_Wincache {} |
@@ -0,0 +1,3 @@ | |||
<?php | |||
class HTTP_Cache extends Kohana_HTTP_Cache {} |
@@ -0,0 +1,324 @@ | |||
<?php | |||
/** | |||
* 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 | |||
* 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 | |||
* * [Memcache](http://memcached.org/) | |||
* * [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( | |||
* 'memcache' => array( // Name of group | |||
* 'driver' => 'memcache', // using Memcache driver | |||
* 'servers' => array( // Available server definitions | |||
* array( | |||
* 'host' => 'localhost', | |||
* 'port' => 11211, | |||
* 'persistent' => FALSE | |||
* ) | |||
* ), | |||
* 'compression' => FALSE, // Use compression? | |||
* ), | |||
* ) | |||
* | |||
* In cases where only one cache group is required, set `Cache::$default` (in your bootstrap, | |||
* or by extending `Kohana_Cache` class) to the name of the group, and use: | |||
* | |||
* $cache = Cache::instance(); // instead of Cache::instance('memcache') | |||
* | |||
* It will return the cache instance of the group it has been set in `Cache::$default`. | |||
* | |||
* #### 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) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
abstract class Kohana_Cache { | |||
const DEFAULT_EXPIRE = 3600; | |||
/** | |||
* @var string default driver to use | |||
*/ | |||
public static $default = 'file'; | |||
/** | |||
* @var Kohana_Cache instances | |||
*/ | |||
public static $instances = []; | |||
/** | |||
* 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 $group the name of the cache group to use [Optional] | |||
* @return Cache | |||
* @throws Cache_Exception | |||
*/ | |||
public static function instance($group = NULL) | |||
{ | |||
// If there is no group supplied, try to get it from the config | |||
if ($group === NULL) | |||
{ | |||
$group = Kohana::$config->load('cache.default'); | |||
} | |||
// If there is no group supplied | |||
if ($group === NULL) | |||
{ | |||
// Use the default setting | |||
$group = Cache::$default; | |||
} | |||
if (isset(Cache::$instances[$group])) | |||
{ | |||
// Return the current group if initiated already | |||
return Cache::$instances[$group]; | |||
} | |||
$config = Kohana::$config->load('cache'); | |||
if ( ! $config->offsetExists($group)) | |||
{ | |||
throw new Cache_Exception( | |||
'Failed to load Kohana Cache group: :group', | |||
[':group' => $group] | |||
); | |||
} | |||
$config = $config->get($group); | |||
// Create a new cache type instance | |||
$cache_class = 'Cache_'.ucfirst($config['driver']); | |||
Cache::$instances[$group] = new $cache_class($config); | |||
// Return the instance | |||
return Cache::$instances[$group]; | |||
} | |||
/** | |||
* @var Config | |||
*/ | |||
protected $_config = []; | |||
/** | |||
* Ensures singleton pattern is observed, loads the default expiry | |||
* | |||
* @param array $config configuration | |||
*/ | |||
protected function __construct(array $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 Cache_Exception | |||
*/ | |||
final public function __clone() | |||
{ | |||
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 id of cache to entry | |||
* @param string $default default value to return if cache miss | |||
* @return mixed | |||
* @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)) | |||
* { | |||
* // Cache was set successfully | |||
* return | |||
* } | |||
* | |||
* @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 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(); | |||
* | |||
* @return boolean | |||
*/ | |||
abstract public function delete_all(); | |||
/** | |||
* Replaces troublesome characters with underscores and adds prefix to avoid duplicates | |||
* | |||
* // Sanitize a cache id | |||
* $id = $this->_sanitize_id($id); | |||
* | |||
* @param string $id id of cache to sanitize | |||
* @return string | |||
*/ | |||
protected function _sanitize_id($id) | |||
{ | |||
// adding cache prefix to avoid duplicates | |||
$prefix = ''; | |||
// configuration for the specific cache group | |||
if (isset($this->_config['prefix']) AND $this->_config['prefix'] !== NULL) | |||
{ | |||
$prefix = $this->_config['prefix']; | |||
} | |||
// prefix general configuration cache | |||
else | |||
{ | |||
$prefix = Kohana::$config->load('cache.prefix'); | |||
} | |||
// sha1 the id makes sure name is not too long and has not any not allowed characters | |||
return $prefix.sha1($id); | |||
} | |||
} | |||
// End Kohana_Cache |
@@ -0,0 +1,166 @@ | |||
<?php | |||
/** | |||
* [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) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
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 $config configuration | |||
* @throws Cache_Exception | |||
*/ | |||
protected function __construct(array $config) | |||
{ | |||
if ( ! extension_loaded('apc')) | |||
{ | |||
throw new Cache_Exception('PHP APC extension is not available.'); | |||
} | |||
parent::__construct($config); | |||
} | |||
/** | |||
* 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 id of cache to entry | |||
* @param string $default default value to return if cache miss | |||
* @return mixed | |||
* @throws Cache_Exception | |||
*/ | |||
public function get($id, $default = NULL) | |||
{ | |||
$data = apc_fetch($this->_sanitize_id($id), $success); | |||
return $success ? $data : $default; | |||
} | |||
/** | |||
* 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 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) | |||
{ | |||
if ($lifetime === NULL) | |||
{ | |||
$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE); | |||
} | |||
return apc_store($this->_sanitize_id($id), $data, $lifetime); | |||
} | |||
/** | |||
* Delete a cache entry based on id | |||
* | |||
* // Delete 'foo' entry from the apc group | |||
* Cache::instance('apc')->delete('foo'); | |||
* | |||
* @param string $id id to remove from cache | |||
* @return boolean | |||
*/ | |||
public function delete($id) | |||
{ | |||
return apc_delete($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 apc group | |||
* Cache::instance('apc')->delete_all(); | |||
* | |||
* @return boolean | |||
*/ | |||
public function delete_all() | |||
{ | |||
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 |
@@ -0,0 +1,174 @@ | |||
<?php | |||
/** | |||
* [Kohana Cache](api/Kohana_Cache) APCu data store driver for Kohana Cache | |||
* library. | |||
* | |||
* ### Configuration example | |||
* | |||
* Below is an example of an _apcu_ server configuration. | |||
* | |||
* return array( | |||
* 'apcu' => array( // Driver group | |||
* 'driver' => 'apcu', // using APCu 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 | |||
* * APCu PHP extension | |||
* | |||
* @package Kohana/Cache | |||
* @category Base | |||
* @author Kohana Team | |||
* @copyright (c) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
class Kohana_Cache_Apcu extends Cache implements Cache_Arithmetic { | |||
/** | |||
* Check for existence of the APCu extension This method cannot be invoked externally. The driver must | |||
* be instantiated using the `Cache::instance()` method. | |||
* | |||
* @param array $config configuration | |||
* @throws Cache_Exception | |||
*/ | |||
protected function __construct(array $config) | |||
{ | |||
if ( ! extension_loaded('apcu')) | |||
{ | |||
throw new Cache_Exception('PHP APCu extension is not available.'); | |||
} | |||
parent::__construct($config); | |||
} | |||
/** | |||
* Retrieve a cached value entry by id. | |||
* | |||
* // Retrieve cache entry from apcu group | |||
* $data = Cache::instance('apcu')->get('foo'); | |||
* | |||
* // Retrieve cache entry from apcu group and return 'bar' if miss | |||
* $data = Cache::instance('apcu')->get('foo', 'bar'); | |||
* | |||
* @param string $id id of cache to entry | |||
* @param string $default default value to return if cache miss | |||
* @return mixed | |||
* @throws Cache_Exception | |||
*/ | |||
public function get($id, $default = NULL) | |||
{ | |||
$data = apcu_fetch($this->_sanitize_id($id), $success); | |||
return $success ? $data : $default; | |||
} | |||
/** | |||
* Set a value to cache with id and lifetime | |||
* | |||
* $data = 'bar'; | |||
* | |||
* // Set 'bar' to 'foo' in apcu group, using default expiry | |||
* Cache::instance('apcu')->set('foo', $data); | |||
* | |||
* // Set 'bar' to 'foo' in apcu group for 30 seconds | |||
* Cache::instance('apcu')->set('foo', $data, 30); | |||
* | |||
* @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) | |||
{ | |||
if ($lifetime === NULL) | |||
{ | |||
$lifetime = Arr::get($this->_config, 'default_expire', Cache::DEFAULT_EXPIRE); | |||
} | |||
return apcu_store($this->_sanitize_id($id), $data, $lifetime); | |||
} | |||
/** | |||
* Delete a cache entry based on id | |||
* | |||
* // Delete 'foo' entry from the apcu group | |||
* Cache::instance('apcu')->delete('foo'); | |||
* | |||
* @param string $id id to remove from cache | |||
* @return boolean | |||
*/ | |||
public function delete($id) | |||
{ | |||
return apcu_delete($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 apcu group | |||
* Cache::instance('apcu')->delete_all(); | |||
* | |||
* @return boolean | |||
*/ | |||
public function delete_all() | |||
{ | |||
return apcu_clear_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) | |||
{ | |||
if (apcu_exists($id)) { | |||
return apcu_inc($id, $step); | |||
} else { | |||
return FALSE; | |||
} | |||
} | |||
/** | |||
* 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) | |||
{ | |||
if (apcu_exists($id)) { | |||
return apcu_dec($id, $step); | |||
} else { | |||
return FALSE; | |||
} | |||
} | |||
} // End Kohana_Cache_Apcu |
@@ -0,0 +1,39 @@ | |||
<?php | |||
/** | |||
* Kohana Cache Arithmetic Interface, for basic cache integer based | |||
* arithmetic, addition and subtraction | |||
* | |||
* @package Kohana/Cache | |||
* @category Base | |||
* @author Kohana Team | |||
* @copyright (c) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
* @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 |
@@ -0,0 +1,11 @@ | |||
<?php | |||
/** | |||
* Kohana Cache Exception | |||
* | |||
* @package Kohana/Cache | |||
* @category Base | |||
* @author Kohana Team | |||
* @copyright (c) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
class Kohana_Cache_Exception extends Kohana_Exception {} |
@@ -0,0 +1,492 @@ | |||
<?php | |||
/** | |||
* [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) Kohana Team | |||
* @license https://koseven.ga/LICENSE.md | |||
*/ | |||
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 string to hash into filename | |||
* @return string | |||
*/ | |||
protected static function filename($string) | |||
{ | |||
return sha1($string).'.cache'; | |||
} | |||
/** | |||
* @var string the caching directory | |||
*/ | |||
protected $_cache_dir; | |||
/** | |||
* @var boolean does the cache directory exists and writeable | |||
*/ | |||
protected $_cache_dir_usable = FALSE; | |||
/** | |||
* Check that the cache directory exists and writeable. Attempts to create | |||
* it if not exists. | |||
* | |||
* @throws Cache_Exception | |||
*/ | |||
protected function _check_cache_dir() | |||
{ | |||
try | |||
{ | |||
$directory = Arr::get($this->_config, 'cache_dir', Kohana::$cache_dir); | |||
$this->_cache_dir = new SplFileInfo($directory); | |||
} | |||
catch (UnexpectedValueException $e) | |||
{ | |||
$this->_cache_dir = $this->_make_directory($directory, 0777, TRUE); | |||
} | |||
// If the defined directory is a file, get outta here | |||
if ($this->_cache_dir->isFile()) | |||
{ | |||
throw new Cache_Exception('Unable to create cache directory as a file already exists : :resource', [':resource' => $this->_cache_dir->getRealPath()]); | |||
} | |||
// Check the read status of the directory | |||
if ( ! $this->_cache_dir->isReadable()) | |||
{ | |||
throw new Cache_Exception('Unable to read from the cache directory :resource', [':resource' => $this->_cache_dir->getRealPath()]); | |||
} | |||
// Check the write status of the directory | |||
if ( ! $this->_cache_dir->isWritable()) | |||
{ | |||
throw new Cache_Exception('Unable to write to the cache directory :resource', [':resource' => $this->_cache_dir->getRealPath()]); | |||
} | |||
$this->_cache_dir_usable = TRUE; | |||
} | |||
/** | |||
* 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 id of cache to entry | |||
* @param string $default default value to return if cache miss | |||
* @return mixed | |||
* @throws Cache_Exception | |||
*/ | |||
public function get($id, $default = NULL) | |||
{ | |||
$this->_cache_dir_usable or $this->_check_cache_dir(); | |||
$filename = Cache_File::filename($this->_sanitize_id($id)); | |||
$directory = $this->_resolve_directory($filename); | |||
// Wrap operations in try/catch to handle notices | |||
try | |||
{ | |||
// Open file | |||
$file = new SplFileInfo($directory.$filename); | |||
// If file does not exist | |||
if ( ! $file->isFile()) | |||
{ | |||
// Return default value | |||
return $default; | |||
} | |||
else | |||
{ | |||
// Test the expiry | |||
if ($this->_is_expired($file)) | |||
{ | |||
// Delete the file | |||
$this->_delete_file($file, FALSE, TRUE); | |||
return $default; | |||
} | |||
// open the file to read data | |||
$data = $file->openFile(); | |||
// Run first fgets(). Cache data starts from the second line | |||
// as the first contains the lifetime timestamp | |||
$data->fgets(); | |||
$cache = ''; | |||
while ($data->eof() === FALSE) | |||
{ | |||
$cache .= $data->fgets(); | |||
} | |||
return unserialize($cache); | |||
} | |||
} | |||
catch (ErrorException $e) | |||
{ | |||
// Handle ErrorException caused by failed unserialization | |||
if ($e->getCode() === E_NOTICE) | |||