How to add email verification on registration Cakephp 3.x
In this tutorial we will add email verification on user register so whenever a new user registered in our site then he will receive an email with confirmation link and after confirmation link click , his account will activate. this tutorial is also for that users that want to learn how to setup email configration in cakephp 3.x. for basic knowledge you can check this post
Send mail using mail class in cakephp 3
SO FOLLOW THESE SIMPLE STEPS TO VERIFY USER EMAIL ON REGISTRATIONFirst we need to add one table with three columns id email and status . you can run below query to create a table
CREATE TABLE `cake`.`users` ( `id` INT NOT NULL AUTO_INCREMENT , `email` VARCHAR(50) NOT NULL , `otp` VARCHAR(50) NOT NULL , `status` INT NOT NULL DEFAULT '0' , PRIMARY KEY (`id`)) ENGINE = InnoDB;
Your database table should look like
In this tutorial we will use gmail for smtp so first we need to configure EmailTransport for gmail. so open rootDirectory/config/app and search for EmailTransport then add new settings like below we add gmail.
'EmailTransport' => [ 'default' => [ 'className' => 'Mail', // The following keys are used in SMTP transports 'host' => 'localhost', 'port' => 25, 'timeout' => 30, 'username' => 'user', 'password' => 'secret', 'client' => null, 'tls' => null, 'url' => env('EMAIL_TRANSPORT_DEFAULT_URL', null), ], 'gmail'=> [ 'host' => 'ssl://smtp.gmail.com', 'port' => 465, 'username' => 'yourEmail@gmail.com', 'password' => 'YOURPASSWORD', 'className' => 'Smtp', 'log' => true, 'context' => [ 'ssl' => [ 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ] ] ], ],
Now we setup gmail for send email and its also working for localhost
You can send email with cakephp simply by using this code in your controller
Note:- make sure use Cake\Mailer\Email; class loaded in your controller
$email = new Email('default'); $email->from(['me@example.com' => 'My Site']) ->to('you@example.com') ->subject('About') ->send('My message');
the above example is for send email with cakephp 3.x But for this tutorial we will
create a component for email
Create a file MainComponent.ctp in ProjectRootDirectory/src/Controller/Component and paste this code
<?php namespace App\Controller\Component; use Cake\Controller\Component; use Cake\Controller\ComponentRegistry; use Cake\Mailer\Email; use Cake\Core\Configure; use Cake\Routing\Router; /** * Main component */ class MainComponent extends Component { /** * Default configuration. * * @var array */ protected $_defaultConfig = []; /* * Email Configuration * @params : array $config [Cake Email Params] * - $config[to] - Email of receiver * - $config[from] - Email of sender * - $cofig[message] - Message of email * - $config[subject] - subject of email * @return : boolean */ public function sendEmail($config= array()){ //pr($config); exit; $defaults = array_merge(array('sendAs'=>'html','transport'=>'gmail','from'=>'test'),$config); try{ $Email = new Email(); $Email->from(Configure::read('Site.email_from')) ->template('themetemplate', 'themelayout') ->to($defaults['to']) ->subject($defaults['subject']) ->emailFormat($defaults['sendAs']) ->transport($defaults['transport']) ->viewVars(['title' => $config['title'],'content'=>$config['body']]); if(isset($defaults['fileurl']) && isset($defaults['filename'])){ $Email->attachments([ $defaults['filename'] => [ 'file' => $defaults['fileurl'] ] ]); } if(!$Email->send()) return false; } catch (\Exception $e) { return false; //$this->Flash->error($e->getMessage()); } return true; } }
Explaination -
->template => using for set html tempalte for email
->to => pass to user email
->emailFormat => type of email like text or html
->transport => set transport for email , we already added gmail for transport in app.php so we passing gmail in transport
Now we will create layout and template for email that we mentioned in our mail configuration
Create Layout src/Template/Layout/Email/html/themelayout.ctp and paste this code
<?php /** * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) * @link http://cakephp.org CakePHP(tm) Project * @since 0.10.0 * @license http://www.opensource.org/licenses/mit-license.php MIT License */ ?> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN"> <html> <head> <title><?= $this->fetch('title') ?></title> </head> <body> <?= $this->fetch('content') ?> </body> </html>
Create template src/Template/Email/html/themetemplate.ctp and paste this code
<table> <tbody style="background-color:#F5F5F5;"> <tr> <td colspan="2" valign="top" style="padding-top:35px;color:rgb(79,129,189);font-size:23px;text-align:center"> <?= $title ?> </td> </tr> <tr> <td colspan="2" style="padding:40px 25px 40px; color:#666;font-size:14px;line-height:22px;font-family:Verdana,sans;margin-top:0;margin-bottom:20px;font-weight:normal"> <?= $content ?> </td> </tr> </tbody> </table>
Here we passing $title and $content, that values we already send from our email configuration
Now everything setup for email
Now we need to create a src/Template/register.ctp you can bake tempalte using cake bake template users or if want to do manually then follow below steps
Now create a form in this file or Paste this code into your register.ctp
<div class="row"> <div class="col-sm-12"> <?= $this->Form->create($user);?> <div class="form-group "> <?= $this->Form->input('email',['class'=>'form-control','required'=>'required','type'=>'email']);?> </div> <div class="row"> <div class="col-sm-12"> <?= $this->Form->button('Login',['class'=>'btn btn-primary','type'=>'submit']); ?> </div> </div> <?= $this->Form->end() ?> </div> </div>
Now we will create a src/Controller/UserController.php and to use our email component we need to call component in our controller. you can call it in AppController so you can use from any controller for example we using in our controller .Here we call it in initialize function of controller by
Call Custom Component in cakephp.
public function initialize() { parent::initialize(); $this->loadComponent('Main'); }
you can bake controller using cake bake all users or if want to do manually then follow below steps
Now Paste this code into your usersController.php
<?php namespace App\Controller; use App\Controller\AppController; use Cake\Core\Configure; use Cake\Network\Exception\NotFoundException; use Cake\View\Exception\MissingTemplateException; use Cake\Error\Debugger; use Cake\Event\Event; use Cake\Routing\Router; /** * Users Controller * * @ perty \App\Model\Table\UsersTable $Users */ class UsersController extends AppController { /** * Register method * * @return \Cake\Network\Response|null * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */
public function initialize() { parent::initialize();
$this->loadComponent('Main'); }
public function register(){ $user = $this->Users->newEntity(); try { if($this->request->is('post')) { $uniquecode = substr(md5(microtime()),0,10); //generate random string $randomKey = substr(md5(microtime()),0,10); $this->request->data['otp'] = $uniquecode; $getUserEmail = $this->Request->data['email']; $user = $this->Users->patchEntity($user,$this->request->data); if($this->Users->save($user)){ $bodyEmail = "You have successfully registered."; $bodyEmail .= "To active account please click on below link"; $aLink = Router::url(array("controller"=>"users","action"=>"activate", $uniquecode, $randomKey),true); $bodyEmail .= '<p><br><br><a style="width:50%;color:#fff;text-decoration:none;background:#333;display:block;padding:10px;text-align:center;-webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px;margin:10px auto " href="'.$aLink.'"> Please verify your email address </a></p>'; if($this->Main->sendEmail(['to'=>$getUserEmail,'subject'=>'Registration Complete','title'=>'Registration Complete','body'=>$bodyEmail)){ $this->Flash->success(__('Your account has been registered. please check your email address to activate your account')); return $this->redirect(['action' => 'register']); }else{ $this->Flash->error(__('Registration not completed. Please try again.')); return $this->redirect(['action' => 'index']); } }else{ $this->Flash->error(__('Unable to register your account.')); } } }catch (\Exception $e) { $this->Flash->error($e->getMessage()); return $this->redirect(['action' => 'register']); } $this->set('user',$user); $this->set('page_title',__('Registeration')); } /** * Activate method * * @return \Cake\Network\Response|null * @throws \Cake\Datasource\Exception\RecordNotFoundException When record not found. */ public function activate($getUniCode='', $randomKey='') { if(trim($getUniCode)!="" && $randomKey!="") { $getUniCode = filter_var($getUniCode, FILTER_SANITIZE_STRING); $getUser = $this->Users->find('all',['conditions'=> ['otp'=> $getUniCode,'status'=> 0]])->first(); if($getUser) { $getUserId = $getUser->id; $updateActivate = $this->Users->updateAll(['status'=> 1, 'otp'=> ''], ['id'=> $getUserId]); $this->Flash->success(__('Your account has been Activated successfully. please login')); return $this->redirect(['action' => 'register']); } } } }
NOTE:-
Please check your both action allowed for all users . otherwise it will show "You are not authorized to access that location" . to allow action paste this code into initialize() or beforeFilter() function.
$this->Auth->allow(['register','activate']);
this will allow user to access that actions without login.
Explanation
Here we create 2 actions first is register to save register user email and generate u unique otp code and save it into db and send an email . second function is activate when a user click on activate link then it will redirect to activate action where we checking user otp is correct or not if its correct then activate his account and delete otp so he cant use same link to activate again.
Now run your register action of users controller and submit your email and you will receive an activation link email, using this link you can activate your account.
So we have successfully completed user email verification in cakephp 3.x. and also learn how to create component and use with cakephp 3.x .
Thank You.
Other Links
How to send OTP Email in cakephp 3x
How to send email with verification code in cakephp 3.x
Comments
Post a Comment