Hello. What i want to achieve is to pass a model to controller, which will be loaded only if the slug param in route is in format: "id-name" and both of them are correct for some record.
Here is the example URL: "hostname/post/edit/10-some-post-name" where in the last part "10" is the post id and "some-post-name" is some other index in table.
Here is what I've got. It is working but I wonder if there is a more native way of implementing this. I am aware that in 2.1.0 there is something like model binding but thats not the thing i want, since I want this to be strict connection of two table indexes.
$route->add('hostname/post/edit/{post}', 'Posts::edit');
class PostsController
{
public function beforeExecuteRoute($dispatcher)
{
// One of the route parameters must be named as controller's default model
// so we will know that it is our slug.
// Just like :int and :controller modifiers does
if (($slug = $dispatcher->getParam('post', 'string')) !== null) {
if (preg_match('/^([0-9]+)-([a-z0-9-]+)$/', $slug, $matches)) {
$post = Posts::findFirst([
'id' => $matches[1],
'title' => str_replace('-', ' ', $matches[2])
]);
if ($post) {
$dispatcher->setParam('post', $post);
return true;
}
}
$this->view->disable();
$this->flashSession->error('The requested post does not exist');
$this->response->redirect(['for' => 'post-search']);
return false;
}
return true;
}
public function editAction(Posts $post)
{
// This time $post is not in zombie state
// which can happen when using model binding
}
}