EllisLab text mark
Advanced Search
     
Url Segment Validation
Posted: 28 April 2010 06:43 AM   [ Ignore ]
Avatar
Joined: 2007-08-10
71 posts

I wanted something similar to form validation for validating url segments.  Basically to be able to use any form validation function, helper, php or callback functions to validate passed data. 

I have seen countless programmers not check data passed via the url and leading to broken CI pages…for example if they don’t check that they actually got a database result when using an id passed via the url that is not what was expected. 

It’s handy for times you want to check that a passed user id is the current logged in user.  Any function you want to use you can…you can even use the 2nd argument like match[1].  You can also pass FALSE as the site url and it will return the FALSE result.

In this example I immediately redirect with an error if one of the checks fails but it uses my set_message() function.  So just take that out or add your own function for setting the user message.

This could be further enhanced to use the validation language capabilities and maybe added to the url class and allow you to save rules in a config file.

/** 
* Validates data passed via the url by segment number. 
* Redirects on fail to specified site url or returns result
* if the passed $site_url param is bool FALSE.  Returns the segment 
* data on success or returns the formatted data if a prepping function was used.
* @param string 
* @param string 
* @param string 
* @return bool or data 
*/ 
 
function validate_segment($segment$rules$site_url TRUE)
{
        $CI 
= &get;_instance();    
        
$CI->load->library('form_validation');
        
$data $CI ->uri->segment($segment);
        
        
$rules explode('|',$rules);
        
        if(!
in_array('required'$rules) && $data == '')
        
{
            
return $data;
        
}        
    
        
if (in_array('required'$rules) AND $data == '')
        
{
            set_message
('The url has missing data.','error');
                
            if(
$site_url)
            
{
                $site_url 
is_string($site_url) ? $site_url '';
                
redirect($site_url);
            
}
        }
        
// --------------------------------------------------------------------
        // Cycle through each rule and run it
        
foreach ($rules As $rule)
        
{
            
if($rule == 'required')
            
{
                
continue;
            
}
            
            
// Is the rule a callback?            
            
$callback FALSE;
            if (
substr($rule09) == 'callback_')
            
{
                $rule 
substr($rule9);
                
$callback TRUE;
            
}
            
            
// Strip the parameter (if exists) from the rule
            // Rules can contain a parameter: max_length[5]
            
$param FALSE;
            if (
preg_match("/(.*?)\[(.*?)\]/"$rule$match))
            
{
                $rule    
$match[1];
                
$param    $match[2];
            
}
            
            
// Call the function that corresponds to the rule
            
if ($callback === TRUE)
            
{
                
if ( ! method_exists($CI$rule))
                
{         
                    $validates 
FALSE;
                
}
                
                
if($param)
                
{
                    $result 
$CI->$rule($data$param);    
                
}                        
                
else
                
{
                    $result 
$CI->$rule($data);
                
}
    
            }
            
else
            
{                
                
if ( ! method_exists($CI->form_validation$rule))
                
{
                    
// If our own wrapper function doesn't exist we see if a native PHP function does. 
                    // Users can use any native PHP function call that has one param.
                    
if (function_exists($rule))
                    
{
                        
if($param)
                        
{
                            $result 
$rule($data$param);    
                        
}                        
                        
else
                        
{
                            $result 
$rule($data);    
                        
}
                    }
                    
                }
                
else
                
{
                    
if($param)
                    
{
                        $result 
$CI->form_validation->$rule($data$param);
                    
}
                    
else
                    
{
                        $result 
$CI->form_validation->$rule($data);
                    
}
                    
                }
            }
            
            
//is it a bool or did the function change the data and send it back
            
$data = (is_bool($result)) ? $data $result;
            
            
// Did the rule test negatively?  If so, grab the error.    
            
if(is_bool($result) && $result === FALSE)
            
{
                
if($site_url)
                
{
                    $site_url 
is_string($site_url) ? $site_url '';
                    
set_message('The url has incorrect data.','error');
                    
redirect($site_url);
                
}
                
                
return $data;                
            
}
    
        }
        
    
return $data;

Usage:

$id validate_segment('3''required|is_natural_no_zero');
$user_id validate_segment('4''required|is_natural_no_zero|is_admin|is_current_user');
$page_name validate_segment('5''alpha_dash'); 

That’s 3 short lines of code to run 7 validation functions and redirect with a message if any of the passed data is not what you wanted.

Let me know if anyone finds it useful.  It’s not bug tested at all yet but seems to be working so far.

 Signature 

—————————————————
More Snippets and Code On My Blog | Validate Your Url Segments

 
Posted: 15 June 2010 12:41 AM   [ Ignore ]   [ # 1 ]   [ Rating: 0 ]
Joined: 2010-01-27
29 posts

This is great, thanks for sharing!

 
Posted: 15 June 2010 06:23 AM   [ Ignore ]   [ # 2 ]   [ Rating: 0 ]
Avatar
Joined: 2007-06-06
511 posts

Thanks, this is great!

 Signature 

In need for a good host for your Codeigniter Apps? Try Webfaction! It’s fast, reliable, technically sound, in the USA, EU and Asia.

 
Posted: 21 April 2011 08:15 PM   [ Ignore ]   [ # 3 ]   [ Rating: 0 ]
Avatar
Joined: 2007-07-14
28 posts

Thanks!! This is exactly what I was looking for! Will give it a try!

 Signature 

feedbleed.com - Saving music… one download at a time.
mmmmail.com - Disposable Email to RSS service.

 
Posted: 22 April 2011 01:37 PM   [ Ignore ]   [ # 4 ]   [ Rating: 0 ]
Avatar
Joined: 2007-07-14
28 posts

Hey!...

After reviewing your helper and seeing it was pretty much a copy of form_validation->_execute(), I started hacking some code and ended up with my own version.

I think it’s a bit simpler because I tried to keep code to a minimum by extending form_validation instead of writing a helper.
I guess it could be considered a big hack / slimmed down version of form_validation->run()

For flexibility I also added a callback and some default error message reformatting… but I guess that could be removed if not required.

I have no idea if doing the same thing by extending uri class would be possible… (since form_validation->_execute() is private i guess not).

Haven’t tested it too much yet but it seems to work fine on 2.0.2

<?php if (!defined('BASEPATH')) exit('No direct script access allowed'); }

/**
 * MY_Form_Validation Class
 *
 * Extends Validation library
 *
 * Adds generic validation() method to allow variable validation.
 *
 */

class MY_Form_validation extends CI_Form_validation
{

    
function __construct(){
        parent
::__construct();
    
}

    
/**
     * Executes the Validation routines on a var instead of _POST
     *
     * @access    public
     * @param    mixed        Single value or array of values to validate.
     * @param    string        String of cascading rules.
     * @param    function    Callback function with error string as parameter.
     * @return    boolean        True on success, false on fail.
     */
    
function validate($var$rules$callback=NULL)
    
{
        
// Load the language file containing error messages
        
$this->CI->lang->load('form_validation');
    
        
// Let's fake the required variables
        
$is_array FALSE;
        if(
is_array($var))
        
{
            $is_array 
TRUE;
        
}
        
        $row 
= array('field'=>'fake''label'=>'fake''rules'=>$rules'is_array'=>$is_array'keys'=>array(), 'postdata'=>NULL'error'=>'' );                
        
$this->_field_data['fake']['postdata'$var;
        
        
// Test for errors exactly like run() does...
        
$this->_execute($rowexplode('|'$row['rules']), $this->_field_data['fake']['postdata']);
        
        
// We have an error!
        
if ( isset($this->_field_data['fake']['error']) )
        
{
            
// Slightly reformat the default error messages
            
$error ucfirststr_replace'The fake field ' '' ,  $this->_field_data['fake']['error'));
            
            
// Callback func
            
if(is_callable($callback))
            
{
                call_user_func
($callback$error);
            
}
            
return FALSE;
        
}
        
return TRUE;
    
}

}

/* end file */ 


Simple usage with uri segment..

if( !$this->form_validation->validate($this->uri->segment(n), 'required|numeric|less_than[100]') )
{
    
echo 'Less than 100 please!!';

   
and using callback to log & redirect…

$this->form_validation->validate(array('10.0.0.z',''), 'required|valid_ip', function($error){ log_message('error'$error); show_error($error); ); 
 Signature 

feedbleed.com - Saving music… one download at a time.
mmmmail.com - Disposable Email to RSS service.

 
Posted: 25 February 2012 11:54 AM   [ Ignore ]   [ # 5 ]   [ Rating: 0 ]
Joined: 2011-09-07
6 posts

you can use the form validation class for this. just load it and call the validation function you need using it like any other class:
$this->load->library(‘form_validation’);
if($this->form_validation->alpha_numeric($this->uri->segment(2)))
{
  //do something…
}

 
Posted: 28 June 2012 05:15 AM   [ Ignore ]   [ # 6 ]   [ Rating: 0 ]
Joined: 2012-06-01
31 posts

I’ve just used your function. Simply perfect. Thanks for sharing