我正在处理的其中一个网站中的用户注册是一个多步骤的过程,需要来自同一控制器的各种操作,甚至来自不同的控制器。
确保用户在流程开始时启动的最佳方法是什么,并确保用户在访问步骤2之前已完成步骤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');
一种方法可能是存储步骤编号,每个操作都可以
存储所涉及的步骤列表会很有帮助,因此每个操作都可以重用逻辑:
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试图为你做上述事情,但我不能保证它们有效(特别是跨多个控制器)或者它们会帮助你找到工作做得更快。 :)