From bf8e804a5607caf086a96127781496fad2c0dd98 Mon Sep 17 00:00:00 2001 From: joelpittet Date: Mon, 20 Jun 2011 10:35:54 -0500 Subject: [PATCH 01/27] extending the example for filters in issue #4056 --- guide/orm/filters.md | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/guide/orm/filters.md b/guide/orm/filters.md index 5f20e60..8441ab3 100644 --- a/guide/orm/filters.md +++ b/guide/orm/filters.md @@ -1,22 +1,42 @@ # Filters -Filters in ORM work much like they used to when they were part of the Validate class in 3.0.x however they have been modified to match the flexible syntax of [Validation] rules in 3.1.x. Filters run as soon as the field is set in your model and should be used to format the data before it is inserted into the Database. +Filters in the ORM work much like they used to when they were part of the Validate class in 3.0.x however they have been modified to match the flexible syntax of [Validation] rules in 3.1.x. Filters run as soon as the field is set in your model and should be used to format the data before it is inserted into the Database. Define your filters the same way you define rules, as an array returned by the `ORM::filters()` method like the following: public function filters() { return array( - 'username' => array( + // Field Filters + // $field_name => array(mixed $callback[, array $params = array(':value')]), + 'username' => array( + // PHP Function Callback, default implicit param of ':value' array('trim'), ), 'password' => array( - array(array($this, 'hash_password')), + // Callback method with object context and params + array(array($this, 'hash_password'), array(':value', Model_User::salt())), ), - 'created_on' => array( - array('Format::date', array(':value', 'Y-m-d H:i:s')), + 'created_on' => array( + // Callback static method with params + array('Format::date', array(':value', 'Y-m-d H:i:s')), ), + 'other_field' => array( + // Callback static method with implicit param of ':value' + array('MyClass::static_method'), + // Callback method with object context with implicit param of ':value' + array(array($this, 'change_other_field')), + // PHP function callback with explicit params + array('str_replace', array('luango', 'thomas', ':value'), + // Function as the callback (PHP 5.3+) + array(function($value) { + // Do something to $value and return it. + return some_function($value); + }), + ), + ); } + [!!] When defining filters, you may use the parameters `:value`, `:field`, and `:model` to refer to the field value, field name, and the model instance respectively. From d3d7e8e772ed0699149d540b5f4ccdf7cba29b63 Mon Sep 17 00:00:00 2001 From: Martino di Filippo Date: Sun, 10 Jul 2011 17:35:16 +0200 Subject: [PATCH 02/27] Fixes #3817 --- classes/kohana/orm.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 33a8574..41a2d05 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -1286,6 +1286,12 @@ public function create(Validation $validation = NULL) $this->_object[$this->_primary_key] = $this->_primary_key_value = $result[0]; } + if (empty($this->_primary_key_value)) + { + // Set the primary key value if it was manually chosen by the user + $this->_primary_key_value = $this->_object[$this->_primary_key]; + } + // Object is now loaded and saved $this->_loaded = $this->_saved = TRUE; From 24685c28c1baa4f91152f8371dfafa8ad74d731d Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sat, 17 Sep 2011 10:48:58 -0700 Subject: [PATCH 03/27] checkstyle fixes --- classes/kohana/orm.php | 74 +++++++++++++++++++++--------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 048d351..d0c1ffd 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -503,7 +503,7 @@ public function serialize() * Check whether the model data has been modified. * If $field is specified, checks whether that field was modified. * - * @param string field to check for changes + * @param string $field field to check for changes * @return bool Whether or not the field has changed */ public function changed($field = NULL) @@ -1677,9 +1677,9 @@ public function errors_filename() /** * Alias of and_where() * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function where($column, $op, $value) @@ -1696,9 +1696,9 @@ public function where($column, $op, $value) /** * Creates a new "AND WHERE" condition for the query. * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function and_where($column, $op, $value) @@ -1715,9 +1715,9 @@ public function and_where($column, $op, $value) /** * Creates a new "OR WHERE" condition for the query. * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function or_where($column, $op, $value) @@ -1818,8 +1818,8 @@ public function or_where_close() /** * Applies sorting with "ORDER BY ..." * - * @param mixed column name or array($column, $alias) or object - * @param string direction of sorting + * @param mixed $column column name or array($column, $alias) or object + * @param string $direction direction of sorting * @return $this */ public function order_by($column, $direction = NULL) @@ -1836,7 +1836,7 @@ public function order_by($column, $direction = NULL) /** * Return up to "LIMIT ..." results * - * @param integer maximum results to return + * @param integer $number maximum results to return * @return $this */ public function limit($number) @@ -1853,7 +1853,7 @@ public function limit($number) /** * Enables or disables selecting only unique columns using "SELECT DISTINCT" * - * @param boolean enable or disable distinct columns + * @param boolean $value enable or disable distinct columns * @return $this */ public function distinct($value) @@ -1870,7 +1870,7 @@ public function distinct($value) /** * Choose the columns to select from. * - * @param mixed column name or array($column, $alias) or object + * @param mixed $columns column name or array($column, $alias) or object * @param ... * @return $this */ @@ -1890,7 +1890,7 @@ public function select($columns = NULL) /** * Choose the tables to select "FROM ..." * - * @param mixed table name or array($table, $alias) or object + * @param mixed $tables table name or array($table, $alias) or object * @param ... * @return $this */ @@ -1910,8 +1910,8 @@ public function from($tables) /** * Adds addition tables to "JOIN ...". * - * @param mixed column name or array($column, $alias) or object - * @param string join type (LEFT, RIGHT, INNER, etc) + * @param mixed $table column name or array($column, $alias) or object + * @param string $type join type (LEFT, RIGHT, INNER, etc) * @return $this */ public function join($table, $type = NULL) @@ -1928,9 +1928,9 @@ public function join($table, $type = NULL) /** * Adds "ON ..." conditions for the last created JOIN statement. * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column name or array($column, $alias) or object + * @param mixed $ci column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $c2 column name or array($column, $alias) or object * @return $this */ public function on($c1, $op, $c2) @@ -1947,7 +1947,7 @@ public function on($c1, $op, $c2) /** * Creates a "GROUP BY ..." filter. * - * @param mixed column name or array($column, $alias) or object + * @param mixed $columns column name or array($column, $alias) or object * @param ... * @return $this */ @@ -1967,9 +1967,9 @@ public function group_by($columns) /** * Alias of and_having() * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function having($column, $op, $value = NULL) @@ -1980,9 +1980,9 @@ public function having($column, $op, $value = NULL) /** * Creates a new "AND HAVING" condition for the query. * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function and_having($column, $op, $value = NULL) @@ -1999,9 +1999,9 @@ public function and_having($column, $op, $value = NULL) /** * Creates a new "OR HAVING" condition for the query. * - * @param mixed column name or array($column, $alias) or object - * @param string logic operator - * @param mixed column value + * @param mixed $column column name or array($column, $alias) or object + * @param string $op logic operator + * @param mixed $value column value * @return $this */ public function or_having($column, $op, $value = NULL) @@ -2102,7 +2102,7 @@ public function or_having_close() /** * Start returning results after "OFFSET ..." * - * @param integer starting result number + * @param integer $number starting result number * @return $this */ public function offset($number) @@ -2119,7 +2119,7 @@ public function offset($number) /** * Enables the query to be cached for a specified amount of time. * - * @param integer number of seconds to cache + * @param integer $lifetime number of seconds to cache * @return $this * @uses Kohana::$cache_life */ @@ -2137,8 +2137,8 @@ public function cached($lifetime = NULL) /** * Set the value of a parameter in the query. * - * @param string parameter key to replace - * @param mixed value to use + * @param string $param parameter key to replace + * @param mixed $value value to use * @return $this */ public function param($param, $value) @@ -2156,8 +2156,8 @@ public function param($param, $value) * Checks whether a column value is unique. * Excludes itself if loaded. * - * @param string the field to check for uniqueness - * @param mixed the value to check for uniqueness + * @param string $field the field to check for uniqueness + * @param mixed $value the value to check for uniqueness * @return bool whteher the value is unique */ public function unique($field, $value) From 55f5d73e68412bfd70e1a587480fc614530beddb Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sat, 17 Sep 2011 10:53:30 -0700 Subject: [PATCH 04/27] checkstyle fixes --- classes/kohana/auth/orm.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/classes/kohana/auth/orm.php b/classes/kohana/auth/orm.php index 4a6d16a..14bc7eb 100644 --- a/classes/kohana/auth/orm.php +++ b/classes/kohana/auth/orm.php @@ -60,9 +60,9 @@ public function logged_in($role = NULL) /** * Logs a user in. * - * @param string username - * @param string password - * @param boolean enable autologin + * @param string $username + * @param string $password + * @param boolean $remember enable autologin * @return boolean */ protected function _login($user, $password, $remember) @@ -110,8 +110,8 @@ protected function _login($user, $password, $remember) /** * Forces a user to be logged in, without specifying a password. * - * @param mixed username string, or user ORM object - * @param boolean mark the session as forced + * @param mixed $user username string, or user ORM object + * @param boolean $mark_session_as_forced mark the session as forced * @return boolean */ public function force_login($user, $mark_session_as_forced = FALSE) @@ -176,6 +176,7 @@ public function auto_login() * Gets the currently logged in user from the session (with auto_login check). * Returns FALSE if no user is currently logged in. * + * @param mixed $default * @return mixed */ public function get_user($default = NULL) @@ -194,8 +195,8 @@ public function get_user($default = NULL) /** * Log a user out and remove any autologin cookies. * - * @param boolean completely destroy the session - * @param boolean remove all tokens for user + * @param boolean $destroy completely destroy the session + * @param boolean $logout_all remove all tokens for user * @return boolean */ public function logout($destroy = FALSE, $logout_all = FALSE) @@ -227,7 +228,7 @@ public function logout($destroy = FALSE, $logout_all = FALSE) /** * Get the stored password for a username. * - * @param mixed username string, or user ORM object + * @param mixed $user username string, or user ORM object * @return string */ public function password($user) @@ -248,7 +249,7 @@ public function password($user) * Complete the login for a user by incrementing the logins and setting * session data: user_id, username, roles. * - * @param object user ORM object + * @param object $user user ORM object * @return void */ protected function complete_login($user) From 43bec864806401d8d62a8cb942e7145f09f40372 Mon Sep 17 00:00:00 2001 From: Kiall Mac Innes Date: Fri, 23 Sep 2011 17:20:54 +0100 Subject: [PATCH 05/27] Fixing CS Issues. Uppercase Constants and Logical Operators --- classes/auth/orm.php | 2 +- classes/kohana/auth/orm.php | 2 +- classes/kohana/orm.php | 2 +- classes/kohana/orm/validation/exception.php | 2 +- classes/model/auth/role.php | 2 +- classes/model/auth/user.php | 2 +- classes/model/auth/user/token.php | 2 +- classes/model/role.php | 2 +- classes/model/user.php | 2 +- classes/model/user/token.php | 2 +- classes/orm.php | 2 +- classes/orm/validation/exception.php | 2 +- config/userguide.php | 2 +- guide/orm/examples/simple.md | 4 ++-- guide/orm/examples/validation.md | 2 +- 15 files changed, 16 insertions(+), 16 deletions(-) diff --git a/classes/auth/orm.php b/classes/auth/orm.php index ecff72d..590bef1 100644 --- a/classes/auth/orm.php +++ b/classes/auth/orm.php @@ -1,3 +1,3 @@ - Date: Mon, 31 Oct 2011 23:16:36 +0100 Subject: [PATCH 06/27] Allow custom primary key on User table when logging in --- classes/kohana/auth/orm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/auth/orm.php b/classes/kohana/auth/orm.php index 4ba2637..3ac05b9 100644 --- a/classes/kohana/auth/orm.php +++ b/classes/kohana/auth/orm.php @@ -89,7 +89,7 @@ protected function _login($user, $password, $remember) { // Token data $data = array( - 'user_id' => $user->id, + 'user_id' => $user->pk(), 'expires' => time() + $this->_config['lifetime'], 'user_agent' => sha1(Request::$user_agent), ); From e40fa17ece7ece837c5cbc9de180b1be3ddd9b07 Mon Sep 17 00:00:00 2001 From: Chris Smith Date: Fri, 6 Jan 2012 15:36:24 +0000 Subject: [PATCH 07/27] Store PK if it has been set on a created model, fixes #4244 --- classes/kohana/orm.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index d0c1ffd..7f1a471 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -1226,6 +1226,10 @@ public function create(Validation $validation = NULL) // Load the insert id as the primary key if it was left out $this->_object[$this->_primary_key] = $this->_primary_key_value = $result[0]; } + else + { + $this->_primary_key_value = $this->_object[$this->_primary_key]; + } // Object is now loaded and saved $this->_loaded = $this->_saved = TRUE; From 5212e9856a81cf741510769937f267df0e47541f Mon Sep 17 00:00:00 2001 From: Kiall Mac Innes Date: Tue, 10 Jan 2012 19:04:44 +0000 Subject: [PATCH 08/27] Update @copyright notices to 2012. Fixes #4396. --- classes/kohana/auth/orm.php | 2 +- classes/kohana/orm.php | 2 +- classes/kohana/orm/validation/exception.php | 2 +- classes/model/auth/user.php | 2 +- classes/model/auth/user/token.php | 2 +- config/userguide.php | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/classes/kohana/auth/orm.php b/classes/kohana/auth/orm.php index ce2639e..a69c63d 100644 --- a/classes/kohana/auth/orm.php +++ b/classes/kohana/auth/orm.php @@ -4,7 +4,7 @@ * * @package Kohana/Auth * @author Kohana Team - * @copyright (c) 2007-2011 Kohana Team + * @copyright (c) 2007-2012 Kohana Team * @license http://kohanaframework.org/license */ class Kohana_Auth_ORM extends Auth { diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index dc90885..5848cbc 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -10,7 +10,7 @@ * * @package Kohana/ORM * @author Kohana Team - * @copyright (c) 2007-2010 Kohana Team + * @copyright (c) 2007-2012 Kohana Team * @license http://kohanaframework.org/license * * diff --git a/classes/kohana/orm/validation/exception.php b/classes/kohana/orm/validation/exception.php index 805c512..89728f5 100644 --- a/classes/kohana/orm/validation/exception.php +++ b/classes/kohana/orm/validation/exception.php @@ -4,7 +4,7 @@ * * @package Kohana/ORM * @author Kohana Team - * @copyright (c) 2007-2010 Kohana Team + * @copyright (c) 2007-2012 Kohana Team * @license http://kohanaframework.org/license */ class Kohana_ORM_Validation_Exception extends Kohana_Exception { diff --git a/classes/model/auth/user.php b/classes/model/auth/user.php index 31c29f7..ecec16b 100644 --- a/classes/model/auth/user.php +++ b/classes/model/auth/user.php @@ -4,7 +4,7 @@ * * @package Kohana/Auth * @author Kohana Team - * @copyright (c) 2007-2011 Kohana Team + * @copyright (c) 2007-2012 Kohana Team * @license http://kohanaframework.org/license */ class Model_Auth_User extends ORM { diff --git a/classes/model/auth/user/token.php b/classes/model/auth/user/token.php index 3d8a69c..4fe94b4 100644 --- a/classes/model/auth/user/token.php +++ b/classes/model/auth/user/token.php @@ -4,7 +4,7 @@ * * @package Kohana/Auth * @author Kohana Team - * @copyright (c) 2007-2011 Kohana Team + * @copyright (c) 2007-2012 Kohana Team * @license http://kohanaframework.org/license */ class Model_Auth_User_Token extends ORM { diff --git a/config/userguide.php b/config/userguide.php index f64cc92..cfd7429 100644 --- a/config/userguide.php +++ b/config/userguide.php @@ -17,7 +17,7 @@ 'description' => 'Official ORM module, a modeling library for object relational mapping.', // Copyright message, shown in the footer for this module - 'copyright' => '© 2008–2011 Kohana Team', + 'copyright' => '© 2008–2012 Kohana Team', ) ) ); From bc56b3d42274013c61a2fcfda41c5545bf849697 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Mon, 16 Jan 2012 19:14:08 -0500 Subject: [PATCH 09/27] Fixes #4406 - Make sure we check for NULL value before loading belongs to data. --- classes/kohana/orm.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 3101cb3..f596675 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -562,8 +562,14 @@ public function __get($column) // Use this model's column and foreign model's primary key $col = $model->_object_name.'.'.$model->_primary_key; $val = $this->_object[$this->_belongs_to[$column]['foreign_key']]; - - $model->where($col, '=', $val)->find(); + + // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would + // return the last inserted record instead of an empty result. + // See: http://mysql.localhost.net.ar/doc/refman/5.1/en/server-session-variables.html#sysvar_sql_auto_is_null + if ($val !== NULL) + { + $model->where($col, '=', $val)->find(); + } return $this->_related[$column] = $model; } From b577baee991282c9dda19cfb2c6ee04940325cdb Mon Sep 17 00:00:00 2001 From: Rad Date: Sat, 28 Jan 2012 00:02:39 +0000 Subject: [PATCH 10/27] The foreign key in the belongs_to relationship is now only set to the value's primary key if the value is an instance of ORM, otherwise the foreign key is set to NULL. Fixes #4420 --- classes/kohana/orm.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index f596675..79d9e38 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -678,7 +678,9 @@ public function set($column, $value) $this->_related[$column] = $value; // Update the foreign key of this model - $this->_object[$this->_belongs_to[$column]['foreign_key']] = $value->pk(); + $this->_object[$this->_belongs_to[$column]['foreign_key']] = ($value instanceof ORM) + ? $value->pk() + : NULL; $this->_changed[$column] = $this->_belongs_to[$column]['foreign_key']; } From 0d6c71e7968bc738cf4f6f1c21419b935f6329c8 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Mon, 30 Jan 2012 23:54:23 -0500 Subject: [PATCH 11/27] Fixes #4423 and #4424 - Run validation before checking changed. Always run validation if additional validation is supplied. --- classes/kohana/orm.php | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 5848cbc..ceffa1c 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -1254,7 +1254,7 @@ public function create(Validation $validation = NULL) throw new Kohana_Exception('Cannot create :model model because it is already loaded.', array(':model' => $this->_object_name)); // Require model validation before saving - if ( ! $this->_valid) + if ( ! $this->_valid OR $validation) { $this->check($validation); } @@ -1313,16 +1313,16 @@ public function update(Validation $validation = NULL) if ( ! $this->_loaded) throw new Kohana_Exception('Cannot update :model model because it is not loaded.', array(':model' => $this->_object_name)); - if (empty($this->_changed)) + // Run validation if the model isn't valid or we have additional validation rules. + if ( ! $this->_valid OR $validation) { - // Nothing to update - return $this; + $this->check($validation); } - // Require model validation before saving - if ( ! $this->_valid) + if (empty($this->_changed)) { - $this->check($validation); + // Nothing to update + return $this; } $data = array(); From e179155c236b3806cfb0d8007b3501eb90fccca9 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Mon, 16 Jan 2012 19:14:08 -0500 Subject: [PATCH 12/27] Fixes #4406 - Make sure we check for NULL value before loading belongs to data. --- classes/kohana/orm.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index ceffa1c..e55fc87 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -632,8 +632,14 @@ public function __get($column) // Use this model's column and foreign model's primary key $col = $model->_table_name.'.'.$model->_primary_key; $val = $this->_object[$this->_belongs_to[$column]['foreign_key']]; - - $model->where($col, '=', $val)->find(); + + // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would + // return the last inserted record instead of an empty result. + // See: http://mysql.localhost.net.ar/doc/refman/5.1/en/server-session-variables.html#sysvar_sql_auto_is_null + if ($val !== NULL) + { + $model->where($col, '=', $val)->find(); + } return $this->_related[$column] = $model; } From c1d5f2f119afed15a34f5cc2b8a181d276707d17 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Tue, 31 Jan 2012 01:06:12 -0500 Subject: [PATCH 13/27] Fixes #3587 - Select columns by name instead of doing select * --- classes/kohana/orm.php | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index e55fc87..2bdb1c0 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -632,8 +632,8 @@ public function __get($column) // Use this model's column and foreign model's primary key $col = $model->_table_name.'.'.$model->_primary_key; $val = $this->_object[$this->_belongs_to[$column]['foreign_key']]; - - // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would + + // Make sure we don't run WHERE "AUTO_INCREMENT column" = NULL queries. This would // return the last inserted record instead of an empty result. // See: http://mysql.localhost.net.ar/doc/refman/5.1/en/server-session-variables.html#sysvar_sql_auto_is_null if ($val !== NULL) @@ -993,6 +993,24 @@ public function find_all() return $this->_load_result(TRUE); } + /** + * Returns an array of columns to include in the select query. This method + * can be overridden to change the default select behavior. + * + * @return array Columns to select + */ + protected function _build_select() + { + $columns = array(); + + foreach ($this->_table_columns as $column => $_) + { + $columns[] = array($this->_table_name.'.'.$column, $column); + } + + return $columns; + } + /** * Loads a database result, either as a new record for this model, or as * an iterator for multiple rows. @@ -1012,7 +1030,7 @@ protected function _load_result($multiple = FALSE) } // Select all columns by default - $this->_db_builder->select($this->_table_name.'.*'); + $this->_db_builder->select_array($this->_build_select()); if ( ! isset($this->_db_applied['order_by']) AND ! empty($this->_sorting)) { @@ -1631,4 +1649,4 @@ public function reset($next = TRUE) return $this; } -} // End ORM +} // End ORM \ No newline at end of file From 2f68382df5767ac5f5a69bfb23c48d8b4a392ce0 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sun, 5 Feb 2012 01:20:53 -0800 Subject: [PATCH 14/27] handling external validation differently from merged model validation (fixes #4185) --- classes/kohana/orm/validation/exception.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/classes/kohana/orm/validation/exception.php b/classes/kohana/orm/validation/exception.php index a225539..bff0c3c 100644 --- a/classes/kohana/orm/validation/exception.php +++ b/classes/kohana/orm/validation/exception.php @@ -150,7 +150,11 @@ protected function generate_errors($alias, array $array, $directory, $translate) { if (is_array($object)) { - $errors[$key] = $this->generate_errors($key, $object, $directory, $translate); + $errors[$key] = ($key === '_external') + // Search for errors in $alias/_external.php + ? $this->generate_errors($alias.'/'.$key, $object, $directory, $translate) + // Regular models get their own file not nested within $alias + : $this->generate_errors($key, $object, $directory, $translate); } elseif ($object instanceof Validation) { From 894c6884f5808306f0a48ae990b619d342158a98 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Sat, 10 Mar 2012 13:16:34 +0100 Subject: [PATCH 15/27] Build select quickfix --- classes/kohana/orm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 36afadf..b6e1fa7 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -940,7 +940,7 @@ protected function _build_select() foreach ($this->_table_columns as $column => $_) { - $columns[] = array($this->_table_name.'.'.$column, $column); + $columns[] = array($this->_object_name.'.'.$column, $column); } return $columns; From ebe9cd6ece76802d233ce51ec86db6c9b5096fc0 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Mon, 5 Mar 2012 09:08:37 +0100 Subject: [PATCH 16/27] Refs #4466 - ORM::values() documentation --- guide/orm/using.md | 19 +++++++++++++++++++ guide/orm/validation.md | 35 +++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 16 deletions(-) diff --git a/guide/orm/using.md b/guide/orm/using.md index 8d54d65..878c62a 100644 --- a/guide/orm/using.md +++ b/guide/orm/using.md @@ -73,3 +73,22 @@ To delete an object, you can call the [ORM::delete] method on a loaded ORM model $user = ORM::factory('user', 20); $user->delete(); + +## Mass assignment + + +To set multiple values at once, use [ORM::values] + + try + { + $user = ORM::factory('user') + ->values($this->request->post(), array('username','password')) + ->create(); + } + catch (ORM_Validation_Exception $e) + { + // Handle validation errors ... + } + +[!!] Although the second argument is optional, it is *highly recommended* to specify the list of columns you expect to change. Not doing so will leave your code _vulnerable_ in case the attacker adds fields you didn't expect. + diff --git a/guide/orm/validation.md b/guide/orm/validation.md index d83414f..609496b 100644 --- a/guide/orm/validation.md +++ b/guide/orm/validation.md @@ -77,23 +77,26 @@ Certain forms contain information that should not be validated by the model, but public function action_create() { - try - { - $user = ORM::factory('user'); - $user->username = $_POST['username']; - $user->password = $_POST['password']; - - $extra_rules = Validation::factory($_POST) - ->rule('password_confirm', 'matches', array( - ':validation', ':field', 'password' - )); - - // Pass the extra rules to be validated with the model - $user->save($extra_rules); - } - catch (ORM_Validation_Exception $e) + if ($this->request->method === Request::POST) { - $errors = $e->errors('models'); + try + { + $user = ORM::factory('user'); + + $user->values($this->request->post(), array('username','password')); + + $extra_rules = Validation::factory($this->request->post()) + ->rule('password_confirm', 'matches', array( + ':validation', ':field', 'password' + )); + + // Pass the extra rules to be validated with the model + $user->save($extra_rules); + } + catch (ORM_Validation_Exception $e) + { + $errors = $e->errors('models'); + } } } From 6a628773e240a0dff7481986b83296290b0394a4 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Tue, 27 Mar 2012 23:36:17 +0200 Subject: [PATCH 17/27] Refs #3747 - Wrong return value for ORM::serialize() --- classes/kohana/orm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 2bdb1c0..cefea07 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -533,7 +533,7 @@ public function __toString() * Allows serialization of only the object data and state, to prevent * "stale" objects being unserialized, which also requires less memory. * - * @return array + * @return string */ public function serialize() { From d121c9d40170e23e337a76d5de562a1001598b63 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Tue, 27 Mar 2012 23:39:30 +0200 Subject: [PATCH 18/27] Refs #3714 - Remove the comment about deleting multiple records --- classes/kohana/orm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index cefea07..941588f 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -1402,7 +1402,7 @@ public function save(Validation $validation = NULL) } /** - * Deletes a single record or multiple records, ignoring relationships. + * Deletes a single record while ignoring relationships. * * @chainable * @return ORM From b9dea3bb717f65b720e7a261cc60a2ef077bd2a0 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Tue, 27 Mar 2012 23:52:56 +0200 Subject: [PATCH 19/27] Refs #3714 - ORM::delete_all() doesn't exist --- classes/kohana/auth/orm.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/classes/kohana/auth/orm.php b/classes/kohana/auth/orm.php index a69c63d..953306a 100644 --- a/classes/kohana/auth/orm.php +++ b/classes/kohana/auth/orm.php @@ -214,7 +214,13 @@ public function logout($destroy = FALSE, $logout_all = FALSE) if ($token->loaded() AND $logout_all) { - ORM::factory('user_token')->where('user_id', '=', $token->user_id)->delete_all(); + // Delete all user tokens. This isn't the most elegant solution but does the job + $tokens = ORM::factory('user_token')->where('user_id','=',$token->user_id)->find_all(); + + foreach ($tokens as $_token) + { + $_token->delete(); + } } elseif ($token->loaded()) { From 30a175a74d4dc6ba2828afd0da2788ab4e5e9961 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Wed, 28 Mar 2012 00:03:15 +0200 Subject: [PATCH 20/27] Refs #3889 - Model_User_Token doesn't specify the created column --- classes/model/auth/user/token.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/classes/model/auth/user/token.php b/classes/model/auth/user/token.php index 4fe94b4..c78cce0 100644 --- a/classes/model/auth/user/token.php +++ b/classes/model/auth/user/token.php @@ -11,6 +11,11 @@ class Model_Auth_User_Token extends ORM { // Relationships protected $_belongs_to = array('user' => array()); + + protected $_created_column = array( + 'column' => 'created', + 'format' => TRUE, + ); /** * Handles garbage collection and deleting of expired objects. From a28fd80f76783c6d8a07b7465ab77a241ae809bf Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Wed, 28 Mar 2012 00:07:30 +0200 Subject: [PATCH 21/27] Refs #3738 - ORM::primary_val nonexistant --- classes/kohana/orm.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 941588f..18c9c2f 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -49,7 +49,6 @@ * @property bool $loaded ORM object was loaded? * @property bool $saved ORM object was saved? * @property mixed $primary_key - * @property mixed $primary_val * @property string $table_name * @property string $table_columns * @property array $has_one @@ -87,7 +86,7 @@ class Kohana_ORM extends Model implements serializable { protected static $_properties = array ( 'object_name', 'object_plural', 'loaded', 'saved', // Object - 'primary_key', 'primary_val', 'table_name', 'table_columns', // Table + 'primary_key', 'table_name', 'table_columns', // Table 'has_one', 'belongs_to', 'has_many', 'has_many_through', 'load_with', // Relationships 'updated_column', 'created_column', 'validation', From ccfab2bb5de56e4666d645d0caaecb4cbaec4ee4 Mon Sep 17 00:00:00 2001 From: Kemal Delalic Date: Wed, 28 Mar 2012 00:21:39 +0200 Subject: [PATCH 22/27] Refs #4018 - ORM Auth driver breaks default value behavior with Auth::get_user() --- classes/kohana/auth/orm.php | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/classes/kohana/auth/orm.php b/classes/kohana/auth/orm.php index 953306a..9f10104 100644 --- a/classes/kohana/auth/orm.php +++ b/classes/kohana/auth/orm.php @@ -174,19 +174,20 @@ public function auto_login() /** * Gets the currently logged in user from the session (with auto_login check). - * Returns FALSE if no user is currently logged in. + * Returns $default if no user is currently logged in. * - * @param mixed $default + * @param mixed $default to return in case user isn't logged in * @return mixed */ public function get_user($default = NULL) { $user = parent::get_user($default); - if ( ! $user) + if ($user === $default) { // check for "remembered" login - $user = $this->auto_login(); + if (($user = $this->auto_login()) === FALSE) + return $default; } return $user; From fb9f7db6ad7c9cd172be77b14673c5fb8f31bab9 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Thu, 31 May 2012 21:09:44 -0700 Subject: [PATCH 23/27] Fixes #4071 - Reset the Model loaded state to false in ORM::clear(). --- classes/kohana/orm.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index 18c9c2f..ea131d2 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -464,6 +464,9 @@ public function clear() // Reset primary key $this->_primary_key_value = NULL; + + // Reset the loaded state + $this->_loaded = FALSE; $this->reset(); From 8a886eb9bbf354cfbfb0ff962f0db6e1d06132e3 Mon Sep 17 00:00:00 2001 From: Isaiah DeRose-Wilson Date: Thu, 31 May 2012 21:25:23 -0700 Subject: [PATCH 24/27] Fixes #4010 - Remove ambiguous ORM::list_columns() parameter --- classes/kohana/orm.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index ea131d2..2ed3a32 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -435,7 +435,7 @@ public function reload_columns($force = FALSE) else { // Grab column information from database - $this->_table_columns = $this->list_columns(TRUE); + $this->_table_columns = $this->list_columns(); // Load column cache ORM::$_column_cache[$this->_object_name] = $this->_table_columns; From 9750511bf76f7854f16f8f88e94705f378e0a8c6 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Fri, 1 Jun 2012 22:27:32 -0700 Subject: [PATCH 25/27] fix documentation grammar refs #4056 --- guide/orm/filters.md | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/guide/orm/filters.md b/guide/orm/filters.md index 8441ab3..218f0a4 100644 --- a/guide/orm/filters.md +++ b/guide/orm/filters.md @@ -1,25 +1,25 @@ # Filters -Filters in the ORM work much like they used to when they were part of the Validate class in 3.0.x however they have been modified to match the flexible syntax of [Validation] rules in 3.1.x. Filters run as soon as the field is set in your model and should be used to format the data before it is inserted into the Database. +Filters in ORM work much like they used to when they were part of the Validate class in 3.0.x. However, they have been modified to match the flexible syntax of [Validation] rules in 3.1.x. -Define your filters the same way you define rules, as an array returned by the `ORM::filters()` method like the following: +Filters run as soon as the field is set in your model and should be used to format the data before it is inserted into the Database. Filters are defined the same way you define [rules](validation), as an array returned by the `ORM::filters()` method, like the following: public function filters() { return array( // Field Filters // $field_name => array(mixed $callback[, array $params = array(':value')]), - 'username' => array( + 'username' => array( // PHP Function Callback, default implicit param of ':value' array('trim'), ), 'password' => array( // Callback method with object context and params - array(array($this, 'hash_password'), array(':value', Model_User::salt())), + array(array($this, 'hash_password'), array(':value', Model_User::salt())), ), - 'created_on' => array( + 'created_on' => array( // Callback static method with params - array('Format::date', array(':value', 'Y-m-d H:i:s')), + array('Format::date', array(':value', 'Y-m-d H:i:s')), ), 'other_field' => array( // Callback static method with implicit param of ':value' @@ -37,6 +37,5 @@ Define your filters the same way you define rules, as an array returned by the ` ); } - [!!] When defining filters, you may use the parameters `:value`, `:field`, and `:model` to refer to the field value, field name, and the model instance respectively. From 71403b99727f6ad03622d23359b3169aa21ba5af Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Sat, 2 Jun 2012 15:13:45 -0700 Subject: [PATCH 26/27] add KEY for expires column (refs #3031) --- auth-schema-mysql.sql | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/auth-schema-mysql.sql b/auth-schema-mysql.sql index ec4a4a8..f129793 100644 --- a/auth-schema-mysql.sql +++ b/auth-schema-mysql.sql @@ -38,7 +38,8 @@ CREATE TABLE IF NOT EXISTS `user_tokens` ( `expires` int(10) UNSIGNED NOT NULL, PRIMARY KEY (`id`), UNIQUE KEY `uniq_token` (`token`), - KEY `fk_user_id` (`user_id`) + KEY `fk_user_id` (`user_id`), + KEY `expires` (`expires`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; ALTER TABLE `roles_users` From dffef9d24b155b14cff224fcfed6d8930bfe6b33 Mon Sep 17 00:00:00 2001 From: Lorenzo Pisani Date: Wed, 25 Jul 2012 22:10:24 -0700 Subject: [PATCH 27/27] remove alias for DELETE queries (refs #4177) --- classes/kohana/orm.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/kohana/orm.php b/classes/kohana/orm.php index ca32644..3a4bedc 100644 --- a/classes/kohana/orm.php +++ b/classes/kohana/orm.php @@ -865,7 +865,8 @@ protected function _build($type) $this->_db_builder = DB::update(array($this->_table_name, $this->_object_name)); break; case Database::DELETE: - $this->_db_builder = DB::delete(array($this->_table_name, $this->_object_name)); + // Cannot use an alias for DELETE queries + $this->_db_builder = DB::delete($this->_table_name); } // Process pending database method calls