Show
Ignore:
Timestamp:
04/14/2008 11:26:42 PM (7 months ago)
Author:
Shadowhand
Message:

Added Validation::safe_array() to extract only keys that were validated.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • trunk/system/libraries/Validation.php

    r2449 r2490  
    7070 
    7171        /** 
    72          * Returns the ArrayObject array values. 
     72         * Returns the ArrayObject values. 
    7373         * 
    7474         * @return  array 
     
    8080 
    8181        /** 
    82          * Add a pre-filter to one or more inputs. 
    83          * 
    84          * @chainable 
    85          * @param   callback  filter 
    86          * @param   string    fields to apply filter to, use TRUE for all fields 
    87          * @return  object 
    88          */ 
    89         public function pre_filter($filter, $field = TRUE) 
    90         { 
    91                 if ( ! is_callable($filter)) 
    92                         throw new Kohana_Exception('validation.filter_not_callable'); 
    93  
    94                 $filter = (is_string($filter) AND strpos($filter, '::') !== FALSE) ? explode('::', $filter) : $filter; 
    95  
    96                 if ($field === TRUE) 
    97                 { 
    98                         // Handle "any field" filters 
    99                         $fields = array($this->any_field); 
    100                 } 
    101                 else 
    102                 { 
    103                         // Add the filter to specific inputs 
    104                         $fields = func_get_args(); 
    105                         $fields = array_slice($fields, 1); 
    106                 } 
    107  
    108                 foreach ($fields as $field) 
    109                 { 
    110                         // Add the filter to specified field 
    111                         $this->pre_filters[$field][] = $filter; 
    112                 } 
    113  
    114                 return $this; 
    115         } 
    116  
    117         /** 
    118          * Add a post-filter to one or more inputs. 
    119          * 
    120          * @chainable 
    121          * @param   callback  filter 
    122          * @param   string    fields to apply filter to, use TRUE for all fields 
    123          * @return  object 
    124          */ 
    125         public function post_filter($filter, $field = TRUE) 
    126         { 
    127                 if ( ! is_callable($filter, TRUE)) 
    128                         throw new Kohana_Exception('validation.filter_not_callable'); 
    129  
    130                 $filter = (is_string($filter) AND strpos($filter, '::') !== FALSE) ? explode('::', $filter) : $filter; 
    131  
    132                 if ($field === TRUE) 
    133                 { 
    134                         // Handle "any field" filters 
    135                         $fields = array($this->any_field); 
    136                 } 
    137                 else 
    138                 { 
    139                         // Add the filter to specific inputs 
    140                         $fields = func_get_args(); 
    141                         $fields = array_slice($fields, 1); 
    142                 } 
    143  
    144                 foreach ($fields as $field) 
    145                 { 
    146                         // Add the filter to specified field 
    147                         $this->post_filters[$field][] = $filter; 
    148                 } 
    149  
    150                 return $this; 
    151         } 
    152  
    153         /** 
    154          * Add rules to a field. Rules are callbacks or validation methods. Rules can 
    155          * only return TRUE or FALSE. 
    156          * 
    157          * @chainable 
    158          * @param   string    field name 
    159          * @param   callback  rules (unlimited number) 
    160          * @return  object 
    161          */ 
    162         public function add_rules($field, $rules) 
    163         { 
    164                 // Handle "any field" filters 
    165                 ($field === TRUE) and $field = $this->any_field; 
    166  
    167                 // Get the rules 
    168                 $rules = func_get_args(); 
    169                 $rules = array_slice($rules, 1); 
    170  
    171                 foreach ($rules as $rule) 
    172                 { 
    173                         // Rule arguments 
    174                         $args = NULL; 
    175  
    176                         if (is_string($rule)) 
    177                         { 
    178                                 if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) 
    179                                 { 
    180                                         // Split the rule into the function and args 
    181                                         $rule = $matches[1]; 
    182                                         $args = preg_split('/(?<!\\\\),\s*/', $matches[2]); 
    183  
    184                                         // Replace escaped comma with comma 
    185                                         $args = str_replace('\,', ',', $args); 
    186                                 } 
    187  
    188                                 if (method_exists($this, $rule)) 
    189                                 { 
    190                                         // Make the rule a valid callback 
    191                                         $rule = array($this, $rule); 
    192                                 } 
    193                                 elseif (method_exists('valid', $rule)) 
    194                                 { 
    195                                         // Make the rule a callback for the valid:: helper 
    196                                         $rule = array('valid', $rule); 
    197                                 } 
    198                         } 
    199  
    200                         if ( ! is_callable($rule, TRUE)) 
    201                                 throw new Kohana_Exception('validation.rule_not_callable'); 
    202  
    203                         $rule = (is_string($rule) AND strpos($rule, '::') !== FALSE) ? explode('::', $rule) : $rule; 
    204  
    205                         // Add the rule to specified field 
    206                         $this->rules[$field][] = array($rule, $args); 
    207                 } 
    208  
    209                 return $this; 
    210         } 
    211  
    212         /** 
    213          * Add callbacks to a field. Callbacks must accept the Validation object 
    214          * and the input name. Callback returns are not processed. 
    215          * 
    216          * @chainable 
    217          * @param   string     field name 
    218          * @param   callbacks  callbacks (unlimited number) 
    219          * @return  object 
    220          */ 
    221         public function add_callbacks($field, $callbacks) 
    222         { 
    223                 // Handle "any field" filters 
    224                 ($field === TRUE) and $field = $this->any_field; 
    225  
    226                 if (func_get_args() > 2) 
    227                 { 
    228                         // Multiple callback 
    229                         $callbacks = array_slice(func_get_args(), 1); 
    230                 } 
    231                 else 
    232                 { 
    233                         // Only one callback 
    234                         $callbacks = array($callbacks); 
    235                 } 
    236  
    237                 foreach ($callbacks as $callback) 
    238                 { 
    239                         if ( ! is_callable($callback, TRUE)) 
    240                                 throw new Kohana_Exception('validation.callback_not_callable'); 
    241  
    242                         $callback = (is_string($callback) AND strpos($callback, '::') !== FALSE) ? explode('::', $callback) : $callback; 
    243  
    244                         // Add the callback to specified field 
    245                         $this->callbacks[$field][] = $callback; 
    246                 } 
    247  
    248                 return $this; 
    249         } 
    250  
    251         /** 
    252          * Validate by processing pre-filters, rules, callbacks, and post-filters. 
    253          * All fields that have filters, rules, or callbacks will be initialized if 
    254          * they are undefined. Validation will only be run if there is data already 
    255          * in the array. 
    256          * 
    257          * @return bool 
    258          */ 
    259         public function validate() 
     82         * Returns the ArrayObject values, removing all inputs without rules. 
     83         * 
     84         * @return  array 
     85         */ 
     86        public function safe_array() 
    26087        { 
    26188                // All the fields that are being validated 
     
    26895                )); 
    26996 
     97                $safe = array(); 
     98                foreach ($all_fields as $i => $field) 
     99                { 
     100                        // Ignore "any field" key 
     101                        if ($field === $this->any_field) continue; 
     102 
     103                        // Make sure all fields are defined 
     104                        $safe[$field] = isset($this[$field]) ? $this[$field] : NULL; 
     105                } 
     106 
     107                return $safe; 
     108        } 
     109 
     110        /** 
     111         * Add a pre-filter to one or more inputs. 
     112         * 
     113         * @chainable 
     114         * @param   callback  filter 
     115         * @param   string    fields to apply filter to, use TRUE for all fields 
     116         * @return  object 
     117         */ 
     118        public function pre_filter($filter, $field = TRUE) 
     119        { 
     120                if ( ! is_callable($filter)) 
     121                        throw new Kohana_Exception('validation.filter_not_callable'); 
     122 
     123                $filter = (is_string($filter) AND strpos($filter, '::') !== FALSE) ? explode('::', $filter) : $filter; 
     124 
     125                if ($field === TRUE) 
     126                { 
     127                        // Handle "any field" filters 
     128                        $fields = array($this->any_field); 
     129                } 
     130                else 
     131                { 
     132                        // Add the filter to specific inputs 
     133                        $fields = func_get_args(); 
     134                        $fields = array_slice($fields, 1); 
     135                } 
     136 
     137                foreach ($fields as $field) 
     138                { 
     139                        // Add the filter to specified field 
     140                        $this->pre_filters[$field][] = $filter; 
     141                } 
     142 
     143                return $this; 
     144        } 
     145 
     146        /** 
     147         * Add a post-filter to one or more inputs. 
     148         * 
     149         * @chainable 
     150         * @param   callback  filter 
     151         * @param   string    fields to apply filter to, use TRUE for all fields 
     152         * @return  object 
     153         */ 
     154        public function post_filter($filter, $field = TRUE) 
     155        { 
     156                if ( ! is_callable($filter, TRUE)) 
     157                        throw new Kohana_Exception('validation.filter_not_callable'); 
     158 
     159                $filter = (is_string($filter) AND strpos($filter, '::') !== FALSE) ? explode('::', $filter) : $filter; 
     160 
     161                if ($field === TRUE) 
     162                { 
     163                        // Handle "any field" filters 
     164                        $fields = array($this->any_field); 
     165                } 
     166                else 
     167                { 
     168                        // Add the filter to specific inputs 
     169                        $fields = func_get_args(); 
     170                        $fields = array_slice($fields, 1); 
     171                } 
     172 
     173                foreach ($fields as $field) 
     174                { 
     175                        // Add the filter to specified field 
     176                        $this->post_filters[$field][] = $filter; 
     177                } 
     178 
     179                return $this; 
     180        } 
     181 
     182        /** 
     183         * Add rules to a field. Rules are callbacks or validation methods. Rules can 
     184         * only return TRUE or FALSE. 
     185         * 
     186         * @chainable 
     187         * @param   string    field name 
     188         * @param   callback  rules (unlimited number) 
     189         * @return  object 
     190         */ 
     191        public function add_rules($field, $rules) 
     192        { 
     193                // Handle "any field" filters 
     194                ($field === TRUE) and $field = $this->any_field; 
     195 
     196                // Get the rules 
     197                $rules = func_get_args(); 
     198                $rules = array_slice($rules, 1); 
     199 
     200                foreach ($rules as $rule) 
     201                { 
     202                        // Rule arguments 
     203                        $args = NULL; 
     204 
     205                        if (is_string($rule)) 
     206                        { 
     207                                if (preg_match('/^([^\[]++)\[(.+)\]$/', $rule, $matches)) 
     208                                { 
     209                                        // Split the rule into the function and args 
     210                                        $rule = $matches[1]; 
     211                                        $args = preg_split('/(?<!\\\\),\s*/', $matches[2]); 
     212 
     213                                        // Replace escaped comma with comma 
     214                                        $args = str_replace('\,', ',', $args); 
     215                                } 
     216 
     217                                if (method_exists($this, $rule)) 
     218                                { 
     219                                        // Make the rule a valid callback 
     220                                        $rule = array($this, $rule); 
     221                                } 
     222                                elseif (method_exists('valid', $rule)) 
     223                                { 
     224                                        // Make the rule a callback for the valid:: helper 
     225                                        $rule = array('valid', $rule); 
     226                                } 
     227                        } 
     228 
     229                        if ( ! is_callable($rule, TRUE)) 
     230                                throw new Kohana_Exception('validation.rule_not_callable'); 
     231 
     232                        $rule = (is_string($rule) AND strpos($rule, '::') !== FALSE) ? explode('::', $rule) : $rule; 
     233 
     234                        // Add the rule to specified field 
     235                        $this->rules[$field][] = array($rule, $args); 
     236                } 
     237 
     238                return $this; 
     239        } 
     240 
     241        /** 
     242         * Add callbacks to a field. Callbacks must accept the Validation object 
     243         * and the input name. Callback returns are not processed. 
     244         * 
     245         * @chainable 
     246         * @param   string     field name 
     247         * @param   callbacks  callbacks (unlimited number) 
     248         * @return  object 
     249         */ 
     250        public function add_callbacks($field, $callbacks) 
     251        { 
     252                // Handle "any field" filters 
     253                ($field === TRUE) and $field = $this->any_field; 
     254 
     255                if (func_get_args() > 2) 
     256                { 
     257                        // Multiple callback 
     258                        $callbacks = array_slice(func_get_args(), 1); 
     259                } 
     260                else 
     261                { 
     262                        // Only one callback 
     263                        $callbacks = array($callbacks); 
     264                } 
     265 
     266                foreach ($callbacks as $callback) 
     267                { 
     268                        if ( ! is_callable($callback, TRUE)) 
     269                                throw new Kohana_Exception('validation.callback_not_callable'); 
     270 
     271                        $callback = (is_string($callback) AND strpos($callback, '::') !== FALSE) ? explode('::', $callback) : $callback; 
     272 
     273                        // Add the callback to specified field 
     274                        $this->callbacks[$field][] = $callback; 
     275                } 
     276 
     277                return $this; 
     278        } 
     279 
     280        /** 
     281         * Validate by processing pre-filters, rules, callbacks, and post-filters. 
     282         * All fields that have filters, rules, or callbacks will be initialized if 
     283         * they are undefined. Validation will only be run if there is data already 
     284         * in the array. 
     285         * 
     286         * @return bool 
     287         */ 
     288        public function validate() 
     289        { 
     290                // All the fields that are being validated 
     291                $all_fields = array_unique(array_merge 
     292                ( 
     293                        array_keys($this->pre_filters), 
     294                        array_keys($this->rules), 
     295                        array_keys($this->callbacks), 
     296                        array_keys($this->post_filters) 
     297                )); 
     298 
    270299                foreach ($all_fields as $i => $field) 
    271300                {