wordpress外掛開發 結合PHPMailer發信(低安全性模式)+簡易信箱認證

本篇主要 在介紹 當自己開發的外掛有發信需求時,如何使用PHPMailer來達成需求,記得用本篇教學方式用來發信的gmail信箱請記得設定成 ‘低安全性’ 否則google會阻擋來自你外掛的發信請求,之後再詳細寫一篇如何用高安全性模式發信

首先先下載PHPMailer:

https://drive.google.com/file/d/1Lp1w0nXb60om9aXdVyEx-dS2uIT94zdq/view?usp=sharing

然後將其解壓縮放在外掛資料夾下,我自己的習慣是設個email資料夾再把PHPMailer解壓縮到資料夾內

接下來是主要的發信部分,我開發成function的方式,後來發現如果你本身要開發的外掛有數種不同的發信需求的話,這樣會比較便於使用,如果有閱讀本網站的簡易外掛開發的話,我習慣將此function放在class_myplugin-cofunction.php

<?php
    use PHPMailer\PHPMailer\PHPMailer;//必須加在call這支函式的php檔的最上方<?php之後
	function MPsendMail($title,$content,$email){
		//記得要替換成PHPMailer與根目錄的相對位置
		require_once MP_DIR.'/email/PHPMailer/src/PHPMailer.php';
		require_once MP_DIR.'/email/PHPMailer/src/SMTP.php';
		require_once MP_DIR.'/email/PHPMailer/src/Exception.php';
		$mail= new PHPMailer();                             //建立新物件
		$mail->SMTPDebug = 0;                        
		$mail->IsSMTP();                                    //設定使用SMTP方式寄信
		$mail->SMTPAuth = true;                        //設定SMTP需要驗證
		$mail->SMTPSecure = "ssl";                    // Gmail的SMTP主機需要使用SSL連線
		$mail->Host = "smtp.gmail.com";             //Gamil的SMTP主機
		$mail->Port = 465;                                 //Gamil的SMTP主機的埠號(Gmail為465)。
		$mail->CharSet = "utf-8";                       //郵件編碼
		$mail->Username = "$Gamil帳號";       //Gamil帳號
		$mail->Password = "$Gmail密碼";       //Gmail密碼
		$mail->From = "$寄件者信箱";        //寄件者信箱
		$mail->FromName = "XX網站";                  //寄件者姓名
		$mail->Subject = $title; //郵件標題
		$mail->Body = $content; //郵件內容
		$mail->IsHTML(true);//郵件內容為html
		$mail->AddAddress($email);//收件者郵件及名稱
		$mail->Send();
	}
?>

記得呼叫此函式的php檔開頭的地方要加上use PHPMailer\PHPMailer\PHPMailer;
這是 PHPMailer 的標準使用方式,一定要加不然程式不能正常執行!

加碼一下簡易的信箱認證邏輯

首先要建立認證頁面的部分,方法的話有推薦兩種
1.寫成templates的形式然後用shortcode插入elementor,不了解的可以翻一下本網站的外掛框架教學
2.把這個頁面設成wordpress範本,在發佈頁面的時候可以使用該模板

個人比較推薦方法一,因為方法二得要直接打開檔案進行編輯,無法在wp後台進行處理
但有時候這種處理回傳值的頁面必須得採用方法二的方式,尤其是在串接第三方API需要回傳值的時候,這牽扯到wp的頁面展示方式,之後會用另一篇跟大家說明

首先是模板的程式碼,各位可以依需求自行調整機制
邏輯上很簡單,就是用get的方式取得網址後面的驗證碼,然後到資料庫check是否有相同驗證碼跟期限是否已過,個人覺得這方法的驗證可能有點過於簡單,但這邊先以達到需求為主,有興趣的各位可以再延伸研究較為安全的驗證方式

<?php
global $wpdb;
if($_GET['verify']==""){
	echo '<script>alert("不要亂點");location.href = "./";</script>';
	//避免被亂玩,建議沒驗證碼的時候導回首頁
	return;
}
$verify = stripslashes(trim($_GET['verify']));
$nowtime = time();

$cond = $wpdb->prepare(' AND `信箱驗證碼` = %s ', $verify); //記得AND前面要留空
$sql = "select `ID`,`信箱驗證有效期` from {$wpdb->prefix}Mailregister where `信箱認證狀態`=''";
$sql.=$cond;

$dbResult = $wpdb->get_results($sql);
if($dbResult){
	foreach($dbResult as $value){
		if($nowtime>$value->信箱驗證有效期){ 
			$msg = '<div style="font-size:20px">您的帳號認證有效期已過,請登錄您的帳號重新發送認證郵件!再<div id="time" style="display:inline;"></div>秒跳轉到主頁面</div>';
		}
		else{
			$sql = "UPDATE {$wpdb->prefix}Mailregister SET `信箱認證狀態` = 'T' WHERE `ID` = '".$value->ID."'";
			$intReturn=$wpdb->query($sql);
			if($intReturn==0){
				$msg = '<div style="font-size:20px; letter-spacing:5px;">帳號認證失敗!再<div id="time" style="display:inline;"></div>秒跳轉到主頁面</div>'; 
			}

			$msg = '<div style="font-size:20px; letter-spacing:5px;">帳號認證成功!再<div id="time" style="display:inline;"></div>秒跳轉到主頁面</div>';
		}
	}    
}
else{
	$msg = '<div style="font-size:20px; letter-spacing:5px;">帳號認證失敗!再<div id="time" style="display:inline;"></div>秒跳轉到主頁面</div>'; 
}    

echo $msg;
echo "
        <script>
        //設定倒數秒數
        var t = 5;

        //顯示倒數秒收
        function showTime()
        {
            t -= 1;
            document.getElementById('time').innerHTML=t;

            if(t==0)
            {
                location.href='https://codream.empathy.tw/wordpress/';
            }

            //每秒執行一次,showTime()
            setTimeout('showTime()',1000);
        }
        //執行showTime()
        showTime();</script>";


?>

接下來是發送驗證信的function
這邊的呼叫方式是使用ajax呼叫我自己的習慣是放在include裡的main

add_action('wp_ajax_nopriv_$hook的ajax名稱', array($this, 'MPEmailVerify'));
add_action('wp_ajax_$hook的ajax名稱', array($this, 'MPEmailVerify'));
<?php
function MPEmailVerify(){
		global $wpdb;
		$ID=MPCheckLogin();//這個函式是我做登入模組用來確認登入狀態的.之後會有另一篇介紹簡易的登入模組如何製作
		$cond = $wpdb->prepare(' AND ID = %s ', $ID); //記得AND前面要留空
		$sql = "SELECT * FROM {$wpdb->prefix}userdata where 1=1";
		//假設有個資料表裡面有user的ID,密碼,暱稱
		$sql.=$cond;

		$dbResult = $wpdb->get_results($sql);
		if($dbResult){
			foreach($dbResult as $value){
				$password = md5(trim($value->密碼)); //加密密碼
				$email =$value->信箱; //信箱
				$nickname = $value->暱稱;
			}
		}
		$regtime = time();
		$token = md5($email.$password.$regtime); //使用user的ID,密碼,暱稱創建用於驗證的識別碼
		$token_exptime = time()+60*15;//過期時間為15分鐘後

		$sql="UPDATE {$wpdb->prefix}Mailregister SET `信箱驗證碼`= '".$token."', `信箱驗證有效期` ='".$token_exptime."' WHERE ID = '".$ID."'";//ID是用來記錄是哪個帳號進行認證
		$wpdb->query($sql);

		$title="XX網站認證信";
		$content="親愛的用戶您好:<br /><br />歡迎您註冊,請點擊認證您的帳號<br /> <a href=$認證頁面網址?verify=".$token." 'target='_blank'>$認證頁面網址?verify=".$token."</a><br/>如果以上連結無法點擊,請將它複製到你的瀏覽器網址欄中進入訪問,該連結15分鐘內有效。";

		MPsendMail($title,$content,$email);
		echo json_encode(array('success'=>'認證信已發送至您的信箱!'));
		exit();
	}
?>

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *