Welcome Guest, Not a member yet? Register   Sign In
Dynamic Route to Specific Controller
#1

[eluser]solepixel[/eluser]
I have a dynamic URI CMS system in place and the user can control the URI of any page. I'm having a slight issue when it comes to pointing a content item to a CI Controller. If i setup the route like this:

$route['some_url_in_cms'] = 'programmed_controller';

It works fine, however what I'd like to happen is all things appended to the URI get appended in the route. So I tried to setup my route like this:

$route['some_url_in_cms/(.*)'] = 'programmed_controller/$1';

I also tried:
$route['some_url_in_cms/(:any)'] = 'programmed_controller/$1';

Neither of these worked even if the URI is:
http://somedomain.com/some_url_in_cms/
and of course the following didn't point to my controller either:
http://somedomain.com/some_url_in_cms/test_sublevel/

So how do I accomplish this. I'm a bit confused why it's not working. Please help!
#2

[eluser]alexanderm[/eluser]
I've been working with routes for the past hour or so to try to get them to do the same thing.

To be sure I understand:
You want www.x.com/.../some_url_in_cms to map to www.x.com/.../programmed_controller.
You also want any following URI to be appended, regardless of whether it's 'function/123' or 'id/123/name/alex'

If this is what you want, then when I was working with a normal CI controller, this worked:

$route['some_url_in_cms/(.+)'] = "$1";, where 'some_url_in_cms' is not the whole url, but the rest of the url after the base url.

If this doesn't work, I don't think your problem is with the syntax in routes.php.

Consequently, I have the same problem. I want to use routes to map api/(.+) to $1, bec I want my api to be common, but I want to have many underlying controllers that actually deal with the requests. I'm using Phil Sturgeon's REST_Controller, and I think the fanciness that maps HTTP requests to methods can't work its magic if routes are involved.
#3

[eluser]pickupman[/eluser]
You may find it helpful to try something like
Code:
$route['some_url_in_cms/(:any)'] = 'programmed_controller/$1';
$route['some_url_in_cms'] = 'programmed_controller';

This will help match if you don't have any segments or slashes after the controller name. By "doesn't work", what is actually happening? Are you getting a CI 404 error, apache 404 error, blank page? Have your tried bumping up your error logging in /application/config/config.php, then checking your /system/logs/ folder?
#4

[eluser]solepixel[/eluser]
Well, after further evaluation of trying to do this, some questions/issues came up, the biggest one being trying to determine URI segments inside the application.

When referencing the URI for the controller, it's no longer "programmed_controller" then slash whatever, it could be any number of URI segments before the methods I need. For example, The Reviews controller has 2 methods:

index() - displays the reviews for the given ID (/reviews/65/) (/reviews/ with no other segments displays 404)
write() - allows a user to write a review for a given ID (/reviews/write/65/)

With the part "reviews" being completely dynamic, it makes it a lot more difficult to determine which URI segment contains the ID and which one contains the method. If the user sets the path to:

$route['products/reviews'] = 'reviews';

That makes the URI /products/reviews/65/ and /products/reviews/write/65/. So now all my references to uri->segment(2) and uri->segment(3) are pointing to the wrong segment.

I tried to use uri->rsegment(2) and uri->rsegment(3) but they didn't seem to work.

The only thing I can think of is to extend the URI library rsegment method and get it to work the way I want. Any ideas/suggestions? Anyone done this before?
#5

[eluser]Buso[/eluser]
if you are sending data via URL, you should get it via the parameters of the method (instead of fetching segment 2 or 3 or anything else)

for this URL: /products/reviews/65

you can get the value 65 like this:

Code:
function reviews($id) {

  // at this point, $id == 65

}
#6

[eluser]pickupman[/eluser]
For what you are doing, you almost need to create routes for each controller that will have rewritten url's. You will probably also need three rules. The routing feature works like mod_rewrite, where CI will take the first match. Therefore, you need to make sure you have them ordered correctly.
1.) uri = /reviews/
2.) url = /reviews/65
3.) uri = /reviews/write/65
In each scenario, you need a way to protect against errant url's say someone uses a product id that doesn't exist. Or where does someone go when they only have /reviews/ without a product id at all?
The rsegment function should work as advertised.

How about you post your actual routes.php file or at least the block of uri routes?
#7

[eluser]solepixel[/eluser]
Ok, my routes are generated dynamically. The code that does it is here:
Code:
list($route,$qs) = (strpos($_SERVER['REQUEST_URI'], '?') !== false) ? explode('?', $_SERVER['REQUEST_URI']) : array($_SERVER['REQUEST_URI'],'');
$uri = $route;
if($uri != '/'){
    $uri = trim($uri, '/');

    $route = trim($route, '/');
    $route = str_replace('-', '_', $route);
}
$path = ($row->controller == '/') ? 'index_controller' : trim($row->controller, '/');

$route_uri = trim($row->uri,'/').'/(.*)';
$DB_ROUTES[$route_uri] = $path.'/$1';

$DB_ROUTES[$route] = $path;

$row is my row from the DB, controller specifies which controller to use for the request, and uri is the customized uri in the CMS and $DB_ROUTES is an array that is merged with the $routes array in the routes.php config file.

The output for the URI /reviews/test/write/65/ is:
Code:
Array
(
    [reviews/test/(.*)] => reviews/$1
    [reviews/test/write/65] => reviews
)

reviews/test is the customized URI, reviews is the controller to handle the request.

Inside my reviews controller, here's the top of the index method:
Code:
function index($uri2='', $uri3='')
{
    echo 'uri2: '.$uri2.'<br />';
    echo 'uri3: '.$uri3.'<br />';
    echo $this->uri->rsegment(1) . ' vs. ' . $this->uri->segment(1).'<br />';
    echo $this->uri->rsegment(2) . ' vs. ' . $this->uri->segment(2).'<br />';
    echo $this->uri->rsegment(3) . ' vs. ' . $this->uri->segment(3).'<br />';
    echo $this->uri->rsegment(4) . ' vs. ' . $this->uri->segment(4).'<br />';
    exit();

This code outputs:
Code:
uri2:
uri3:
reviews vs. reviews
index vs. test
vs. write
vs. 65

As you can see, the URL variables give me nothing when passed into the method. The rsegments only give me the the hard coded routes and segments give me what I expect. So maybe I can hack up the rsegments method and maybe pass a 2nd paramater that gives the ROUTED uri segment, which is what I expect it to do in the first place. I figured it would work like the way CI handles uri segments. If your applications starts at /my/application/, then uri segments start AFTER /my/application/ so uri->segment(1) would return '' instead of 'my'.

Anyway, thanks for helping, i'm definitely open to suggestions. I'm now determined to figure this out.

On a side note, i had a terrible time typing This without $this - Thanks CI!
#8

[eluser]pickupman[/eluser]
Quote:On a side note, i had a terrible time typing This without $this - Thanks CI!
I can't tell you how many times I have done this as well.

Code:
[reviews/test/(.*)] => reviews/$1
[reviews/test/write/65] => reviews

Your routes are backwards, as they will only work for /reviews/test/index(or some other method name.

Should be something like
Code:
$route['reviews/(:any)'] = 'reviews/test/$1';
$route['reviews'] = 'reviews/test/write/65';

The left side of = is what you want to see in the browser, and the right side of = will be what url it will be mapped to CI.
#9

[eluser]solepixel[/eluser]
If the array index is the what's in the browser, and the value is the actual route (i.e. the controller), then I do have it right. The browser reads /reviews/test/write/65/ and the route should actually be reviews/write/65.
#10

[eluser]pickupman[/eluser]
Since you are doing this dynamically, what happens if you use a static route? When you merge the arrays, is the order of the array getting changed?




Theme © iAndrew 2016 - Forum software by © MyBB