AKKAweb
AKKAweb

Reputation: 3817

CakePHP: Routing Problems

All,

I am currently using CakePHP to completely revamp my current NEWS site. I have or will transfer all current articles to my new site and they will take on the same article_id as the current site. However, I have realized of the following problem.

My current site uses the following setup as URL:

http://www.mydomain.com/?c=140&a=4388

c=references the category ID and a=references the article ID. My new setup (CakePHP) I take advantage of slugs and now my articles URLs display as:

http://www.mydomain.com/noticia/this-is-an-article-slug

Since, I have noticed, thru webstats, that many of my articles are accessed thru links setup on other sites like Facebook, I thought it would be crucial to create a system/route that will take care of this issue for me.

This is what I am thinking:

  1. Create a route that detects requests similar to what is mentioned above
  2. Make the route pass the a value as parameter to a redirect function in my articles controller, such as articleRedirect($article_id)
  3. This function would then look up in the database for slug based on the passed $article_id and redirect to the new address (See function below)

    // Function in articles controller to redirect old site's article url to 
    // new websites url format
    
    function articleRedirect($article_id = NULL){
        $this->Article->recursive = -1;
        $slug = $this->Article->findById($article_id);        
        if($slug == NULL){
            $this->Session->setFlash('Article not found');
            $this->redirect('/noticias');
        }else{
            $this->redirect('/noticia/'.$slug['Article']['slug']);
        }
    }
    

I think that should work. However, I need some serious help with routing. Can anyone suggest a route I can use.

Thank you very much.

Upvotes: 1

Views: 1004

Answers (2)

AKKAweb
AKKAweb

Reputation: 3817

Thanks for Oldskool for the willingness to help. However, I had trouble implementing it. I decided to stay away from using .htaccess or routes and opted to implement a function in app_controller that will handle it for me as such:

In my app_controller's beforeFilter() I added the following:

//Check old url style as in http://www.bravanews.com/?c=123&a=2345 for redirection
    //to the correct new url style as in http://www.bravanews.com/noticia/news-title-using-slug
    $this->CheckOldUrl();

Then in my app_controller.php I created the following function:

function CheckOldUrl(){
    preg_match("/\?c=(\w+)\&a=(\w+)/i", $_SERVER['REQUEST_URI'], $matches);
    if(!$matches == NULL){
        $this->redirect('/noticias/articleRedirect/'.$matches[2]);
    }
}

If old url the above function will transfer to the articleRedirect function which will then redirect to the right document

// Function in articles controller to redirect old site's article url to 
// new websites url format

function articleRedirect($article_id = NULL){
    $this->Article->recursive = -1;
    $slug = $this->Article->findById($article_id);        
    if($slug == NULL){
        $this->Session->setFlash('Article not found');
        $this->redirect('/noticias');
    }else{
        $this->redirect('/noticia/'.$slug['Article']['slug']);
    }
}

It is probably not the best way to handle this kind of things this way since it makes a call to that function everytime time my site is accessed, but it is working for me without major problems.

Upvotes: 0

Oldskool
Oldskool

Reputation: 34877

The easiest way would be re-model your URL's a little bit to still hold the article ID. For example:

http://www.example.com/noticia/4388/this-is-an-article-slug

Then you can create 1 single RewriteRule to rewrite all old URL's to this new structure and use 1 Route to route them to your controller's action. This way it would only take 2 lines of configuration to migrate old URL's to your new ones. Your route would then look something like this:

Router::connect(
    '/noticia/:article-id/:slug',
    array('controller' => 'noticias', 'action' => 'view'),
    array('pass' => 'article-id'),
    'article-id' => '[0-9]+'
);

That would call the view action of your NoticiasController and pass the article id from the URL to it. The RewriteRule you'd have to add to your .htaccess should look something like this (untested, but just to give you a pointer):

RewriteRule ^/?c=[0-9]+&a=([0-9]+)$ /noticia/$1/

Upvotes: 3

Related Questions