Route Deja Vu

I just had one of those odd moments that happen when you are stuck and are trawling through Google and you come across something you have written. At the moment I have a blessed respite from the usual rubbish at work of sorting out and extending other peoples bad code, and I am writing a pretty big website CMS using CakePHP. (I haven’t touched it for about a month and I had quite forgotten how pleasant it can be to work with.)

I’ve got a bit of a routing issue – well kind of – I have a situation like this:

I have a controller called Products based on a table called products that also uses a table called product_items (products is actually a table of product categories – but this is all in the name of nice urls, product_items contains the actual products)

For example:

  • http://www.somewebsite.com/products – shows you a list of product categories e.g. ‘Pet Foods’
  • http://www.somewebsite.com/products/pet_foods – shows you all the products within the ‘Pet Foods’ category
  • http://www.somewebsite.com/products/pet_foods/chappie – shows you the detail page for chappie

This all works fine – the way I have done it is to do the following, I have set up the following route:


$Route->connect('/products/(.*)', array('controller' => 'products', 'action' => 'index'));

So anything gets pointed at the index method in the controller, my code within the index method looks something like this:


function index($product_cat_url = null, $product_item_url = null) {

		
		
	if($product_cat_url)
			{
                           // check the product cat is valid
                        }

        if($product_item_url)
			{
                           // check the product item is valid
                        }

        etc.

This lets me pass all the actions through a single method – works great – but now I want to add locations so for instance I might have a url like:

  • http://www.somewebsite.com/products/london/pet_foods – shows you all the products within the ‘Pet Foods’ category in london

Obviously I can just add more code in the index method, but then this in itself might get really unwieldy – but it has got me thinking is there a better way of doing this? I was Googling and found the following thread where I used a beforeFilter() to pass it to a different controller – but then I might just end up duplicating loads of code in two methods…