Cakephp - 确保动作之间的单向流动的最佳方法是什么?

时间:2011-12-14 16:05:12

标签: cakephp

我正在处理的其中一个网站中的用户注册是一个多步骤的过程,需要来自同一控制器的各种操作,甚至来自不同的控制器。

确保用户在流程开始时启动的最佳方法是什么,并确保用户在访问步骤2之前已完成步骤1?我了解新用户不会知道这些操作的网址,但仍然可以。

我应该使用会话变量吗?或者也许在每个动作开始时检查引用者?

由于

1 个答案:

答案 0 :(得分:1)

<强>路线

首先,由于您提到了多个控制器,因此可能值得考虑创建路由以使注册过程的URL看起来用户友好且流畅:

Router::connect('/register', array('controller' => 'users', 'action' => 'register'));
Router::connect('/register/step1', array('controller' => 'profile', 'action' => 'add'));
Router::connect('/register/step2', array('controller' => 'users', 'action' => 'verify'));

完成上述操作后,它应该使流逻辑更清晰。

单一控制器操作

向导最直接的方法之一就是简单地将$step参数传递给控制器​​操作:

public function register($step) {
    if ($step == 'profile') {
        // do stuff
        if ($hasProfile) {
           $this->redirect(array('verify'));
        }
    }
    if ($step == 'verify') {
        if (!$hasProfile) {
           return $this->redirect(array('profile'));
        }
        // do stuff
    }
    if ($step == 'done') {
        if (!$hasProfile) {
           return $this->redirect(array('profile'));
        }
        if (!$hasVerified) {
           return $this->redirect(array('verify'));
        }
        // do stuff
    }
    $this->redirect('profile'); // default step
}

这种方法可能不适用于您的应用程序,但在解决问题之前,最好将问题考虑在最简单的状态,以便您可以保持任何不必要的复杂性。

<强>会话

我很想使用用户的会话来坚持已经完成哪些步骤,因为不建议您信任从客户端收到的内容。 (客户端为每个请求提交会话ID,但会话存储是服务器端)。具体如何,这取决于您的实施:

$this->Session->write('Auth.registration_step', '2');

一种方法可能是存储步骤编号,每个操作都可以

  1. 更新步骤编号并在完成时重定向
  2. 强制执行步骤编号,并在用户尝试向前跳过时重定向回上一步。
  3. 存储所涉及的步骤列表会很有帮助,因此每个操作都可以重用逻辑:

    public function enforceRegistrationFlow() {
        $flow = array(
            1 => array('controller' => 'users', 'action' => 'register'),
            2 => array('controller' => 'profile', 'action' => 'add'),
            3 => array('controller' => 'users', 'action' => 'verify')
        );
        $step = $this->Session->read('Auth.registration_step');
        if ($flow[$step] !== /* current controller/action */) {
            $this->redirect($flow[$step]);
        }
    }
    

    最后,有一些不同质量的wizard components试图为你做上述事情,但我不能保证它们有效(特别是跨多个控制器)或者它们会帮助你找到工作做得更快。 :)