Kristo
Kristo

Reputation: 125

Kohana 3.3 Route - action not found redirected to default of the controller

currently with Kohana 3.3 default route if i have say controller user and action login and i call /user/login, everything is fine, the action is called and executed.

but now if i change the url to /user/logins, then system does not find any action named as logins and return error "Kohana_HTTP_Exception [ 404 ]: The requested URL user/logins was not found on this server."

my question is if there is a way to force redirect to /user/index (default action) in case there is called an action not found in the controller?

cheers!

Upvotes: 1

Views: 1252

Answers (3)

f1ames
f1ames

Reputation: 1734

EDIT:

So as @Darsstar suggested in comment, it's better to change action in before method in controller than to override execute method. So it goes like this, in your User controller:

protected $default_action = 'index';

public function before()
{
    $action = 'action_'.$this->request->action();
    if (!empty($this->default_action) && !method_exists($this, $action))
    {
        $this->request->action($this->default_action);
    }
}

So if there is no current action and default action is defined it changes current request action to default. You can put this code into main Controller and define only $default_action in subcontrollers.


Old answer:

You should override execute method from Controller class. Normally it looks like this:

public function execute()
{
    // Execute the "before action" method
    $this->before();

    // Determine the action to use
    $action = 'action_'.$this->request->action();

    // If the action doesn't exist, it's a 404
    if ( ! method_exists($this, $action))
    {
        throw HTTP_Exception::factory(404,
            'The requested URL :uri was not found on this server.',
            array(':uri' => $this->request->uri())
        )->request($this->request);
    }

    // Execute the action itself
    $this->{$action}();

    // Execute the "after action" method
    $this->after();

    // Return the response
    return $this->response;
}

Change it to something like this:

public function execute()
{
    // Execute the "before action" method
    $this->before();

    // Determine the action to use
    $action = 'action_'.$this->request->action();

    // If the action doesn't exist, check default action
    if ( ! method_exists($this, $action))
    {
                //Can be hardcoded action_index or $this->default_action set in controller
                $action = 'action_index';

                // If the action doesn't exist, it's a 404
                if ( ! method_exists($this, $action))
                {
                    throw HTTP_Exception::factory(404,
                            'The requested URL :uri was not found on this server.',
                            array(':uri' => $this->request->uri())
                    )->request($this->request);
                }
    }

    // Execute the action itself
    $this->{$action}();

    // Execute the "after action" method
    $this->after();

    // Return the response
    return $this->response;
}

Now if action doesn't exist it checks default action and runs it, or if doesn't exist throws 404.

Upvotes: 1

Spell
Spell

Reputation: 8658

Actually you must override HTTP_Exception_404 class.

You can make a 404 NotFound page there. But if you want to redirect to some page - you need to do next:

class HTTP_Exception_401 extends Kohana_HTTP_Exception_401 {

/**
 * Generate a Response for the 401 Exception.
 * 
 * The user should be redirect to a login page.
 * 
 * @return Response
 */
    public function get_response() 
    {
        $response = Response::factory()
            ->status(401)
            ->headers('Location', URL::site('user/index'));

        return $response;
    }
}

Upvotes: 1

Denis Petrov
Denis Petrov

Reputation: 123

You can override HTTP_Exception_404 class and make a redirect there manually.

Upvotes: 2

Related Questions