cakephp UsersController::register() function


cakephp UsersController::register() function

我对cakepp很陌生,但我从一开始就喜欢它。经过数小时的研究和教程,我现在觉得能够创建一个符合我要求的User::register()函数。该函数运行良好,但在某些方面我对代码不满意。由于我想确保我很好地理解cakepp的逻辑,我想问你是否有更好的方法来做这件事,或者它的代码是否很好(见评论):

public function register() {
    if ($this->request->is('post')) {
        //setting the data, so that it can be validated 
        $this->User->set($this->request->data);
        //go on if no error occurs    
        if($this->User->validates()) {        
            //creatin a verification code the user has to click in the confirmation email to activate his account
            //i think this is not solved very well, because i set the verification code in 2 variables. 
            //also: is there a better way to set the verification code to the user model than setting $this->request->data['User']['verification_code'] ?
            $vcode = $this->request->data['User']['verification_code'] = sha1($this->request->data['User']['email'].rand(0,100));
            //creating the record in database
            $this->User->create();
            //save, dont validate again
            if ($this->User->save($this->request->data, array('validate' => FALSE))) {
                //sending mail
                $Email = new CakeEmail();
                $Email->from(array('no-reply@'.$_SERVER['SERVER_NAME'] => $this->viewVars['appName']))
                    ->to($this->request->data['User']['email'])
                    ->subject(__('Deine Registrierung bei %s',$this->viewVars['appName']))
                    ->template('register_confirmation','default')
                    ->emailFormat('both')
                    ->viewVars(array(
                        'appName' => $this->viewVars['appName'],
                        'first_name' => $this->data['User']['first_name'],
                        'verificationLink' => Router::url(array('controller' => 'users', 'action' => 'verifyEmail'),true).'?vcode='.$vcode //with the verification code. heres where is need the $vcode variable again. 
                        //i thought it would be pretty ugly to write $this->request->data['User']['verification_code'] again
                    ));
                if($Email->send()) {
                    $this->Session->setFlash(__('Registrierung erfolgreich! Wir haben eine Bestätigungs-E-Mail an %s gesendet. Klicke auf den darinstehenden Link, um dein Konto zu aktivieren.',array('<strong>'.$this->request->data['User']['email'].'</strong>')),'flash_alert_success');  
                    return $this->redirect(array('controller' => 'users', 'action' => 'login'));
                }                     
                $this->Session->setFlash(__('Die E-mail konnte nicht versendet werden. Fordere eine neue Bestätigungs E-Mail an.'),'flash_alert_error');
            }
            $this->Session->setFlash(__('Die Registrierung ist fehlgeschlagen. Bitte versuche es erneut.'),'flash_alert_error');
        } else {
            //ist there a better way to catch and display the validation errors?
            $errmsg = __('%sDie Registrierung konnte nicht abgeschlossen werden:%s','<strong>','</strong><br />');
            foreach($this->User->validationErrors as $key => $val) {
                $errmsg .= __($val[0]).'<br />';
            }
            $this->Session->setFlash($errmsg,'flash_alert_error');
        }
    }
}

如有任何意见,我们将不胜感激。

提前感谢大家,oligen

体系结构

将电子邮件发送代码移动到一个单独的方法中。好的OOP意味着一个方法只做一项任务,您的注册方法也处理电子邮件发送,将其分离到另一个方法中,并从您的注册方式中调用它。为了能够更好地进行单元测试,我通常会创建一个类似的方法

public function getCakeEmail($config = null) {
    return new CakeEmail($config);
}

在我的AppModel中,很容易在测试中模拟该方法,并返回一个模拟的CakeEmail对象,然后断言该方法对它的调用。

将整个数据处理逻辑移动到模型层中(显示控制器调用模型方法):

public function register() {
    if ($this->request->is('post')) {
        if ($this->User->register($this->request->post)) {
            //...
        } else {
            //...
        }
    }
}

最佳实践

$errmsg, $vcode

不要使用简短的变量名,这一个是可以猜测的,但通常易于阅读和理解的代码比缩短任何内容都要好。那么,为什么不称之为$errorMessage和$verficationCode呢?

if($this->User->validates()) {  

if后面缺少空格,请遵循编码约定。您可以使用类似phpcs的工具来验证您的代码。

MVC违反,除非在视图层,否则您永远不希望在脚本中使用HTML。

$errmsg .= __($val[0]).'<br />';

这里甚至没有使用<br>,使用CSS在元素之间创建空间。<br>换行,不被认为被滥用为创建间距的"设计元素"。不需要运行验证错误数组并添加<br>

如果您遵循约定,如果每个输入字段的验证规则失败,CakePHP应该自动在该字段下面显示错误消息。