Persisting data through legacy routes
Usually when a website is migrated to a new version or system, old URLs will break. To circumvent this problem, legacy URLs are redirected to their new destination through some kind of router. CakePHP offers this functionality through Router::redirect() and the RedirectRoute class. But how do you persist URL parameters (like IDs) to the new URL? It's pretty simple.
When I launched the new version of this site, I had to setup legacy routes for blog posts. The old URLs were structured as so blog/read/[id]/[inflected_title], where the new ones are structured like blog/read/[slug]. From the looks of it, no parameters are the same, so this will require a middleman controller. First, I need to map the redirect using the persist option (this is crucial).
Router::redirect('/blog/read/:id/*', array('controller' => 'jump', 'action' => 'blog'), array(
'id' => '[0-9]+',
'pass' => array('id'),
'persist' => array('id')
));
This route will redirect the old URL to JumpController::blog($id) while passing the ID from the URL as the first argument. The JumpController is used to power my tiny URLs — so it now serves 2 purposes. Next up is defining the action logic.
public function blog($id = null) {
if ($blog = $this->Entry->getById($id)) {
$this->redirect(array('controller' => 'blog', 'action' => 'read', $blog['Entry']['slug']), 301);
}
throw new NotFoundException();
}
When the action is called, the code attempts to find a blog entry that matches the ID. If an entry is found it will redirect with a 301 (Moved Permanently), else it throws a 404 (Not Found). That's all there is too it!