What should I do with Kohana 3 to make route actions' hyphens change to underscores?

老子叫甜甜 提交于 2019-12-08 21:22:44

The simplest is to hack Kohana_Request::execute()@1112

$class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);

change to

$class->getMethod('action_'.str_replace('-', '_', $action))->invokeArgs($controller, $this->_params);

But you understand, that you have to do this patch in each next kohana version.

More harmless could be to extend Kohana_Route::matches()

class Route extends Kohana_Route
{
    public function matches($uri)
    {
        $matches = parent::matches($uri);
        if (isset($matches['action']))
        {
            $matches['action'] = str_replace('-', '_', $matches['action'];
        }
        return $matches;
    }
}

Did not check, but I bet it should work.

My solution for Kohana 3.2 for routing hyphenated actions to the appropriate underscored method:
Extend Kohana_Route and insert this code

if($key == 'action')
{
    $params[$key] = str_replace('-','_',$value);
}
else
{
    $params[$key] = $value;
}

Full Solution: Create a file route.php in application/classes/

<?php defined('SYSPATH') or die('No direct script access.');

class Route extends Kohana_Route
{
    public function matches($uri)
    {
        if ($this->_callback)
        {
            $closure = $this->_callback;
            $params = call_user_func($closure, $uri);

            if ( ! is_array($params))
                return FALSE;
        }
        else
        {
            if ( ! preg_match($this->_route_regex, $uri, $matches))
                return FALSE;

            $params = array();
            foreach ($matches as $key => $value)
            {
                if (is_int($key))
                {
                    // Skip all unnamed keys
                    continue;
                }

                // Set the value for all matched keys
                                if($key == 'action')
                                {
                                    $params[$key] = str_replace('-','_',$value);
                                }
                                else
                                {
                                    $params[$key] = $value;
                                }
            }
        }

        foreach ($this->_defaults as $key => $value)
        {
            if ( ! isset($params[$key]) OR $params[$key] === '')
            {
                // Set default values for any key that was not matched
                $params[$key] = $value;
            }
        }

        return $params;
    }
}

Since Kohana 3.3 came out this method no longer works. I have found a solution that, so far, works for me.

When upgrading to 3.3, you don't need to edit the Internal.php request file. Instead, you can create a Route Filter. All you need to do is replace hyphen in the action to an underscore.

Route::set('default', '(<controller>(/<action>(/<id>)))')
    ->filter(function($route, $params, $request) {
        // Replacing the hyphens for underscores.
        $params['action'] = str_replace('-', '_', $params['action']);
        return $params; // Returning an array will replace the parameters.
    })
    ->defaults(array(
         'controller' => 'welcome',
         'action'     => 'index',
    ));

This obviously only works for the methods. However, if you explore a little further, you can create a better function for the directory, controller, etc.

An update to zerkms's method. In Kohana 3.2, you need to edit the file system/classes/kohana/request/client/internal.php line 106.

Replace:

$action = $request->action();

By:

$action = str_replace('-', '_', $request->action());

I dislike hacking frameworks but this is by far the simplest and most reliable solution. Renaming the action in the Route class can lead to all sorts of troubles, because the action will then sometime be called my_action (internally) and sometime my-action (in links).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!