Welcome Guest, Not a member yet? Register   Sign In
URI Routing, better way to do that
#1

[eluser]sybrex[/eluser]
Hello!
I have such url:

http://mysite.com/region/category/subcat...new/page_n

Where all these segments are optional which makes a lot of variants like:
Code:
http://mysite.com/
http://mysite.com/region/
http://mysite.com/category/
http://mysite.com/region/category/
...

Region is a string like 'street1', 'street2'..
There are only two categories: 'events', 'places';
Subcategory is a string like 'fun', 'sport'..
New is also a string and can be: 'new' or ''
Page_n is a numeric value

I just want to know if it is the best way to make a controller like this:
Code:
class Postlist extends Controller
{            
    function Postlist()
    {
        parent::Controller();        
    }

    function posts($region = NULL, $category = 'events', $subcategory = NULL, $new = NULL, $page_n = 1)
    {        
    }                
}

and to write rules to all of the variants?
routes.php:
Code:
$route['(:any)/(events|places)/(:any)/(new|)/(:num)'] = 'postlist/posts/$1/$2/$3/$4/$5';
$route['(events|places)/(:any)/(new|)/(:num)'] = 'postlist/posts//$1/$2/$3/$4';
...
#2

[eluser]pistolPete[/eluser]
I suggest using a route like that:
Code:
$route[':any'] = "postlist";
In your postlist controller use the _remap() function, to process
Code:
$this->uri->segment_array()
and find out which parameters are actualle passed.
Have a look at the user guide.
#3

[eluser]Phil Sturgeon[/eluser]
I'd use an associative array, which is explained in the URI class manual.

Then you can do:

Code:
class Postlist extends Controller
{            
    function Postlist()
    {
        parent::Controller();        
    }

    function posts()
    {  
        $args =& func_get_args();
        
        if(array_key_exists('region'))
        {
            // do something special
        }

        // etc
    }                
}

You could extract() args too to get use variables instead of array keys.
#4

[eluser]sybrex[/eluser]
[quote author="pyromaniac" date="1234462923"]I'd use an associative array, which is explained in the URI class manual.
[/quote]

Yes, it is a good way, but as far as I understand my url from this:
http://mysite.com/region/category/subcat...new/page_n
must transform to this:
http://mysite.com/region/region_name/cat...age/page_n
and it is not very nice for me

P.S. Working now on _remap() function, not so easy as I thought at first, many variants Smile
#5

[eluser]xwero[/eluser]
If the url structure is still being discussed maybe you better create a category/region/subcategory structure.

Then you only have to use your last route. Having a catch all first segment should be avoided because all controllers that are not defined in the routes will route to the catch all route.

Your routes are too specific
Code:
$route['(events|places)/(:any)/(new|)/(:num)'] = 'postlist/posts/$1/$2/$3/$4';
only gets triggered by an url like this; events/fun/new/1.
Code:
$route['(events|places)(.*)'] = 'postlist/posts/$1$2';

and then you controller method can look like this
Code:
function posts()
{
   if($this->uri->total_segments() == 1)
   {
      // general category page
   }
   else
   {
       if($this->uri->segment(2) == 'new')
       {
           // new posts in category
       }
       else
       {
          $region = $this->uri->segment(2);
          if($this->uri->segment(3) == 'new')
          {
               // new posts for category/region
          }
          else
          {
              // and so on
          }
       }
   }
}
#6

[eluser]sybrex[/eluser]
[quote author="xwero" date="1234470597"]If the url structure is still being discussed maybe you better create a category/region/subcategory structure.[/quote]
Agree with you, but have to go with the old structure now.

Well, finally I wrote the _remap() function:
Code:
function _remap()
{
    // Set default values
    $region = 'default_region';
    $category = 'events';
    $subcategory = 'default_subcategory';
    $new = FALSE;
    $page = 1;                        
        
    switch ($this->uri->total_segments())
    {
        /*******************
        /region
        /category
        /new
        /page
        *******************/
        case 1:
            $seg = $this->uri->segment(1);                
            if ($seg == 'events' OR $seg == 'places') $category = $seg;                    
            elseif ($seg == 'new') $new = true;
            elseif (is_numeric($seg)) $page = (int)$seg;
            else $region = $seg;                
            break;
        
        /*******************
        /region/place
        /region/new
        /region/page
        /category/new
        /category/page
        /category/subcategory
        /new/page
        *******************/
        case 2:
            $seg1 = $this->uri->segment(1);
            $seg2 = $this->uri->segment(2);
            if ($seg1 == 'events' OR $seg1 == 'places')
            {
                $category = $seg1;
                if ($seg2 == 'new') $new = TRUE;
                elseif (is_numeric($seg2)) $page = (int)$seg2;
                else $subcategory = $seg2;
            }
            elseif($seg1 == 'new')
            {
                $new = TRUE;
                $page = (int)$seg2;
            }
            else
            {
                $region = $seg1;
                if ($seg2 == 'new') $new = TRUE;
                elseif(is_numeric($seg2)) $page = (int)$seg2;
                else $category = $seg2;
            }                
            break;
        
        /*******************
        /region/category/new
        /region/category/page
        /region/category/subcategory
        /region/new/page
        /category/subcategory/page
        /category/subcategory/new
        *******************/
        case 3:
            $seg1 = $this->uri->segment(1);
            $seg2 = $this->uri->segment(2);
            $seg3 = $this->uri->segment(3);
            if ($seg1 == 'events' OR $seg1 == 'places')
            {
                $category = $seg1;
                $subcategory = $seg2;
                if ($seg3 == 'new') $new = TRUE;
                else $page = (int)$seg3;
            }
            else
            {
                $region = $seg1;
                if ($seg2 == 'new')
                {
                    $new = TRUE;
                    $page = (int)$seg3;
                }
                else
                {
                    $category = $seg2;
                    if ($seg3 == 'new') $new = TRUE;
                    else if(is_numeric($seg3)) $page = (int)$seg3;
                    else $subcategory = $seg3;
                }
            }
            break;
        
        /*******************        
        /region/category/subcategory/new
        /region/category/subcategory/page
        /category/subcategory/new/page/
        *******************/
        case 4:
            $seg1 = $this->uri->segment(1);
            $seg2 = $this->uri->segment(2);
            $seg3 = $this->uri->segment(3);
            $seg4 = $this->uri->segment(4);
            if ($seg1 == 'events' OR $seg1 == 'places')
            {
                $category = $seg1;
                $subcategory = $seg2;
                $new = TRUE;
                $page = (int)$seg4;
            }
            else
            {
                $region = $seg1;
                $category = $seg2;
                $subcategory = $seg3;
                if ($seg4 == 'new') $new = TRUE;
                else $page = (int)$seg4;
            }
            break;
        
        /*******************        
        /region/category/subcategory/new/page        
        *******************/
        case 5:
            $region = $this->uri->segment(1);
            $category = $this->uri->segment(2);
            $subcategory = $this->uri->segment(3);
            $new = TRUE;
            $page = (int)$this->uri->segment(5);
            break;            
    }          
}

It works fine, but I begin thinking about my first way of solving the problem again...




Theme © iAndrew 2016 - Forum software by © MyBB