O que devo fazer com o Kohana 3 para fazer com que os hífens das ações da rota mudem para sublinhados?
Pergunta
Considere esta rota em 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'
));
o default-emails
está tentando executar o action_default-emails()
Método que obviamente não existe e não pode existir.
Que parte de Kohana devo se estender para mapear esse hífen em um subliminário internamente?
Devo estar preocupado que, se eu fizer isso, será acessível através de ambos _
e -
rotas delimitadas?
Obrigado.
Solução
O mais simples é hackear Kohana_Request::execute()@1112
$class->getMethod('action_'.$action)->invokeArgs($controller, $this->_params);
mudar para
$class->getMethod('action_'.str_replace('-', '_', $action))->invokeArgs($controller, $this->_params);
Mas você entende que precisa fazer esse patch em cada próxima versão Kohana.
Mais inofensivo pode ser estender 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;
}
}
Não verificou, mas aposto que deveria funcionar.
Outras dicas
Minha solução para Kohana 3.2 para rotear ações hifenizadas para o método sublinhado apropriado:
Estender kohana_route e inserir este código
if($key == 'action')
{
$params[$key] = str_replace('-','_',$value);
}
else
{
$params[$key] = $value;
}
Solução completa: Crie uma rota de arquivo.php no aplicativo/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;
}
}
Como o Kohana 3.3 saiu, esse método não funciona mais. Eu encontrei uma solução que, até agora, funciona para mim.
Ao atualizar para 3.3, você não precisa editar o arquivo de solicitação interno.php. Em vez disso, você pode criar um filtro de rota. Tudo o que você precisa fazer é substituir o hífen na ação por um sublinhado.
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',
));
Obviamente, isso funciona apenas para os métodos. No entanto, se você explorar um pouco mais, poderá criar uma função melhor para o diretório, controlador etc.
Uma atualização do método de Zerkms. Dentro Kohana 3.2, você precisa editar o arquivo system/classes/kohana/request/client/internal.php
linha 106.
Substituir:
$action = $request->action();
Por:
$action = str_replace('-', '_', $request->action());
Não gosto de estruturas de hackers, mas essa é de longe a solução mais simples e confiável. Renomear a ação na classe de rota pode levar a todos os tipos de problemas, porque a ação será chamada de my_action (internamente) e em algum momento da minha ação (nos links).