|
<?php
// +----------------------------------------------------------------------
// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]
// +----------------------------------------------------------------------
// | Copyright (c) 2010 http://thinkphp.cn All rights reserved.
// +----------------------------------------------------------------------
// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )
// +----------------------------------------------------------------------
// | Author: luofei614 <www.3g4k.com>
// +----------------------------------------------------------------------
// $Id: SaeMail.class.php 2766 2012-02-20 15:58:21Z luofei614@gmail.com $
/**
*Mail模拟器
*todu, 支持ssl和附件上传。
*现在暂不支持ssl,建议不用使用gmail测试。
*/
class SaeMail extends SaeObject{
private $msp = array(
"sina.com" => array("smtp.sina.com",25,0),
"sina.cn" => array("smtp.sina.cn",25,0),
"163.com" => array("smtp.163.com",25,0),
"263.com" => array("smtp.263.com",25,0),
"gmail.com" => array("smtp.gmail.com",587,1),
"sohu.com" => array("smtp.sohu.com",25,0),
"qq.com" => array("smtp.qq.com",25,0),
"vip.qq.com" => array("smtp.qq.com",25,0),
"126.com" => array("smtp.126.com",25,0),
);
private $_post=array();
const mail_limitsize=1048576;
const subject_limitsize=256;
private $_count;
private $_attachSize;
private $_allowedAttachType = array("bmp","css","csv","gif","htm","html","jpeg","jpg","jpe","pdf","png","rss","text","txt","asc","diff","pot","tiff","tif","wbmp","ics","vcf");
public function __construct($options=array()){
$this->setOpt($options);
}
public function clean(){
$this->_post = array();
$this->_count = 0;
$this->_attachSize = 0;
return true;
}
public function quickSend($to,$subject,$msgbody,$smtp_user,$smtp_pass,$smtp_host='',$smtp_port=25,$smtp_tls=false){
$to = trim($to);
$subject = trim($subject);
$msgbody = trim($msgbody);
$smtp_user = trim($smtp_user);
$smtp_host = trim($smtp_host);
$smtp_port = intval($smtp_port);
$this->_count = strlen($msgbody) + $this->_attachSize;
if(strlen($subject) > self::subject_limitsize) {
$this->errno = SAE_ErrParameter;
$this->errmsg = "subject cannot larger than ".self::subject_limitsize." bytes";
return false;
}
if($this->_count > self::mail_limitsize) {
$this->errno = SAE_ErrParameter;
$this->errmsg = "mail size cannot larger than ".self::subject_limitsize." bytes";
return false;
}
if (filter_var($smtp_user, FILTER_VALIDATE_EMAIL)) {
preg_match('/([^@]+)@(.*)/', $smtp_user, $match);
$user = $match[1]; $host = $match[2];
if(empty($smtp_host)) {
//print_r($match);
if(isset($this->msp[$host])) { $smtp_host = $this->msp[$host][0]; }
else {
$this->errno = SAE_ErrParameter;
$this->errmsg = "you can set smtp_host explicitly or choose msp from sina,gmail,163,265,netease,qq,sohu,yahoo";
return false;
}
}
if($smtp_port == 25 and isset($this->msp[$host])) {
$smtp_port = $this->msp[$host][1];
}
if(!$smtp_tls and isset($this->msp[$host])) {
$smtp_tls = $this->msp[$host][2];
}
$smtp_tls = ($smtp_tls == true);
$username = $user;
} else {
$this->_errno = SAE_ErrParameter;
$this->_errmsg = "invalid email address";
return false;
}
$this->_post = array_merge($this->_post, array("from"=>$smtp_user, "smtp_username"=>$username, "smtp_password"=>$smtp_pass, "smtp_host"=>$smtp_host, "smtp_port"=>$smtp_port, 'to'=>$to,'subject'=>$subject,'content'=>$msgbody, 'tls'=>$smtp_tls));
return $this->send();
}
public function send(){
if ( empty($this->_post['from'])
|| empty($this->_post['to'])
|| empty($this->_post['smtp_host'])
|| empty($this->_post['smtp_username'])
|| empty($this->_post['smtp_password'])
|| empty($this->_post['subject']) ) {
$this->_errno = SAE_ErrParameter;
$this->_errmsg = "parameters from, to, subject, smtp_host, smtp_username, smtp_password can no be empty";
return false;
}
if($this->_count > self::mail_limitsize) {
$this->_errno = SAE_ErrForbidden;
$this->_errmsg = "mail size cannot larger than ".self::mail_limitsize." bytes";
return false;
}
//连接服务器
$fp = fsockopen ( $this->_post['smtp_host'], $this->_post['smtp_port'], $errno, $errstr, 60);
if (!$fp ) return "联接服务器失败".__LINE__;
stream_set_blocking($fp, true );
$lastmessage=fgets($fp,512);
if ( substr($lastmessage,0,3) != 220 ) return "error1:".$lastmessage.__LINE__;
//HELO
$yourname = "YOURNAME";
$lastact="EHLO ".$yourname."\r\n";
fputs($fp, $lastact);
$lastmessage == fgets($fp,512);
if (substr($lastmessage,0,3) != 220 ) return "error2:$lastmessage".__LINE__;
while (true) {
$lastmessage = fgets($fp,512);
if ( (substr($lastmessage,3,1) != "-") or (empty($lastmessage)) )
break;
}
//身份验证
//验证开始
$lastact="AUTH LOGIN"."\r\n";
fputs( $fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != 334) return "error3:$lastmessage".__LINE__;
//用户姓名
$lastact=base64_encode($this->_post['smtp_username'])."\r\n";
fputs( $fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != 334) return "error4:$lastmessage".__LINE__;
//用户密码
$lastact=base64_encode($this->_post['smtp_password'])."\r\n";
fputs( $fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != "235") return "error5:$lastmessage".__LINE__;
//FROM:
$lastact="MAIL FROM: ". $this->_post['from'] . "\r\n";
fputs( $fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != 250) return "error6:$lastmessage".__LINE__;
//TO:
$lastact="RCPT TO: ".$this->_post['to']. "\r\n";
fputs( $fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != 250) return "error7:$lastmessage".__LINE__;
//DATA
$lastact="DATA\r\n";
fputs($fp, $lastact);
$lastmessage = fgets ($fp,512);
if (substr($lastmessage,0,3) != 354) return "error8:$lastmessage".__LINE__;
//处理Subject头
$head="Subject: ".$this->_post['subject']."\r\n";
$message = $head."\r\n".$this->_post['content'];
//处理From头
$head="From: ".$this->_post['from']."\r\n";
$message = $head.$message;
//处理To头
$head="To: ".$this->_post['to']."\r\n";
$message = $head.$message;
//加上结束串
$message .= "\r\n.\r\n";
//发送信息
fputs($fp, $message);
$lastact="QUIT\r\n";
fputs($fp,$lastact);
fclose($fp);
}
public function setAttach($attach){
if(!is_array($attach)) {
$this->errmsg = "attach parameter must be an array!";
$this->errno = SAE_ErrParameter;
return false;
}
$this->_attachSize = 0;
foreach($attach as $fn=>$blob) {
$suffix = end(explode(".", $fn));
if(!in_array($suffix, $this->_allowedAttachType)) {
$this->errno = SAE_ErrParameter;
$this->errmsg = "Invalid attachment type";
return false;
}
$this->_attachSize += strlen($blob);
$this->_count = $this->_attachSize + strlen($this->_post['content']);
if($this->_count > self::mail_limitsize) {
$this->errno = SAE_ErrForbidden;
$this->errmsg = "mail size cannot larger than ".self::mail_limitsize." bytes";
return false;
}
//$this->_post = array_merge($this->_post, array("attach:$fn:B:".$this->_disposition[$suffix] => base64_encode($blob)));
}
return true;
}
public function setOpt($options){
if (isset($options['subject']) && strlen($options['subject']) > self::subject_limitsize) {
$this->errno = SAE_ErrParameter;
$this->errmsg = Imit_L("_SAE_MAIL_SIZE_lARGER_");
return false;
}
if(isset($options['content']))
$this->_count = $this->_attachSize + strlen($options['content']);
if($this->_count > self::mail_limitsize) {
$this->errno = SAE_ErrParameter;
$this->errmsg = Imit_L("_SAE_MAIL_SIZE_lARGER_");
return false;
}
$this->_post = array_merge($this->_post, $options);
return true;
}
}
|