diff --git a/system/guide/kohana/autoloading.md b/system/guide/kohana/autoloading.md index 8ebdcb7..79e8176 100644 --- a/system/guide/kohana/autoloading.md +++ b/system/guide/kohana/autoloading.md @@ -44,29 +44,29 @@ You can easily gain access to other libraries if they include an autoloader. For Somewhere in `application/bootstrap.php`, copy the following code: - /** - * Enable Zend Framework autoloading - */ - if ($path = Kohana::find_file('vendor', 'Zend/Loader')) - { - ini_set('include_path', - ini_get('include_path').PATH_SEPARATOR.dirname(dirname($path))); - - require_once 'Zend/Loader/Autoloader.php'; - Zend_Loader_Autoloader::getInstance(); - } - + /** + * Enable Zend Framework autoloading + */ + if ($path = Kohana::find_file('vendor', 'Zend/Loader')) + { + ini_set('include_path', + ini_get('include_path').PATH_SEPARATOR.dirname(dirname($path))); + + require_once 'Zend/Loader/Autoloader.php'; + Zend_Loader_Autoloader::getInstance(); + } + #### Usage example You can now autoload any Zend Framework classes from inside your Kohana application. - if ($validate($this->request->post())) - { - $mailer = new Zend_Mail; - - $mailer->setBodyHtml($view) - ->setFrom(Kohana::$config->load('site')->email_from) - ->addTo($email) - ->setSubject($message) - ->send(); - } + if ($validate($this->request->post())) + { + $mailer = new Zend_Mail; + + $mailer->setBodyHtml($view) + ->setFrom(Kohana::$config->load('site')->email_from) + ->addTo($email) + ->setSubject($message) + ->send(); + } diff --git a/system/guide/kohana/bootstrap.md b/system/guide/kohana/bootstrap.md index 0d7ecae..eecf956 100644 --- a/system/guide/kohana/bootstrap.md +++ b/system/guide/kohana/bootstrap.md @@ -33,7 +33,7 @@ Kohana is then initialized by calling [Kohana::init], and the log and [config](f Kohana::init(array(' base_url' => '/kohana/', - index_file => false, + index_file => false, )); // Attach the file writer to logging. Multiple writers are supported. @@ -54,11 +54,11 @@ You can add conditional statements to make the bootstrap have different values b */ if (strpos($_SERVER['HTTP_HOST'], 'kohanaframework.org') !== FALSE) { - // We are live! - Kohana::$environment = Kohana::PRODUCTION; + // We are live! + Kohana::$environment = Kohana::PRODUCTION; - // Turn off notices and strict errors - error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT); + // Turn off notices and strict errors + error_reporting(E_ALL ^ E_NOTICE ^ E_STRICT); } /** @@ -66,10 +66,10 @@ if (strpos($_SERVER['HTTP_HOST'], 'kohanaframework.org') !== FALSE) ... [trimmed] */ Kohana::init(array( - 'base_url' => Kohana::$environment === Kohana::PRODUCTION ? '/' : '/kohanaframework.org/', - 'caching' => Kohana::$environment === Kohana::PRODUCTION, - 'profile' => Kohana::$environment !== Kohana::PRODUCTION, - 'index_file' => FALSE, + 'base_url' => Kohana::$environment === Kohana::PRODUCTION ? '/' : '/kohanaframework.org/', + 'caching' => Kohana::$environment === Kohana::PRODUCTION, + 'profile' => Kohana::$environment !== Kohana::PRODUCTION, + 'index_file' => FALSE, )); ... [trimmed] @@ -89,9 +89,9 @@ Each key in the array should be the name of the module, and the value is the pat // Example excerpt from bootstrap.php Kohana::modules(array( - 'database' => MODPATH.'database', - 'orm' => MODPATH.'orm', - 'userguide' => MODPATH.'userguide', + 'database' => MODPATH.'database', + 'orm' => MODPATH.'orm', + 'userguide' => MODPATH.'userguide', )); ~~~ @@ -104,8 +104,8 @@ Kohana::modules(array( ~~~ // The default route that comes with Kohana 3 Route::set('default', '((/(/)))') - ->defaults(array( - 'controller' => 'Welcome', - 'action' => 'index', - )); + ->defaults(array( + 'controller' => 'Welcome', + 'action' => 'index', + )); ~~~ diff --git a/system/guide/kohana/config.md b/system/guide/kohana/config.md index 68ef26e..38d7834 100644 --- a/system/guide/kohana/config.md +++ b/system/guide/kohana/config.md @@ -15,8 +15,8 @@ you need a **Config Writer**. Implementing them is as simple as extending the [Kohana_Config_Reader] / [Kohana_Config_Writer] interfaces: - class Kohana_Config_Database_Reader implements Kohana_Config_Reader - class Kohana_Config_Database_Writer extends Kohana_Config_Database_Reader implements Kohana_Config_Writer + class Kohana_Config_Database_Reader implements Kohana_Config_Reader + class Kohana_Config_Database_Writer extends Kohana_Config_Database_Reader implements Kohana_Config_Writer You'll notice in the above example that the Database Writer extends the Database Reader. This is the convention with config sources, the reasoning being that if you can write to a @@ -35,44 +35,44 @@ the database source uses a column to distinguish between groups. To load a config group simply call `Kohana::$config->load()` with the name of the group you wish to load: - $config = Kohana::$config->load('my_group'); + $config = Kohana::$config->load('my_group'); `load()` will return an instance of [Config_Group] which encapsulates the config values and ensures that any modifications made will be passed back to the config writers. To get a config value from a [Config_Group] object simply call [Config_Group::get]: - $config = Kohana::$config->load('my_group'); - $value = $config->get('var'); + $config = Kohana::$config->load('my_group'); + $value = $config->get('var'); To modify a value call [Config_Group::set]: - $config = Kohana::$config->load('my_group'); - $config->set('var', 'new_value'); + $config = Kohana::$config->load('my_group'); + $config->set('var', 'new_value'); ### Alternative methods for getting / setting config In addition to the methods described above you can also access config values using dots to outline a path from the config group to the value you want: - // Config file: database.php - return array( - 'default' => array( - 'connection' => array( - 'hostname' => 'localhost' - ) - ) - ); + // Config file: database.php + return array( + 'default' => array( + 'connection' => array( + 'hostname' => 'localhost' + ) + ) + ); - // Code which needs hostname: - $hostname = Kohana::$config->load('database.default.connection.hostname'); + // Code which needs hostname: + $hostname = Kohana::$config->load('database.default.connection.hostname'); Which is equivalent to: - $config = Kohana::$config->load('database')->get('default'); + $config = Kohana::$config->load('database')->get('default'); - $hostname = $config['connection']['hostname']; + $hostname = $config['connection']['hostname']; Obviously this method is a lot more compact than the original. However, please bear in mind that using `dot.notation` is a _lot_ slower than calling `get()` and traversing the array yourself. Dot notation @@ -81,13 +81,13 @@ can be useful if you only need one specific variable, but otherwise it's best to As [Config_Group] extends [Array_Object](http://php.net/manual/en/class.arrayobject.php) you can also use array syntax to get/set config vars: - $config = Kohana::$config->load('database'); + $config = Kohana::$config->load('database'); - // Getting the var - $hostname = $config['default']['connection']['hostname']; + // Getting the var + $hostname = $config['default']['connection']['hostname']; - // Setting the var - $config['default']['connection']['hostname'] = '127.0.0.1'; + // Setting the var + $config['default']['connection']['hostname'] = '127.0.0.1'; Again, this syntax is more costly than calling `get()` / `set()`. @@ -106,66 +106,66 @@ The position of sources in the stack is determined by how they are loaded in you By default when you load a source it is pushed to the top of a stack: // Stack: - Kohana::$config->attach(new Config_File); - // Stack: Config_File - Kohana::$config->attach(new Config_Database); - // Stack: Config_Database, Config_File + Kohana::$config->attach(new Config_File); + // Stack: Config_File + Kohana::$config->attach(new Config_Database); + // Stack: Config_Database, Config_File In the example above, any config values found in the database will override those found in the filesystem. For example, using the setup outlined above: - // Configuration in the filesystem: - email: - sender: - email: my.awesome.address@example.com - name: Unknown - method: smtp - - // Configuration in the database: - email: - sender: - email: my.supercool.address@gmail.com - name: Kohana Bot - - // Configuration returned by Kohana::$config->load('email') - email: - sender: - email: my.supercool.address@gmail.com - name: Kohana Bot - method: smtp + // Configuration in the filesystem: + email: + sender: + email: my.awesome.address@example.com + name: Unknown + method: smtp + + // Configuration in the database: + email: + sender: + email: my.supercool.address@gmail.com + name: Kohana Bot + + // Configuration returned by Kohana::$config->load('email') + email: + sender: + email: my.supercool.address@gmail.com + name: Kohana Bot + method: smtp [!!] **Note:** The above syntax is simply pseudo code to illustrate the concept of config merging. On some occasions you may want to append a config source to the bottom of the stack, to do this pass `FALSE` as the second parameter to `attach()`: - // Stack: - Kohana::$config->attach(new Config_File); - // Stack: Config_File - Kohana::$config->attach(new Config_Database, FALSE); - // Stack: Config_File, Config_Database + // Stack: + Kohana::$config->attach(new Config_File); + // Stack: Config_File + Kohana::$config->attach(new Config_Database, FALSE); + // Stack: Config_File, Config_Database In this example, any values found in the filesystem will override those found in the db. For example: - // Configuration in the filesystem: - email: - sender: - email: my.awesome.address@example.com - name: Unknown - method: smtp - - // Configuration in the database: - email: - sender: - email: my.supercool.address@gmail.com - name: Kohana Bot - - // Configuration returned by Kohana::$config->load('email') - email: - sender: - email: my.awesome.address@example.com - name: Unknown - method: smtp + // Configuration in the filesystem: + email: + sender: + email: my.awesome.address@example.com + name: Unknown + method: smtp + + // Configuration in the database: + email: + sender: + email: my.supercool.address@gmail.com + name: Kohana Bot + + // Configuration returned by Kohana::$config->load('email') + email: + sender: + email: my.awesome.address@example.com + name: Unknown + method: smtp ## Using different config sources based on the environment @@ -180,14 +180,14 @@ so replacing the default `Config_File` source isn't really an option. To get around this you can attach a separate config file reader which loads its config from a subdir of `config` called "testing": - Kohana::$config->attach(new Config_File); + Kohana::$config->attach(new Config_File); - Kohana::$config->attach(new Config_Database); + Kohana::$config->attach(new Config_Database); - if (Kohana::$environment === Kohana::TESTING) - { - Kohana::$config->attach(new Config_File('config/testing')); - } + if (Kohana::$environment === Kohana::TESTING) + { + Kohana::$config->attach(new Config_File('config/testing')); + } During normal development the config source stack looks like `Config_Database, Config_File('config')`. However, when `Kohana::$environment === Kohana::TESTING` the stack looks like `Config_File('config/testing'), Config_Database, Config_File('config')` \ No newline at end of file diff --git a/system/guide/kohana/conventions.md b/system/guide/kohana/conventions.md index ed22a2c..a8f757d 100644 --- a/system/guide/kohana/conventions.md +++ b/system/guide/kohana/conventions.md @@ -1,6 +1,6 @@ # Conventions and Coding Style -It is encouraged that you follow Kohana's coding style. This makes code more readable and allows for easier code sharing and contributing. +It is encouraged that you follow Kohana's coding style. This makes code more readable and allows for easier code sharing and contributing. ## Class Names and File Location @@ -37,69 +37,69 @@ Please use [BSD/Allman Style](http://en.wikipedia.org/wiki/Indent_style#BSD.2FAl Curly brackets are placed on their own line, indented to the same level as the control statement. - // Correct - if ($a === $b) - { - ... - } - else - { - ... - } - - // Incorrect - if ($a === $b) { - ... - } else { - ... - } + // Correct + if ($a === $b) + { + ... + } + else + { + ... + } + + // Incorrect + if ($a === $b) { + ... + } else { + ... + } #### Class Brackets The only exception to the curly bracket rule is, the opening bracket of a class goes on the same line. - // Correct - class Foo { + // Correct + class Foo { - // Incorrect - class Foo - { + // Incorrect + class Foo + { #### Empty Brackets Don't put any characters inside empty brackets. - // Correct - class Foo {} + // Correct + class Foo {} - // Incorrect - class Foo { } + // Incorrect + class Foo { } #### Array Brackets Arrays may be single line or multi-line. - array('a' => 'b', 'c' => 'd') - - array( - 'a' => 'b', - 'c' => 'd', - ) + array('a' => 'b', 'c' => 'd') + + array( + 'a' => 'b', + 'c' => 'd', + ) ##### Opening Parenthesis The opening array parenthesis goes on the same line. - // Correct - array( - ... - ) + // Correct + array( + ... + ) - // Incorrect: - array - ( - ... - ) + // Incorrect: + array + ( + ... + ) ##### Closing parenthesis @@ -107,56 +107,56 @@ The opening array parenthesis goes on the same line. The closing parenthesis of a multi-line single dimension array is placed on its own line, indented to the same level as the assignment or statement. - // Correct - $array = array( - ... - ) + // Correct + $array = array( + ... + ) - // Incorrect - $array = array( - ... - ) + // Incorrect + $array = array( + ... + ) ###### Multidimensional The nested array is indented one tab to the right, following the single dimension rules. - // Correct - array( - 'arr' => array( - ... - ), - 'arr' => array( - ... - ), - ) - - array( - 'arr' => array(...), - 'arr' => array(...), - ) - + // Correct + array( + 'arr' => array( + ... + ), + 'arr' => array( + ... + ), + ) + + array( + 'arr' => array(...), + 'arr' => array(...), + ) + ##### Arrays as Function Arguments - // Correct - do(array( - ... - )) - - // Incorrect - do(array( - ... - )) + // Correct + do(array( + ... + )) + + // Incorrect + do(array( + ... + )) As noted at the start of the array bracket section, single line syntax is also valid. - // Correct - do(array(...)) - - // Alternative for wrapping long lines - do($bar, 'this is a very long line', - array(...)); + // Correct + do(array(...)) + + // Alternative for wrapping long lines + do($bar, 'this is a very long line', + array(...)); ### Naming Conventions @@ -164,40 +164,40 @@ Kohana uses under_score naming, not camelCase naming. #### Classes - // Controller class, uses Controller_ prefix - class Controller_Apple extends Controller { + // Controller class, uses Controller_ prefix + class Controller_Apple extends Controller { - // Model class, uses Model_ prefix - class Model_Cheese extends Model { + // Model class, uses Model_ prefix + class Model_Cheese extends Model { - // Regular class - class Peanut { + // Regular class + class Peanut { When creating an instance of a class, don't use parentheses if you're not passing something on to the constructor: - // Correct: - $db = new Database; + // Correct: + $db = new Database; - // Incorrect: - $db = new Database(); + // Incorrect: + $db = new Database(); #### Functions and Methods Functions should be all lowercase, and use under_scores to separate words: - function drink_beverage($beverage) - { + function drink_beverage($beverage) + { #### Variables All variables should be lowercase and use under_score, not camelCase: - // Correct: - $foo = 'bar'; - $long_example = 'uses underscores'; + // Correct: + $foo = 'bar'; + $long_example = 'uses underscores'; - // Incorrect: - $weDontWantThis = 'understood?'; + // Incorrect: + $weDontWantThis = 'understood?'; ### Indentation @@ -205,170 +205,170 @@ You must use tabs to indent your code. Using spaces for tabbing is strictly forb Vertical spacing (for multi-line) is done with spaces. Tabs are not good for vertical alignment because different people have different tab widths. - $text = 'this is a long text block that is wrapped. Normally, we aim for ' - .'wrapping at 80 chars. Vertical alignment is very important for ' - .'code readability. Remember that all indentation is done with tabs,' - .'but vertical alignment should be completed with spaces, after ' - .'indenting with tabs.'; + $text = 'this is a long text block that is wrapped. Normally, we aim for ' + .'wrapping at 80 chars. Vertical alignment is very important for ' + .'code readability. Remember that all indentation is done with tabs,' + .'but vertical alignment should be completed with spaces, after ' + .'indenting with tabs.'; ### String Concatenation Do not put spaces around the concatenation operator: - // Correct: - $str = 'one'.$var.'two'; + // Correct: + $str = 'one'.$var.'two'; - // Incorrect: - $str = 'one'. $var .'two'; - $str = 'one' . $var . 'two'; + // Incorrect: + $str = 'one'. $var .'two'; + $str = 'one' . $var . 'two'; ### Single Line Statements Single-line IF statements should only be used when breaking normal execution (e.g. return or continue): - // Acceptable: - if ($foo == $bar) - return $foo; + // Acceptable: + if ($foo == $bar) + return $foo; - if ($foo == $bar) - continue; + if ($foo == $bar) + continue; - if ($foo == $bar) - break; + if ($foo == $bar) + break; - if ($foo == $bar) - throw new Exception('You screwed up!'); + if ($foo == $bar) + throw new Exception('You screwed up!'); - // Not acceptable: - if ($baz == $bun) - $baz = $bar + 2; + // Not acceptable: + if ($baz == $bun) + $baz = $bar + 2; ### Comparison Operations Please use OR and AND for comparison: - // Correct: - if (($foo AND $bar) OR ($b AND $c)) + // Correct: + if (($foo AND $bar) OR ($b AND $c)) + + // Incorrect: + if (($foo && $bar) || ($b && $c)) - // Incorrect: - if (($foo && $bar) || ($b && $c)) - Please use elseif, not else if: - // Correct: - elseif ($bar) + // Correct: + elseif ($bar) - // Incorrect: - else if($bar) + // Incorrect: + else if($bar) ### Switch Structures Each case, break and default should be on a separate line. The block inside a case or default must be indented by 1 tab. - switch ($var) - { - case 'bar': - case 'foo': - echo 'hello'; - break; - case 1: - echo 'one'; - break; - default: - echo 'bye'; - break; - } + switch ($var) + { + case 'bar': + case 'foo': + echo 'hello'; + break; + case 1: + echo 'one'; + break; + default: + echo 'bye'; + break; + } ### Parentheses There should be one space after statement name, followed by a parenthesis. The ! (bang) character must have a space on either side to ensure maximum readability. Except in the case of a bang or type casting, there should be no whitespace after an opening parenthesis or before a closing parenthesis. - // Correct: - if ($foo == $bar) - if ( ! $foo) + // Correct: + if ($foo == $bar) + if ( ! $foo) - // Incorrect: - if($foo == $bar) - if(!$foo) - if ((int) $foo) - if ( $foo == $bar ) - if (! $foo) + // Incorrect: + if($foo == $bar) + if(!$foo) + if ((int) $foo) + if ( $foo == $bar ) + if (! $foo) ### Ternaries All ternary operations should follow a standard format. Use parentheses around expressions only, not around just variables. - $foo = ($bar == $foo) ? $foo : $bar; - $foo = $bar ? $foo : $bar; + $foo = ($bar == $foo) ? $foo : $bar; + $foo = $bar ? $foo : $bar; All comparisons and operations must be done inside of a parentheses group: - $foo = ($bar > 5) ? ($bar + $foo) : strlen($bar); + $foo = ($bar > 5) ? ($bar + $foo) : strlen($bar); When separating complex ternaries (ternaries where the first part goes beyond ~80 chars) into multiple lines, spaces should be used to line up operators, which should be at the front of the successive lines: - $foo = ($bar == $foo) - ? $foo - : $bar; + $foo = ($bar == $foo) + ? $foo + : $bar; ### Type Casting Type casting should be done with spaces on each side of the cast: - // Correct: - $foo = (string) $bar; - if ( (string) $bar) + // Correct: + $foo = (string) $bar; + if ( (string) $bar) - // Incorrect: - $foo = (string)$bar; + // Incorrect: + $foo = (string)$bar; When possible, please use type casting instead of ternary operations: - // Correct: - $foo = (bool) $bar; + // Correct: + $foo = (bool) $bar; - // Incorrect: - $foo = ($bar == TRUE) ? TRUE : FALSE; + // Incorrect: + $foo = ($bar == TRUE) ? TRUE : FALSE; When casting type to integer or boolean, use the short format: - // Correct: - $foo = (int) $bar; - $foo = (bool) $bar; + // Correct: + $foo = (int) $bar; + $foo = (bool) $bar; - // Incorrect: - $foo = (integer) $bar; - $foo = (boolean) $bar; + // Incorrect: + $foo = (integer) $bar; + $foo = (boolean) $bar; ### Constants Always use uppercase for constants: - // Correct: - define('MY_CONSTANT', 'my_value'); - $a = TRUE; - $b = NULL; + // Correct: + define('MY_CONSTANT', 'my_value'); + $a = TRUE; + $b = NULL; - // Incorrect: - define('MyConstant', 'my_value'); - $a = True; - $b = null; + // Incorrect: + define('MyConstant', 'my_value'); + $a = True; + $b = null; Place constant comparisons at the end of tests: - // Correct: - if ($foo !== FALSE) + // Correct: + if ($foo !== FALSE) - // Incorrect: - if (FALSE !== $foo) + // Incorrect: + if (FALSE !== $foo) This is a slightly controversial choice, so I will explain the reasoning. If we were to write the previous example in plain English, the correct example would read: - if variable $foo is not exactly FALSE + if variable $foo is not exactly FALSE And the incorrect example would read: - if FALSE is not exactly variable $foo + if FALSE is not exactly variable $foo Since we are reading left to right, it simply doesn't make sense to put the constant first. @@ -378,41 +378,41 @@ Since we are reading left to right, it simply doesn't make sense to put the cons Use //, preferably above the line of code you're commenting on. Leave a space after it and start with a capital. Never use #. - // Correct + // Correct - //Incorrect - // incorrect - # Incorrect + //Incorrect + // incorrect + # Incorrect ### Regular Expressions When coding regular expressions please use PCRE rather than the POSIX flavor. PCRE is considered more powerful and faster. - // Correct: - if (preg_match('/abc/i', $str)) + // Correct: + if (preg_match('/abc/i', $str)) - // Incorrect: - if (eregi('abc', $str)) + // Incorrect: + if (eregi('abc', $str)) Use single quotes around your regular expressions rather than double quotes. Single-quoted strings are more convenient because of their simplicity. Unlike double-quoted strings they don't support variable interpolation nor integrated backslash sequences like \n or \t, etc. - // Correct: - preg_match('/abc/', $str); + // Correct: + preg_match('/abc/', $str); - // Incorrect: - preg_match("/abc/", $str); + // Incorrect: + preg_match("/abc/", $str); When performing a regular expression search and replace, please use the $n notation for backreferences. This is preferred over \\n. - // Correct: - preg_replace('/(\d+) dollar/', '$1 euro', $str); + // Correct: + preg_replace('/(\d+) dollar/', '$1 euro', $str); - // Incorrect: - preg_replace('/(\d+) dollar/', '\\1 euro', $str); + // Incorrect: + preg_replace('/(\d+) dollar/', '\\1 euro', $str); Finally, please note that the $ character for matching the position at the end of the line allows for a following newline character. Use the D modifier to fix this if needed. [More info](http://blog.php-security.org/archives/76-Holes-in-most-preg_match-filters.html). - $str = "email@example.com\n"; + $str = "email@example.com\n"; - preg_match('/^.+@.+$/', $str); // TRUE - preg_match('/^.+@.+$/D', $str); // FALSE \ No newline at end of file + preg_match('/^.+@.+$/', $str); // TRUE + preg_match('/^.+@.+$/D', $str); // FALSE \ No newline at end of file diff --git a/system/guide/kohana/cookies.md b/system/guide/kohana/cookies.md index bb2c762..f08fb13 100644 --- a/system/guide/kohana/cookies.md +++ b/system/guide/kohana/cookies.md @@ -6,14 +6,14 @@ Kohana provides classes that make it easy to work with both cookies and sessions [!!] Kohana uses "signed" cookies. Every cookie that is stored is combined with a secure hash to prevent modification of the cookie. If a cookie is modified outside of Kohana the hash will be incorrect and the cookie will be deleted. This hash is generated using [Cookie::salt()], which uses the [Cookie::$salt] property. You must define this setting in your bootstrap.php: - Cookie::$salt = 'foobar'; + Cookie::$salt = 'foobar'; Or define an extended cookie class in your application: - class Cookie extends Kohana_Cookie - { - public static $salt = 'foobar'; - } + class Cookie extends Kohana_Cookie + { + public static $salt = 'foobar'; + } You should set the salt to a secure value. The example above is only for demonstrative purposes. @@ -46,7 +46,7 @@ Getting session or cookie data is done using the [Cookie::get] method: ### Deleting Data Deleting session or cookie data is done using the [Cookie::delete] method: - + // Delete cookie data Cookie::delete($key); @@ -90,7 +90,7 @@ To only allow the cookie to be accessed over a secure (HTTPS) connection, use th // Allow cookies to be accessed only on a secure connection Cookie::$secure = TRUE; - + // Allow cookies to be accessed on any connection Cookie::$secure = FALSE; diff --git a/system/guide/kohana/errors.md b/system/guide/kohana/errors.md index 9f40f8b..d872b1d 100644 --- a/system/guide/kohana/errors.md +++ b/system/guide/kohana/errors.md @@ -41,7 +41,7 @@ Errors should **always** be displayed, even in production, because it allows you Kohana comes with a robust system for handing http errors. It includes exception classes for each http status code. To trigger a 404 in your application (the most common scenario): - throw HTTP_Exception::factory(404, 'File not found!'); + throw HTTP_Exception::factory(404, 'File not found!'); To register error pages for these, using 404 as an example: diff --git a/system/guide/kohana/extension.md b/system/guide/kohana/extension.md index f042635..260f4c2 100644 --- a/system/guide/kohana/extension.md +++ b/system/guide/kohana/extension.md @@ -62,15 +62,15 @@ When you add your transparently extended cookie class at `application/classes/Co If you are using the [Cookie](cookies) class, and want to change a setting, you should do so using transparent extension, rather than editing the file in the system folder. If you edit it directly, and in the future you upgrade your Kohana version by replacing the system folder, your changes will be reverted and your cookies will probably be invalid. Instead, create a Cookie.php file either in `application/classes/Cookie.php` or a module (`MODPATH//classes/Cookie.php`). - class Cookie extends Kohana_Cookie { - - // Set a new salt - public $salt = "some new better random salt phrase"; - - // Don't allow javascript access to cookies - public $httponly = TRUE; - - } + class Cookie extends Kohana_Cookie { + + // Set a new salt + public $salt = "some new better random salt phrase"; + + // Don't allow javascript access to cookies + public $httponly = TRUE; + + } ## Example: TODO: an example @@ -88,14 +88,14 @@ TODO: Provide some links to modules on github, etc that have examples of transpa If you are extending a Kohana class in a module, you should maintain transparent extensions. In other words, do not include any variables or function in the "base" class (eg. Cookie). Instead make your own namespaced class, and have the "base" class extend that one. With our Encrypted cookie example we can create `MODPATH/mymod/Encrypted/Cookie.php`: - class Encrypted_Cookie extends Kohana_Cookie { + class Encrypted_Cookie extends Kohana_Cookie { - // Use the same encrypt() and decrypt() methods as above + // Use the same encrypt() and decrypt() methods as above - } + } And create `MODPATH/mymod/Cookie.php`: - class Cookie extends Encrypted_Cookie {} + class Cookie extends Encrypted_Cookie {} This will still allow users to add their own extension to [Cookie] while leaving your extensions intact. To do that they would make a cookie class that extends `Encrypted_Cookie` (rather than `Kohana_Cookie`) in their application folder. diff --git a/system/guide/kohana/files.md b/system/guide/kohana/files.md index 877c4e0..4531598 100644 --- a/system/guide/kohana/files.md +++ b/system/guide/kohana/files.md @@ -2,13 +2,13 @@ The Kohana filesystem is a hierarchy of similar directory structures that cascade. The hierarchy in Kohana (used when a file is loaded by [Kohana::find_file]) is in the following order: -1. **Application Path** +1. **Application Path** Defined as `APPPATH` in `index.php`. The default value is `application`. -2. **Module Paths** +2. **Module Paths** This is set as an associative array using [Kohana::modules] in `APPPATH/bootstrap.php`. Each of the values of the array will be searched **in the order that the modules are defined**. -3. **System Path** +3. **System Path** Defined as `SYSPATH` in `index.php`. The default value is `system`. All of the main or "core" files and classes are defined here. Files that are in directories higher up the include path order take precedence over files of the same name lower down the order, which makes it is possible to overload any file by placing a file with the same name in a "higher" directory: @@ -58,14 +58,14 @@ The path to any file within the filesystem can be found by calling [Kohana::find // Find the full path to "views/user/login.php" $path = Kohana::find_file('views', 'user/login'); - + If the file doesn't have a `.php` extension, pass the extension as the third param. - // Find the full path to "guide/menu.md" - $path = Kohana::find_file('guide', 'menu', 'md'); + // Find the full path to "guide/menu.md" + $path = Kohana::find_file('guide', 'menu', 'md'); - // If $name is "2000-01-01-first-post" this would look for "posts/2000-01-01-first-post.textile" - $path = Kohana::find_file('posts', $name, '.textile'); + // If $name is "2000-01-01-first-post" this would look for "posts/2000-01-01-first-post.textile" + $path = Kohana::find_file('posts', $name, '.textile'); ## Vendor Extensions diff --git a/system/guide/kohana/files/classes.md b/system/guide/kohana/files/classes.md index b3823c4..c0084bd 100644 --- a/system/guide/kohana/files/classes.md +++ b/system/guide/kohana/files/classes.md @@ -12,26 +12,26 @@ Kohana 3 does not differentiate between "helper" classes and "library" classes l To create a new class, simply place a file in the `classes/` directory at any point in the [Cascading Filesystem](files), that follows the [Class naming conventions](conventions#class-names-and-file-location). For example, lets create a `Foobar` class. - // classes/Foobar.php - - class Foobar { - static function magic() { - // Does something - } - } - + // classes/Foobar.php + + class Foobar { + static function magic() { + // Does something + } + } + We can now call `Foobar::magic()` any where and Kohana will [autoload](autoloading) the file for us. We can also put classes in subdirectories. - // classes/Professor/Baxter.php - - class Professor_Baxter { - static function teach() { - // Does something - } - } - + // classes/Professor/Baxter.php + + class Professor_Baxter { + static function teach() { + // Does something + } + } + We could now call `Professor_Baxter::teach()` any where we want. For examples of how to create and use classes, simply look at the 'classes' folder in `system` or any module. diff --git a/system/guide/kohana/files/config.md b/system/guide/kohana/files/config.md index 877f8cd..eb5b195 100644 --- a/system/guide/kohana/files/config.md +++ b/system/guide/kohana/files/config.md @@ -50,35 +50,35 @@ We could now call `Kohana::$config->load('site.title')` to get the site name, an Let's say we want an archive of versions of some software. We could use config files to store each version, and include links to download, documentation, and issue tracking. - // config/versions.php + // config/versions.php + + array( - 'codename' => 'Frog', - 'download' => 'files/ourapp-1.0.0.tar.gz', - 'documentation' => 'docs/1.0.0', - 'released' => '06/05/2009', - 'issues' => 'link/to/bug/tracker', - ), - '1.1.0' => array( - 'codename' => 'Lizard', - 'download' => 'files/ourapp-1.1.0.tar.gz', - 'documentation' => 'docs/1.1.0', - 'released' => '10/15/2009', - 'issues' => 'link/to/bug/tracker', - ), - /// ... etc ... - ); + '1.0.0' => array( + 'codename' => 'Frog', + 'download' => 'files/ourapp-1.0.0.tar.gz', + 'documentation' => 'docs/1.0.0', + 'released' => '06/05/2009', + 'issues' => 'link/to/bug/tracker', + ), + '1.1.0' => array( + 'codename' => 'Lizard', + 'download' => 'files/ourapp-1.1.0.tar.gz', + 'documentation' => 'docs/1.1.0', + 'released' => '10/15/2009', + 'issues' => 'link/to/bug/tracker', + ), + /// ... etc ... + ); You could then do the following: - // In your controller - $view->versions = Kohana::$config->load('versions'); - - // In your view: - foreach ($versions as $version) - { - // echo some html to display each version - } + // In your controller + $view->versions = Kohana::$config->load('versions'); + + // In your view: + foreach ($versions as $version) + { + // echo some html to display each version + } diff --git a/system/guide/kohana/files/i18n.md b/system/guide/kohana/files/i18n.md index 52efc81..136aa21 100644 --- a/system/guide/kohana/files/i18n.md +++ b/system/guide/kohana/files/i18n.md @@ -8,7 +8,7 @@ Kohana has a __() function to do your translations for you. This function is onl To echo a translated string: - + This will echo 'Home' unless you've changed the defined language, which is explained below. @@ -16,7 +16,7 @@ This will echo 'Home' unless you've changed the defined language, which is expla Use the I18n::lang() method to change the displayed language: - I18n::lang('fr'); + I18n::lang('fr'); This will change the language to 'es-es'. @@ -24,12 +24,12 @@ This will change the language to 'es-es'. To define the language file for the above language change, create a `i18n/fr.php` that contains: - 'Bonjour, monde!', - ); + 'Bonjour, monde!', + ); Now when you do `__('Hello, world!')`, you will get `Bonjour, monde!` @@ -37,31 +37,31 @@ Now when you do `__('Hello, world!')`, you will get `Bonjour, monde!` You can define variables in your __() calls like so: - echo __('Hello, :user', array(':user' => $username)); + echo __('Hello, :user', array(':user' => $username)); Your i18n key in your translation file will need to be defined as: - 'Bonjour, :user', - ); + 'Bonjour, :user', + ); ## Defining your own __() function You can define your own __() function by simply defining your own i18n class: - 'Hello, world!', - ); + 'Hello, world!', + ); You can also look in subfolders and sub-keys: - Kohana::message('forms/contact', 'foobar.bar'); + Kohana::message('forms/contact', 'foobar.bar'); This will look in the `messages/forms/contact.php` for the `[foobar][bar]` key: - array( - 'bar' => 'Hello, world!', - ), - ); + array( + 'bar' => 'Hello, world!', + ), + ); ## Notes diff --git a/system/guide/kohana/flow.md b/system/guide/kohana/flow.md index 76fdfe8..88d12b0 100644 --- a/system/guide/kohana/flow.md +++ b/system/guide/kohana/flow.md @@ -3,25 +3,25 @@ Every application follows the same flow: 1. Application starts from `index.php`. - 1. The application, module, and system paths are set. (`APPPATH`, `MODPATH`, and `SYSPATH`) - 2. Error reporting levels are set. - 3. Install file is loaded, if it exists. - 4. The bootstrap file, `APPPATH/bootstrap.php`, is included. + 1. The application, module, and system paths are set. (`APPPATH`, `MODPATH`, and `SYSPATH`) + 2. Error reporting levels are set. + 3. Install file is loaded, if it exists. + 4. The bootstrap file, `APPPATH/bootstrap.php`, is included. 2. Once we are in `bootstrap.php`: - 6. The [Kohana] class is loaded. - 7. [Kohana::init] is called, which sets up error handling, caching, and logging. - 8. [Kohana_Config] readers and [Kohana_Log] writers are attached. - 9. [Kohana::modules] is called to enable additional modules. - * Module paths are added to the [cascading filesystem](files). - * 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::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. - 4. Calls the controller action, which generates the request response. - 5. Calls the [Controller::after] method. - * The above 5 steps can be repeated multiple times when using [HMVC sub-requests](requests). + 6. The [Kohana] class is loaded. + 7. [Kohana::init] is called, which sets up error handling, caching, and logging. + 8. [Kohana_Config] readers and [Kohana_Log] writers are attached. + 9. [Kohana::modules] is called to enable additional modules. + * Module paths are added to the [cascading filesystem](files). + * 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::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. + 4. Calls the controller action, which generates the request response. + 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 + 12. The main [Request] response is displayed diff --git a/system/guide/kohana/fragments.md b/system/guide/kohana/fragments.md index 0d47a68..d134105 100644 --- a/system/guide/kohana/fragments.md +++ b/system/guide/kohana/fragments.md @@ -31,10 +31,10 @@ In this example we will calculate pi to 1000 places, and cache the result using ~~~ if ( ! Fragment::load('pi1000', Date::HOUR * 4)) -{ +{ // Change function nesting limit ini_set('xdebug.max_nesting_level',1000); - + // Source: http://mgccl.com/2007/01/22/php-calculate-pi-revisited function bcfact($n) { @@ -52,10 +52,10 @@ if ( ! Fragment::load('pi1000', Date::HOUR * 4)) } return bcdiv(1,(bcmul(12,($num))),$precision); } - + echo bcpi(1000); - - Fragment::save(); + + Fragment::save(); } echo View::factory('profiler/stats'); @@ -74,26 +74,26 @@ $limit = 50; // Displayed feeds are cached for 30 seconds (default) if ( ! Fragment::load('rss:'.$feed)): - // Parse the feed - $items = Feed::parse($feed, $limit); - - foreach ($items as $item): - - // Convert $item to object - $item = (object) $item; - - echo HTML::anchor($item->link,$item->title); - - ?> -
-

author: creator ?>

-

date: pubDate ?>

-
- link,$item->title); + + ?> +
+

author: creator ?>

+

date: pubDate ?>

+
+ Home page stuff

"; - - // Pretend like we are actually doing something :) - sleep(2); - - // Cache this every hour since it doesn't change as often - if ( ! Fragment::load('homepage-subfragment', Date::HOUR)): - - echo "

Home page special thingy

"; - - // Pretend like this takes a long time - sleep(5); - - Fragment::save(); endif; - - echo "

More home page stuff

"; - - Fragment::save(); + echo "

Home page stuff

"; + + // Pretend like we are actually doing something :) + sleep(2); + + // Cache this every hour since it doesn't change as often + if ( ! Fragment::load('homepage-subfragment', Date::HOUR)): + + echo "

Home page special thingy

"; + + // Pretend like this takes a long time + sleep(5); + + Fragment::save(); endif; + + echo "

More home page stuff

"; + + Fragment::save(); endif; diff --git a/system/guide/kohana/helpers.md b/system/guide/kohana/helpers.md index 4023c78..31c5af8 100644 --- a/system/guide/kohana/helpers.md +++ b/system/guide/kohana/helpers.md @@ -11,43 +11,43 @@ You can make your own helpers by simply making a class and putting it in the `cl - **[Cookie]** - Covered in more detail on the [Cookies](cookies) page. - **[Date]** - Useful date functions and constants. Time between two dates, convert between am/pm and military, date offset, etc. - + - **[Encrypt]** - Covered in more detail on the [Security](security) page. - + - **[Feed]** - Parse and create RSS feeds. - + - **[File]** - Get file type by mime, split and merge a file into small pieces. - - - **[Form]** - Create HTML form elements. - + + - **[Form]** - Create HTML form elements. + - **[Fragment]** - Simple file based caching. Covered in more detail on the [Fragments](fragments) page. - **[HTML]** - Useful HTML functions. Encode, obfuscate, create script, anchor, and image tags, etc. - + - **[I18n]** - Internationalization helper for creating multilanguage sites. - + - **[Inflector]** - Change a word into plural or singular form, camelize or humanize a phrase, etc. - + - **[Kohana]** - The Kohana class is also a helper. Debug variables (like print_r but better), file loading, etc. - + - **[Num]** - Provides locale aware formating and english ordinals (th, st, nd, etc). - + - **[Profiler]** - Covered in more detail on the [Profiling](profiling) page. - **[Remote]** - Remote server access helper using [CURL](http://php.net/curl). - - - **[Request]** - Get the current request url, create expire tags, send a file, get the user agent, etc. - + + - **[Request]** - Get the current request url, create expire tags, send a file, get the user agent, etc. + - **[Route]** - Create routes, create an internal link using a route. - + - **[Security]** - Covered in more detail on the [Security](security) page. - + - **[Session]** - Covered in more detail on the [Sessions](sessions) page. - + - **[Text]** - Autolink, prevent window words, convert a number to text, etc. - + - **[URL]** - Create a relative or absolute URL, make a URL-safe title, etc. - + - **[UTF8]** - Provides multi-byte aware string functions like strlen, strpos, substr, etc. - + - **[Upload]** - Helper for uploading files from a form. diff --git a/system/guide/kohana/install.md b/system/guide/kohana/install.md index 233f267..d0cf746 100644 --- a/system/guide/kohana/install.md +++ b/system/guide/kohana/install.md @@ -30,7 +30,7 @@ date_default_timezone_set('America/Sao_Paulo'); * Apache's DocumentRoot configured to /var/www */ Kohana::init(array( - 'base_url' => '/kohana/', + 'base_url' => '/kohana/', )); ~~~ @@ -39,10 +39,10 @@ Kohana::init(array( [!!] Do not forget to escape your dots (.) as these are regex patterns. These patterns should always fully match, as they are prepended with `^` and appended with `$`. ~~~ return array( - 'trusted_hosts' => array( - 'example\.org', - '.*\.example\.org', - ), + 'trusted_hosts' => array( + 'example\.org', + '.*\.example\.org', + ), ); ~~~ diff --git a/system/guide/kohana/modules.md b/system/guide/kohana/modules.md index 6753489..e02d322 100644 --- a/system/guide/kohana/modules.md +++ b/system/guide/kohana/modules.md @@ -14,18 +14,18 @@ Andrew Hutchings has created [kohana-modules](http://www.kohana-modules.com) whi Modules are enabled by calling [Kohana::modules] and passing an array of `'name' => 'path'`. The name isn't important, but the path obviously is. A module's path does not have to be in `MODPATH`, but usually is. You can only call [Kohana::modules] once. - Kohana::modules(array( - 'auth' => MODPATH.'auth', // Basic authentication - 'cache' => MODPATH.'cache', // Caching with multiple backends - 'codebench' => MODPATH.'codebench', // Benchmarking tool - 'database' => MODPATH.'database', // Database access - 'image' => MODPATH.'image', // Image manipulation - 'orm' => MODPATH.'orm', // Object Relationship Mapping - 'oauth' => MODPATH.'oauth', // OAuth authentication - 'pagination' => MODPATH.'pagination', // Paging of results - 'unittest' => MODPATH.'unittest', // Unit testing - 'userguide' => MODPATH.'userguide', // User guide and API documentation - )); + Kohana::modules(array( + 'auth' => MODPATH.'auth', // Basic authentication + 'cache' => MODPATH.'cache', // Caching with multiple backends + 'codebench' => MODPATH.'codebench', // Benchmarking tool + 'database' => MODPATH.'database', // Database access + 'image' => MODPATH.'image', // Image manipulation + 'orm' => MODPATH.'orm', // Object Relationship Mapping + 'oauth' => MODPATH.'oauth', // OAuth authentication + 'pagination' => MODPATH.'pagination', // Paging of results + 'unittest' => MODPATH.'unittest', // Unit testing + 'userguide' => MODPATH.'userguide', // User guide and API documentation + )); ## Init.php diff --git a/system/guide/kohana/mvc/controllers.md b/system/guide/kohana/mvc/controllers.md index 4f06cb2..c1b2fbf 100644 --- a/system/guide/kohana/mvc/controllers.md +++ b/system/guide/kohana/mvc/controllers.md @@ -15,42 +15,42 @@ In order to function, a controller must do the following: Some examples of controller names and file locations: - // classes/Controller/Foobar.php - class Controller_Foobar extends Controller { - - // classes/Controller/Admin.php - class Controller_Admin extends Controller { + // classes/Controller/Foobar.php + class Controller_Foobar extends Controller { + + // classes/Controller/Admin.php + class Controller_Admin extends Controller { Controllers can be in sub-folders: - // classes/Controller/Baz/Bar.php - class Controller_Baz_Bar extends Controller { - - // classes/Controller/Product/Category.php - class Controller_Product_Category extends Controller { - + // classes/Controller/Baz/Bar.php + class Controller_Baz_Bar extends Controller { + + // classes/Controller/Product/Category.php + class Controller_Product_Category extends Controller { + [!!] Note that controllers in sub-folders can not be called by the default route, you will need to define a route that has a [directory](routing#directory) param or sets a default value for directory. Controllers can extend other controllers. - // classes/Controller/Users.php - class Controller_Users extends Controller_Template - - // classes/Controller/Api.php - class Controller_Api extends Controller_REST - + // classes/Controller/Users.php + class Controller_Users extends Controller_Template + + // classes/Controller/Api.php + class Controller_Api extends Controller_REST + [!!] [Controller_Template] is an example controller provided in Kohana. You can also have a controller extend another controller to share common things, such as requiring you to be logged in to use all of those controllers. - // classes/Controller/Admin.php - class Controller_Admin extends Controller { - // This controller would have a before() that checks if the user is logged in - - // classes/Controller/Admin/Plugins.php - class Controller_Admin_Plugins extends Controller_Admin { - // Because this controller extends Controller_Admin, it would have the same logged in check - + // classes/Controller/Admin.php + class Controller_Admin extends Controller { + // This controller would have a before() that checks if the user is logged in + + // classes/Controller/Admin/Plugins.php + class Controller_Admin_Plugins extends Controller_Admin { + // Because this controller extends Controller_Admin, it would have the same logged in check + ## $this->request 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)`. @@ -77,65 +77,65 @@ An action method will decide what should be done based on the current request, i A very basic action method that simply loads a [view](mvc/views) file. - public function action_hello() - { - $this->response->body(View::factory('hello/world')); // This will load views/hello/world.php - } + public function action_hello() + { + $this->response->body(View::factory('hello/world')); // This will load views/hello/world.php + } ### Parameters Parameters are accessed by calling `$this->request->param('name')` where `name` is the name defined in the route. - // Assuming Route::set('example','(/(/(/)))'); - - public function action_foobar() - { - $id = $this->request->param('id'); - $new = $this->request->param('new'); + // Assuming Route::set('example','(/(/(/)))'); + + public function action_foobar() + { + $id = $this->request->param('id'); + $new = $this->request->param('new'); If that parameter is not set it will be returned as NULL. You can provide a second parameter to set a default value if that param is not set. - public function action_foobar() - { - // $id will be false if it was not supplied in the url - $id = $this->request->param('user',FALSE); + public function action_foobar() + { + // $id will be false if it was not supplied in the url + $id = $this->request->param('user',FALSE); ### Examples A view action for a product page. - public function action_view() - { - $product = new Model_Product($this->request->param('id')); + public function action_view() + { + $product = new Model_Product($this->request->param('id')); - if ( ! $product->loaded()) - { - throw HTTP_Exception::factory(404, 'Product not found!'); - } + if ( ! $product->loaded()) + { + throw HTTP_Exception::factory(404, 'Product not found!'); + } - $this->response->body(View::factory('product/view') - ->set('product', $product)); - } + $this->response->body(View::factory('product/view') + ->set('product', $product)); + } A user login action. - public function action_login() - { - $view = View::factory('user/login'); + public function action_login() + { + $view = View::factory('user/login'); - if ($this->request->post()) - { - // Try to login - if (Auth::instance()->login($this->request->post('username'), $this->request->post('password'))) - { - $this->redirect('home', 303); - } + if ($this->request->post()) + { + // Try to login + if (Auth::instance()->login($this->request->post('username'), $this->request->post('password'))) + { + $this->redirect('home', 303); + } - $view->errors = 'Invalid email or password'; - } + $view->errors = 'Invalid email or password'; + } - $this->response->body($view); - } + $this->response->body($view); + } ## Before and after @@ -145,36 +145,36 @@ For example, if you look in `Controller_Template` you can see that in the be You can check what action has been requested (via `$this->request->action`) and do something based on that, such as requiring the user to be logged in to use a controller, unless they are using the login action. - // Checking auth/login in before, and redirecting if necessary: + // Checking auth/login in before, and redirecting if necessary: - Controller_Admin extends Controller { + Controller_Admin extends Controller { - public function before() - { - // If this user doesn't have the admin role, and is not trying to login, redirect to login - if ( ! Auth::instance()->logged_in('admin') AND $this->request->action !== 'login') - { - $this->redirect('admin/login', 302); - } - } - - public function action_login() { - ... + public function before() + { + // If this user doesn't have the admin role, and is not trying to login, redirect to login + if ( ! Auth::instance()->logged_in('admin') AND $this->request->action !== 'login') + { + $this->redirect('admin/login', 302); + } + } + + public function action_login() { + ... ### Custom __construct() function In general, you should not have to change the `__construct()` function, as anything you need for all actions can be done in `before()`. If you need to change the controller constructor, you must preserve the parameters or PHP will complain. This is so the Request object that called the controller is available. *Again, in most cases you should probably be using `before()`, and not changing the constructor*, but if you really, *really* need to it should look like this: - // You should almost never need to do this, use before() instead! + // You should almost never need to do this, use before() instead! + + // Be sure Kohana_Request is in the params + public function __construct(Request $request, Response $response) + { + // You must call parent::__construct at some point in your function + parent::__construct($request, $response); - // Be sure Kohana_Request is in the params - public function __construct(Request $request, Response $response) - { - // You must call parent::__construct at some point in your function - parent::__construct($request, $response); - - // Do whatever else you want - } + // Do whatever else you want + } ## Extending other controllers diff --git a/system/guide/kohana/mvc/models.md b/system/guide/kohana/mvc/models.md index bfcf240..79e8808 100644 --- a/system/guide/kohana/mvc/models.md +++ b/system/guide/kohana/mvc/models.md @@ -8,28 +8,28 @@ From Wikipedia: Creating a simple model: - class Model_Post extends Model - { - public function do_stuff() - { - // This is where you do domain logic... - } - } + class Model_Post extends Model + { + public function do_stuff() + { + // This is where you do domain logic... + } + } If you want database access, have your model extend the Model_Database class: - class Model_Post extends Model_Database - { - public function do_stuff() - { - // This is where you do domain logic... - } - - public function get_stuff() - { - // Get stuff from the database: - return $this->db->query(...); - } - } + class Model_Post extends Model_Database + { + public function do_stuff() + { + // This is where you do domain logic... + } + + public function get_stuff() + { + // Get stuff from the database: + return $this->db->query(...); + } + } If you want CRUD/ORM capabilities, see the [ORM Module](../../guide/orm) \ No newline at end of file diff --git a/system/guide/kohana/mvc/views.md b/system/guide/kohana/mvc/views.md index e2314c2..417b3d6 100644 --- a/system/guide/kohana/mvc/views.md +++ b/system/guide/kohana/mvc/views.md @@ -56,16 +56,16 @@ Once view has been loaded, variables can be assigned to it using the [View::set] You can also assign variables directly to the View object. This is identical to calling `set()`; - public function action_roadtrip() - { - $view = View::factory('user/roadtrip'); - - $view->places = array('Rome', 'Paris', 'London', 'New York', 'Tokyo'); + public function action_roadtrip() + { + $view = View::factory('user/roadtrip'); + + $view->places = array('Rome', 'Paris', 'London', 'New York', 'Tokyo'); $view->user = $this->user; // The view will have $places and $user variables $this->response->body($view); - } + } ### Global Variables @@ -109,42 +109,42 @@ Next, the home controller will extend `Controller_Website`: ## Views Within Views If you want to include another view within a view, there are two choices. By calling [View::factory] you can sandbox the included view. This means that you will have to provide all of the variables to the view using [View::set] or [View::bind]: - - // In your view file: - + + // In your view file: + // Only the $user variable will be available in "views/user/login.php" bind('user', $user) ?> The other option is to include the view directly, which makes all of the current variables available to the included view: - // In your view file: - + // In your view file: + // Any variable defined in this view will be included in "views/message.php" You can also assign a variable of your parent view to be the child view from within your controller. For example: - // In your controller: - - public function action_index() - { - $view = View::factory('common/template'); - - $view->title = "Some title"; - $view->body = View::factory('pages/foobar'); - } - - // In views/common/template.php: - - - - <?php echo $title> - - - - - - + // In your controller: + + public function action_index() + { + $view = View::factory('common/template'); + + $view->title = "Some title"; + $view->body = View::factory('pages/foobar'); + } + + // In views/common/template.php: + + + + <?php echo $title> + + + + + + Of course, you can also load an entire [Request] within a view: diff --git a/system/guide/kohana/profiling.md b/system/guide/kohana/profiling.md index 0409668..f966ee1 100644 --- a/system/guide/kohana/profiling.md +++ b/system/guide/kohana/profiling.md @@ -13,25 +13,25 @@ Kohana provides a very simple way to display statistics about your application: You can easily add profiling to your own functions and code. This is done using the [Profiler::start()] function. The first parameter is the group, the second parameter is the name of the benchmark. - public function foobar($input) - { - // Be sure to only profile if it's enabled - if (Kohana::$profiling === TRUE) - { - // Start a new benchmark - $benchmark = Profiler::start('Your Category', __FUNCTION__); - } - - // Do some stuff - - if (isset($benchmark)) - { - // Stop the benchmark - Profiler::stop($benchmark); - } - - return $something; - } + public function foobar($input) + { + // Be sure to only profile if it's enabled + if (Kohana::$profiling === TRUE) + { + // Start a new benchmark + $benchmark = Profiler::start('Your Category', __FUNCTION__); + } + + // Do some stuff + + if (isset($benchmark)) + { + // Stop the benchmark + Profiler::stop($benchmark); + } + + return $something; + } ## How to read the profiling report diff --git a/system/guide/kohana/requests.md b/system/guide/kohana/requests.md index eca76a6..e9c0220 100644 --- a/system/guide/kohana/requests.md +++ b/system/guide/kohana/requests.md @@ -14,7 +14,7 @@ Creating a request is very easy: An internal request is a request calling to the internal application. It utilizes [routes](routing) to direct the application based on the URI that is passed to it. A basic internal request might look something like: - $request = Request::factory('welcome'); + $request = Request::factory('welcome'); In this example, the URI is 'welcome'. @@ -22,7 +22,7 @@ In this example, the URI is 'welcome'. Since Kohana uses HMVC, you can call many requests inside each other. The first request (usually called from `index.php`) is called the "initial request". You can access this request via: - Request::initial(); + Request::initial(); You should only use this method if you are absolutely sure you want the initial request. Otherwise you should use the `Request::current()` method. @@ -32,7 +32,7 @@ You can call a request at any time in your application by using the `Request::fa Other than this difference, they are exactly the same. You can detect if the request is a sub-request in your controller with the is_initial() method: - $sub_request = ! $this->request->is_initial() + $sub_request = ! $this->request->is_initial() ### External Requests @@ -40,48 +40,48 @@ An external request calls out to a third party website. You can use this to scrape HTML from a remote site, or make a REST call to a third party API: - // This uses GET - $request = Request::factory('http://www.google.com/'); + // This uses GET + $request = Request::factory('http://www.google.com/'); - // This uses PUT - $request = Request::factory('http://example.com/put_api')->method(Request::PUT)->body(json_encode('the body'))->headers('Content-Type', 'application/json'); + // This uses PUT + $request = Request::factory('http://example.com/put_api')->method(Request::PUT)->body(json_encode('the body'))->headers('Content-Type', 'application/json'); - // This uses POST - $request = Request::factory('http://example.com/post_api')->method(Request::POST)->post(array('foo' => 'bar', 'bar' => 'baz')); + // This uses POST + $request = Request::factory('http://example.com/post_api')->method(Request::POST)->post(array('foo' => 'bar', 'bar' => 'baz')); ## Executing Requests To execute a request, use the `execute()` method on it. This will give you a [response](responses) object. - $request = Request::factory('welcome'); - $response = $request->execute(); + $request = Request::factory('welcome'); + $response = $request->execute(); ### Header callbacks The request client supports header callbacks - an array of callbacks that will be triggered when a specified header is included in the response from a server. Header callbacks provide a powerful way to deal with scenarios including authentication, rate limiting, redirects and other application-specific use cases: - $request = Request::factory('http://example.com/user', array( - 'header_callbacks' => array( - 'Content-Encoding' => - function (Request $request, Response $response, Request_Client $client) - { - // Uncompress the response - $response->body(GZIP::expand($response->body())); - }, - 'X-Rate-Limited' => - function (Request $request, Response $response, Request_Client $client) - { - // Log the rate limit event - // And perhaps set a deadlock in cache to prevent further requests - }, - 'WWW-Authenticate' => - function (Request $request, Response $response, Request_Client $client) - { - // Execute a request to refresh your OAuth token somehow - // Have the original request resent - return Request::factory($request->uri()) - ->query($request->query()) - ->headers('Authorization', 'token'.$token); - })); + $request = Request::factory('http://example.com/user', array( + 'header_callbacks' => array( + 'Content-Encoding' => + function (Request $request, Response $response, Request_Client $client) + { + // Uncompress the response + $response->body(GZIP::expand($response->body())); + }, + 'X-Rate-Limited' => + function (Request $request, Response $response, Request_Client $client) + { + // Log the rate limit event + // And perhaps set a deadlock in cache to prevent further requests + }, + 'WWW-Authenticate' => + function (Request $request, Response $response, Request_Client $client) + { + // Execute a request to refresh your OAuth token somehow + // Have the original request resent + return Request::factory($request->uri()) + ->query($request->query()) + ->headers('Authorization', 'token'.$token); + })); Where multiple headers are present in the response, callbacks will be executed in sequence. Callbacks can be any valid PHP callback type and have three possible return types: @@ -99,33 +99,33 @@ If your callback executes a new request itself and returns the response, it is r #### Callback parameters Arbitrary parameters can be passed to the callbacks through the [Request_Client::callback_params()] property: - $request = Request::factory('http://example.com/foo', array( - 'header_callbacks' => array( - 'X-Custom-1' => - function (Request $request, Response $response, Request_Client $client) - { - // Do something that needs an external parameter - if ($client->callback_params('foo') == 'bar') - { - // etc - } - }, - ) - 'callback_params' => array( - 'foo' => 'bar' - ) - )); - - // later on - $request->client()->callback_params('foo',FALSE); + $request = Request::factory('http://example.com/foo', array( + 'header_callbacks' => array( + 'X-Custom-1' => + function (Request $request, Response $response, Request_Client $client) + { + // Do something that needs an external parameter + if ($client->callback_params('foo') == 'bar') + { + // etc + } + }, + ) + 'callback_params' => array( + 'foo' => 'bar' + ) + )); + + // later on + $request->client()->callback_params('foo',FALSE); As with nested requests, callback_params will automatically be passed to subrequests if the callback returns a new Request object. If the callback returns a Response object, it is responsible for passing on any relevant parameters. #### Following redirects The request client ships with a standard callback to automatically follow redirects - [Request_Client::on_header_location()]. This will recursively follow redirects that are specified with a Location header and a status code in 201, 301, 302, 303, 307. This behaviour is disabled by default, but can be enabled by passing a set of options to the Request's constructor: - $request = Request::factory('http://example.com/redirectme', array( - 'follow' => TRUE)); + $request = Request::factory('http://example.com/redirectme', array( + 'follow' => TRUE)); [!!] If you define additional header callbacks of your own, you will need to include the 'Location' callback in your callbacks array. @@ -145,6 +145,6 @@ You can easily alter this behaviour by configuring your own 'Location' header ca You can cache requests for fast execution by passing a cache instance in as the second parameter of factory: - $request = Request::factory('welcome', array('cache'=>Cache::instance())); + $request = Request::factory('welcome', array('cache'=>Cache::instance())); TODO diff --git a/system/guide/kohana/routing.md b/system/guide/kohana/routing.md index 62b274c..9a8c392 100644 --- a/system/guide/kohana/routing.md +++ b/system/guide/kohana/routing.md @@ -10,12 +10,12 @@ As mentioned in the [Request Flow](flow) section, a request is handled by the [R If you look in `APPPATH/bootstrap.php` you will see the "default" route as follows: - Route::set('default', '((/(/)))') - ->defaults(array( - 'controller' => 'Welcome', - 'action' => 'index', - )); - + Route::set('default', '((/(/)))') + ->defaults(array( + 'controller' => 'Welcome', + 'action' => 'index', + )); + [!!] The default route is simply provided as a sample, you can remove it and replace it with your own routes. So this creates a route with the name `default` that will match urls in the format of `((/(/)))`. @@ -44,22 +44,22 @@ The Kohana route system uses [perl compatible regular expressions](http://perldo In this example, we have controllers in two directories, `admin` and `affiliate`. Because this route will only match urls that begin with `admin` or `affiliate`, the default route would still work for controllers in `classes/Controller`. - Route::set('sections', '(/(/(/)))', - array( - 'directory' => '(admin|affiliate)' - )) - ->defaults(array( - 'controller' => 'Home', - 'action' => 'index', - )); + Route::set('sections', '(/(/(/)))', + array( + 'directory' => '(admin|affiliate)' + )) + ->defaults(array( + 'controller' => 'Home', + 'action' => 'index', + )); You can also use a less restrictive regex to match unlimited parameters, or to ignore overflow in a route. In this example, the url `foobar/baz/and-anything/else_that/is-on-the/url` would be routed to `Controller_Foobar::action_baz()` and the `"stuff"` parameter would be `"and-anything/else_that/is-on-the/url"`. If you wanted to use this for unlimited parameters, you could [explode](http://php.net/manual/en/function.explode.php) it, or you just ignore the overflow. - Route::set('default', '((/(/)))', array('stuff' => '.*')) - ->defaults(array( - 'controller' => 'Welcome', - 'action' => 'index', - )); + Route::set('default', '((/(/)))', array('stuff' => '.*')) + ->defaults(array( + 'controller' => 'Welcome', + 'action' => 'index', + )); ### Default values @@ -84,32 +84,32 @@ TODO: example of either using directory or controller where it isn't in the rout In 3.3, you can specify advanced routing schemes by using filter callbacks. When you need to match a route based on more than just the URI of a request, for example, based on the method request (GET/POST/DELETE), a filter will allow you to do so. These filters will receive the `Route` object being tested, the currently matched `$params` array, and the `Request` object as the three parameters. Here's a simple example: - Route::set('save-form', 'save') - ->filter(function($route, $params, $request) - { - if ($request->method() !== HTTP_Request::POST) - { - return FALSE; // This route only matches POST requests - } - }); + Route::set('save-form', 'save') + ->filter(function($route, $params, $request) + { + if ($request->method() !== HTTP_Request::POST) + { + return FALSE; // This route only matches POST requests + } + }); Filters can also replace or alter the array of parameters: - Route::set('rest-api', 'api/') - ->filter(function($route, $params, $request) - { - // Prefix the method to the action name - $params['action'] = strtolower($request->method()).'_'.$params['action']; - return $params; // Returning an array will replace the parameters - }) - ->defaults(array( - 'controller' => 'api', - )); + Route::set('rest-api', 'api/') + ->filter(function($route, $params, $request) + { + // Prefix the method to the action name + $params['action'] = strtolower($request->method()).'_'.$params['action']; + return $params; // Returning an array will replace the parameters + }) + ->defaults(array( + 'controller' => 'api', + )); If you are using php 5.2, you can still use any valid callback for this behavior: - Route::set('testing', 'foo') - ->filter(array('Class', 'method_to_process_my_uri')); + Route::set('testing', 'foo') + ->filter(array('Class', 'method_to_process_my_uri')); ## Examples @@ -125,7 +125,7 @@ There are countless other possibilities for routes. Here are some more examples: ->defaults(array( 'controller' => 'Auth' )); - + /* * Multi-format feeds * 452346/comments.rss @@ -140,7 +140,7 @@ There are countless other possibilities for routes. Here are some more examples: 'controller' => 'Feeds', 'action' => 'status', )); - + /* * Static pages */ @@ -152,7 +152,7 @@ There are countless other possibilities for routes. Here are some more examples: 'controller' => 'Static', 'action' => 'index', )); - + /* * You don't like slashes? * EditGallery:bahamas @@ -166,7 +166,7 @@ There are countless other possibilities for routes. Here are some more examples: ->defaults(array( 'controller' => 'Slideshow', )); - + /* * Quick search */ @@ -180,43 +180,43 @@ There are countless other possibilities for routes. Here are some more examples: The `directory`, `controller` and `action` can be accessed from the [Request] as public properties like so: - // From within a controller: - $this->request->action(); - $this->request->controller(); - $this->request->directory(); - - // Can be used anywhere: - Request::current()->action(); - Request::current()->controller(); - Request::current()->directory(); + // From within a controller: + $this->request->action(); + $this->request->controller(); + $this->request->directory(); + + // Can be used anywhere: + Request::current()->action(); + Request::current()->controller(); + Request::current()->directory(); All other keys specified in a route can be accessed via [Request::param()]: - // From within a controller: - $this->request->param('key_name'); - - // Can be used anywhere: - Request::current()->param('key_name'); + // From within a controller: + $this->request->param('key_name'); + + // Can be used anywhere: + Request::current()->param('key_name'); The [Request::param] method takes an optional second argument to specify a default return value in case the key is not set by the route. If no arguments are given, all keys are returned as an associative array. In addition, `action`, `controller` and `directory` are not accessible via [Request::param()]. For example, with the following route: - Route::set('ads','ad/(/)') - ->defaults(array( - 'controller' => 'ads', - 'action' => 'index', - )); - + Route::set('ads','ad/(/)') + ->defaults(array( + 'controller' => 'ads', + 'action' => 'index', + )); + If a url matches the route, then `Controller_Ads::index()` will be called. You can access the parameters by using the `param()` method of the controller's [Request]. Remember to define a default value (via the second, optional parameter of [Request::param]) if you didn't in `->defaults()`. - class Controller_Ads extends Controller { - public function action_index() - { - $ad = $this->request->param('ad'); - $affiliate = $this->request->param('affiliate',NULL); - } - + class Controller_Ads extends Controller { + public function action_index() + { + $ad = $this->request->param('ad'); + $affiliate = $this->request->param('affiliate',NULL); + } + ## Where should routes be defined? diff --git a/system/guide/kohana/security/deploying.md b/system/guide/kohana/security/deploying.md index 4b670de..eb4658d 100644 --- a/system/guide/kohana/security/deploying.md +++ b/system/guide/kohana/security/deploying.md @@ -11,16 +11,16 @@ There are a few things you'll want to do with your application before moving int 2. Turn on APC or some kind of opcode caching. This is the single easiest performance boost you can make to PHP itself. The more complex your application, the bigger the benefit of using opcode caching. - /** - * Set the environment string by the domain (defaults to Kohana::DEVELOPMENT). - */ - Kohana::$environment = ($_SERVER['SERVER_NAME'] !== 'localhost') ? Kohana::PRODUCTION : Kohana::DEVELOPMENT; - /** - * Initialise Kohana based on environment - */ - Kohana::init(array( - 'base_url' => '/', - 'index_file' => FALSE, - 'profile' => Kohana::$environment !== Kohana::PRODUCTION, - 'caching' => Kohana::$environment === Kohana::PRODUCTION, - )); + /** + * Set the environment string by the domain (defaults to Kohana::DEVELOPMENT). + */ + Kohana::$environment = ($_SERVER['SERVER_NAME'] !== 'localhost') ? Kohana::PRODUCTION : Kohana::DEVELOPMENT; + /** + * Initialise Kohana based on environment + */ + Kohana::init(array( + 'base_url' => '/', + 'index_file' => FALSE, + 'profile' => Kohana::$environment !== Kohana::PRODUCTION, + 'caching' => Kohana::$environment === Kohana::PRODUCTION, + )); diff --git a/system/guide/kohana/sessions.md b/system/guide/kohana/sessions.md index 779e3d0..7761aa5 100644 --- a/system/guide/kohana/sessions.md +++ b/system/guide/kohana/sessions.md @@ -24,7 +24,7 @@ You can also use this to overload the `$_SESSION` global to get and set data in // Overload $_SESSION with the session data $_SESSION =& $session->as_array(); - + // Set session data $_SESSION[$key] = $value; @@ -34,8 +34,8 @@ Storing session or cookie data is done using the `set` method: // Set session data $session->set($key, $value); - // Or - Session::instance()->set($key, $value); + // Or + Session::instance()->set($key, $value); // Store a user id $session->set('user_id', 10); @@ -107,8 +107,8 @@ You can apply configuration settings to each of the session adapters by creating 'table' => 'table_name', 'columns' => array( 'session_id' => 'session_id', - 'last_active' => 'last_active', - 'contents' => 'contents' + 'last_active' => 'last_active', + 'contents' => 'contents' ), 'gc' => 500, ), diff --git a/system/guide/kohana/tips.md b/system/guide/kohana/tips.md index 9f8c8a6..5ce7ec0 100644 --- a/system/guide/kohana/tips.md +++ b/system/guide/kohana/tips.md @@ -4,7 +4,7 @@ This is a collection of tips and common mistakes or errors you may encounter. ## Never edit the `system` folder! -You should (almost) never edit the system folder. Any change you want to make to files in system and modules can be made via the [cascading filesystem](files) and [transparent extension](extension) and won't break when you try to update your Kohana version. +You should (almost) never edit the system folder. Any change you want to make to files in system and modules can be made via the [cascading filesystem](files) and [transparent extension](extension) and won't break when you try to update your Kohana version. ## Don't try and use one route for everything @@ -22,8 +22,8 @@ Sometimes your application is sufficiently complex that you have many routes and If you get a Reflection_Exception when setting up your site, it is almost certainly because your [Kohana::init] 'base_url' setting is wrong. If your base url is correct something is probably wrong with your [routes](routing). - ReflectionException [ -1 ]: Class controller_ does not exist - // where is part of the url you entered in your browser + ReflectionException [ -1 ]: Class controller_ does not exist + // where is part of the url you entered in your browser ### Solution {#reflection-exception-solution} @@ -33,8 +33,8 @@ Set your [Kohana::init] 'base_url' to the correct setting. The base url should b There is a bug in php which can corrupt your session after a fatal error. A production server shouldn't have uncaught fatal errors, so this bug should only happen during development, when you do something stupid and cause a fatal error. On the next page load you will get a database connection error, then all subsequent page loads will display the following error: - ErrorException [ Notice ]: Undefined index: id - MODPATH/orm/classes/kohana/orm.php [ 1308 ] + ErrorException [ Notice ]: Undefined index: id + MODPATH/orm/classes/kohana/orm.php [ 1308 ] ### Solution {#orm-session-sleep-solution} diff --git a/system/guide/kohana/tutorials/clean-urls.md b/system/guide/kohana/tutorials/clean-urls.md index 2a9accd..7c3e4e3 100644 --- a/system/guide/kohana/tutorials/clean-urls.md +++ b/system/guide/kohana/tutorials/clean-urls.md @@ -38,11 +38,11 @@ If you get a "404 Not Found" error when trying to view a page then it's likely A In the main apache configuration file (usually `httpd.conf`), or in the virtual server configuration file, check that the `AccessFileName` directive is set to `.htaccess` and the `AllowOverride` directive is set to `All`. - AccessFileName .htaccess + AccessFileName .htaccess - - AllowOverride All - + + AllowOverride All + ### Failed! @@ -65,7 +65,7 @@ To something more simple: ### Still Failed! -If you are still getting errors, check to make sure that your host supports URL `mod_rewrite`. If you can change the Apache configuration, add these lines to the configuration, usually `httpd.conf`: +If you are still getting errors, check to make sure that your host supports URL `mod_rewrite`. If you can change the Apache configuration, add these lines to the configuration, usually `httpd.conf`: Order allow,deny diff --git a/system/guide/kohana/tutorials/error-pages.md b/system/guide/kohana/tutorials/error-pages.md index adb027f..b9775f7 100644 --- a/system/guide/kohana/tutorials/error-pages.md +++ b/system/guide/kohana/tutorials/error-pages.md @@ -17,83 +17,83 @@ For each [HTTP_Exception] class we can individually override the generation of t For example, to handle 404 pages we can do this in APPPATH/classes/HTTP/Exception/404.php: - class HTTP_Exception_404 extends Kohana_HTTP_Exception_404 { - - /** - * Generate a Response for the 404 Exception. - * - * The user should be shown a nice 404 page. - * - * @return Response - */ - public function get_response() - { - $view = View::factory('errors/404'); - - // Remembering that `$this` is an instance of HTTP_Exception_404 - $view->message = $this->getMessage(); - - $response = Response::factory() - ->status(404) - ->body($view->render()); - - return $response; - } - } + class HTTP_Exception_404 extends Kohana_HTTP_Exception_404 { + + /** + * Generate a Response for the 404 Exception. + * + * The user should be shown a nice 404 page. + * + * @return Response + */ + public function get_response() + { + $view = View::factory('errors/404'); + + // Remembering that `$this` is an instance of HTTP_Exception_404 + $view->message = $this->getMessage(); + + $response = Response::factory() + ->status(404) + ->body($view->render()); + + return $response; + } + } Another example, this time to handle 401 Unauthorized errors (aka "Not Logged In") we can do this in APPPATH/classes/HTTP/Exception/401.php: - class HTTP_Exception_401 extends Kohana_HTTP_Exception_401 { - - /** - * Generate a Response for the 401 Exception. - * - * The user should be redirect to a login page. - * - * @return Response - */ - public function get_response() - { - $response = Response::factory() - ->status(401) - ->headers('Location', URL::site('account/login')); - - return $response; - } - } + class HTTP_Exception_401 extends Kohana_HTTP_Exception_401 { + + /** + * Generate a Response for the 401 Exception. + * + * The user should be redirect to a login page. + * + * @return Response + */ + public function get_response() + { + $response = Response::factory() + ->status(401) + ->headers('Location', URL::site('account/login')); + + return $response; + } + } Finally, to override the default [Response] for all [HTTP_Exception]'s without a more specific override we can do this in APPPATH/classes/HTTP/Exception.php: - class HTTP_Exception extends Kohana_HTTP_Exception { - - /** - * Generate a Response for all Exceptions without a more specific override - * - * The user should see a nice error page, however, if we are in development - * mode we should show the normal Kohana error page. - * - * @return Response - */ - public function get_response() - { - // Lets log the Exception, Just in case it's important! - Kohana_Exception::log($this); - - if (Kohana::$environment >= Kohana::DEVELOPMENT) - { - // Show the normal Kohana error page. - return parent::get_response(); - } - else - { - // Generate a nicer looking "Oops" page. - $view = View::factory('errors/default'); - - $response = Response::factory() - ->status($this->getCode()) - ->body($view->render()); - - return $response; - } - } - } \ No newline at end of file + class HTTP_Exception extends Kohana_HTTP_Exception { + + /** + * Generate a Response for all Exceptions without a more specific override + * + * The user should see a nice error page, however, if we are in development + * mode we should show the normal Kohana error page. + * + * @return Response + */ + public function get_response() + { + // Lets log the Exception, Just in case it's important! + Kohana_Exception::log($this); + + if (Kohana::$environment >= Kohana::DEVELOPMENT) + { + // Show the normal Kohana error page. + return parent::get_response(); + } + else + { + // Generate a nicer looking "Oops" page. + $view = View::factory('errors/default'); + + $response = Response::factory() + ->status($this->getCode()) + ->body($view->render()); + + return $response; + } + } + } \ No newline at end of file diff --git a/system/guide/kohana/tutorials/hello-world.md b/system/guide/kohana/tutorials/hello-world.md index cae024d..6ebb4cc 100644 --- a/system/guide/kohana/tutorials/hello-world.md +++ b/system/guide/kohana/tutorials/hello-world.md @@ -12,28 +12,28 @@ Create the file `application/classes/Controller/Hello.php` in your application f template->message = 'hello, world!'; - } - } + public function action_index() + { + $this->template->message = 'hello, world!'; + } + } `extends Controller_Template` -: We're now extending the template controller, it makes it more convenient to use views within our controller. +: We're now extending the template controller, it makes it more convenient to use views within our controller. `public $template = 'site';` -: The template controller needs to know what template you want to use. It'll automatically load the view defined in this variable and assign the view object to it. +: The template controller needs to know what template you want to use. It'll automatically load the view defined in this variable and assign the view object to it. `$this->template->message = 'hello, world!';` -: `$this->template` is a reference to the view object for our site template. What we're doing here is assigning a variable called "message", with a value of "hello, world!" to the view. +: `$this->template` is a reference to the view object for our site template. What we're doing here is assigning a variable called "message", with a value of "hello, world!" to the view. Now lets try running our code... @@ -80,20 +80,20 @@ If we look at the error message we can see that the View library wasn't able to Let's go and make the view file `application/views/site.php` for our message: - - - We've got a message for you! - - - -

-

We just wanted to say it! :)

- - + + + We've got a message for you! + + + +

+

We just wanted to say it! :)

+ + If we refresh the page then we can see the fruits of our labour: