Возможно ли в Cakephp перехватить событие «нет действия» и обработать его в контроллере? - PullRequest
1 голос
/ 01 сентября 2011

Я хотел бы обработать пропущенное действие в одном из моих контроллеров в действии по умолчанию. Теперь поведение по умолчанию - выбросить ошибку. Я хотел бы иметь возможность иметь действие по умолчанию в этом контроллере, которое вызывается и передается имя запрашиваемого действия, чтобы я мог что-то с ним сделать. Теперь я знаю, что вы можете изменить всю недостающую страницу действий, а это не то, что я хочу сделать. Любое подстрекательство к этому было бы здорово, если это невозможно, пожалуйста, дайте мне знать.

Спасибо

Ответы [ 2 ]

2 голосов
/ 01 сентября 2011

В зависимости от степени исключения из ваших обычных действий, изменение в маршрутизации может иметь больше смысла:

Router::connect('/mycontroller/*',
                array('controller' => 'mycontroller', 'action' => 'catchall'));

Если у вас есть некоторые нормальные действия в этом контроллере, определите маршрут для них до этого универсального маршрута, чтобы они обрабатывались нормально.

Если вы действительно хотите поработать с обработкой действий в самом контроллере, вы можете сделать это в beforeFilter:

public function beforeFilter() {
    if (!method_exists($this, $this->action)) {
        unshift($this->params['pass'], $this->action);
        $this->action = 'catchall';
    }
}

По крайней мере, что-то подобное, это просто быстрая непроверенная идея.

1 голос
/ 21 июля 2012

Я столкнулся с той же проблемой. Мне пришлось запретить страницу ошибок HTML по умолчанию для JSON-отвечающего контроллера.

Способ, предложенный @deceze, не работал для меня по нескольким причинам:

  1. После направления с подстановочным знаком на конкретное действие, вызванное действие всегда будет тем, которое вы определили в routes.php. НО действие из URI передается в качестве первого аргумента.
  2. Вы не можете перезаписать $this->action, но вы можете использовать $this->setAction()

Что я сделал:

  1. Направить все вызовы на определенное действие

    Router::connect('/ajax/*', array('controller' => 'ajax', 'action' => 'handle'));
    
  2. Разбор вызова в этом действии

    public function beforeFilter() {
        $this->autoRender = false;
    }
    
    public function index($arg1 = false) {
        return new CakeResponse(array('body' => json_encode(array('foo' => $arg1))));
    }
    
    public function handle($action = '') {
        if (method_exists($this, $action)) {
            return call_user_func_array(array($this,'setAction'),  func_get_args());
        } else {
            return $this->_error();
        }
    }
    
    private function _error() {
        return new CakeResponse(array('body' => json_encode(array('status' => 'error'))));
    }
    

Надеюсь, это кому-нибудь пригодится.

...