Edit: This is an edited answer after I realized my last answer was flawed when it came to ArticlesConntroller::redirect
For anyone who has managed to read this entire question/comments and care to know the answer. I figured out a solution thanks to Jeztah's assistance whom I will be awarding this bounty to. One of the issues giving me a hard time was the fact that a page could have 2 URLs. For example: http://www.domain.com/potc or http://www.domain.com/movies/106. Basically I used a combination of mine and Jeztah's ideas.
First, I have to perform a check in the routes.php to see if the first param after the .com matches a page's shortcut "link" (example: http://www.domain.com/potc = potc).
// get params of URL
$requestURI = explode('/', $_SERVER['REQUEST_URI']);
$scriptName = explode('/',$_SERVER['SCRIPT_NAME']);
for($i= 0;$i < sizeof($scriptName);$i++) {
if ($requestURI[$i] == $scriptName[$i]) {
unset($requestURI[$i]);
}
}
$param = array_values($requestURI);
// only concerned about first param
$param1 = $param[0];
// do the following routes if url != http://www.domain.com/users/* or http://www.domain.com
if($param1 != "users" && $param1){
// convert http://www.domain.com/assassins-creed to "assassins creed"
$pagelink = str_replace('-', ' ', $param1);
$pagesModel = ClassRegistry::init('Page');
// check if there is a page whose "link" matches converted link, if so, get the field "id"
$matched_page_id = $pagesModel->field('id', array('Page.link LIKE' => "$pagelink"));
// if there is a match, route as follows
if($matched_page_id){
// Jeztah's way with some modifications
// domain.com/potc/articles/edit/1
Router::connect(
'/:link/:controller/:action/:id',
array('page_id' => $matched_page_id, 'category' => 0),
array(
'pass' => array('id', 'link', 'category', 'page_id'),
'link' => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
'persist' => array('link'),
'id' => '[0-9]+'
)
);
// domain.com/potc/articles/1
Router::connect(
'/:link/:controller/:id',
array('action' => 'view', 'page_id' => $matched_page_id, 'category' => 0),
array(
'pass' => array('id', 'link', 'category', 'page_id'),
'link' => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
'persist' => array('link'),
'id' => '[0-9]+'
)
);
// domain.com/potc/articles/add
Router::connect(
'/:link/:controller/:action',
array('page_id' => $matched_page_id, 'category' => 0),
array(
'pass' => array('link', 'category', 'page_id'),
'link' => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
'persist' => array('link'),
'action' => 'add|uncategorized',
)
);
// domain.com/potc/articles OR domain.com/articles/page:2
Router::connect(
'/:link/:controller/*',
array('action' => 'index', 'page_id' => $matched_page_id, 'category' => 0),
array(
'pass' => array('link', 'category', 'page_id'),
'link' => '[a-z0-9]{1}([a-z0-9\-]{2,}[a-z0-9]{1})?',
'persist' => array('link'),
)
);
} // end if first param matches a page's "link" shortcut
} // end if first param is not users and is not empty
// do some general site routing
// do some general site routing
// now route for page's that do not have a link shortcut (example: http://www.domain.com/movies/106)
// domain.com/movies/106/articles/edit/1
Router::connect(
'/:category/:page_id/:controller/:action/:id',
array('link' => '0'),
array(
'pass' => array('id', 'link', 'category', 'page_id'),
'page_id' => '[0-9]+',
'id' => '[0-9]+'
)
);
// domain.com/movies/106/articles/1
Router::connect(
'/:category/:page_id/:controller/:id',
array('action' => 'view', 'link' => '0'),
array(
'pass' => array('id', 'link', 'category', 'page_id'),
'page_id' => '[0-9]+',
'id' => '[0-9]+'
)
);
// domain.com/movies/106/articles/add
Router::connect(
'/:category/:page_id/:controller/:action',
array('link' => '0'),
array(
'pass' => array('link', 'category', 'page_id'),
'page_id' => '[0-9]+',
'action' => 'add|uncategorized'
)
);
// domain.com/movies/106/articles OR domain.com/movies/106/articles/page:2
Router::connect(
'/:category/:page_id/:controller/*',
array('action' => 'index', 'link' => '0'),
array(
'pass' => array('link', 'category', 'page_id', 'controller'),
'page_id' => '[0-9]+'
)
);
because page_id is being passed in both the :link routing and the :category routing, I don't have to have a component that get's the page's id as suggested.
Now in my ArticlesController
public function index($link = null, $category = null, $page_id = null, $controller = null) {
if($page_id){
// display all articles for a particular page if on
// http://www.domain.com/potc/articles or http://www.domain.com/movies/106/articles
$this->set('articles', $this->paginate('Article', array('Article.page_id' => $page_id, 'Article.status <= 5')));
}
else{
// display all articles if on http://www.domain.com/articles
$this->set('articles', $this->paginate('Article', array('Article.status <= 5')));
}
} // end index function
public function view($id = null, $link = null, $category = null, $page_id = null) {
$this->Article->id = $id;
$article_page = $this->Article->field('page_id', array('id =' => $id));
if (!$this->Article->exists()) {
$this->Session->setFlash('This article does not exist');
// using PageLinkRedirect function of my custom component,
// determine where to redirect. Either to "potc/articles" or
// "movies/106/articles";
$this->redirect('../'.$this->CustomPage->PageLinkRedirect($link, $category, $page_id).'/articles', null, true);
}
elseif($article_page != $page_id) {
$this->Session->setFlash('Invalid article for this page');
// using PageLinkRedirect function of my custom component,
// determine where to redirect. Either to "potc/articles" or
// "movies/106/articles";
$this->redirect('../'.$this->CustomPage->PageLinkRedirect($link, $category, $page_id).'/articles', null, true);
}
else{
$this->set('title_for_layout', $this->Article->field('title', array('id =' => $id)));
$this->set('article', $this->Article->read(null, $id));
$this->set('comments', $this->paginate($this->Article->Comment, array('Comment.module_id' => $this->viewVars['module_id'], 'Comment.post_id' => $id)));
} // end else
} // end view function
My pagination is stored in an element but I load the element at the bottom of the Articles index.ctp view
<?php echo $this->element('all/pagination', array('pagination_url' => 'articles')); ?>
I would place the same code for each of my different controllers but change out the word "articles" (example : "reviews", "news/topics", etc)
My pagination.ctp element looks like this
<?php
if($this->params['paging'][key($this->params['paging'])]['pageCount'] > 1){
$pagination_class = "pagination_enabled";
}
else{
$pagination_class = "pagination_disabled";
}
?>
<div class="<?php echo $pagination_class; ?>">
<?php echo $this->Paginator->counter(array(
'format' => __('Page {:page} of {:pages}, showing {:current} records out of {:count} total, starting on record {:start}, ending on {:end}')
));
?>
<ul>
<?php
// $link is set in AppController from the link param, same with category and page_id
if($link){
$this->Paginator->options = array('url' => array('controller' => null, $link, $pagination_url));
// This outputs http://www.domain.com/potc/articles where articles
// is from the passed $pagination_url when I loaded the element
// in my Articles index.ctp view. I have to set controller = null
// or else the link will output as http://www.domain.com/articles/potc/articles
}
else{
$this->Paginator->options = array('url' => array('controller' => null, 'link' => null, $category, $page_id, $pagination_url));
// This outputs http://www.domain.com/movies/106/articles where articles
// is from the passed $pagination_url when I loaded the element
// in my Articles index.ctp view. I have to set controller = null AND
// link = null or else the link will output as
// http://www.domain.com/articles/0/movies/9/articles
}
echo $this->Paginator->prev('< ' . __('previous'), array('tag' => 'li'), null, array('class' => 'prev disabled'));
if($this->Paginator->numbers){echo $this->Paginator->numbers(array('tag' => 'li', 'separator' => ''));}
echo $this->Paginator->next(__('next') . ' >', array('tag' => 'li'), null, array('class' => 'next disabled'));
?>
</ul></div>