Custom 404 for different cases

It github, for example, there is path for ajax only requests - login/email checking. And when you try open this uri in browser (non-ajax request) you get 404 page, the same page as for nonexistent uri. How to do this right and gracefully in Phalcon? For example I can use

<?
$this->response->setStatusCode(404, "Not Found");
$this->dispatcher->forward(array(
        'controller' => 'error',
        'action'     => '_404',
));
return;

but it is not pretty, because if I want to change action I have to change it in many places where I do 404.



83.5k

You could add that logic to a ControllerBase:

class ControllerBase extends Phalcon\Mvc\Controller
{
    protected function checkAjaxRequired()
    {
        if (!$this->request->isAjax()) {
            $this->response->setStatusCode(404, "Not Found");
            $this->dispatcher->forward(array(
                'controller' => 'error',
                'action'     => '_404',
            ));
            return false;
        }
        return true;
    }
}

Then check if in specific actions:

class ProductsController extends ControllerBase
{
    public function saveAction()
    {
        if ($this->checkAjaxRequired()) {
            //...
        }
    }
}

Another option is create a plugin that check for methods marked with an annotation:

class ProductsController extends Phalcon\Mvc\Controller
{
    /**  
     * @RequireAjax
     */
    public function saveAction()
    {
        //...
    }
}

```php <?php

class CheckAjaxPlugin extends \Phalcon\Mvc\User\Plugin {

public function beforeExecuteRoute($event, $dispatcher)
{

    $annotations = $this->annotations->getMethod(
        $dispatcher->getActiveController(),
        $dispatcher->getActiveMethod()
    );

    //Check if the method has an annotation 'RequireAjax'
    if ($annotations->has('RequireAjax')) {
        if (!$this->request->isAjax()) {
            $this->response->setStatusCode(404, "Not Found");
            $this->dispatcher->forward(array(
                'controller' => 'error',
                'action'     => '_404',
            ));
            return false;
        }
    }

    return true;
}

} ```



21.5k

Thanks, I'll try. Annotations is really pretty thing =)

Sorry for a question but docs are a little bit hard to understanding =) What about merging it with "real" "Not Found"? Call beforeException inside beforeExecute, and then call 404 from beforeException?