0

Is there any way to write a Zend route with dynamic composite action, meaning an action that combines more than one matched pattern or a combination of a matched pattern with a static text?

Example:

uri -> desired action
/company/unique-product-code/overview -> product-overview
/company/unique-product-code/gallery -> product-gallery
/company/unique-product-code/... -> product-...

Current code (that does not work):

$regexp = new Zend_Controller_Router_Route_Regex(
    '^(company)/([a-z-]+)/([a-z-]+)/?',
    array(),
    array(1 => 'controller', 2 => 'productCode', 'product-3' => 'action')
);
i--
  • 4,349
  • 2
  • 27
  • 35

2 Answers2

1

I have a found a few answers to your question. I guess it all depends on how you want to structure your Zend Framework Software.

From my understanding, you have a controller called Company. Then, it has various actions that include productOverviewAction(), etc.

So, here are a few 'almost there' solutions - and then I'll solve your current dilema. :)

First Possible Answer

You may want to use the controller Company for company specific information. Perhaps you'll make a controller called Product for product information. Then, you would actually want to go to something like /product/[unique-id]/overview - nice URL. Here's the route to match that:

$route = new Zend_Controller_Router_Route(
    'product/:productCode/:action',
    array(
        'controller'=>'product'
    )
);

As you see, it's not even a regular expression, so it can be fast!

Second Possible Answer

The reason you need the regular expression is because the action does not match the url, but is made of part of it. However, let's say you changed Company::productOverviewAction() to Company::OverviewAction() - you then could use this route:

$route = new Zend_Controller_Router_Route(
    'company/:productCode/:action',
    array(
        'controller'=>'company'
    )
);

However, I know that's not exactly what you asked...

The Almost Exact Answer

Without doing modifications to the routing class, you can use the following router:

$route = new Zend_Controller_Router_Route(
    'company/:productCode/:action',
    array(
        'controller'=>'company'
    )
);

And then, since it gets directed to each action, you can proxy the actions in the CompanyController. For example:

public function overviewAction()
{
    return $this->productOverviewAction();
}

*Note: I did not use _forward() as not to redispatch (I think that happens...)

Best of luck!

Aaron Saray
  • 1,178
  • 6
  • 19
  • I do currently use your solution #2, which was also mentioned in the answer by @TimFountain which I implemented before asking this question. However, I chose to ask it exactly due to now knowing if solution to it is even possible. +1 for taking the time and for the details. – i-- Jun 06 '13 at 03:26
  • Thanks! I thought through it and I really WANTED to solve it - but I kept thinking - its just not gonna work without creating a brand new router... glad you have something that works. :) – Aaron Saray Jun 15 '13 at 23:40
0

I don't actually think this is possible with the standard route classes. You could either extend the router, extend the regexp route class or use a controller plugin to manipulate the matched action name; but really it would be much easier if you could change the action names in your controller to match the actions in the URLs.

Tim Fountain
  • 33,093
  • 5
  • 41
  • 69
  • Thanks. I will give some time to this question to hang and do some more research before marking it as answered. – i-- Jun 05 '13 at 20:11