From 4c554da8eba4e319b3b1c8c4a5c9b13b515ea27f Mon Sep 17 00:00:00 2001 From: Jeremy Bush Date: Thu, 23 Aug 2012 21:56:20 -0500 Subject: [PATCH 01/72] bump version to 3.2.1 --- classes/kohana/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 674c6b52e..f98e5bd8c 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -16,8 +16,8 @@ class Kohana_Core { // Release version and codename - const VERSION = '3.2.0'; - const CODENAME = 'Kolibri'; + const VERSION = '3.2.1'; + const CODENAME = 'Milvago'; // Common environment type constants for consistency and convenience const PRODUCTION = 10; From 97ccdecb053025e8287f1e5dfed520a81f864c96 Mon Sep 17 00:00:00 2001 From: Thomas Buck Date: Mon, 27 Aug 2012 16:06:58 +0000 Subject: [PATCH 02/72] Add Windows 8 support --- config/user_agents.php | 1 + 1 file changed, 1 insertion(+) diff --git a/config/user_agents.php b/config/user_agents.php index e92a632ca..6f929458d 100644 --- a/config/user_agents.php +++ b/config/user_agents.php @@ -3,6 +3,7 @@ return array( 'platform' => array( + 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', 'windows nt 6.0' => 'Windows Vista', 'windows nt 5.2' => 'Windows 2003', From 7da9089767f3333d136c6ae214d7e43a4d822d0d Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Mon, 27 Aug 2012 12:52:24 -0500 Subject: [PATCH 03/72] Revert "Add Windows 8 support" This reverts commit 97ccdecb053025e8287f1e5dfed520a81f864c96. --- config/user_agents.php | 1 - 1 file changed, 1 deletion(-) diff --git a/config/user_agents.php b/config/user_agents.php index 6f929458d..e92a632ca 100644 --- a/config/user_agents.php +++ b/config/user_agents.php @@ -3,7 +3,6 @@ return array( 'platform' => array( - 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', 'windows nt 6.0' => 'Windows Vista', 'windows nt 5.2' => 'Windows 2003', From 92a1724c1a35783e2cf352f92eb29aa81828d570 Mon Sep 17 00:00:00 2001 From: MichalM Date: Mon, 22 Oct 2012 17:05:08 +0200 Subject: [PATCH 04/72] stdout and stderr now use file log writer's format to display readable log levels --- classes/kohana/log/stderr.php | 5 +---- classes/kohana/log/stdout.php | 5 +---- 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/classes/kohana/log/stderr.php b/classes/kohana/log/stderr.php index 715ce902d..6c5210906 100644 --- a/classes/kohana/log/stderr.php +++ b/classes/kohana/log/stderr.php @@ -19,13 +19,10 @@ class Kohana_Log_StdErr extends Log_Writer { */ public function write(array $messages) { - // Set the log line format - $format = 'time --- type: body'; - foreach ($messages as $message) { // Writes out each message - fwrite(STDERR, PHP_EOL.strtr($format, $message)); + fwrite(STDERR, PHP_EOL.$message['time'].' --- '.$this->_log_levels[$message['level']].': '.$message['body']); } } } // End Kohana_Log_StdErr diff --git a/classes/kohana/log/stdout.php b/classes/kohana/log/stdout.php index 26c9668b5..0ef61c4a2 100644 --- a/classes/kohana/log/stdout.php +++ b/classes/kohana/log/stdout.php @@ -19,13 +19,10 @@ class Kohana_Log_StdOut extends Log_Writer { */ public function write(array $messages) { - // Set the log line format - $format = 'time --- type: body'; - foreach ($messages as $message) { // Writes out each message - fwrite(STDOUT, PHP_EOL.strtr($format, $message)); + fwrite(STDOUT, PHP_EOL.$message['time'].' --- '.$this->_log_levels[$message['level']].': '.$message['body']); } } } // End Kohana_Log_StdOut From 0e52dfc09f6ae50d830f102829a59af182ac8ee6 Mon Sep 17 00:00:00 2001 From: Evan Purkhiser Date: Sun, 4 Nov 2012 16:51:24 -0500 Subject: [PATCH 05/72] Use the current exception handler during shutdown It's possible that a different exception handler is defined than the default `Kohana_Exception::hander`. Refs #4627 --- classes/kohana/core.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 58c3481fc..12af46a86 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -968,7 +968,6 @@ public static function error_handler($code, $error, $file = NULL, $line = NULL) /** * Catches errors that are not caught by the error handler, such as E_PARSE. * - * @uses Kohana_Exception::handler * @return void */ public static function shutdown_handler() @@ -979,6 +978,12 @@ public static function shutdown_handler() return; } + // Retrieve the current exception handler + $handler = set_exception_handler(array('Kohana_Exception', 'handler')); + + // Restore it back to it's previous state + restore_exception_handler(); + try { if (Kohana::$caching === TRUE AND Kohana::$_files_changed === TRUE) @@ -990,7 +995,7 @@ public static function shutdown_handler() catch (Exception $e) { // Pass the exception to the handler - Kohana_Exception::handler($e); + call_user_func($handler, $e); } if (Kohana::$errors AND $error = error_get_last() AND in_array($error['type'], Kohana::$shutdown_errors)) @@ -999,7 +1004,7 @@ public static function shutdown_handler() ob_get_level() and ob_clean(); // Fake an exception for nice debugging - Kohana_Exception::handler(new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); + call_user_func($handler, new ErrorException($error['message'], $error['type'], 0, $error['file'], $error['line'])); // Shutdown now to avoid a "death loop" exit(1); From 4cf93923ced3afbaa7086d53f6c1aa5175b96d3f Mon Sep 17 00:00:00 2001 From: Marek Szymczuk Date: Sat, 7 Sep 2013 22:06:16 +0200 Subject: [PATCH 06/72] Update the license url, fixes #4778 --- classes/kohana/config/group.php | 2 +- classes/kohana/config/source.php | 2 +- classes/kohana/config/writer.php | 2 +- classes/kohana/debug.php | 2 +- classes/kohana/http.php | 2 +- classes/kohana/http/header.php | 2 +- classes/kohana/http/message.php | 2 +- classes/kohana/http/request.php | 2 +- classes/kohana/http/response.php | 2 +- classes/kohana/log/stderr.php | 2 +- classes/kohana/log/stdout.php | 2 +- classes/kohana/response.php | 2 +- tests/kohana/Config/File/ReaderTest.php | 2 +- tests/kohana/Config/GroupTest.php | 2 +- tests/kohana/DebugTest.php | 2 +- tests/kohana/Http/HeaderTest.php | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) diff --git a/classes/kohana/config/group.php b/classes/kohana/config/group.php index 3adfbba69..f6e00ac66 100644 --- a/classes/kohana/config/group.php +++ b/classes/kohana/config/group.php @@ -12,7 +12,7 @@ * @category Configuration * @author Kohana Team * @copyright (c) 2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Config_Group extends ArrayObject { diff --git a/classes/kohana/config/source.php b/classes/kohana/config/source.php index fcc57f3e3..1ed18a58f 100644 --- a/classes/kohana/config/source.php +++ b/classes/kohana/config/source.php @@ -8,7 +8,7 @@ * @category Configuration * @author Kohana Team * @copyright (c) 2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ interface Kohana_Config_Source {} diff --git a/classes/kohana/config/writer.php b/classes/kohana/config/writer.php index ea2b19ab8..cc7ae5291 100644 --- a/classes/kohana/config/writer.php +++ b/classes/kohana/config/writer.php @@ -8,7 +8,7 @@ * @package Kohana * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ interface Kohana_Config_Writer extends Kohana_Config_Source { diff --git a/classes/kohana/debug.php b/classes/kohana/debug.php index 435387d67..fd8d795b0 100644 --- a/classes/kohana/debug.php +++ b/classes/kohana/debug.php @@ -6,7 +6,7 @@ * @category Base * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Debug { diff --git a/classes/kohana/http.php b/classes/kohana/http.php index 066464d1a..b254fd074 100644 --- a/classes/kohana/http.php +++ b/classes/kohana/http.php @@ -12,7 +12,7 @@ * @author Kohana Team * @since 3.1.0 * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ abstract class Kohana_HTTP { diff --git a/classes/kohana/http/header.php b/classes/kohana/http/header.php index 96d5e124a..7e8573f7b 100644 --- a/classes/kohana/http/header.php +++ b/classes/kohana/http/header.php @@ -10,7 +10,7 @@ * @author Kohana Team * @since 3.1.0 * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_HTTP_Header extends ArrayObject { diff --git a/classes/kohana/http/message.php b/classes/kohana/http/message.php index 9cbf18008..b699cbd57 100644 --- a/classes/kohana/http/message.php +++ b/classes/kohana/http/message.php @@ -8,7 +8,7 @@ * @author Kohana Team * @since 3.1.0 * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ interface Kohana_HTTP_Message { diff --git a/classes/kohana/http/request.php b/classes/kohana/http/request.php index b5b283eac..88eaa64c3 100644 --- a/classes/kohana/http/request.php +++ b/classes/kohana/http/request.php @@ -9,7 +9,7 @@ * @author Kohana Team * @since 3.1.0 * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ interface Kohana_HTTP_Request extends HTTP_Message { diff --git a/classes/kohana/http/response.php b/classes/kohana/http/response.php index 06a67fd78..8a337bce6 100644 --- a/classes/kohana/http/response.php +++ b/classes/kohana/http/response.php @@ -9,7 +9,7 @@ * @author Kohana Team * @since 3.1.0 * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ interface Kohana_HTTP_Response extends HTTP_Message { diff --git a/classes/kohana/log/stderr.php b/classes/kohana/log/stderr.php index 715ce902d..57bca9e3e 100644 --- a/classes/kohana/log/stderr.php +++ b/classes/kohana/log/stderr.php @@ -6,7 +6,7 @@ * @category Logging * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Log_StdErr extends Log_Writer { /** diff --git a/classes/kohana/log/stdout.php b/classes/kohana/log/stdout.php index 26c9668b5..2911ac717 100644 --- a/classes/kohana/log/stdout.php +++ b/classes/kohana/log/stdout.php @@ -6,7 +6,7 @@ * @category Logging * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Log_StdOut extends Log_Writer { /** diff --git a/classes/kohana/response.php b/classes/kohana/response.php index 51381fc20..2a820d828 100644 --- a/classes/kohana/response.php +++ b/classes/kohana/response.php @@ -8,7 +8,7 @@ * @category Base * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license * @since 3.1.0 */ class Kohana_Response implements HTTP_Response { diff --git a/tests/kohana/Config/File/ReaderTest.php b/tests/kohana/Config/File/ReaderTest.php index ab22d14ae..7a365d183 100644 --- a/tests/kohana/Config/File/ReaderTest.php +++ b/tests/kohana/Config/File/ReaderTest.php @@ -11,7 +11,7 @@ * @author Jeremy Bush * @author Matt Button * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Config_File_ReaderTest extends Kohana_Unittest_TestCase { diff --git a/tests/kohana/Config/GroupTest.php b/tests/kohana/Config/GroupTest.php index f18e44e1f..b78fbcfbc 100644 --- a/tests/kohana/Config/GroupTest.php +++ b/tests/kohana/Config/GroupTest.php @@ -11,7 +11,7 @@ * @author Jeremy Bush * @author Matt Button * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_Config_GroupTest extends Kohana_Unittest_TestCase { diff --git a/tests/kohana/DebugTest.php b/tests/kohana/DebugTest.php index 218309db4..ed9d09b54 100644 --- a/tests/kohana/DebugTest.php +++ b/tests/kohana/DebugTest.php @@ -14,7 +14,7 @@ * @author Kohana Team * @author Jeremy Bush * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_DebugTest extends Unittest_TestCase { diff --git a/tests/kohana/Http/HeaderTest.php b/tests/kohana/Http/HeaderTest.php index c7dffdaa5..4c82172e2 100644 --- a/tests/kohana/Http/HeaderTest.php +++ b/tests/kohana/Http/HeaderTest.php @@ -12,7 +12,7 @@ * @category Tests * @author Kohana Team * @copyright (c) 2008-2012 Kohana Team - * @license http://kohanaphp.com/license + * @license http://kohanaframework.org/license */ class Kohana_HTTP_HeaderTest extends Unittest_TestCase { From f7a4f3622fd186937622a3e42b37747e8f27dd24 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 26 Sep 2013 11:43:20 +0100 Subject: [PATCH 07/72] Don't set empty body on external curl requests [Fixes #4791] When the CURLOPT_POSTFIELDS option is present, curl adds a default Content-Type header which can be changed but not removed, causing authentication problems with signed requests. The option should only be set if a request body is being sent. --- classes/kohana/request/client/curl.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/classes/kohana/request/client/curl.php b/classes/kohana/request/client/curl.php index 2dd6ea3cc..5a92b5ab4 100644 --- a/classes/kohana/request/client/curl.php +++ b/classes/kohana/request/client/curl.php @@ -33,7 +33,10 @@ public function _send_message(Request $request) // if using a request other than POST. PUT does support this method // and DOES NOT require writing data to disk before putting it, if // reading the PHP docs you may have got that impression. SdF - $options[CURLOPT_POSTFIELDS] = $request->body(); + // This will also add a Content-Type: application/x-www-form-urlencoded header unless you override it + if ($body = $request->body()) { + $options[CURLOPT_POSTFIELDS] = $body; + } // Process headers if ($headers = $request->headers()) From 3be2d3d22d912d629b2a76fe90865d65c9305cef Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Sat, 11 Jan 2014 16:52:15 +0000 Subject: [PATCH 08/72] #4201 - Issue with validation labels --- classes/kohana/validation.php | 2 +- tests/kohana/ValidationTest.php | 44 +++++++++++++++++++++++++++++++++ 2 files changed, 45 insertions(+), 1 deletion(-) diff --git a/classes/kohana/validation.php b/classes/kohana/validation.php index 50c29eee1..f71c576fe 100644 --- a/classes/kohana/validation.php +++ b/classes/kohana/validation.php @@ -219,7 +219,7 @@ public function rule($field, $rule, array $params = NULL) if ($field !== TRUE AND ! isset($this->_labels[$field])) { // Set the field label to the field name - $this->_labels[$field] = preg_replace('/[^\pL]+/u', ' ', $field); + $this->_labels[$field] = $field); } // Store the rule and params for this rule diff --git a/tests/kohana/ValidationTest.php b/tests/kohana/ValidationTest.php index 05258495a..b29aaecb3 100644 --- a/tests/kohana/ValidationTest.php +++ b/tests/kohana/ValidationTest.php @@ -665,4 +665,48 @@ public function test_error_type_check() $this->assertSame($errors, $validation->errors('validation')); } + /** + * Provides test data for test_rule_label_regex + * + * @return array + */ + public function provider_rule_label_regex() + { + // $data, $field, $rules, $expected + return array( + array( + array( + 'email1' => '', + ), + 'email1', + array( + array( + 'not_empty' + ) + ), + array( + 'email1' => 'email1 must not be empty' + ), + ) + ); + } + + /** + * http://dev.kohanaframework.org/issues/4201 + * + * @test + * @ticket 4201 + * @covers Validation::rule + * @dataProvider provider_rule_label_regex + */ + public function test_rule_label_regex($data, $field, $rules, $expected) + { + $validation = Validation::factory($data)->rules($field, $rules); + + $validation->check(); + + $errors = $validation->errors(''); + + $this->assertSame($errors, $expected); + } } From fb52a03da4e0e4af02501ab2edd414588329641c Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Sat, 11 Jan 2014 17:08:24 +0000 Subject: [PATCH 09/72] #4079 - Route::uri() Should encode parameters Route::uri() does not handle special characters well, so now it uses rawurlencode to fix this problem See: http://dev.kohanaframework.org/issues/4079 --- classes/kohana/route.php | 5 +++++ tests/kohana/RouteTest.php | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/classes/kohana/route.php b/classes/kohana/route.php index 39f7720c8..19d47e970 100644 --- a/classes/kohana/route.php +++ b/classes/kohana/route.php @@ -456,6 +456,11 @@ public function is_external() */ public function uri(array $params = NULL) { + if (is_array($params)) + { + $params = array_map('rawurlencode', $params); + } + // Start with the routed URI $uri = $this->_uri; diff --git a/tests/kohana/RouteTest.php b/tests/kohana/RouteTest.php index e57c45a9e..30104cd39 100644 --- a/tests/kohana/RouteTest.php +++ b/tests/kohana/RouteTest.php @@ -715,4 +715,41 @@ public function test_external_route_includes_params_in_uri($route, $defaults, $e $this->assertSame($expected_uri, Route::get('test')->uri()); } + + /** + * Provides test data for test_route_uri_encode_parameters + * + * @return array + */ + public function provider_route_uri_encode_parameters() + { + return array( + array( + 'article', + 'blog/article/', + array( + 'controller' => 'home', + 'action' => 'index' + ), + 'blog/article/Article%20name%20with%20special%20chars%20%5C%20%23%23' + ) + ); + } + + /** + * http://dev.kohanaframework.org/issues/4079 + * + * @test + * @covers Route::get + * @ticket 4079 + * @dataProvider provider_route_uri_encode_parameters + */ + public function test_route_uri_encode_parameters($name, $uri_callback, $defaults, $expected) + { + Route::set($name, $uri_callback)->defaults($defaults); + + $get_route_uri = Route::get($name)->uri(array('article_name' => 'Article name with special chars \\ ##')); + + $this->assertSame($expected, $get_route_uri); + } } From ce4ab50c08f57a37d0d8fd080e0cb64bc6dd76f7 Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Sat, 11 Jan 2014 19:20:05 +0000 Subject: [PATCH 10/72] Fixed the typo with additional braclet --- classes/kohana/validation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/validation.php b/classes/kohana/validation.php index f71c576fe..b0232686d 100644 --- a/classes/kohana/validation.php +++ b/classes/kohana/validation.php @@ -219,7 +219,7 @@ public function rule($field, $rule, array $params = NULL) if ($field !== TRUE AND ! isset($this->_labels[$field])) { // Set the field label to the field name - $this->_labels[$field] = $field); + $this->_labels[$field] = $field; } // Store the rule and params for this rule From 91202dd18178ad2e3c710677f3f11bf994a85707 Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Sat, 11 Jan 2014 21:22:19 +0000 Subject: [PATCH 11/72] #4482 - Array to string conversion in deep Arr::merge When using Arr::merge to merge arrays, the deeper array merges failed and caused a ErrorException [ Notice ]: Array to string conversion See: http://dev.kohanaframework.org/issues/4482 --- classes/kohana/arr.php | 10 +++++++++- tests/kohana/ArrTest.php | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 1 deletion(-) diff --git a/classes/kohana/arr.php b/classes/kohana/arr.php index 9df715ee6..e45f6df5f 100644 --- a/classes/kohana/arr.php +++ b/classes/kohana/arr.php @@ -441,7 +441,15 @@ public static function merge(array $a1, array $a2) else { // Find the values that are not already present - $diff = array_diff($val, $result[$key]); + $diff = array(); + + foreach ($val as $val_val) + { + if ( ! in_array($val_val, $result[$key])) + { + $diff[] = $val_val; + } + } // Indexed arrays are merged to prevent duplicates $result[$key] = array_merge($result[$key], $diff); diff --git a/tests/kohana/ArrTest.php b/tests/kohana/ArrTest.php index 54bdc7cea..435cc470c 100644 --- a/tests/kohana/ArrTest.php +++ b/tests/kohana/ArrTest.php @@ -280,6 +280,45 @@ public function provider_merge() array('foo' => array('bar')), array('foo' => 'bar'), ), + /** + * @ticket 4482 + */ + array( + array( + 'foo' => array( + 'bar' => array( + array( + 'foo' => 'bar', + 'bar' => TRUE, + ), + array( + 'foo1' => 'foo', + 'bar1' => FALSE, + ), + ), + ), + ), + array( + 'foo' => array( + 'bar' => array( + array( + 'foo' => 'bar', + 'bar' => TRUE, + ), + ), + ), + ), + array( + 'foo' => array( + 'bar' => array( + array( + 'foo1' => 'foo', + 'bar1' => FALSE, + ), + ), + ), + ) + ) ); } From 00df092ca43faeb6cac33da10e0c28e11440a072 Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Sat, 11 Jan 2014 22:09:51 +0000 Subject: [PATCH 12/72] Added strict in in_array Added extra entry to array in test and changed in_array to strict. Performance: Non Strinct: http://i.imgur.com/JiRtUxQ.png Strict: http://i.imgur.com/nRmgHVS.png --- classes/kohana/arr.php | 2 +- tests/kohana/ArrTest.php | 13 +++++-------- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/classes/kohana/arr.php b/classes/kohana/arr.php index e45f6df5f..945247114 100644 --- a/classes/kohana/arr.php +++ b/classes/kohana/arr.php @@ -445,7 +445,7 @@ public static function merge(array $a1, array $a2) foreach ($val as $val_val) { - if ( ! in_array($val_val, $result[$key])) + if ( ! in_array($val_val, $result[$key], TRUE)) { $diff[] = $val_val; } diff --git a/tests/kohana/ArrTest.php b/tests/kohana/ArrTest.php index 435cc470c..2260cd3c6 100644 --- a/tests/kohana/ArrTest.php +++ b/tests/kohana/ArrTest.php @@ -287,22 +287,19 @@ public function provider_merge() array( 'foo' => array( 'bar' => array( + 'foo' => TRUE, array( - 'foo' => 'bar', 'bar' => TRUE, - ), - array( - 'foo1' => 'foo', 'bar1' => FALSE, ), ), - ), + ) ), array( 'foo' => array( 'bar' => array( + 'foo' => 'php', array( - 'foo' => 'bar', 'bar' => TRUE, ), ), @@ -311,14 +308,14 @@ public function provider_merge() array( 'foo' => array( 'bar' => array( + 'foo' => TRUE, array( - 'foo1' => 'foo', 'bar1' => FALSE, ), ), ), ) - ) + ), ); } From 7ca1fe68ada69cee45f631c49cf0885de7d8d040 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sun, 30 Sep 2012 21:30:28 -0700 Subject: [PATCH 13/72] the third parameter is the one you are matching, not the second refs (#4432) --- messages/validation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/messages/validation.php b/messages/validation.php index dcaa38987..345a5e8e0 100644 --- a/messages/validation.php +++ b/messages/validation.php @@ -15,7 +15,7 @@ 'exact_length' => ':field must be exactly :param2 characters long', 'in_array' => ':field must be one of the available options', 'ip' => ':field must be an ip address', - 'matches' => ':field must be the same as :param2', + 'matches' => ':field must be the same as :param3', 'min_length' => ':field must be at least :param2 characters long', 'max_length' => ':field must not exceed :param2 characters long', 'not_empty' => ':field must not be empty', From 29073be965cbaa84e685d33307d9a1a935d662d7 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sat, 11 Jan 2014 15:39:48 -0800 Subject: [PATCH 14/72] refs #3896 - fix unit tests for proper matches validation --- tests/kohana/CoreTest.php | 2 +- tests/kohana/ValidationTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/kohana/CoreTest.php b/tests/kohana/CoreTest.php index 5f4adf0d8..cd70bd024 100644 --- a/tests/kohana/CoreTest.php +++ b/tests/kohana/CoreTest.php @@ -171,7 +171,7 @@ public function provider_message() 'exact_length' => ':field must be exactly :param2 characters long', 'in_array' => ':field must be one of the available options', 'ip' => ':field must be an ip address', - 'matches' => ':field must be the same as :param2', + 'matches' => ':field must be the same as :param3', 'min_length' => ':field must be at least :param2 characters long', 'max_length' => ':field must not exceed :param2 characters long', 'not_empty' => ':field must not be empty', diff --git a/tests/kohana/ValidationTest.php b/tests/kohana/ValidationTest.php index b29aaecb3..6acb292fa 100644 --- a/tests/kohana/ValidationTest.php +++ b/tests/kohana/ValidationTest.php @@ -542,7 +542,7 @@ public function test_data_stays_unaltered() public function test_object_parameters_not_in_messages() { $validation = Validation::factory(array('foo' => 'foo')) - ->rule('bar', 'matches', array(':validation', 'foo', ':field')); + ->rule('bar', 'matches', array(':validation', ':field', 'foo')); $validation->check(); $errors = $validation->errors('validation'); From 8f99de40049c39932faa0f568de422e5b82294f6 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sat, 11 Jan 2014 17:32:59 -0800 Subject: [PATCH 15/72] refs #4287 - fix memory leak in validation class --- classes/kohana/validation.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/classes/kohana/validation.php b/classes/kohana/validation.php index b0232686d..1c8d8abb3 100644 --- a/classes/kohana/validation.php +++ b/classes/kohana/validation.php @@ -430,6 +430,13 @@ public function check() } } + // Unbind all the automatic bindings to avoid memory leaks. + unset($this->_bound[':validation']); + unset($this->_bound[':data']); + unset($this->_bound[':field']); + unset($this->_bound[':value']); + + // Restore the data to its original form $this->_data = $original; From 14342a5f9678d243f5483303c80b15c4cef87085 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sun, 12 Jan 2014 12:58:59 -0800 Subject: [PATCH 16/72] Avoid division by zero --- views/profiler/stats.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/views/profiler/stats.php b/views/profiler/stats.php index ebfb489b7..c7cc550f9 100755 --- a/views/profiler/stats.php +++ b/views/profiler/stats.php @@ -35,7 +35,7 @@
s
-
+
@@ -47,7 +47,7 @@
kB
-
+
@@ -71,4 +71,4 @@ - \ No newline at end of file + From 1ad289c152b8622a31b549c847a3e85f3e007c08 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sun, 12 Jan 2014 19:35:33 -0800 Subject: [PATCH 17/72] Follow up to 3bc535eb536e54451b722da9699d052c863ac1b4, determine the download mime by the extension rather than the actual download file (which will probably not exist). Refs #4344 refs #4592 Conflicts: classes/kohana/response.php --- classes/kohana/response.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/kohana/response.php b/classes/kohana/response.php index 51381fc20..420dc9a07 100644 --- a/classes/kohana/response.php +++ b/classes/kohana/response.php @@ -445,8 +445,8 @@ public function send_file($filename, $download = NULL, array $options = NULL) if ( ! isset($mime)) { - // Get the mime type - $mime = File::mime_by_ext(strtolower(pathinfo($download, PATHINFO_EXTENSION))); + // Get the mime type from the extension of the download file + $mime = File::mime_by_ext(pathinfo($download, PATHINFO_EXTENSION)); } // Open the file for reading From db3e91fc7a15b2a47f33004b36cd7a2ac57af55c Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sun, 12 Jan 2014 20:51:15 -0800 Subject: [PATCH 18/72] Replaced empty string with zero Outputing as inline style, so empty string doesn't help --- views/profiler/stats.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/profiler/stats.php b/views/profiler/stats.php index c7cc550f9..f134cf824 100755 --- a/views/profiler/stats.php +++ b/views/profiler/stats.php @@ -35,7 +35,7 @@
s
-
+
@@ -47,7 +47,7 @@
kB
-
+
From d93caff9f563c6ee830d7ada01607b1906bdb09e Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sun, 12 Jan 2014 23:21:03 -0800 Subject: [PATCH 19/72] replaced occurances of kohanaphp.com with kohanaframework.org except the occurance: github.com/isaiahdw/kohanaphp.com/blob/f2afe8e28b/application/bootstrap.php was not replaced --- guide/kohana/bootstrap.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/guide/kohana/bootstrap.md b/guide/kohana/bootstrap.md index 2b8c26ad5..19379249a 100644 --- a/guide/kohana/bootstrap.md +++ b/guide/kohana/bootstrap.md @@ -52,7 +52,7 @@ You can add conditional statements to make the bootstrap have different values b /** * Set the environment status by the domain. */ -if (strpos($_SERVER['HTTP_HOST'], 'kohanaphp.com') !== FALSE) +if (strpos($_SERVER['HTTP_HOST'], 'kohanaframework.org') !== FALSE) { // We are live! Kohana::$environment = Kohana::PRODUCTION; @@ -66,7 +66,7 @@ if (strpos($_SERVER['HTTP_HOST'], 'kohanaphp.com') !== FALSE) ... [trimmed] */ Kohana::init(array( - 'base_url' => Kohana::$environment === Kohana::PRODUCTION ? '/' : '/kohanaphp.com/', + 'base_url' => Kohana::$environment === Kohana::PRODUCTION ? '/' : '/kohanaframework.org/', 'caching' => Kohana::$environment === Kohana::PRODUCTION, 'profile' => Kohana::$environment !== Kohana::PRODUCTION, 'index_file' => FALSE, From 4fc1eaba0bb4bd93f8548d01cc8908e43b3505f6 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sun, 12 Jan 2014 23:25:35 -0800 Subject: [PATCH 20/72] replaced occurances of kohanaphp.com with kohanaframework.org --- guide/kohana/index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guide/kohana/index.md b/guide/kohana/index.md index 102439634..32c308751 100644 --- a/guide/kohana/index.md +++ b/guide/kohana/index.md @@ -20,4 +20,4 @@ We are working very hard to provide complete documentation. To help improve the ## Unofficial Documentation -If you are having trouble finding an answer here, have a look through the [unofficial wiki](http://kerkness.ca/wiki/doku.php). Your answer may also be found by searching the [forum](http://forum.kohanaphp.com/) or [stackoverflow](http://stackoverflow.com/questions/tagged/kohana) followed by asking your question on either. Additionally, you can chat with the community of developers on the freenode [#kohana](irc://irc.freenode.net/kohana) IRC channel. \ No newline at end of file +If you are having trouble finding an answer here, have a look through the [unofficial wiki](http://kerkness.ca/wiki/doku.php). Your answer may also be found by searching the [forum](http://forum.kohanaframework.org/) or [stackoverflow](http://stackoverflow.com/questions/tagged/kohana) followed by asking your question on either. Additionally, you can chat with the community of developers on the freenode [#kohana](irc://irc.freenode.net/kohana) IRC channel. From 6f73da3eaa66c833addd753af93420e90a0fd147 Mon Sep 17 00:00:00 2001 From: Jack Ellis Date: Mon, 13 Jan 2014 09:15:21 +0000 Subject: [PATCH 21/72] Removed pointless array check and moved uri's key & value to provider --- classes/kohana/route.php | 2 +- tests/kohana/RouteTest.php | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/classes/kohana/route.php b/classes/kohana/route.php index 19d47e970..b4c5dfc8f 100644 --- a/classes/kohana/route.php +++ b/classes/kohana/route.php @@ -456,7 +456,7 @@ public function is_external() */ public function uri(array $params = NULL) { - if (is_array($params)) + if ($params) { $params = array_map('rawurlencode', $params); } diff --git a/tests/kohana/RouteTest.php b/tests/kohana/RouteTest.php index 30104cd39..86ad5ac7c 100644 --- a/tests/kohana/RouteTest.php +++ b/tests/kohana/RouteTest.php @@ -731,6 +731,8 @@ public function provider_route_uri_encode_parameters() 'controller' => 'home', 'action' => 'index' ), + 'article_name', + 'Article name with special chars \\ ##', 'blog/article/Article%20name%20with%20special%20chars%20%5C%20%23%23' ) ); @@ -744,11 +746,11 @@ public function provider_route_uri_encode_parameters() * @ticket 4079 * @dataProvider provider_route_uri_encode_parameters */ - public function test_route_uri_encode_parameters($name, $uri_callback, $defaults, $expected) + public function test_route_uri_encode_parameters($name, $uri_callback, $defaults, $uri_key, $uri_value, $expected) { Route::set($name, $uri_callback)->defaults($defaults); - $get_route_uri = Route::get($name)->uri(array('article_name' => 'Article name with special chars \\ ##')); + $get_route_uri = Route::get($name)->uri(array($uri_key => $uri_value)); $this->assertSame($expected, $get_route_uri); } From 6fb0eff9b9c314d536d0f1d6963a25044309dd70 Mon Sep 17 00:00:00 2001 From: biakaveron Date: Mon, 13 Jan 2014 22:10:57 +0400 Subject: [PATCH 22/72] Internal routing must ignore external routes, fixes #4235 --- classes/kohana/request.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classes/kohana/request.php b/classes/kohana/request.php index c362076f5..5436c7474 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -578,6 +578,12 @@ public static function process_uri($uri, $routes = NULL) foreach ($routes as $name => $route) { + // Use external routes for reverse routing only + if ($route->is_external()) + { + continue; + } + // We found something suitable if ($params = $route->matches($uri)) { From 83f8f781b98217c0bd9d32f7cdc815ff9dbd051c Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Thu, 23 Jan 2014 16:41:25 +0200 Subject: [PATCH 23/72] created failing test --- tests/kohana/TextTest.php | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/tests/kohana/TextTest.php b/tests/kohana/TextTest.php index 1d5d867c9..93ce7ee5a 100644 --- a/tests/kohana/TextTest.php +++ b/tests/kohana/TextTest.php @@ -384,9 +384,23 @@ function provider_widont() { return array ( - array('No gain, no pain', 'No gain, no pain'), - array("spaces?what'rethey?", "spaces?what'rethey?"), - array('', ''), + array( + 'No gain, no pain', + 'No gain, no pain', + ), + array( + "spaces?what'rethey?", + "spaces?what'rethey?", + ), + // @issue 3499 + array( + 'with HTML at the end: Kohana', + 'with HTML at the end: Kohana', + ), + array( + '', + '', + ), ); } From c0cc9a97e59c799e24ba5d4966d58f16a0f23b31 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Thu, 23 Jan 2014 16:43:54 +0200 Subject: [PATCH 24/72] fixed with regex courtesy of the Typogrify project --- classes/kohana/text.php | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/classes/kohana/text.php b/classes/kohana/text.php index 17dcca3a8..e3d48fd43 100644 --- a/classes/kohana/text.php +++ b/classes/kohana/text.php @@ -587,20 +587,23 @@ public static function number($number) * * echo Text::widont($text); * + * regex courtesy of the Typogrify project + * @link http://code.google.com/p/typogrify/ + * * @param string $str text to remove widows from * @return string */ public static function widont($str) { - $str = rtrim($str); - $space = strrpos($str, ' '); - - if ($space !== FALSE) - { - $str = substr($str, 0, $space).' '.substr($str, $space + 1); - } - - return $str; + $widont_regex = " + ((?:]*>)|[^<>\s]) # must be proceeded by an approved inline opening or closing tag or a nontag/nonspace + \s+ # the space to replace + ([^<>\s]+ # must be flollowed by non-tag non-space characters + \s* # optional white space! + (\s*)* # optional closing inline tags with optional white space after each + (()|$)) # end with a closing p, h1-6, li or the end of the string + "; + return preg_replace($widont_regex, ' $2', $str); } } // End text From 8d7b304181c0a637fdfea55c13a7630ba7a3384c Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 24 Jan 2014 15:54:23 +0200 Subject: [PATCH 25/72] fixed phpdoc for Request::url function params Removed * @param array $params URI parameters --- classes/kohana/request.php | 1 - 1 file changed, 1 deletion(-) diff --git a/classes/kohana/request.php b/classes/kohana/request.php index c362076f5..a2993e51f 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -899,7 +899,6 @@ public function uri() * * echo URL::site($this->request->uri(), $protocol); * - * @param array $params URI parameters * @param mixed $protocol protocol string or Request object * @return string * @since 3.0.7 From 89d0d99df4cf82003fabade3bde64fce41fde7ff Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 24 Jan 2014 15:58:04 +0200 Subject: [PATCH 26/72] fixed phpdoc for test_url function --- tests/kohana/RequestTest.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/kohana/RequestTest.php b/tests/kohana/RequestTest.php index 3941d5488..6e332f0f6 100644 --- a/tests/kohana/RequestTest.php +++ b/tests/kohana/RequestTest.php @@ -310,10 +310,10 @@ public function provider_url() * @test * @dataProvider provider_url * @covers Request::url - * @param string $route the route to use - * @param array $params params to pass to route::uri - * @param string $protocol the protocol to use - * @param array $expected The string we expect + * @param string $uri the uri to use + * @param mixed $protocol the protocol to use (string or Request object) + * @param bool $is_cli whether the call is from CLI or not + * @param string $expected The url string we expect */ public function test_url($uri, $protocol, $is_cli, $expected) { From 27f3f75114d69e37c74dbadb8f490dbc5b4fa5c3 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 24 Jan 2014 16:04:57 +0200 Subject: [PATCH 27/72] add the failing test --- tests/kohana/RequestTest.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/kohana/RequestTest.php b/tests/kohana/RequestTest.php index 6e332f0f6..a3a3c1fbf 100644 --- a/tests/kohana/RequestTest.php +++ b/tests/kohana/RequestTest.php @@ -301,6 +301,12 @@ public function provider_url() TRUE, 'http://localhost/kohana/foo' ), + array( + 'http://www.google.com', + 'http', + TRUE, + 'http://www.google.com' + ), ); } From c14bbbddc34717636111c2bc90a3a90869be13ea Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 24 Jan 2014 16:05:46 +0200 Subject: [PATCH 28/72] add a condition to test if the url is external --- classes/kohana/request.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/classes/kohana/request.php b/classes/kohana/request.php index a2993e51f..9ee2854ee 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -906,8 +906,11 @@ public function uri() */ public function url($protocol = NULL) { - // Create a URI with the current route and convert it to a URL - return URL::site($this->uri(), $protocol); + return $this->is_external() ? + // if it is an external request return the uri + $this->uri() : + // Create a URI with the current route and convert it to a URL + URL::site($this->uri(), $protocol); } /** From 1f86402f4735a74077acac0ff24d7b2e2a632195 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 24 Jan 2014 22:44:01 +0200 Subject: [PATCH 29/72] Use Kohana_UTF8 from version 3.3 to apply all the patches Fixes Kohana_UTF8Test::test_clean with data set no.3 and Kohana_DebugTest::test_dump with data set no.6 --- classes/kohana/utf8.php | 112 +++++++++++++++++++++------------------- 1 file changed, 60 insertions(+), 52 deletions(-) diff --git a/classes/kohana/utf8.php b/classes/kohana/utf8.php index c3135d3fd..386ed8a87 100644 --- a/classes/kohana/utf8.php +++ b/classes/kohana/utf8.php @@ -63,21 +63,21 @@ public static function clean($var, $charset = NULL) foreach ($var as $key => $val) { // Recursion! - $var[self::clean($key)] = self::clean($val); + $var[UTF8::clean($key)] = UTF8::clean($val); } } elseif (is_string($var) AND $var !== '') { // Remove control characters - $var = self::strip_ascii_ctrl($var); + $var = UTF8::strip_ascii_ctrl($var); - if ( ! self::is_ascii($var)) + if ( ! UTF8::is_ascii($var)) { // Disable notices $error_reporting = error_reporting(~E_NOTICE); // iconv is expensive, so it is only used when needed - $var = iconv($charset, $charset.'//IGNORE', $var); + $var = mb_convert_encoding($var, $charset, $charset); // Turn notices back on error_reporting($error_reporting); @@ -144,12 +144,12 @@ public static function strip_non_ascii($str) */ public static function transliterate_to_ascii($str, $case = 0) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _transliterate_to_ascii($str, $case); @@ -170,12 +170,12 @@ public static function strlen($str) if (UTF8::$server_utf8) return mb_strlen($str, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strlen($str); @@ -200,12 +200,12 @@ public static function strpos($str, $search, $offset = 0) if (UTF8::$server_utf8) return mb_strpos($str, $search, $offset, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strpos($str, $search, $offset); @@ -230,12 +230,12 @@ public static function strrpos($str, $search, $offset = 0) if (UTF8::$server_utf8) return mb_strrpos($str, $search, $offset, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strrpos($str, $search, $offset); @@ -262,12 +262,12 @@ public static function substr($str, $offset, $length = NULL) ? mb_substr($str, $offset, mb_strlen($str), Kohana::$charset) : mb_substr($str, $offset, $length, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _substr($str, $offset, $length); @@ -287,12 +287,12 @@ public static function substr($str, $offset, $length = NULL) */ public static function substr_replace($str, $replacement, $offset, $length = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _substr_replace($str, $replacement, $offset, $length); @@ -314,12 +314,12 @@ public static function strtolower($str) if (UTF8::$server_utf8) return mb_strtolower($str, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strtolower($str); @@ -340,12 +340,12 @@ public static function strtoupper($str) if (UTF8::$server_utf8) return mb_strtoupper($str, Kohana::$charset); - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strtoupper($str); @@ -363,12 +363,12 @@ public static function strtoupper($str) */ public static function ucfirst($str) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _ucfirst($str); @@ -387,12 +387,12 @@ public static function ucfirst($str) */ public static function ucwords($str) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _ucwords($str); @@ -413,12 +413,12 @@ public static function ucwords($str) */ public static function strcasecmp($str1, $str2) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strcasecmp($str1, $str2); @@ -442,12 +442,12 @@ public static function strcasecmp($str1, $str2) */ public static function str_ireplace($search, $replace, $str, & $count = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _str_ireplace($search, $replace, $str, $count); @@ -468,12 +468,12 @@ public static function str_ireplace($search, $replace, $str, & $count = NULL) */ public static function stristr($str, $search) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _stristr($str, $search); @@ -494,12 +494,12 @@ public static function stristr($str, $search) */ public static function strspn($str, $mask, $offset = NULL, $length = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strspn($str, $mask, $offset, $length); @@ -520,12 +520,12 @@ public static function strspn($str, $mask, $offset = NULL, $length = NULL) */ public static function strcspn($str, $mask, $offset = NULL, $length = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strcspn($str, $mask, $offset, $length); @@ -546,12 +546,12 @@ public static function strcspn($str, $mask, $offset = NULL, $length = NULL) */ public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_type = STR_PAD_RIGHT) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _str_pad($str, $final_str_length, $pad_str, $pad_type); @@ -570,12 +570,12 @@ public static function str_pad($str, $final_str_length, $pad_str = ' ', $pad_typ */ public static function str_split($str, $split_length = 1) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _str_split($str, $split_length); @@ -592,12 +592,12 @@ public static function str_split($str, $split_length = 1) */ public static function strrev($str) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _strrev($str); @@ -616,12 +616,12 @@ public static function strrev($str) */ public static function trim($str, $charlist = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _trim($str, $charlist); @@ -640,12 +640,12 @@ public static function trim($str, $charlist = NULL) */ public static function ltrim($str, $charlist = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _ltrim($str, $charlist); @@ -664,12 +664,12 @@ public static function ltrim($str, $charlist = NULL) */ public static function rtrim($str, $charlist = NULL) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _rtrim($str, $charlist); @@ -687,12 +687,12 @@ public static function rtrim($str, $charlist = NULL) */ public static function ord($chr) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _ord($chr); @@ -717,12 +717,12 @@ public static function ord($chr) */ public static function to_unicode($str) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _to_unicode($str); @@ -747,12 +747,12 @@ public static function to_unicode($str) */ public static function from_unicode($arr) { - if ( ! isset(self::$called[__FUNCTION__])) + if ( ! isset(UTF8::$called[__FUNCTION__])) { require Kohana::find_file('utf8', __FUNCTION__); // Function has been called - self::$called[__FUNCTION__] = TRUE; + UTF8::$called[__FUNCTION__] = TRUE; } return _from_unicode($arr); @@ -760,6 +760,14 @@ public static function from_unicode($arr) } // End UTF8 +/** + * Set the mb_substitute_character to "none" + * + * @link http://www.php.net/manual/function.mb-substitute-character.php + */ + +mb_substitute_character('none'); + if (Kohana_UTF8::$server_utf8 === NULL) { // Determine if this server supports UTF-8 natively From eba1b22f9c85ab40ae7e7f80a9a736fd14b87441 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sat, 25 Jan 2014 09:26:47 +0200 Subject: [PATCH 30/72] Set and reset mb_substitute_character To disable substituting illigal characters with the default `'?'` character. I think this solution is better than to set `mb_substitute_character('none');` at the end of the file. I also think this solution makes the setting of `mb_substitute_character('none');` in `bootstrap.php` redundant. --- classes/kohana/utf8.php | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/classes/kohana/utf8.php b/classes/kohana/utf8.php index 386ed8a87..4e5a26282 100644 --- a/classes/kohana/utf8.php +++ b/classes/kohana/utf8.php @@ -73,14 +73,19 @@ public static function clean($var, $charset = NULL) if ( ! UTF8::is_ascii($var)) { - // Disable notices - $error_reporting = error_reporting(~E_NOTICE); + // Set the mb_substitute_character() value into temporary variable + $mb_substitute_character = mb_substitute_character(); + + // Disable substituting illigal characters with the default '?' character + mb_substitute_character('none'); + // iconv is expensive, so it is only used when needed $var = mb_convert_encoding($var, $charset, $charset); + + // Reset mb_substitute_character() value back to the original setting + mb_substitute_character($mb_substitute_character); - // Turn notices back on - error_reporting($error_reporting); } } @@ -760,14 +765,6 @@ public static function from_unicode($arr) } // End UTF8 -/** - * Set the mb_substitute_character to "none" - * - * @link http://www.php.net/manual/function.mb-substitute-character.php - */ - -mb_substitute_character('none'); - if (Kohana_UTF8::$server_utf8 === NULL) { // Determine if this server supports UTF-8 natively From 3fb562f9c12cd222526aa64e29e0aa84da5114e1 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Sat, 25 Jan 2014 09:28:32 +0200 Subject: [PATCH 31/72] replaced iconv with mb_convert_encoding in comments --- classes/kohana/utf8.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/utf8.php b/classes/kohana/utf8.php index 4e5a26282..72fba8966 100644 --- a/classes/kohana/utf8.php +++ b/classes/kohana/utf8.php @@ -80,7 +80,7 @@ public static function clean($var, $charset = NULL) // Disable substituting illigal characters with the default '?' character mb_substitute_character('none'); - // iconv is expensive, so it is only used when needed + // mb_convert_encoding is expensive, so it is only used when needed $var = mb_convert_encoding($var, $charset, $charset); // Reset mb_substitute_character() value back to the original setting From 3a8443e53c2fe462af3cd9e22fc2e29828ecfa2c Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Tue, 28 Jan 2014 05:56:37 -0800 Subject: [PATCH 32/72] default to original ini setting if Cookie::$domain not set We should not let PHP override the default setting if Cookie::$domain is not set. Otherwise it will send cookies with the host name of the server which generated the cookie. --- classes/kohana/session/native.php | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/classes/kohana/session/native.php b/classes/kohana/session/native.php index 0858f2ab7..e7edf057f 100644 --- a/classes/kohana/session/native.php +++ b/classes/kohana/session/native.php @@ -24,8 +24,29 @@ public function id() */ protected function _read($id = NULL) { + // session_set_cookie_params will override php ini settings + // If Cookie::$domain is NULL or empty and is passed, PHP + // will override ini and sent cookies with the host name + // of the server which generated the cookie + // + // see issue #3604 + // + // see http://www.php.net/manual/en/function.session-set-cookie-params.php + // see http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain + // + // set to Cookie::$domain if available, otherwise default to ini setting + $session_cookie_domain = empty(Cookie::$domain) + ? ini_get('session.cookie_domain') + : Cookie::$domain; + // Sync up the session cookie with Cookie parameters - session_set_cookie_params($this->_lifetime, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly); + session_set_cookie_params( + $this->_lifetime, + Cookie::$path, + $session_cookie_domain, + Cookie::$secure, + Cookie::$httponly + ); // Do not allow PHP to send Cache-Control headers session_cache_limiter(FALSE); From 84ebc36a082ca805c009f2ed59ea4cc38a820cc0 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 29 Jan 2014 07:56:55 -0800 Subject: [PATCH 33/72] Adjusted ternary operator to comply with coding standards --- classes/kohana/request.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classes/kohana/request.php b/classes/kohana/request.php index 9ee2854ee..df562e335 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -906,11 +906,12 @@ public function uri() */ public function url($protocol = NULL) { - return $this->is_external() ? + // test if the request is external + return $this->is_external() // if it is an external request return the uri - $this->uri() : + ? $this->uri() // Create a URI with the current route and convert it to a URL - URL::site($this->uri(), $protocol); + : URL::site($this->uri(), $protocol); } /** From 071fab978ba43c44d70cbb87c838fdb78eb93eca Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 29 Jan 2014 08:01:20 -0800 Subject: [PATCH 34/72] Make it more readable, as suggested by @WinterSilence --- classes/kohana/request.php | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/classes/kohana/request.php b/classes/kohana/request.php index df562e335..3e33cd939 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -906,14 +906,15 @@ public function uri() */ public function url($protocol = NULL) { - // test if the request is external - return $this->is_external() - // if it is an external request return the uri - ? $this->uri() - // Create a URI with the current route and convert it to a URL - : URL::site($this->uri(), $protocol); - } + if ($this->is_external()) + { + // If it's an external request return the URI + return $this->uri(); + } + // Create a URI with the current route, convert to a URL and returns + return URL::site($this->uri(), $protocol); + } /** * Retrieves a value from the route parameters. * From e55bffd1f78e5e1a179c70c328eccc25cb951333 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 29 Jan 2014 10:06:01 -0800 Subject: [PATCH 35/72] commented comments to a multi line comment block as suggested by @Zeelot --- classes/kohana/session/native.php | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/classes/kohana/session/native.php b/classes/kohana/session/native.php index e7edf057f..626f6bd16 100644 --- a/classes/kohana/session/native.php +++ b/classes/kohana/session/native.php @@ -24,17 +24,19 @@ public function id() */ protected function _read($id = NULL) { - // session_set_cookie_params will override php ini settings - // If Cookie::$domain is NULL or empty and is passed, PHP - // will override ini and sent cookies with the host name - // of the server which generated the cookie - // - // see issue #3604 - // - // see http://www.php.net/manual/en/function.session-set-cookie-params.php - // see http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain - // - // set to Cookie::$domain if available, otherwise default to ini setting + /** + * session_set_cookie_params will override php ini settings + * If Cookie::$domain is NULL or empty and is passed, PHP + * will override ini and sent cookies with the host name + * of the server which generated the cookie + * + * see issue #3604 + * + * see http://www.php.net/manual/en/function.session-set-cookie-params.php + * see http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain + * + * set to Cookie::$domain if available, otherwise default to ini setting + * / $session_cookie_domain = empty(Cookie::$domain) ? ini_get('session.cookie_domain') : Cookie::$domain; From 4d13bfbfc4ddba45ce45d30c27dc9de385823888 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Mon, 3 Feb 2014 03:44:20 -0800 Subject: [PATCH 36/72] Properly close multi-line comment (remove space) --- classes/kohana/session/native.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/session/native.php b/classes/kohana/session/native.php index 626f6bd16..172d3b9e6 100644 --- a/classes/kohana/session/native.php +++ b/classes/kohana/session/native.php @@ -36,7 +36,7 @@ protected function _read($id = NULL) * see http://www.php.net/manual/en/session.configuration.php#ini.session.cookie-domain * * set to Cookie::$domain if available, otherwise default to ini setting - * / + */ $session_cookie_domain = empty(Cookie::$domain) ? ini_get('session.cookie_domain') : Cookie::$domain; From e722128f645a0b391f620a3bf6b49d5cb81ee721 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 5 Feb 2014 10:56:50 +0200 Subject: [PATCH 37/72] Added a bunch of tests from the Typogrify project Also, comment out the tests from issue no. 3499 --- tests/kohana/TextTest.php | 77 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 5 deletions(-) diff --git a/tests/kohana/TextTest.php b/tests/kohana/TextTest.php index 93ce7ee5a..2084229c4 100644 --- a/tests/kohana/TextTest.php +++ b/tests/kohana/TextTest.php @@ -384,6 +384,66 @@ function provider_widont() { return array ( + // A very simple widont test + array( + 'A very simple test', + 'A very simple test', + ), + // Single word items shouldn't be changed + array( + 'Test', + 'Test', + ), + // Single word after single space shouldn't be changed either + array( + ' Test', + ' Test', + ), + // Single word with HTML all around + array( + '
  • Test

    • ', + '
      • Test

        • ', + ), + // Single word after single space with HTML all around + array( + '
          • Test

            • ', + '
              • Test

                • ', + ), + // Widont with more than one paragraph + array( + '

                  In a couple of paragraphs

                  paragraph two

                  ', + '

                  In a couple of paragraphs

                  paragraph two

                  ', + ), + // a link inside a heading + array( + '

                  In a link inside a heading

                  ', + '

                  In a link inside a heading

                  ', + ), + // a link followed by text + array( + '

                  In a link followed by other text

                  ', + '

                  In a link followed by other text

                  ', + ), + // empty html, with no text inside + array( + '

                  ', + '

                  ', + ), + // apparently, we don't love DIVs + array( + '
                  Divs get no love!
                  ', + '
                  Divs get no love!
                  ', + ), + // we don't love PREs, either + array( + '
                  Neither do PREs
                  ', + '
                  Neither do PREs
                  ', + ), + // but we love DIVs with paragraphs + array( + '

                  But divs with paragraphs do!

                  ', + '

                  But divs with paragraphs do!

                  ', + ), array( 'No gain, no pain', 'No gain, no pain', @@ -392,11 +452,18 @@ function provider_widont() "spaces?what'rethey?", "spaces?what'rethey?", ), - // @issue 3499 - array( - 'with HTML at the end: Kohana', - 'with HTML at the end: Kohana', - ), + /* + * // @issue 3499, with HTML at the end + * array( + * 'with HTML at the end  Kohana', + * 'with HTML at the end Kohana', + * ), + * // @issue 3499, with HTML with attributes at the end + * array( + * 'with HTML at the end: Kohana', + * 'with HTML at the end: Kohana', + * ), + */ array( '', '', From 9f21e222bc1ef790fed3b4ba69c609808642c8c9 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 5 Feb 2014 10:57:48 +0200 Subject: [PATCH 38/72] re-bugfix use '%' as delimiter and 'x' as modifier Also, replace with '$1 $2' instead of ' $2' --- classes/kohana/text.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classes/kohana/text.php b/classes/kohana/text.php index e3d48fd43..eb12254cf 100644 --- a/classes/kohana/text.php +++ b/classes/kohana/text.php @@ -595,15 +595,16 @@ public static function number($number) */ public static function widont($str) { - $widont_regex = " + // use '%' as delimiter and 'x' as modifier + $widont_regex = "% ((?:]*>)|[^<>\s]) # must be proceeded by an approved inline opening or closing tag or a nontag/nonspace \s+ # the space to replace ([^<>\s]+ # must be flollowed by non-tag non-space characters \s* # optional white space! (\s*)* # optional closing inline tags with optional white space after each (()|$)) # end with a closing p, h1-6, li or the end of the string - "; - return preg_replace($widont_regex, ' $2', $str); + %x"; + return preg_replace($widont_regex, '$1 $2', $str); } } // End text From 07e3986e23bba068096370bc104ffed6cc765727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Marinetti?= Date: Tue, 11 Feb 2014 18:16:23 +0100 Subject: [PATCH 39/72] Fix documentation mention of Request::instance Various place in guide and php comments were mentionning Request::instance() to be used. I replaced it either by Request::factory() or something more appropriate. --- classes/kohana/form.php | 2 +- classes/kohana/request.php | 4 ++-- guide/kohana/flow.md | 4 ++-- guide/kohana/mvc/controllers.md | 2 +- guide/kohana/routing.md | 8 ++++---- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/classes/kohana/form.php b/classes/kohana/form.php index f9606f1f1..3e6109d91 100644 --- a/classes/kohana/form.php +++ b/classes/kohana/form.php @@ -28,7 +28,7 @@ class Kohana_Form { * @param mixed $action form action, defaults to the current request URI, or [Request] class to use * @param array $attributes html attributes * @return string - * @uses Request::instance + * @uses Request * @uses URL::site * @uses HTML::attributes */ diff --git a/classes/kohana/request.php b/classes/kohana/request.php index fb59cd428..bd1986717 100644 --- a/classes/kohana/request.php +++ b/classes/kohana/request.php @@ -38,7 +38,7 @@ class Kohana_Request implements HTTP_Request { /** * Creates a new request object for the given URI. New requests should be - * created using the [Request::instance] or [Request::factory] methods. + * created using the [Request::factory] method. * * $request = Request::factory($uri); * @@ -758,7 +758,7 @@ protected static function _parse_accept( & $header, array $accepts = NULL) /** * Creates a new request object for the given URI. New requests should be - * created using the [Request::instance] or [Request::factory] methods. + * created using the [Request::factory] method. * * $request = new Request($uri); * diff --git a/guide/kohana/flow.md b/guide/kohana/flow.md index 81a2e54b1..76fdfe8cb 100644 --- a/guide/kohana/flow.md +++ b/guide/kohana/flow.md @@ -16,7 +16,7 @@ Every application follows the same flow: * Includes each module's `init.php` file, if it exists. * The `init.php` file can perform additional environment setup, including adding routes. 10. [Route::set] is called multiple times to define the [application routes](routing). - 11. [Request::instance] is called to start processing the request. + 11. [Request::factory] is called to start processing the request. 1. Checks each route that has been set until a match is found. 2. Creates the controller instance and passes the request to it. 3. Calls the [Controller::before] method. @@ -24,4 +24,4 @@ Every application follows the same flow: 5. Calls the [Controller::after] method. * The above 5 steps can be repeated multiple times when using [HMVC sub-requests](requests). 3. Application flow returns to index.php - 12. The main [Request] response is displayed \ No newline at end of file + 12. The main [Request] response is displayed diff --git a/guide/kohana/mvc/controllers.md b/guide/kohana/mvc/controllers.md index 29414825a..47af6077b 100644 --- a/guide/kohana/mvc/controllers.md +++ b/guide/kohana/mvc/controllers.md @@ -55,7 +55,7 @@ You can also have a controller extend another controller to share common things, Every controller has the `$this->request` property which is the [Request] object that called the controller. You can use this to get information about the current request, as well as set the response body via `$this->response->body($ouput)`. -Here is a partial list of the properties and methods available to `$this->request`. These can also be accessed via `Request::instance()`, but `$this->request` is provided as a shortcut. See the [Request] class for more information on any of these. +Here is a partial list of the properties and methods available to `$this->request`. See the [Request] class for more information on any of these. Property/method | What it does --- | --- diff --git a/guide/kohana/routing.md b/guide/kohana/routing.md index 07c9f5f77..24c411552 100644 --- a/guide/kohana/routing.md +++ b/guide/kohana/routing.md @@ -248,14 +248,14 @@ Let's say you decided later to make that route definition more verbose by changi One method you might use frequently is the shortcut [Request::uri] which is the same as the above except it assumes the current route, directory, controller and action. If our current route is the default and the uri was `users/list`, we can do the following to generate uris in the format `users/view/$id`: - $this->request->uri(array('action' => 'view', 'id' => $user_id)); - + $this->request->route()->uri(array('action' => 'view', 'id' => $user_id)); + Or if within a view, the preferable method is: - Request::instance()->uri(array('action' => 'view', 'id' => $user_id)); + Route::url('default', array('action' => 'view', 'id' => $user_id)); TODO: examples of using html::anchor in addition to the above examples ## Testing routes -TODO: mention bluehawk's devtools module \ No newline at end of file +TODO: mention bluehawk's devtools module From a8b2fe80aecabd7724ad1103b266cef5e1ef010f Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Thu, 13 Feb 2014 11:17:11 +0200 Subject: [PATCH 40/72] inject routes to avoid conflict with application's routes --- tests/kohana/RequestTest.php | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/tests/kohana/RequestTest.php b/tests/kohana/RequestTest.php index a3a3c1fbf..74c05e251 100644 --- a/tests/kohana/RequestTest.php +++ b/tests/kohana/RequestTest.php @@ -335,7 +335,14 @@ public function test_url($uri, $protocol, $is_cli, $expected) 'Kohana::$is_cli' => $is_cli, )); - $this->assertEquals(Request::factory($uri)->url($protocol), $expected); + // issue #3967: inject the route so that we don't conflict with the application's default route + $route = new Route('((/))'); + $route->defaults(array( + 'controller' => 'welcome', + 'action' => 'index', + )); + + $this->assertEquals(Request::factory($uri, NULL, array($route))->url($protocol), $expected); } /** @@ -436,8 +443,15 @@ public function test_post_max_size_exceeded($content_length, $expected) */ public function provider_uri_only_trimed_on_internal() { + // issue #3967: inject the route so that we don't conflict with the application's default route + $route = new Route('((/))'); + $route->defaults(array( + 'controller' => 'welcome', + 'action' => 'index', + )); + $old_request = Request::$initial; - Request::$initial = new Request(TRUE); + Request::$initial = new Request(TRUE, NULL, array($route)); $result = array( array( From f698da1aca22e24af711d68064625f5449907738 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 14 Feb 2014 14:28:16 +0200 Subject: [PATCH 41/72] allow Kohana shutdown properly, exit(1) in case of exception --- classes/kohana/core.php | 19 +++++++++++++++++++ classes/kohana/kohana/exception.php | 29 ++++++++++++++++++++++++----- 2 files changed, 43 insertions(+), 5 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 647aa6440..c4b6e8378 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -972,6 +972,25 @@ public static function error_handler($code, $error, $file = NULL, $line = NULL) */ public static function shutdown_handler() { + /* + * $shutdown_handler_visited is a static local function + * that will test if this function is already passed + * through by PHP runtime. + * + * If it is passed through already, we should exit with + * an error status. + * + * The second registration occurs inside Kohana's default + * exception handler. + * + * @see issue #3931 + */ + static $shutdown_handler_visited = FALSE; + if ($shutdown_handler_visited) { + exit(1); + } + $shutdown_handler_visited = TRUE; + if ( ! Kohana::$_init) { // Do not execute when not active diff --git a/classes/kohana/kohana/exception.php b/classes/kohana/kohana/exception.php index 6af406d47..65fa39ffb 100644 --- a/classes/kohana/kohana/exception.php +++ b/classes/kohana/kohana/exception.php @@ -89,6 +89,25 @@ public static function handler(Exception $e) { try { + /* + * + * We are registering our shutdown function again. + * By re-registering our shutdown function, we are + * basically asking PHP to run the shutdown function + * twice before exiting. + * + * The $shutdown_for_exception_registered is needed + * to ensure that we are not re-registering our shutdown + * function more than once. + * + * @see issue #3931 + */ + static $shutdown_for_exception_registered = FALSE; + if (!$shutdown_for_exception_registered) { + register_shutdown_function(array('Kohana', 'shutdown_handler')); + $shutdown_for_exception_registered = TRUE; + } + // Get the exception information $type = get_class($e); $code = $e->getCode(); @@ -146,7 +165,7 @@ public static function handler(Exception $e) // Just display the text of the exception echo "\n{$error}\n"; - exit(1); + return TRUE; } if ( ! headers_sent()) @@ -162,7 +181,7 @@ public static function handler(Exception $e) // Just display the text of the exception echo "\n{$error}\n"; - exit(1); + return TRUE; } // Start an output buffer @@ -183,7 +202,7 @@ public static function handler(Exception $e) // Display the contents of the output buffer echo ob_get_clean(); - exit(1); + return TRUE; } catch (Exception $e) { @@ -193,8 +212,8 @@ public static function handler(Exception $e) // Display the exception text echo Kohana_Exception::text($e), "\n"; - // Exit with an error status - exit(1); + // return + return TRUE; } } From e72b0ca8daa2a6aef7fda96e08b3c47d81a9e0be Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Fri, 14 Feb 2014 13:32:08 -0800 Subject: [PATCH 42/72] fix typo --- classes/kohana/core.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index c4b6e8378..1dd28c7f3 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -973,7 +973,7 @@ public static function error_handler($code, $error, $file = NULL, $line = NULL) public static function shutdown_handler() { /* - * $shutdown_handler_visited is a static local function + * $shutdown_handler_visited is a static function variable * that will test if this function is already passed * through by PHP runtime. * From 7ed5c65bbc3ac682eb1022c145f5914acb23495d Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Mon, 17 Feb 2014 10:04:53 +0200 Subject: [PATCH 43/72] some cleanup no need to ensure if we're re-registering the shutdown function more than once. --- classes/kohana/core.php | 20 +++++++------------- classes/kohana/kohana/exception.php | 25 ++++++------------------- 2 files changed, 13 insertions(+), 32 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 1dd28c7f3..4d7c7d539 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -967,24 +967,18 @@ public static function error_handler($code, $error, $file = NULL, $line = NULL) /** * Catches errors that are not caught by the error handler, such as E_PARSE. + * + * In case of an exception, the Kohana exception handler registers + * this shutdown_handler twice. We'll count the number of visits to + * this function using a local static function variable, and exit(1) + * on the second visit. + * @see issue #3931 * * @return void */ public static function shutdown_handler() { - /* - * $shutdown_handler_visited is a static function variable - * that will test if this function is already passed - * through by PHP runtime. - * - * If it is passed through already, we should exit with - * an error status. - * - * The second registration occurs inside Kohana's default - * exception handler. - * - * @see issue #3931 - */ + // test if we have already shutdown, if TRUE, exit(1) static $shutdown_handler_visited = FALSE; if ($shutdown_handler_visited) { exit(1); diff --git a/classes/kohana/kohana/exception.php b/classes/kohana/kohana/exception.php index 65fa39ffb..03a1ed599 100644 --- a/classes/kohana/kohana/exception.php +++ b/classes/kohana/kohana/exception.php @@ -80,7 +80,11 @@ public function __toString() /** * Inline exception handler, displays the error message, source of the * exception, and the stack trace of the error. - * + * + * Re-registers Kohana::shutdown_handler to make the PHP engine + * run the shutdown twice. We'll be exit(1)-ing from there. + * @see issue #3931 + * * @uses Kohana_Exception::text * @param Exception $e * @return boolean @@ -89,24 +93,7 @@ public static function handler(Exception $e) { try { - /* - * - * We are registering our shutdown function again. - * By re-registering our shutdown function, we are - * basically asking PHP to run the shutdown function - * twice before exiting. - * - * The $shutdown_for_exception_registered is needed - * to ensure that we are not re-registering our shutdown - * function more than once. - * - * @see issue #3931 - */ - static $shutdown_for_exception_registered = FALSE; - if (!$shutdown_for_exception_registered) { - register_shutdown_function(array('Kohana', 'shutdown_handler')); - $shutdown_for_exception_registered = TRUE; - } + register_shutdown_function(array('Kohana', 'shutdown_handler')); // Get the exception information $type = get_class($e); From 49c8c46bcb373d91bf61850f444269f8842338f4 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Mon, 24 Feb 2014 05:51:14 -0800 Subject: [PATCH 44/72] fixed a brace according to the coding standard changed the word "twice" to "again" in phpdoc also the brace of `if` should go on the next line thanks @EvanPurkhiser --- classes/kohana/core.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 4d7c7d539..a36092983 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -969,7 +969,7 @@ public static function error_handler($code, $error, $file = NULL, $line = NULL) * Catches errors that are not caught by the error handler, such as E_PARSE. * * In case of an exception, the Kohana exception handler registers - * this shutdown_handler twice. We'll count the number of visits to + * this shutdown_handler again. We'll count the number of visits to * this function using a local static function variable, and exit(1) * on the second visit. * @see issue #3931 @@ -980,7 +980,8 @@ public static function shutdown_handler() { // test if we have already shutdown, if TRUE, exit(1) static $shutdown_handler_visited = FALSE; - if ($shutdown_handler_visited) { + if ($shutdown_handler_visited) + { exit(1); } $shutdown_handler_visited = TRUE; From 4eeacd46f45b6717ecbec30f5013e2c7dfd483a7 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 26 Feb 2014 22:44:52 +0200 Subject: [PATCH 45/72] replace preg_replace /e with preg_replace_callback uses `create_function` to support both PHP 5.2 and PHP 5.5 `create_function` uses `eval` internally so probably it's better to have this fix only for Kohana v.3.2 Thank you @Zeelot for the help --- classes/kohana/text.php | 11 +++++++++-- utf8/ucwords.php | 9 +++++---- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/classes/kohana/text.php b/classes/kohana/text.php index eb12254cf..a9cc91f20 100644 --- a/classes/kohana/text.php +++ b/classes/kohana/text.php @@ -269,6 +269,9 @@ public static function reduce_slashes($str) * 'frick' => '#####', * )); * + * If argument $replacement is a single character, it will be used to replace + * the characters in the badword, otherwise it will replace the badword completely + * * @param string $str phrase to replace words in * @param array $badwords words to replace * @param string $replacement replacement string @@ -293,12 +296,16 @@ public static function censor($str, $badwords, $replacement = '#', $replace_part $regex = '!'.$regex.'!ui'; + // if $replacement is a single character: replace each of the characters of the badword with $replacement if (UTF8::strlen($replacement) == 1) { - $regex .= 'e'; - return preg_replace($regex, 'str_repeat($replacement, UTF8::strlen(\'$1\'))', $str); + // issue #4819: use preg_replace_callback, preg_replace with /e modifier is depricated for PHP 5.5.0 + $callback = create_function('$matches', 'return str_repeat("' . $replacement . '", UTF8::strlen($matches[1]));'); + + return preg_replace_callback($regex, $callback, $str); } + // if $replacement is not a single character, fully replace the badword with $replacement return preg_replace($regex, $replacement, $str); } diff --git a/utf8/ucwords.php b/utf8/ucwords.php index a266702fa..987b36bd1 100644 --- a/utf8/ucwords.php +++ b/utf8/ucwords.php @@ -15,9 +15,10 @@ function _ucwords($str) // [\x0c\x09\x0b\x0a\x0d\x20] matches form feeds, horizontal tabs, vertical tabs, linefeeds and carriage returns. // This corresponds to the definition of a 'word' defined at http://php.net/ucwords - return preg_replace( - '/(?<=^|[\x0c\x09\x0b\x0a\x0d\x20])[^\x0c\x09\x0b\x0a\x0d\x20]/ue', - 'UTF8::strtoupper(\'$0\')', + $callback = create_function('$matches', 'return UTF8::strtoupper($matches[0]);'); + return preg_replace_callback( + '/(?<=^|[\x0c\x09\x0b\x0a\x0d\x20])[^\x0c\x09\x0b\x0a\x0d\x20]/u', + $callback, $str ); -} \ No newline at end of file +} From 5c5aac1b7103172b08908813afddc78785592cef Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 5 Mar 2014 09:25:55 +0200 Subject: [PATCH 46/72] Decode slashes back after rawurlencode --- classes/kohana/route.php | 3 +++ tests/kohana/RouteTest.php | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/classes/kohana/route.php b/classes/kohana/route.php index b4c5dfc8f..51e45dd2d 100644 --- a/classes/kohana/route.php +++ b/classes/kohana/route.php @@ -458,7 +458,10 @@ public function uri(array $params = NULL) { if ($params) { + // @issue #4079 rawurlencode parameters $params = array_map('rawurlencode', $params); + // decode slashes back, see Apache docs about AllowEncodedSlashes and AcceptPathInfo + $params = str_replace(array('%2F', '%5C'), array('/', '\\'), $params); } // Start with the routed URI diff --git a/tests/kohana/RouteTest.php b/tests/kohana/RouteTest.php index 86ad5ac7c..a4747ccd9 100644 --- a/tests/kohana/RouteTest.php +++ b/tests/kohana/RouteTest.php @@ -733,7 +733,7 @@ public function provider_route_uri_encode_parameters() ), 'article_name', 'Article name with special chars \\ ##', - 'blog/article/Article%20name%20with%20special%20chars%20%5C%20%23%23' + 'blog/article/Article%20name%20with%20special%20chars%20\\%20%23%23' ) ); } From c011806aaf3e92b80d30f442dc6bb6d1383117b4 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Wed, 5 Mar 2014 11:39:11 +0200 Subject: [PATCH 47/72] add generating URIs section to the upgrade doc --- guide/kohana/upgrading.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/guide/kohana/upgrading.md b/guide/kohana/upgrading.md index c09a5b00a..9dd2662af 100644 --- a/guide/kohana/upgrading.md +++ b/guide/kohana/upgrading.md @@ -58,6 +58,15 @@ Alternatively it is possible to set a specific client to an individual Request. ->client(new Request_Client_Stream) ->execute(); +## Generating URIs + +In Kohana 3.1, you could generate URIs by passing parameters to the `Request::uri` method. In Kohana 3.2 [Request::uri] +just returns the URI of the current route. URIs can **NOT** be generated using the `Request::uri` method anymore. + +Instead, you should generate your URIs by passing your parameters to the [Route::uri] method. + +For more information, please read the section about [creating URLs and links using routes](routing#creating-urls-and-links-using-routes). + ## HTTP cache control Kohana 3.1 introduced HTTP cache control, providing RFC 2616 fully compliant transparent caching of responses. Kohana 3.2 builds on this moving all caching logic out of `Request_Client` into `HTTP_Cache`. From 9e192d779b0f62d323dd588f1f3c5192fb55c8d7 Mon Sep 17 00:00:00 2001 From: Woody Gilk Date: Wed, 7 May 2014 14:11:46 -0500 Subject: [PATCH 48/72] Bump version --- classes/kohana/core.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/kohana/core.php b/classes/kohana/core.php index 6b33f4e1b..4d34a78a3 100644 --- a/classes/kohana/core.php +++ b/classes/kohana/core.php @@ -16,8 +16,8 @@ class Kohana_Core { // Release version and codename - const VERSION = '3.2.2'; - const CODENAME = 'hypoleucos'; + const VERSION = '3.2.3.1'; + const CODENAME = 'turdus'; // Common environment type constants for consistency and convenience const PRODUCTION = 10; From e472ecfb540ce0130509187a6cbcc3aa822939e1 Mon Sep 17 00:00:00 2001 From: Zogame Date: Fri, 5 Sep 2014 15:26:23 +0900 Subject: [PATCH 49/72] Update Text.php $agent has been already defined --- classes/Kohana/Text.php | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/classes/Kohana/Text.php b/classes/Kohana/Text.php index 942538d42..9a7cd5ac1 100644 --- a/classes/Kohana/Text.php +++ b/classes/Kohana/Text.php @@ -608,15 +608,16 @@ public static function widont($str) * Returns information about the client user agent. * * // Returns "Chrome" when using Google Chrome - * $browser = Text::user_agent('browser'); + * $browser = Text::user_agent($agent, 'browser'); * * Multiple values can be returned at once by using an array: * * // Get the browser and platform with a single call - * $info = Text::user_agent(array('browser', 'platform')); + * $info = Text::user_agent($agent, array('browser', 'platform')); * * When using an array for the value, an associative array will be returned. * + * @param string $agent user_agent * @param mixed $value array or string to return: browser, version, robot, mobile, platform * @return mixed requested information, FALSE if nothing is found * @uses Kohana::$config @@ -650,7 +651,7 @@ public static function user_agent($agent, $value) // Set the browser name $info['browser'] = $name; - if (preg_match('#'.preg_quote($search).'[^0-9.]*+([0-9.][0-9.a-z]*)#i', Request::$user_agent, $matches)) + if (preg_match('#'.preg_quote($search).'[^0-9.]*+([0-9.][0-9.a-z]*)#i', $agent, $matches)) { // Set the version number $info['version'] = $matches[1]; From b8ba46bdc28072c2297ac33305ead6ad768da843 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Wed, 17 Sep 2014 13:07:52 +0100 Subject: [PATCH 50/72] Configure standalone travis build for kohana/core Adds and configures kohana/koharness to build a skeleton Kohana application and then uses that environment to run the unit tests on travis (and locally, if required). --- .gitignore | 3 +++ .travis.yml | 24 ++++++++++++++++++++++++ composer.json | 7 +++++++ koharness.php | 8 ++++++++ 4 files changed, 42 insertions(+) create mode 100644 .travis.yml create mode 100644 koharness.php diff --git a/.gitignore b/.gitignore index b72f9be20..09b35f5ba 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ *~ *.swp +/composer.lock +/vendor +/koharness_bootstrap.php diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 000000000..8f9e0fcae --- /dev/null +++ b/.travis.yml @@ -0,0 +1,24 @@ +language: php + +php: + - 5.3 + - 5.4 + - 5.5 + - 5.6 + - hhvm + +before_script: + - composer install --prefer-dist + - vendor/bin/koharness + +script: + - cd /tmp/koharness && ./vendor/bin/phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php + +notifications: + irc: + channels: + - "irc.freenode.org#kohana" + template: + - "%{repository}/%{branch} (%{commit}) - %{author}: %{message}" + - "Build details: %{build_url}" + email: false diff --git a/composer.json b/composer.json index 2c07aa849..32d2a3252 100644 --- a/composer.json +++ b/composer.json @@ -21,12 +21,19 @@ "require": { "php": ">=5.3.3" }, + "require-dev": { + "kohana/unittest": "3.3.*@dev", + "kohana/koharness": "*@dev" + }, "suggest": { "ext-http": "*", "ext-curl": "*", "ext-mcrypt": "*" }, "extra": { + "installer-paths": { + "vendor/{$vendor}/{$name}": ["type:kohana-module"] + }, "branch-alias": { "dev-3.3/develop": "3.3.x-dev", "dev-3.4/develop": "3.4.x-dev" diff --git a/koharness.php b/koharness.php new file mode 100644 index 000000000..7845498db --- /dev/null +++ b/koharness.php @@ -0,0 +1,8 @@ + array( + 'unittest' => __DIR__ . '/vendor/kohana/unittest' + ), + 'syspath' => __DIR__, +); From 58e842d439ce9f5447d2789885c3dce8955c53d3 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Wed, 17 Sep 2014 13:11:16 +0100 Subject: [PATCH 51/72] Remove physical path dependency in Kohana::module tests Backports dd926956 to 3.3 - MODPATH is unreliable in a koharness environment as it will usually be a symlink. With this change the test of Kohana::modules will pass wherever the code happens to be deployed on the disk. This will conflict when we merge up to 3.4 because that commit uses short array syntax which is not available in the 3.3 series. --- tests/kohana/CoreTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/kohana/CoreTest.php b/tests/kohana/CoreTest.php index 0b93ac755..04b06dfcd 100644 --- a/tests/kohana/CoreTest.php +++ b/tests/kohana/CoreTest.php @@ -296,7 +296,7 @@ public function provider_modules_sets_and_returns_valid_modules() { return array( array(array(), array()), - array(array('unittest' => MODPATH.'unittest'), array('unittest' => $this->dirSeparator(MODPATH.'unittest/'))), + array(array('module' => __DIR__), array('module' => $this->dirSeparator(__DIR__.'/'))), ); } From b880a3eaea7ee553ab78674eee0e1b036658ed8f Mon Sep 17 00:00:00 2001 From: Sakto Date: Wed, 17 Sep 2014 17:09:18 +0200 Subject: [PATCH 52/72] Added failing test for urls starting with // in HTML --- tests/kohana/HTMLTest.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/kohana/HTMLTest.php b/tests/kohana/HTMLTest.php index c4505bc40..ef7c881d5 100644 --- a/tests/kohana/HTMLTest.php +++ b/tests/kohana/HTMLTest.php @@ -117,6 +117,10 @@ public function provider_script() 'https', FALSE ), + array( + '', + '//google.com/script.js', + ), ); } From 9bfb502ad60891f90a8951c9f78c2cf87f944e8e Mon Sep 17 00:00:00 2001 From: Sakto Date: Wed, 17 Sep 2014 17:10:29 +0200 Subject: [PATCH 53/72] Support urls starting with // in HTML::script and HTML::style --- classes/Kohana/HTML.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Kohana/HTML.php b/classes/Kohana/HTML.php index ef226c2c8..9752a1e65 100644 --- a/classes/Kohana/HTML.php +++ b/classes/Kohana/HTML.php @@ -206,7 +206,7 @@ public static function mailto($email, $title = NULL, array $attributes = NULL) */ public static function style($file, array $attributes = NULL, $protocol = NULL, $index = FALSE) { - if (strpos($file, '://') === FALSE) + if (strpos($file, '://') === FALSE AND strpos($file, '//') !== 0) { // Add the base URL $file = URL::site($file, $protocol, $index); @@ -239,7 +239,7 @@ public static function style($file, array $attributes = NULL, $protocol = NULL, */ public static function script($file, array $attributes = NULL, $protocol = NULL, $index = FALSE) { - if (strpos($file, '://') === FALSE) + if (strpos($file, '://') === FALSE AND strpos($file, '//') !== 0) { // Add the base URL $file = URL::site($file, $protocol, $index); From 621b8981905e0f0b12c3465d58169d7db469e82b Mon Sep 17 00:00:00 2001 From: Sakto Date: Wed, 17 Sep 2014 17:36:24 +0200 Subject: [PATCH 54/72] Added failing test to provider_style for urls starting with // --- tests/kohana/HTMLTest.php | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/kohana/HTMLTest.php b/tests/kohana/HTMLTest.php index ef7c881d5..c92ad1bbe 100644 --- a/tests/kohana/HTMLTest.php +++ b/tests/kohana/HTMLTest.php @@ -197,6 +197,13 @@ public function provider_style() 'https', TRUE ), + array( + '', + '//google.com/style.css', + array(), + NULL, + FALSE + ), ); } From 12516f05bc3d4ac758f7ecad69e76b524269d552 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Thu, 18 Sep 2014 11:15:37 +0300 Subject: [PATCH 55/72] incorrect mention of the missing method Request::instance --- classes/Kohana/Form.php | 2 +- classes/Kohana/Request.php | 4 ++-- guide/kohana/flow.md | 2 +- guide/kohana/mvc/controllers.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/classes/Kohana/Form.php b/classes/Kohana/Form.php index 510bd8109..65ed30bb6 100644 --- a/classes/Kohana/Form.php +++ b/classes/Kohana/Form.php @@ -28,7 +28,7 @@ class Kohana_Form { * @param mixed $action form action, defaults to the current request URI, or [Request] class to use * @param array $attributes html attributes * @return string - * @uses Request::instance + * @uses Request * @uses URL::site * @uses HTML::attributes */ diff --git a/classes/Kohana/Request.php b/classes/Kohana/Request.php index bdc059ecf..5343a9c27 100644 --- a/classes/Kohana/Request.php +++ b/classes/Kohana/Request.php @@ -38,7 +38,7 @@ class Kohana_Request implements HTTP_Request { /** * Creates a new request object for the given URI. New requests should be - * created using the [Request::instance] or [Request::factory] methods. + * Created using the [Request::factory] method. * * $request = Request::factory($uri); * @@ -631,7 +631,7 @@ protected static function _parse_accept( & $header, array $accepts = NULL) /** * Creates a new request object for the given URI. New requests should be - * created using the [Request::instance] or [Request::factory] methods. + * Created using the [Request::factory] method. * * $request = new Request($uri); * diff --git a/guide/kohana/flow.md b/guide/kohana/flow.md index 81a2e54b1..e478b2e7f 100644 --- a/guide/kohana/flow.md +++ b/guide/kohana/flow.md @@ -16,7 +16,7 @@ Every application follows the same flow: * Includes each module's `init.php` file, if it exists. * The `init.php` file can perform additional environment setup, including adding routes. 10. [Route::set] is called multiple times to define the [application routes](routing). - 11. [Request::instance] is called to start processing the request. + 11. [Request::factory] is called to start processing the request. 1. Checks each route that has been set until a match is found. 2. Creates the controller instance and passes the request to it. 3. Calls the [Controller::before] method. diff --git a/guide/kohana/mvc/controllers.md b/guide/kohana/mvc/controllers.md index 3a155dbff..2c9f8ab10 100644 --- a/guide/kohana/mvc/controllers.md +++ b/guide/kohana/mvc/controllers.md @@ -55,7 +55,7 @@ You can also have a controller extend another controller to share common things, Every controller has the `$this->request` property which is the [Request] object that called the controller. You can use this to get information about the current request, as well as set the response body via `$this->response->body($ouput)`. -Here is a partial list of the properties and methods available to `$this->request`. These can also be accessed via `Request::instance()`, but `$this->request` is provided as a shortcut. See the [Request] class for more information on any of these. +Here is a partial list of the properties and methods available to `$this->request`. See the [Request] class for more information on any of these. Property/method | What it does --- | --- From 9c377058db39083131d8a44c89a4343ce9180d46 Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Thu, 18 Sep 2014 12:36:29 +0300 Subject: [PATCH 56/72] related to R4813, removes redundant notice disabling lines `mb_convert_encoding`, unlike `iconv`, does not emit `E_NOTICE` --- classes/Kohana/UTF8.php | 6 ------ 1 file changed, 6 deletions(-) diff --git a/classes/Kohana/UTF8.php b/classes/Kohana/UTF8.php index ca5e315a8..d18b31bd2 100644 --- a/classes/Kohana/UTF8.php +++ b/classes/Kohana/UTF8.php @@ -70,13 +70,7 @@ public static function clean($var, $charset = NULL) if ( ! UTF8::is_ascii($var)) { - // Disable notices - $error_reporting = error_reporting(~E_NOTICE); - $var = mb_convert_encoding($var, $charset, $charset); - - // Turn notices back on - error_reporting($error_reporting); } } From a0d06fd01cdad46adf1f9ad1131585b9cc20824e Mon Sep 17 00:00:00 2001 From: Samuel Demirdjian Date: Mon, 22 Sep 2014 14:38:25 +0300 Subject: [PATCH 57/72] Xdebug returns dynamic and static instead of using -> and :: --- classes/Kohana/Kohana/Exception.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/classes/Kohana/Kohana/Exception.php b/classes/Kohana/Kohana/Exception.php index d54b46436..3cbe166bb 100644 --- a/classes/Kohana/Kohana/Exception.php +++ b/classes/Kohana/Kohana/Exception.php @@ -217,6 +217,16 @@ public static function response(Exception $e) $frame['type'] = '??'; } + // Xdebug returns the words 'dynamic' and 'static' instead of using '->' and '::' symbols + if ('dynamic' === $frame['type']) + { + $frame['type'] = '->'; + } + elseif ('static' === $frame['type']) + { + $frame['type'] = '::'; + } + // XDebug also has a different name for the parameters array if (isset($frame['params']) AND ! isset($frame['args'])) { From 2faa4dca5d75f1e2edf0f6a691bc1c1ffee8c272 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Mon, 22 Sep 2014 17:35:42 +0100 Subject: [PATCH 58/72] Specify the COMPOSER_ROOT_VERSION for travis installation This works around the circular dependency on kohana/unittest > kohana/core which leads to resolution problems when working on a feature branch. --- .travis.yml | 2 +- README.md | 28 ++++++++++++++++++++++++++++ composer.json | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 README.md diff --git a/.travis.yml b/.travis.yml index 8f9e0fcae..862a7b467 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,7 @@ php: - hhvm before_script: - - composer install --prefer-dist + - COMPOSER_ROOT_VERSION=3.3.x-dev composer install --prefer-dist - vendor/bin/koharness script: diff --git a/README.md b/README.md new file mode 100644 index 000000000..4fe265fe5 --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# Kohana PHP Framework - core + +This is the core package for the [Kohana](http://kohanaframework.org/) object oriented HMVC framework built using PHP5. +It aims to be swift, secure, and small. + +Released under a [BSD license](http://kohanaframework.org/license), Kohana can be used legally for any open source, +commercial, or personal project. + +## Documentation and installation + +See the [sample application repository](https://github.com/kohana/kohana) for full readme and contributing information. +You will usually add `kohana/core` as a dependency in your own project's composer.json to install and work with this +pacakge. + +## Installation for development + +To work on this package, you'll want to install it with composer to get the required dependencies. Note that there are +currently circular dependencies between this module and kohana/unittest. These may cause you problems if you are working +on a feature branch, because composer may not be able to figure out which version of kohana core you have. + +To work around this, run composer like: `COMPOSER_ROOT_VERSION=3.3.x-dev composer install`. This tells composer that the +current checkout is a 3.3.* development version. Obviously change the argument if your branch is based on a different +version. + +After installing the dependencies, you'll need a skeleton Kohana application before you can run the unit tests etc. The +simplest way to do this is to use kohana/koharness to build a bare project in `/tmp/koharness`. + +If in doubt, check the install and test steps in the [.travis.yml](.travis.yml) file. diff --git a/composer.json b/composer.json index 32d2a3252..9a88f4012 100644 --- a/composer.json +++ b/composer.json @@ -1,4 +1,5 @@ { + "_readme": "NOTE: see readme for COMPOSER_ROOT_VERSION instructions if you have dependency issues", "name": "kohana/core", "description": "Core system classes for the Kohana application framework", "homepage": "http://kohanaframework.org", From a9db554dedb1d9e8aded970f08bc3b748bca5bd3 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Mon, 22 Sep 2014 17:36:10 +0100 Subject: [PATCH 59/72] Remove IRC notifications from travis --- .travis.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 862a7b467..603c929a3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,10 +15,4 @@ script: - cd /tmp/koharness && ./vendor/bin/phpunit --bootstrap=modules/unittest/bootstrap.php modules/unittest/tests.php notifications: - irc: - channels: - - "irc.freenode.org#kohana" - template: - - "%{repository}/%{branch} (%{commit}) - %{author}: %{message}" - - "Build details: %{build_url}" email: false From 526fe4d14435722f2f118d4f6a2bd759643dd89f Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Tue, 23 Sep 2014 08:51:24 +0100 Subject: [PATCH 60/72] Update .gitignore for consistency with other modules --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 09b35f5ba..093963d5e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,5 @@ *~ *.swp /composer.lock -/vendor +/vendor/* /koharness_bootstrap.php From f6aee425f376983d80de607da0cdc9e6c8ac7dd1 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 14:31:32 +0100 Subject: [PATCH 61/72] Rewrite Cookie tests to be runnable and cover current behaviour The cookie tests were all being skipped because headers are always sent by the PHPUnit test runner (fixes kohana/kohana#47). Additionally even when they ran they were covering very little of the actual logic of the class, mostly just asserting that setcookie returns TRUE. Rewrote the tests completely and slightly refactored the Cookie class to allow mocking of the timestamp and setcookie calls. Refs #547. --- classes/Kohana/Cookie.php | 60 +++++-- tests/kohana/CookieTest.php | 314 ++++++++++++++++++++++++++---------- 2 files changed, 280 insertions(+), 94 deletions(-) diff --git a/classes/Kohana/Cookie.php b/classes/Kohana/Cookie.php index fe4cc490d..8ee3d239e 100644 --- a/classes/Kohana/Cookie.php +++ b/classes/Kohana/Cookie.php @@ -78,7 +78,7 @@ public static function get($key, $default = NULL) } // The cookie signature is invalid, delete it - Cookie::delete($key); + static::delete($key); } return $default; @@ -88,33 +88,38 @@ public static function get($key, $default = NULL) * Sets a signed cookie. Note that all cookie values must be strings and no * automatic serialization will be performed! * + * [!!] By default, Cookie::$expiration is 0 - if you skip/pass NULL for the optional + * lifetime argument your cookies will expire immediately unless you have separately + * configured Cookie::$expiration. + * + * * // Set the "theme" cookie * Cookie::set('theme', 'red'); * * @param string $name name of cookie * @param string $value value of cookie - * @param integer $expiration lifetime in seconds + * @param integer $lifetime lifetime in seconds * @return boolean * @uses Cookie::salt */ - public static function set($name, $value, $expiration = NULL) + public static function set($name, $value, $lifetime = NULL) { - if ($expiration === NULL) + if ($lifetime === NULL) { // Use the default expiration - $expiration = Cookie::$expiration; + $lifetime = Cookie::$expiration; } - if ($expiration !== 0) + if ($lifetime !== 0) { // The expiration is expected to be a UNIX timestamp - $expiration += time(); + $lifetime += static::_time(); } // Add the salt to the cookie value $value = Cookie::salt($name, $value).'~'.$value; - return setcookie($name, $value, $expiration, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly); + return static::_setcookie($name, $value, $lifetime, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly); } /** @@ -131,7 +136,7 @@ public static function delete($name) unset($_COOKIE[$name]); // Nullify the cookie and make it expire - return setcookie($name, NULL, -86400, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly); + return static::_setcookie($name, NULL, -86400, Cookie::$path, Cookie::$domain, Cookie::$secure, Cookie::$httponly); } /** @@ -139,8 +144,10 @@ public static function delete($name) * * $salt = Cookie::salt('theme', 'red'); * - * @param string $name name of cookie - * @param string $value value of cookie + * @param string $name name of cookie + * @param string $value value of cookie + * + * @throws Kohana_Exception if Cookie::$salt is not configured * @return string */ public static function salt($name, $value) @@ -157,4 +164,35 @@ public static function salt($name, $value) return sha1($agent.$name.$value.Cookie::$salt); } + /** + * Proxy for the native setcookie function - to allow mocking in unit tests so that they do not fail when headers + * have been sent. + * + * @param string $name + * @param string $value + * @param integer $expire + * @param string $path + * @param string $domain + * @param boolean $secure + * @param boolean $httponly + * + * @return bool + * @see setcookie + */ + protected static function _setcookie($name, $value, $expire, $path, $domain, $secure, $httponly) + { + return setcookie($name, $value, $expire, $path, $domain, $secure, $httponly); + } + + /** + * Proxy for the native time function - to allow mocking of time-related logic in unit tests + * + * @return int + * @see time + */ + protected static function _time() + { + return time(); + } + } diff --git a/tests/kohana/CookieTest.php b/tests/kohana/CookieTest.php index 9c1fe400c..25159b9eb 100644 --- a/tests/kohana/CookieTest.php +++ b/tests/kohana/CookieTest.php @@ -11,13 +11,15 @@ * @category Tests * @author Kohana Team * @author Jeremy Bush - * @copyright (c) 2008-2012 Kohana Team + * @author Andrew Coulton + * @copyright (c) 2008-2014 Kohana Team * @license http://kohanaframework.org/license */ class Kohana_CookieTest extends Unittest_TestCase { + const UNIX_TIMESTAMP = 1411040141; + const COOKIE_EXPIRATION = 60; - protected $_default_salt = 'AdaoidadnA£ASDNadnaoiwdnawd'; /** * Sets up the environment */ @@ -26,152 +28,298 @@ public function setUp() // @codingStandardsIgnoreEnd { parent::setUp(); + Kohana_CookieTest_TestableCookie::$_mock_cookies_set = array(); - Cookie::$salt = $this->_default_salt; + $this->setEnvironment(array( + 'Cookie::$salt' => 'some-random-salt', + 'HTTP_USER_AGENT' => 'cli' + )); } /** - * Tears down the environment + * Tests that cookies are set with the global path, domain, etc options. + * + * @covers Cookie::set */ - // @codingStandardsIgnoreStart - public function tearDown() - // @codingStandardsIgnoreEnd + public function test_set_creates_cookie_with_configured_cookie_options() { - parent::tearDown(); + $this->setEnvironment(array( + 'Cookie::$path' => '/path', + 'Cookie::$domain' => 'my.domain', + 'Cookie::$secure' => TRUE, + 'Cookie::$httponly' => FALSE, + )); - Cookie::$salt = NULL; + Kohana_CookieTest_TestableCookie::set('cookie', 'value'); + + $this->assertSetCookieWith(array( + 'path' => '/path', + 'domain' => 'my.domain', + 'secure' => TRUE, + 'httponly' => FALSE + )); } /** - * Provides test data for test_set() + * Provider for test_set_calculates_expiry_from_lifetime * - * @return array + * @return array of $lifetime, $expect_expiry */ - public function provider_set() + public function provider_set_calculates_expiry_from_lifetime() { return array( - array('foo', 'bar', NULL, TRUE), - array('foo', 'bar', 10, TRUE), + array(NULL, self::COOKIE_EXPIRATION + self::UNIX_TIMESTAMP), + array(0, 0), + array(10, 10 + self::UNIX_TIMESTAMP), ); } /** - * Tests cookie::set() + * @param int $expiration + * @param int $expect_expiry * - * @test - * @dataProvider provider_set - * @covers cookie::set - * @param mixed $key key to use - * @param mixed $value value to set - * @param mixed $exp exp to set - * @param boolean $expected Output for cookie::set() - */ - public function test_set($key, $value, $exp, $expected) - { - if (headers_sent()) { - $this->markTestSkipped('Cannot test setting cookies as headers have already been sent'); - } + * @dataProvider provider_set_calculates_expiry_from_lifetime + * @covers Cookie::set + */ + public function test_set_calculates_expiry_from_lifetime($expiration, $expect_expiry) + { + $this->setEnvironment(array('Cookie::$expiration' => self::COOKIE_EXPIRATION)); + Kohana_CookieTest_TestableCookie::set('foo', 'bar', $expiration); + $this->assertSetCookieWith(array('expire' => $expect_expiry)); + } + + /** + * @covers Cookie::get + */ + public function test_get_returns_default_if_cookie_missing() + { + unset($_COOKIE['missing_cookie']); + $this->assertEquals('default', Cookie::get('missing_cookie', 'default')); + } - $this->assertSame($expected, cookie::set($key, $value, $exp)); + /** + * @covers Cookie::get + */ + public function test_get_returns_value_if_cookie_present_and_signed() + { + Kohana_CookieTest_TestableCookie::set('cookie', 'value'); + $cookie = Kohana_CookieTest_TestableCookie::$_mock_cookies_set[0]; + $_COOKIE[$cookie['name']] = $cookie['value']; + $this->assertEquals('value', Cookie::get('cookie', 'default')); } /** - * Provides test data for test_get() + * Provider for test_get_returns_default_without_deleting_if_cookie_unsigned * * @return array */ - public function provider_get() + public function provider_get_returns_default_without_deleting_if_cookie_unsigned() { - // setUp is called after the provider so we need to specify a - // salt here in order to use it in the provider - Cookie::$salt = $this->_default_salt; - return array( - array('foo', Cookie::salt('foo', 'bar').'~bar', 'bar'), - array('bar', Cookie::salt('foo', 'bar').'~bar', NULL), - array(NULL, Cookie::salt('foo', 'bar').'~bar', NULL), + array('unsalted'), + array('un~salted'), ); } /** - * Tests cookie::set() + * Verifies that unsigned cookies are not available to the kohana application, but are not affected for other + * consumers. + * + * @param string $unsigned_value * - * @test - * @dataProvider provider_get - * @covers cookie::get - * @param mixed $key key to use - * @param mixed $value value to set - * @param boolean $expected Output for cookie::get() + * @dataProvider provider_get_returns_default_without_deleting_if_cookie_unsigned + * @covers Cookie::get */ - public function test_get($key, $value, $expected) + public function test_get_returns_default_without_deleting_if_cookie_unsigned($unsigned_value) { - if (headers_sent()) { - $this->markTestSkipped('Cannot test setting cookies as headers have already been sent'); - } + $_COOKIE['cookie'] = $unsigned_value; + $this->assertEquals('default', Kohana_CookieTest_TestableCookie::get('cookie', 'default')); + $this->assertEquals($unsigned_value, $_COOKIE['cookie'], '$_COOKIE not affected'); + $this->assertEmpty(Kohana_CookieTest_TestableCookie::$_mock_cookies_set, 'No cookies set or changed'); + } - // Force $_COOKIE - if ($key !== NULL) - { - $_COOKIE[$key] = $value; - } + /** + * If a cookie looks like a signed cookie but the signature no longer matches, it should be deleted. + * + * @covers Cookie::get + */ + public function test_get_returns_default_and_deletes_tampered_signed_cookie() + { + $_COOKIE['cookie'] = Cookie::salt('cookie', 'value').'~tampered'; + $this->assertEquals('default', Kohana_CookieTest_TestableCookie::get('cookie', 'default')); + $this->assertDeletedCookie('cookie'); + } + + /** + * @covers Cookie::delete + */ + public function test_delete_removes_cookie_from_globals_and_expires_cookie() + { + $_COOKIE['cookie'] = Cookie::salt('cookie', 'value').'~tampered'; + $this->assertTrue(Kohana_CookieTest_TestableCookie::delete('cookie')); + $this->assertDeletedCookie('cookie'); + } + + /** + * @covers Cookie::delete + * @link http://dev.kohanaframework.org/issues/3501 + * @link http://dev.kohanaframework.org/issues/3020 + */ + public function test_delete_does_not_require_configured_salt() + { + Cookie::$salt = NULL; + $this->assertTrue(Kohana_CookieTest_TestableCookie::delete('cookie')); + $this->assertDeletedCookie('cookie'); + } + + /** + * @covers Cookie::salt + * @expectedException Kohana_Exception + */ + public function test_salt_throws_with_no_configured_salt() + { + Cookie::$salt = NULL; + Cookie::salt('key', 'value'); + } - $this->assertSame($expected, cookie::get($key)); + /** + * @covers Cookie::salt + */ + public function test_salt_creates_same_hash_for_same_values_and_state() + { + $name = 'cookie'; + $value = 'value'; + $this->assertEquals(Cookie::salt($name, $value), Cookie::salt($name, $value)); } /** - * Provides test data for test_delete() + * Provider for test_salt_creates_different_hash_for_different_data * * @return array */ - public function provider_delete() + public function provider_salt_creates_different_hash_for_different_data() { return array( - array('foo', TRUE), + array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('name' => 'changed')), + array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('value' => 'changed')), + array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('salt' => 'changed-salt')), + array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('user-agent' => 'Firefox')), + array(array('name' => 'foo', 'value' => 'bar', 'salt' => 'our-salt', 'user-agent' => 'Chrome'), array('user-agent' => NULL)), ); } /** - * Tests cookie::delete() + * @param array $first_args + * @param array $changed_args * - * @test - * @dataProvider provider_delete - * @covers cookie::delete - * @param mixed $key key to use - * @param boolean $expected Output for cookie::delete() + * @dataProvider provider_salt_creates_different_hash_for_different_data + * @covers Cookie::salt */ - public function test_delete($key, $expected) + public function test_salt_creates_different_hash_for_different_data($first_args, $changed_args) { - if (headers_sent()) { - $this->markTestSkipped('Cannot test setting cookies as headers have already been sent'); + $second_args = array_merge($first_args, $changed_args); + $hashes = array(); + foreach (array($first_args, $second_args) as $args) + { + Cookie::$salt = $args['salt']; + $this->set_or_remove_http_user_agent($args['user-agent']); + + $hashes[] = Cookie::salt($args['name'], $args['value']); } - $this->assertSame($expected, cookie::delete($key)); + $this->assertNotEquals($hashes[0], $hashes[1]); } /** - * Provides test data for test_salt() + * Verify that a cookie was deleted from the global $_COOKIE array, and that a setcookie call was made to remove it + * from the client. * - * @return array + * @param string $name */ - public function provider_salt() + // @codingStandardsIgnoreStart + protected function assertDeletedCookie($name) + // @codingStandardsIgnoreEnd { - return array( - array('foo', 'bar', 'b5773a6255d1deefc23f9f69bcc40fdc998e5802'), - ); + $this->assertArrayNotHasKey($name, $_COOKIE); + // To delete the client-side cookie, Cookie::delete should send a new cookie with value NULL and expiry in the past + $this->assertSetCookieWith(array( + 'name' => $name, + 'value' => NULL, + 'expire' => -86400, + 'path' => Cookie::$path, + 'domain' => Cookie::$domain, + 'secure' => Cookie::$secure, + 'httponly' => Cookie::$httponly + )); } /** - * Tests cookie::salt() + * Verify that there was a single call to setcookie including the provided named arguments * - * @test - * @dataProvider provider_salt - * @covers cookie::salt - * @param mixed $key key to use - * @param mixed $value value to salt with - * @param boolean $expected Output for cookie::delete() + * @param array $expected + */ + // @codingStandardsIgnoreStart + protected function assertSetCookieWith($expected) + // @codingStandardsIgnoreEnd + { + $this->assertCount(1, Kohana_CookieTest_TestableCookie::$_mock_cookies_set); + $relevant_values = array_intersect_key(Kohana_CookieTest_TestableCookie::$_mock_cookies_set[0], $expected); + $this->assertEquals($expected, $relevant_values); + } + + /** + * Configure the $_SERVER[HTTP_USER_AGENT] environment variable for the test + * + * @param string $user_agent + */ + protected function set_or_remove_http_user_agent($user_agent) + { + if ($user_agent === NULL) + { + unset($_SERVER['HTTP_USER_AGENT']); + } + else + { + $_SERVER['HTTP_USER_AGENT'] = $user_agent; + } + } +} + +/** + * Class Kohana_CookieTest_TestableCookie wraps the cookie class to mock out the actual setcookie and time calls for + * unit testing. + */ +class Kohana_CookieTest_TestableCookie extends Cookie { + + /** + * @var array setcookie calls that were made */ - public function test_salt($key, $value, $expected) + public static $_mock_cookies_set = array(); + + /** + * {@inheritdoc} + */ + protected static function _setcookie($name, $value, $expire, $path, $domain, $secure, $httponly) { - $this->assertSame($expected, cookie::salt($key, $value)); + self::$_mock_cookies_set[] = array( + 'name' => $name, + 'value' => $value, + 'expire' => $expire, + 'path' => $path, + 'domain' => $domain, + 'secure' => $secure, + 'httponly' => $httponly + ); + + return TRUE; } + + /** + * @return int + */ + protected static function _time() + { + return Kohana_CookieTest::UNIX_TIMESTAMP; + } + } From 200a25cbe76f06c7341e60bfdf5e6756af70da1d Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 14:44:37 +0100 Subject: [PATCH 62/72] Reinstate skipped Security::csrf tests These tests were disabled in 46e2ee9946 because they were generating an error if headers had already been sent. http://dev.kohanaframework.org/issues/4155 This appears no longer the case - presumably the Session class or test configuration/environment has changed since then. The tests could probably still be clearer and more comprehensive, but they run. --- tests/kohana/SecurityTest.php | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/kohana/SecurityTest.php b/tests/kohana/SecurityTest.php index 4c3b368f5..25eb020b5 100644 --- a/tests/kohana/SecurityTest.php +++ b/tests/kohana/SecurityTest.php @@ -67,17 +67,6 @@ public function test_strip_image_tags($expected, $input) */ public function provider_csrf_token() { - // Unfortunately this data provider has to use the session in order to - // generate its data. If headers have already been sent then this method - // throws an error, even if the test is does not run. If we return an - // empty array then this also causes an error, so the only way to get - // around it is to return an array of misc data and have the test skip - // if headers have been sent. It's annoying this hack has to be - // implemented, but the security code isn't exactly brilliantly - // implemented. Ideally we'd be able to inject a session instance - if (headers_sent()) - return array(array('', '', 0)); - $array = array(); for ($i = 0; $i <= 4; $i++) { @@ -96,10 +85,7 @@ public function provider_csrf_token() */ public function test_csrf_token($expected, $input, $iteration) { - if (headers_sent()) { - $this->markTestSkipped('Headers have already been sent, session not available'); - } - + //@todo: the Security::token tests need to be reviewed to check how much of the logic they're actually covering Security::$token_name = 'token_'.$iteration; $this->assertSame(TRUE, $input); $this->assertSame($expected, Security::token(FALSE)); From fe41689f0700465f2730523ce3ecd578388c1043 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 15:00:05 +0100 Subject: [PATCH 63/72] Reinstate one skipped test for File::mime These tests aren't great, and the PHP mime-type test is particularly likely to be unreliable. We should be able to get a valid (eg image/png) result in all current environments though for the moment. Probably the File::mime method would be best reimplemented with some third-party component, surely this is a solved problem by now. --- tests/kohana/FileTest.php | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/kohana/FileTest.php b/tests/kohana/FileTest.php index 8d4c49112..712bb2cdd 100644 --- a/tests/kohana/FileTest.php +++ b/tests/kohana/FileTest.php @@ -5,7 +5,7 @@ * * @group kohana * @group kohana.core - * @group kohana.core.url + * @group kohana.core.file * * @package Kohana * @category Tests @@ -25,8 +25,7 @@ public function provider_mime() { return array( // $value, $result - array(Kohana::find_file('classes', 'File')), - array(Kohana::find_file('tests', 'test_data/github', 'png')), + array(Kohana::find_file('tests', 'test_data/github', 'png'), 'image/png'), ); } @@ -38,12 +37,10 @@ public function provider_mime() * @param boolean $input Input for File::mime * @param boolean $expected Output for File::mime */ - public function test_mime($input) + public function test_mime($input, $expected) { - $this->markTestSkipped( - 'This test doesn\'t do anything useful!' - ); - $this->assertSame(1, preg_match('/^(?:application|audio|image|message|multipart|text|video)\/[a-z.+0-9-]+$/i', File::mime($input))); + //@todo: File::mime coverage needs significant improvement or to be dropped for a composer package - it's a "horribly unreliable" method with very little testing + $this->assertSame($expected, File::mime($input)); } /** From 5a24c6e185203638d3e92445e415834a536a1683 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 15:10:28 +0100 Subject: [PATCH 64/72] Fix mocking for incomplete Session test --- tests/kohana/SessionTest.php | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/tests/kohana/SessionTest.php b/tests/kohana/SessionTest.php index 1f34fa807..83a35921d 100644 --- a/tests/kohana/SessionTest.php +++ b/tests/kohana/SessionTest.php @@ -95,20 +95,14 @@ public function test_constructor_uses_settings_from_config_and_casts($expected, */ public function test_constructor_loads_session_with_session_id() { - $this->markTestIncomplete( - 'Need to work out why constructor is not being called' - ); - $config = array(); $session_id = 'lolums'; // Don't auto-call constructor, we need to setup the mock first - $session = $this->getMockForAbstractClass( - 'Session', - array(), - '', - FALSE - ); + $session = $this->getMockBuilder('Session') + ->disableOriginalConstructor() + ->setMethods(array('read')) + ->getMockForAbstractClass(); $session ->expects($this->once()) From c7bc251f3d035cfaddbfa75eaca27a6a6dc59041 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 15:37:35 +0100 Subject: [PATCH 65/72] Rewrite Kohana::message tests for fragility and coverage These tests were vulnerable to breakage if modules provide their own validation message files, so were being skipped. Fixed to use (hopefully) collision-proof message files with known values and to cover a broader range of cases including missing file and missing key. Would ideally be further refactored to mock/have complete control of the module search path outside global state. --- tests/kohana/CoreTest.php | 82 +++++++++++-------- .../messages/kohana_core_message_tests.php | 6 ++ .../messages/kohana_core_message_tests.php | 6 ++ 3 files changed, 59 insertions(+), 35 deletions(-) create mode 100644 tests/test_data/message_tests/bottom_module/messages/kohana_core_message_tests.php create mode 100644 tests/test_data/message_tests/top_module/messages/kohana_core_message_tests.php diff --git a/tests/kohana/CoreTest.php b/tests/kohana/CoreTest.php index 04b06dfcd..bdb750914 100644 --- a/tests/kohana/CoreTest.php +++ b/tests/kohana/CoreTest.php @@ -18,6 +18,32 @@ */ class Kohana_CoreTest extends Unittest_TestCase { + protected $old_modules = array(); + + /** + * Captures the module list as it was before this test + * + * @return null + */ + // @codingStandardsIgnoreStart + public function setUp() + // @codingStandardsIgnoreEnd + { + parent::setUp(); + $this->old_modules = Kohana::modules(); + } + + /** + * Restores the module list + * + * @return null + */ + // @codingStandardsIgnoreStart + public function tearDown() + // @codingStandardsIgnoreEnd + { + Kohana::modules($this->old_modules); + } /** * Provides test data for test_sanitize() @@ -157,35 +183,18 @@ public function test_cache($key, $value, $lifetime) public function provider_message() { return array( - // $value, $result - array(':field must not be empty', 'validation', 'not_empty'), - array( + array('no_message_file', 'anything', 'default', 'default'), + array('no_message_file', NULL, 'anything', array()), + array('kohana_core_message_tests', 'bottom_only', 'anything', 'inherited bottom message'), + array('kohana_core_message_tests', 'cfs_replaced', 'anything', 'overriding cfs_replaced message'), + array('kohana_core_message_tests', 'top_only', 'anything', 'top only message'), + array('kohana_core_message_tests', 'missing', 'default', 'default'), + array('kohana_core_message_tests', NULL, 'anything', array( - 'alpha' => ':field must contain only letters', - 'alpha_dash' => ':field must contain only numbers, letters and dashes', - 'alpha_numeric' => ':field must contain only letters and numbers', - 'color' => ':field must be a color', - 'credit_card' => ':field must be a credit card number', - 'date' => ':field must be a date', - 'decimal' => ':field must be a decimal with :param2 places', - 'digit' => ':field must be a digit', - 'email' => ':field must be a email address', - 'email_domain' => ':field must contain a valid email domain', - 'equals' => ':field must equal :param2', - 'exact_length' => ':field must be exactly :param2 characters long', - 'in_array' => ':field must be one of the available options', - 'ip' => ':field must be an ip address', - 'matches' => ':field must be the same as :param2', - 'min_length' => ':field must be at least :param2 characters long', - 'max_length' => ':field must not exceed :param2 characters long', - 'not_empty' => ':field must not be empty', - 'numeric' => ':field must be numeric', - 'phone' => ':field must be a phone number', - 'range' => ':field must be within the range of :param2 to :param3', - 'regex' => ':field does not match the required format', - 'url' => ':field must be a url', - ), - 'validation', NULL, + 'bottom_only' => 'inherited bottom message', + 'cfs_replaced' => 'overriding cfs_replaced message', + 'top_only' => 'top only message' + ) ), ); } @@ -195,15 +204,18 @@ public function provider_message() * * @test * @dataProvider provider_message - * @covers Kohana::message - * @param boolean $expected Output for Kohana::message - * @param boolean $file File to look in for Kohana::message - * @param boolean $key Key for Kohana::message + * @covers Kohana::message + * @param string $file to pass to Kohana::message + * @param string $key to pass to Kohana::message + * @param string $default to pass to Kohana::message + * @param string $expected Output for Kohana::message */ - public function test_message($expected, $file, $key) + public function test_message($file, $key, $default, $expected) { - $this->markTestSkipped('This test is incredibly fragile and needs to be re-done'); - $this->assertEquals($expected, Kohana::message($file, $key)); + $test_path = realpath(dirname(__FILE__).'/../test_data/message_tests'); + Kohana::modules(array('top' => "$test_path/top_module", 'bottom' => "$test_path/bottom_module")); + + $this->assertEquals($expected, Kohana::message($file, $key, $default, $expected)); } /** diff --git a/tests/test_data/message_tests/bottom_module/messages/kohana_core_message_tests.php b/tests/test_data/message_tests/bottom_module/messages/kohana_core_message_tests.php new file mode 100644 index 000000000..efd167999 --- /dev/null +++ b/tests/test_data/message_tests/bottom_module/messages/kohana_core_message_tests.php @@ -0,0 +1,6 @@ + 'inherited bottom message', + 'cfs_replaced' => 'inherited cfs_replaced message', +); diff --git a/tests/test_data/message_tests/top_module/messages/kohana_core_message_tests.php b/tests/test_data/message_tests/top_module/messages/kohana_core_message_tests.php new file mode 100644 index 000000000..07fcd7e2b --- /dev/null +++ b/tests/test_data/message_tests/top_module/messages/kohana_core_message_tests.php @@ -0,0 +1,6 @@ + 'top only message', + 'cfs_replaced' => 'overriding cfs_replaced message', +); From e9cd5ed9301c6abc4240e87ccca3b79077803a1e Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 16:10:07 +0100 Subject: [PATCH 66/72] Reinstate and improve Feed::parse tests Original test was being skipped because it was hitting the internet - the major relevant functionality here is the parsing rather than the remote access. Added local example feeds for RSS2.0 as well as the previously tested atom feed. Also improved the tests to check for the title as well as the number of elements since we now have known content to work with. --- tests/kohana/FeedTest.php | 13 +++++-- tests/test_data/feeds/activity.atom | 58 +++++++++++++++++++++++++++++ tests/test_data/feeds/example.rss20 | 20 ++++++++++ 3 files changed, 87 insertions(+), 4 deletions(-) create mode 100644 tests/test_data/feeds/activity.atom create mode 100644 tests/test_data/feeds/example.rss20 diff --git a/tests/kohana/FeedTest.php b/tests/kohana/FeedTest.php index 40986303b..e4279dd51 100644 --- a/tests/kohana/FeedTest.php +++ b/tests/kohana/FeedTest.php @@ -25,7 +25,8 @@ public function provider_parse() { return array( // $source, $expected - array('http://dev.kohanaframework.org/projects/kohana3/activity.atom', 15), + array(realpath(__DIR__.'/../test_data/feeds/activity.atom'), array('Proposals (Political/Workflow) #4839 (New)', 'Proposals (Political/Workflow) #4782')), + array(realpath(__DIR__.'/../test_data/feeds/example.rss20'), array('Example entry')), ); } @@ -38,11 +39,15 @@ public function provider_parse() * @param string $source URL to test * @param integer $expected Count of items */ - public function test_parse($source, $expected) + public function test_parse($source, $expected_titles) { - $this->markTestSkipped('We don\'t go to the internet for tests.'); + $titles = array(); + foreach (Feed::parse($source) as $item) + { + $titles[] = $item['title']; + } - $this->assertEquals($expected, count(Feed::parse($source))); + $this->assertSame($expected_titles, $titles); } /** diff --git a/tests/test_data/feeds/activity.atom b/tests/test_data/feeds/activity.atom new file mode 100644 index 000000000..7fe42c6b1 --- /dev/null +++ b/tests/test_data/feeds/activity.atom @@ -0,0 +1,58 @@ + + + Kohana v3.x: Activity + + + http://dev.kohanaframework.org/ + http://dev.kohanaframework.org/favicon.ico?1392677580 + 2014-08-28T01:52:12Z + + Kohana Development + + +Redmine + + Proposals (Political/Workflow) #4839 (New) + + http://dev.kohanaframework.org/issues/4839 + 2014-08-28T01:52:12Z + + Guillaume Poirier-Morency + guillaumepoiriermorency@gmail.com + + +<p>I have a prototype here <a class="external" href="https://github.com/arteymix/kohana-makefile">https://github.com/arteymix/kohana-makefile</a></p> + + + <p>The tool is very useful for settings permissions and running tests.</p> + + + <p>I think we should consider having a good make tool in the sample application for the 3.4.*.</p> + + + Proposals (Political/Workflow) #4782 + + http://dev.kohanaframework.org/issues/4782#change-17279 + 2014-08-28T01:44:26Z + + Guillaume Poirier-Morency + guillaumepoiriermorency@gmail.com + + +<p>Moving to composer is a nice idea. This will allow Kohana modules to define a wide range of dependencies.</p> + + + <p>Although, I think that modules designed specifically for Kohana should end in modules and external libraries in application/vendor. This makes a clear dinsinction between what gets autoloaded by the CFS and what gets loaded by composer. Technically, we add "vendor-dir": "application/vendor" in "config" in composer.json.</p> + + + <p>Then, only add a line after the modules loading in bootstrap.php</p> + + +<pre> +// Autoloading composer packages +require Kohana::find_file('vendor', 'autoload'); +</pre> + + <p>This is pretty much what I do right now. This doesn't break anything and allow a full access to composer.</p> + + diff --git a/tests/test_data/feeds/example.rss20 b/tests/test_data/feeds/example.rss20 new file mode 100644 index 000000000..9fc6c39f1 --- /dev/null +++ b/tests/test_data/feeds/example.rss20 @@ -0,0 +1,20 @@ + + + + RSS Title + This is an example of an RSS feed + http://www.example.com/main.html + Mon, 06 Sep 2010 00:01:00 +0000 + Sun, 06 Sep 2009 16:20:00 +0000 + 1800 + + + Example entry + Here is some text containing an interesting description. + http://www.example.com/blog/post/1 + 7bd204c6-1655-4c27-aeee-53f933c5395f + Sun, 06 Sep 2009 16:20:00 +0000 + + + + From 1631e0bf4496bad1f0d3152da90c6e39f84786c1 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Thu, 18 Sep 2014 16:37:06 +0100 Subject: [PATCH 67/72] Remove invalid skipped test - Response does send headers in CLI This test was originally implemented in bf0175f6cd to fix http://dev.kohanaframework.org/issues/3767 - it was required because headers were sent directly by the response class, and once they had been sent it was then very difficult to test other variations. The fact that headers are not relevant in CLI appears to have been a side concern. Subsequently in a1943b0d7d26cf5a header sending moved to HTTP_Header which mocks out `header` with a callback interface for testing instead. Since that refactoring (released in v3.2.0) the headers are always sent in CLI unless headers_sent is already true. Therefore this test is invalid and can be removed. --- tests/kohana/ResponseTest.php | 23 +---------------------- 1 file changed, 1 insertion(+), 22 deletions(-) diff --git a/tests/kohana/ResponseTest.php b/tests/kohana/ResponseTest.php index d5e8870c1..998916314 100644 --- a/tests/kohana/ResponseTest.php +++ b/tests/kohana/ResponseTest.php @@ -171,27 +171,6 @@ public function test_cookie_get() $this->assertSame(Cookie::$expiration, $cookie['expiration']); } - /** - * Tests that the headers are not sent by PHP in CLI mode - * - * @return void - */ - public function test_send_headers_cli() - { - if (headers_sent()) - { - $this->markTestSkipped('Cannot test this feature as headers have already been sent!'); - } - - $content_type = 'application/json'; - $response = new Response; - $response->headers('content-type', $content_type) - ->send_headers(); - - $this->assertFalse(headers_sent()); - - } - /** * Test the content type is sent when set * @@ -205,4 +184,4 @@ public function test_content_type_when_set() $headers = $response->send_headers()->headers(); $this->assertSame($content_type, (string) $headers['content-type']); } -} \ No newline at end of file +} From 67da593df7230a97f13075a17d9fe0d236d51188 Mon Sep 17 00:00:00 2001 From: Kevin Daudt Date: Wed, 24 Sep 2014 22:15:42 +0200 Subject: [PATCH 68/72] Text: provide tests for user_agent method --- tests/kohana/TextTest.php | 107 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) diff --git a/tests/kohana/TextTest.php b/tests/kohana/TextTest.php index a59bd5939..5ede0b077 100644 --- a/tests/kohana/TextTest.php +++ b/tests/kohana/TextTest.php @@ -639,4 +639,111 @@ public function test_auto_link($text, $urls = array(), $emails = array()) } + + public function provider_user_agents() + { + return array( + array( + "Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36", + array( + 'browser' => 'Chrome', + 'version' => '37.0.2049.0', + 'platform' => "Windows 8.1" + ) + ), + array( + "Mozilla/5.0 (Macintosh; U; Mac OS X 10_6_1; en-US) AppleWebKit/530.5 (KHTML, like Gecko) Chrome/ Safari/530.5", + array( + 'browser' => 'Chrome', + 'version' => '530.5', + 'platform' => "Mac OS X" + ) + ), + array( + "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/537.13+ (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2", + array( + 'browser' => 'Safari', + 'version' => '534.57.2', + 'platform' => 'Mac OS X' + ) + ), + array( + "Lynx/2.8.8dev.3 libwww-FM/2.14 SSL-MM/1.4.1", + array( + 'browser' => 'Lynx', + 'version' => '2.8.8dev.3', + 'platform' => false + ) + ) + ); + } + + /** + * Tests Text::user_agent + * + * @dataProvider provider_user_agents + * @group current + */ + public function test_user_agent_returns_correct_browser($userAgent, $expectedData) + { + $browser = Text::user_agent($userAgent, 'browser'); + + $this->assertEquals($expectedData['browser'], $browser); + } + + /** + * Tests Text::user_agent + * + * @dataProvider provider_user_agents + * @test + */ + public function test_user_agent_returns_correct_version($userAgent, $expectedData) + { + $version = Text::user_agent($userAgent, 'version'); + + $this->assertEquals($expectedData['version'], $version); + } + + /** + * Tests Text::user_agent + * @test + */ + public function test_user_agent_recognizes_robots() + { + $bot = Text::user_agent('Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)', 'robot'); + + $this->assertEquals('Googlebot', $bot); + } + + /** + * Tests Text::user_agent + * + * @dataProvider provider_user_agents + * @test + */ + public function test_user_agent_returns_correct_platform($userAgent, $expectedData) + { + $platform = Text::user_agent($userAgent, 'platform'); + + $this->assertEquals($expectedData['platform'], $platform); + } + + + /** + * Tests Text::user_agent + * @test + */ + public function test_user_agent_accepts_array() + { + $agent_info = Text::user_agent( + 'Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 '. + '(KHTML, like Gecko) Chrome/37.0.2049.0 Safari/537.36', + array('browser', 'version', 'platform')); + + $this->assertArrayHasKey('browser', $agent_info); + $this->assertArrayHasKey('version', $agent_info); + $this->assertArrayHasKey('platform', $agent_info); + + } + } From 0699cbf0dc2464a38f28ca3dc072254b6e6c10f2 Mon Sep 17 00:00:00 2001 From: Kevin Daudt Date: Wed, 24 Sep 2014 22:16:05 +0200 Subject: [PATCH 69/72] user_agents: add new windows platform windows nt 6.3 equals Windows 8.1 --- config/user_agents.php | 1 + 1 file changed, 1 insertion(+) diff --git a/config/user_agents.php b/config/user_agents.php index f4b92eac4..3f631a4f0 100644 --- a/config/user_agents.php +++ b/config/user_agents.php @@ -3,6 +3,7 @@ return array( 'platform' => array( + 'windows nt 6.3' => 'Windows 8.1', 'windows nt 6.2' => 'Windows 8', 'windows nt 6.1' => 'Windows 7', 'windows nt 6.0' => 'Windows Vista', From 7bbc0d2067df64ae550e465567bf0c52b8a0402b Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Fri, 26 Sep 2014 11:40:52 +0100 Subject: [PATCH 70/72] Force Debug::dump marker to alpha for type safety [Fixes #559] Resolves a flickering test (and flickering Debug::dump output) where internal recursion markers are left in dumped arrays if the current system microtime produces a uniqid with only numeric characters. --- classes/Kohana/Debug.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/Kohana/Debug.php b/classes/Kohana/Debug.php index 5a82bb623..9106b00c1 100644 --- a/classes/Kohana/Debug.php +++ b/classes/Kohana/Debug.php @@ -133,8 +133,8 @@ protected static function _dump( & $var, $length = 128, $limit = 10, $level = 0) if ($marker === NULL) { - // Make a unique marker - $marker = uniqid("\x00"); + // Make a unique marker - force it to be alphanumeric so that it is always treated as a string array key + $marker = uniqid("\x00")."x"; } if (empty($var)) From 26e83a43674f4790a46ef59d18c3fb8766fc38b6 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Fri, 10 Oct 2014 15:38:26 +0100 Subject: [PATCH 71/72] Add travis build badges [skip ci] --- README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/README.md b/README.md index 4fe265fe5..4689a2182 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,10 @@ # Kohana PHP Framework - core +| ver | Stable | Develop | +|-------|------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------| +| 3.3.x | [![Build Status - 3.3/master](https://travis-ci.org/kohana/core.svg?branch=3.3%2Fmaster)](https://travis-ci.org/kohana/core) | [![Build Status - 3.3/develop](https://travis-ci.org/kohana/core.svg?branch=3.3%2Fdevelop)](https://travis-ci.org/kohana/core) | +| 3.4.x | [![Build Status - 3.4/master](https://travis-ci.org/kohana/core.svg?branch=3.4%2Fmaster)](https://travis-ci.org/kohana/core) | [![Build Status - 3.4/develop](https://travis-ci.org/kohana/core.svg?branch=3.4%2Fdevelop)](https://travis-ci.org/kohana/core) | + This is the core package for the [Kohana](http://kohanaframework.org/) object oriented HMVC framework built using PHP5. It aims to be swift, secure, and small. From eb55e8df2083a279917bd9030a6a6dd190880c13 Mon Sep 17 00:00:00 2001 From: Andrew Coulton Date: Fri, 10 Oct 2014 16:19:12 +0100 Subject: [PATCH 72/72] Update travis configuration and composer dependencies for 3.4 series --- .travis.yml | 3 +-- composer.json | 2 +- koharness.php | 1 + 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 603c929a3..164101d28 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,13 @@ language: php php: - - 5.3 - 5.4 - 5.5 - 5.6 - hhvm before_script: - - COMPOSER_ROOT_VERSION=3.3.x-dev composer install --prefer-dist + - COMPOSER_ROOT_VERSION=3.4.x-dev composer install --prefer-dist - vendor/bin/koharness script: diff --git a/composer.json b/composer.json index e77e40ba5..23ccc16a4 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "php": ">=5.4.0" }, "require-dev": { - "kohana/unittest": "3.3.*@dev", + "kohana/unittest": "3.4.*@dev", "kohana/koharness": "*@dev" }, "suggest": { diff --git a/koharness.php b/koharness.php index 7845498db..28c0705b7 100644 --- a/koharness.php +++ b/koharness.php @@ -1,6 +1,7 @@ '3.4', 'modules' => array( 'unittest' => __DIR__ . '/vendor/kohana/unittest' ),