开发者

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

开发者 https://www.devze.com 2023-01-26 08:15 出处:网络
Consider this route in bootstrap.php... Route::set(\'crud\', \'staff/<controller>(/<action>(/<id>))\', array(

Consider this route in bootstrap.php...

Route::set('crud', 'staff/<controller>(/<action>(/<id>))', array(
            'controller' => '(activities|users|default-emails)',
            'action' => '(new|view|modify|delete)',
            'id' => '\d+'
    ))->defaults(array(
        'directory' => 'staff',
        'action' => 'view'
    ));

The default-emails is trying to run the action_default-emails() method which obviously doesn't and can't exist.

What part of Kohana should I extend to map that hyphen into a underscore internally?

Should I be concerned that if I 开发者_开发问答do do this, then it will be accessible via both _ and - delimited routes?

Thanks.


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;
    }
}


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.


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).

0

精彩评论

暂无评论...
验证码 换一张
取 消