Skip to content

Instantly share code, notes, and snippets.

@YukiYamashina
Last active October 21, 2020 08:45
Show Gist options
  • Save YukiYamashina/2c53e0c43bf035ffc8d2bf0dcfbf7b29 to your computer and use it in GitHub Desktop.
Save YukiYamashina/2c53e0c43bf035ffc8d2bf0dcfbf7b29 to your computer and use it in GitHub Desktop.
QdmailをPHP7.0に対応させる

QdmailをPHP7.0に対応させる

  • コンストラクタ名を__constructorに修正
  • newの前の&を削除
  • QdmailComponent内のfunction & smtpObjectの引数をスーパークラスと合わせて$null = falseに修正
  • HTMLメールでのマルチパート順序をhtml, plain, OMITからplain, html, OMITへ変更
  • iPhone用アドレスをi.softbank.ne.jpからi.softbank.jpに修正
<?php
/**
* Qdmail ver 1.2.6b
* E-Mail for multibyte charset
*
* PHP versions 4 and 5 (PHP4.3 upper)
*
* Copyright 2008, Spok in japan , tokyo
* hal456.net/qdmail : http://hal456.net/qdmail/
* & CPA-LAB/Technical : http://www.cpa-lab.com/tech/
* Licensed under The MIT License License
*
* @copyright Copyright 2008, Spok.
* @link http://hal456.net/qdmail/
* @version 1.2.6b
* @lastmodified 2008-10-23
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
* Qdmail is sending e-mail library for multibyte language ,
* easy , quickly , usefull , and you can specify deeply the details.
* Copyright (C) 2008 spok
*/
//-------------------------------------------
// For CakePHP , extended 'Object' Class ,
// if including in CakePHP Component .
// At normal PHP Script or another Framework ,
// 'QdmailBranch' means Dummy Base Class .
//-------------------------------------------
if (!defined('QD_DS')) {
define('QD_DS', DIRECTORY_SEPARATOR);
}
if ( defined('CAKE_CORE_INCLUDE_PATH') || defined('CAKE')) {
class QdmailBranch extends Object{
}
}else{
class QdmailBranch{
}
}
if( !function_exists( 'qd_send_mail' ) ){
function qd_send_mail( $type , $to = null, $subject = null , $content = null , $other_header = array() , $attach = null, $debug = 0 ){
$type_org = $type;
$mail = & Qdmail::getInstance();
$mail->debug = $debug;
if(!is_array($type)){
$type = array('TYPE'=>$type);
}
list( $type , $link ) = $mail->keyUpper($type);
$option = array();
$return = array();
$type = array_change_key_case( $type , CASE_UPPER ) ;
$option = (isset($type['OPTION']) && is_array($type['OPTION'])) ? $type['OPTION'] : array(); $return = (isset($type['RETURN']) && is_array($type['RETURN'])) ? $type['RETURN'] : array();
if(isset($type['SMTP'])){
$option = array_merge($option,array('SMTP'=>true,'smtpServer'=>$type['SMTP']));
}
$type = isset($type['TYPE']) ? $type['TYPE']:'text';
$_type=array('TEXT'=>'Text','HTML'=>'Html','DECO'=>'Deco' ,'DECOTEMPLATE'=>'DecoTemplate');
$easy_method = isset($_type[strtoupper($type)]) ? 'easy'.$_type[strtoupper($type)]:'_';
if(!method_exists($mail,$easy_method)){
$mail -> errorGather('Illegal type \''.$type.'\'',__LINE__);
return false;
}
$ret = $mail->{$easy_method}( $to , $subject , $content , $other_header , $attach , $option );
foreach($return as $method => $value ){
if(method_exists($mail,$method)){
$type_org[$link['RETURN']][$method] = $mail -> {$method}($value);
}
}
if(0!==count($return)){
$type_org[$link['RETURN']]['qd_send_mail'] = $ret;
$ret = $type_org;
}
return $ret;
}
}
class QdmailBase extends QdmailBranch{
//----------------------------
// Default Language
// If you do not Japanese
// Please change this propaty for your Language and Encoding
//----------------------------
var $lang_def = "ja";
var $encoding_def = "utf-8";
var $detect_def = array('ASCII','JIS','UTF-8','EUC-JP','SJIS');
var $mb_parameter_stack = null;
var $united_charset = null;
var $mime_encode_max = 75;
//------------------------
// Time Zone , Message Id
//------------------------
var $time_zone = null; // '+0900' in Japan
var $message_id = true;
var $salt = 'qdmail';
var $message_id_right = null;
//----------------------------
// Line Feed Character & kana
//----------------------------
var $LFC = "\r\n";// Notice: CRLF ,If you failed, change to "\n"
var $LFC_Qmail = null;
var $is_qmail = null;
var $language = 'ja';
var $kana = false; // kana header
//----------
// sysytem
//----------
var $kana_content_relation = false;
var $name = 'Qdmail';
var $version = '1.2.6b';
var $xmailer = 'PHP-Qdmail';
var $license = 'The_MIT_License';
//--------------------
// charset , encoding
//--------------------
var $charset_header = 'iso-2022-jp';
var $charset_content = 'iso-2022-jp';
var $charset_attach_filename = 'iso-2022-jp';
var $content_transfer_enc_text = '7bit';
var $content_transfer_enc_html = '7bit';
var $detect_order = false;
// var $detect_order = "iso-2022-jp,eucJP-win,UTF-8,SJIS-win,jis,ASCII";
var $qdmail_system_charset = 'utf-8';
var $force_change_charset = false;
var $corres_charset = array(
'HEADER'=>'charset_header',
'BODY'=>'charset_content',
'ATTACH'=>'charset_attach_filename',
'TEXT'=>'content_transfer_enc_text',
'HTML'=>'content_transfer_enc_html',
'DETECT'=>'detect_order',
'SYSTEM'=>'qdmail_system_charset',
) ;
//--------------------------
// for address
//--------------------------
var $varidate_address_regex = '/[^@]+@[^@]+/';
var $allow_blank_header = false;
var $addr_many = array(
'TO' => true,
'CC' => true,
'BCC' => true,
'FROM' => false,
'REPLYTO'=> false
);
var $addr_head_name = array(
'TO' => 'To',
'CC' => 'Cc',
'BCC' => 'Bcc',
'FROM' => 'From',
'REPLYTO'=>'Reply-To'
);
var $header_must =array( 'TO' , 'FROM' , 'SUBJECT' );
var $body_empty_allow = false;
var $tokey = array(
'_ADDR' => 'mail',
'_NAME' => 'name',
);
//--------------
// content_id
//--------------
var $content_id_include_attach_path = false ;
var $content_id_only_filename = true ;
//---------------
// Once mode
//---------------
var $body_structure = array();
var $body_build_once = false;
var $body_already_build = false;
var $attach_build_once = true;
var $attach_already_build = false;
//------------------------------
// simple replace
//------------------------------
var $simple_replace = false;
var $replace = array();
var $replace_with_to_priority= true;
var $replace_def = array();
// simple replace command prefix
var $rep_prefix = null;
//---------
// wordwrap
//---------
var $wordwrap_allow = false;
var $wrap_prohibit_allow = false;
var $wordwrap_length= 45 ;
// inteligent wordwrap
// false is that the word exist in the line ,
// true is that the word must be the beginning of a line
var $wrap_except = array(
'http://'=>false,
'code'=>true,
);
var $wrap_prohibit_top=',.;:–?!‼、。.))]}}〕〉》」』】〙〗〟’”»ヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎ‐〜?!';
var $wrap_prohibit_end='(([{{〔〈《「『【〘〖‘“« ';
var $wrap_prohibit = array();
// multibyte wordwrap , by wordcount or by wordwidth
var $wrap_width = true;
// multibyte wordwidth compare by ascii
var $mb_strwidth_magni = 2;
//------------------
// To Separate mode
//------------------
var $to_separate = false ;
//----------------------------
// html mail
//----------------------------
var $is_html = null ;
var $auto_both = true ; // text & html
var $inline_mode = false;
var $deco_kind = null ; // number of $this->deco_def
var $auto_deco_judge= false;
var $no_inline_attach_structure = 0;
var $deco_def_default = 0;
var $deco_def =array(
array(
'OPTION_NAME' => array( 'MHTML' , 'INLINE' , 'PC' ),
'STRUCTURE' => 1,
'_CHARSET' => 'iso-2022-jp' ,
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => false,
'DISPOSITION' => true,
),
array(
'OPTION_NAME' => array( 'DC' , 'DOCOMO' ),
'STRUCTURE' => 2,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => false,
),
array(
'OPTION_NAME' => array( 'AU' ,'EZ', 'EZWEB'),
'STRUCTURE' => 3,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => true,
),
array(
'OPTION_NAME' => array( 'SB' , 'SOFTBANK' ),
'STRUCTURE' => 4,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => array('this','stripCrlf') ,
'DISPOSITION' => true ,
),
array(
'OPTION_NAME' => array( 'EM','EMOBILE' ,'EMNET'),
'STRUCTURE' => 2,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => array('this','stripCrlf') ,
'DISPOSITION' => true ,
),
array(
'OPTION_NAME' => array( 'WL','WILLCOM' ,'POCKET'),
'STRUCTURE' => 2,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => 'QUOTED-PRINTABLE',
'HTML_EXTERNAL' => array('this','stripCrlf') ,
'DISPOSITION' => true ,
),
array(
'OPTION_NAME' => array( 'TEMPLATE_DC' , 'TEMPLATE_DOCOMO' ,'TPL_DC'),
'STRUCTURE' => 5,
'_CHARSET' => 'Shift_JIS',
'ENC_TEXT' => '8bit',
'ENC_HTML' => '8bit',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => false,
'BOUNDARY' => 'mime9DC9bdary',
'TOP' => array('Decomail-Template'),
'CID_PREFIX' => 'img_',
'CID_NUM_COL' => 3,
),
array(
'OPTION_NAME' => array( 'TEMPLATE_AU','TPL_AU' ,'TPL_AU_2_0'),
'STRUCTURE' => 6,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => '7bit',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => false,
'BOUNDARY' => '--=_KDDI_NEXT_PART_0000',
'TOP' => array('KDDI_HTML_MAIL_2_0'),
'CID_PREFIX' => 'img_cid_',
'CID_NUM_COL' => 3,
),
array(
'OPTION_NAME' => array( 'TEMPLATE_AU_1_0','TPL_AU_1_0' ,'TPL_AU_1_0'),
'STRUCTURE' => 6,
'_CHARSET' => 'iso-2022-jp',
'ENC_TEXT' => '7bit',
'ENC_HTML' => '7bit',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => false,
'BOUNDARY' => '--=_KDDI_NEXT_PART_0000',
'TOP' => array('KDDI_HTML_MAIL_1_0'),
'CID_PREFIX' => 'img_cid_',
'CID_NUM_COL' => 3,
),
array(
'OPTION_NAME' => array( 'TEMPLATE_SB','TPL_SB' ),
'STRUCTURE' => 5,
'_CHARSET' => 'Shift_JIS',
'ENC_TEXT' => '8bit',
'ENC_HTML' => '8bit',
'HTML_EXTERNAL' => array('this','stripCrlf'),
'DISPOSITION' => false,
'BOUNDARY' => 'aremejkj15a14',
'TOP' => array('HTMLMail-Template-Version:1.0',
'HTMLMail-Template-Title:HTMLMail-Template',
''
),
'CID_PREFIX' => '',
'CID_NUM_COL' => 2,
'CID_AFTER' => '@areme.jp',
),
);
var $structure =array(
// no inline attachment
0 => array(
'multipart/mixed' => array(
'multipart/alternative'=>array(
'plain' => 1,
'html' => 1,
'OMIT' => true,
),
'image' => 'BOTH', // Available Inline
'OMIT' => true,
),
'OMIT' => true,
),
// PC inline HTML
1 => array(
'multipart/mixed' => array(
'multipart/alternative'=>array(
'multipart/related' => array(
'html' => 1,
'image' => 'INLINE',
'OMIT' => true,
),
'plain' => 1,
'OMIT' => true,
),
'image' => 'NOT_INLINE', // not inline
'OMIT' => true,
),
'OMIT' => true,
),
2 => array(
'multipart/mixed' => array(
'multipart/related'=>array(
'multipart/alternative' => array(
'plain' => 1,
'html' => 1,
'OMIT' => false,
),
'image' => 'INLINE',
'OMIT' => false,
),
'OMIT' => false,
'image' => 'NOT_INLINE',
),
'OMIT' => false,
),
3 => array(
'multipart/mixed' => array(
'multipart/alternative' => array(
'plain' => 1,
'html' => 1,
'OMIT' => false,
),
'image' => 'BOTH',
'OMIT' => false,
),
'OMIT' => false,
),
4 => array(
'multipart/related'=>array(
'multipart/alternative' => array(
'plain' => 1,
'html' => 1,
'OMIT' => false,
),
'image' => 'INLINE',
'OMIT' => false,
),
'image' => 'NOT_INLINE',
'OMIT' => false,
),
5 => array(
'multipart/related'=>array(
'plain' => 1,
'html' => 1,
'image' => 'INLINE',
'OMIT' => false,
),
'OMIT' => false,
),
6 => array(
'multipart/mixed'=>array(
'plain' => 1,
'html' => 1,
'image' => 'INLINE',
'OMIT' => false,
),
'OMIT' => false,
),
);
var $deco_judge = array(
'docomo.ne.jp' => 'DC',
'softbank.ne.jp' => 'SB',
'i.softbank.jp' => 'SB',
'disney.ne.jp' => 'SB',
'vodafone.ne.jp' => 'SB',
'ezweb.ne.jp' => 'AU',
'emnet.ne.jp' => 'EM',
'pdx.ne.jp' => 'WL',
'gmail.com' => 'DC',
);
//------------------
// using address and content
//------------------
var $to = array() ;
var $from = array() ;
var $cc = array() ;
var $bcc = array() ;
var $done = array() ;
var $undone = array() ;
var $replyto = array() ;
var $recipient = array() ;
var $allways_bcc = null ;
var $header = array() ;
var $other_header = array() ;
var $header_content_type = array();
var $content = array(
'TEXT'=>array(
'CONTENT' => null,
'LENGTH' => null,
'_CHARSET' => null,
'ENC' => null,
'_ORG_CHARSET' => null,
),
'HTML'=>array(
'CONTENT' => null,
'ORG_CONTENT' => null,
'LENGTH' => null,
'_CHARSET' => null,
'ENC' => null,
'_ORG_CHARSET' => null,
),
);
var $header_for_mailfunction_to;
var $header_for_mailfunction_subject;
var $header_for_mailfunction_other;
var $content_for_mailfunction;
var $header_for_smtp_array;
var $content_all_for_smtp;
var $header_for_smtp;
//--------------
// attachament
//--------------
var $attach = array();
var $attach_path = null;
var $auto_ext = true ; // mimetypes
var $content_id_fix = false;
//------------------------
// Mailer
//-------------------------
var $mailer = 'mail';
//------------------------
// Sendmail
//-------------------------
var $sendmail = false ;
var $sendmail_path = null;
//------------------------
// SMTP
//-------------------------
var $smtp = false ;
var $smtp_object = null;
var $smtp_loglevel_link = false;
var $smtp_server = array(
'host' => null ,
'port' => 25 ,
'from' => null,
'user' => null,
'pass' => null,
'protocol' => null,
'pop_host' => null,
'pop_user' => null,
'pop_pass' => null,
);
//------------------------
// render Mode
//------------------------
var $render_mode = false;
var $size = array();
//------------------------
// Priority
//------------------------
var $priority = null;
var $priority_def =array(
'X-Priority' => array( 'HIGH' => 1 , 'NORMAL' => 3 , 'LOW' =>5 ),
'X-MsMail-Priotiry' => array( 'HIGH'=>'High' , 'NORMAL'=>'Normal' , 'LOW'=>'Low' ),
'Priotiry' => array( 'HIGH'=>'urgent' , 'NORMAL' => 'normal' , 'LOW'=> 'non-urgent' ),
'Importance' => array( 'HIGH' =>'High' , 'NORMAL'=>'Normal' ,'LOW' =>'Low' ),
);
//------------------------
// signed
//------------------------
var $sign = false;
var $smime = false;
var $pgp = false;
var $private_key_file = 'private.pem';
var $certificate_file = 'cert.pem';
var $certificate_pass = null;
var $certificate_file_path = null;
var $certificate_temp_path = null;
var $certificate_file_path_win = 'c:\cert';
var $certificate_temp_path_win = 'c:\temp';
var $certificate_file_path_unix = '/user/local/cert';
var $certificate_temp_path_unix = '/tmp';
//------------------------
// etc
//------------------------
var $temporary_path = null;
var $simple_attach = false;
var $keep_parameter = array(false);
var $mta_option = null ;
var $is_create = false;
var $address_validation_method = array('this','validateAddr');
var $boundary_base_degit= 2 ;
var $stack_construct = null ;
var $start_time = null;
var $framework = null;
//-------------------------------
// logs
// 0 is nolog,
// 1 is simple(Message 'Success' & recipt e-mail@address ),
// 2 is including header data,
// 3 is including fulldata,
//------------------------------
var $log_level = 0 ;
var $log_level_max = 3 ;
var $log_path = './';
var $log_filename = 'qdmail.log';
var $log_append = 'a' ;
var $log_dateformat = 'Y-m-d H:i:s';
var $log_LFC = "\n";
// -------------------------------
// error & error logs
// 0 is nolog,
// 1 is simple,
// 2 is including header data,
// 3 is inc fulldata
//--------------------------------
var $error = array();
var $error_stack = array();
var $error_display = true;
var $errorlog_level = 0 ;
var $errorlog_level_max = 3 ;
var $errorlog_path = './';
var $errorlog_filename= 'qbmail_error.log';
var $errorlog_append= 'a' ;
var $ignore_error = false ;
//----------------
// debug
// 0 is no debug mode & really sending ,
// 1 is showing header&body & really sending ,
// 2 is no sending & showing header&body and some vars
//----------------
var $debug = 0 ;
var $debug_report = false;
var $debug_report_path = './';
var $debug_echo_charset= true;
//****************************************************
// Methods
//****************************************************
//--------------------------------
// constructor set error display
// $charset_def = null,
// $error_display = true
// $mail -> (&) new Qdmail( Charset , Encoding , DetectOrder , error_display );
//--------------------------------
function __construct( $param = null ){
$this->stack_construct = $param ;
if( !empty( $param[0] ) && !empty( $param[1] ) ){
$this->charset( $param[0] , $param[1] );
}elseif( !empty( $param[0] ) ){
$this->charset( $param[0] );
}
if( !empty( $param[2] ) ){
$this->detect_order = $param[1];
}
if( false !== $this->detect_order ){
$this->qd_detect_order( $this->detect_order );
}
if( !empty( $param[3] ) ){
$this->error_display = $param[2];
}
if(is_null($this->LFC)){
$this->LFC = chr(13) . chr(10);
}
if(is_null($this->LFC_Qmail)){
$this->LFC_Qmail = chr(10);
}
if($this->isQmail()){
$this->LFC = $this->LFC_Qmail;
}
$this->optionNameLink();
$this->wordwrapProhibitConstruct();
$this->sendmail_path = ini_get("sendmail_path");
}
function & getInstance(){
static $instance = array();
if( isset($instance[0]) && is_object($instance[0]) ){
$keep = $instance[0]->keep_parameter;
if( is_string($keep[0]) ){
$stack = array();
foreach($keep as $method){
if( !is_string( $method ) || !method_exists( $instance[0] , $method ) ){
continue;
}
$stack[$method] = $instance[0]->{$method}();
}
$instance[0] -> reset();
foreach($stack as $method => $value){
$instance[0]->{$method}($value);
}
}elseif( true !== $keep[0] ){
$instance[0] -> reset();
}
return $instance[0];
}
$instance[0] = new Qdmail();
return $instance[0];
}
//--------------------------
// Decoration Mail Template
//--------------------------
function makeDecoTemplate( $deco_kind , $content ){
if(false===($this->deco_kind=$this->decoSelect( $deco_kind ))){
return $this->errorGather('Illegal Decoration Kind \''.$deco_kind.'\'',__LINE__);
}
$DECO = new QdDeco;
$DECO -> template($content);
$DECO -> decode();
$content = $DECO -> get('HTML');
$attach = $DECO -> get('ATTACH');
$this -> renderMode( true );
$this -> to('[email protected]');
$this -> from('[email protected]');
$this -> subject('dummy_subject');
$this->body = null;
$this->after_id = null;
$this->content_id_fix = true;
$this->is_html = 'HTML';
$count = 0;
$content = $this->qd_convert_encoding($content,'utf-8',$this->qd_detect_encoding($content));
$content=preg_replace('/\r?\n/','',$content);
foreach($attach as $key => $att){
if( empty( $attach[$key]['CONTENT-ID'] ) ){
continue;
}
$aft = isset($this->deco_def[$this->deco_kind]['CID_AFTER']) ? $this->deco_def[$this->deco_kind]['CID_AFTER']:'';
$prefix = isset($this->deco_def[$this->deco_kind]['CID_PREFIX']) ? $this->deco_def[$this->deco_kind]['CID_PREFIX']:'';
$col_num = isset($this->deco_def[$this->deco_kind]['CID_NUM_COL']) ? $this->deco_def[$this->deco_kind]['CID_NUM_COL']:3;
$ct = '00'.$count++;
$start = (strlen($ct)-$col_num) < 0 ? 0:strlen($ct)-$col_num;
$end = strlen($ct)-$start;
$new_cid = $prefix
. substr($ct,$start,$end)
. $aft;
$content=preg_replace('/<\s*IMG\s+SRC\s*=\s*"cid:'.$attach[$key]['CONTENT-ID'].'"/is','<IMG SRC="cid:'.$new_cid.'"',$content);
$attach[$key]['CONTENT-ID'] = $new_cid;
}
$this->html( $content , null , null , 'utf-8' );
if( 0 < count($attach) ){
$this->attach( $attach );
}
$this->createMail(
$this->deco_def[$this->deco_kind]['BOUNDARY'],
true
);
$header = '';
foreach($this->deco_def[$this->deco_kind]['TOP'] as $line){
$header .= $line .$this->LFC;
}
$header .= 'MIME-Version: 1.0' . $this->LFC
. 'Content-type: ' . key($this->structure[$this->deco_def[$this->deco_kind]['STRUCTURE']])
. '; boundary="'.$this->deco_def[$this->deco_kind]['BOUNDARY'] . '"'
. $this->LFC;
return $header . $this->LFC . $this -> smtpDataBody() . $this->LFC ;
}
//-------------------
// Easy Base
//-------------------
function easy( $type , $to , $subject , $content , $other_header = array() , $attach = null ){
if(is_null($other_header)){
$other_header=array();
}
$this->resetHeaderBody();
$option_return = array();
if( is_array($type) ){
$type = array_change_key_case( $type , CASE_UPPER );
if( isset( $type['SMTP'] ) ){
$this->smtp( true );
$this->smtpServer( $type['SMTP'] );
}
if(isset( $type['OPTION'] )){
$type['OPTION'] = array_change_key_case( $type['OPTION'] , CASE_UPPER );
foreach($type['OPTION'] as $method => $param ){
if(method_exists($this,$method)){
$option_return[$method] = $this->{$method}($param);
}
}
}
$type = isset( $type['TYPE'] ) ? $type['TYPE'] : 'TEXT' ;
}
if( (empty($to) && ( !empty($subject) || !empty($content) ))){
return $this->errorGather('Parameter Specified Error',__LINE__);
}elseif( empty($to) ){
return $option_return;
}
if( 'TEXT' == strtoupper( $type ) || 'HTML' == strtoupper( $type ) ){
$type=strtolower( $type );
}else{
$this->error[]='Illegal spcify \'type\' in '.$type.' .'.__LINE__;
return $this->errorGather();
}
$to = is_string($to) ? array($to) : $to ;
$other_header = is_string($other_header) ? array('From' => $other_header) : $other_header ;
list($other_header_temp , $link ) = $this->keyUpper( $other_header );
if(!isset($other_header_temp['FROM'])){
$fromAddr = null;
if( isset($other_header[0]) ){
$fromAddr = $other_header[0];
unset($other_header[0]);
}
$fromName = null;
if(isset($other_header[1])){
$fromName = $other_header[1];
unset($other_header[1]);
}
if(!empty($fromAddr)){
$other_header = array_merge( $other_header,array('FROM'=>array( $fromAddr , $fromName )));
}
}
$other_header = array_merge(array('TO'=>$to),$other_header);
$section = array('TO'=>'to','CC'=>'cc','BCC'=>'bcc','REPLY-TO'=>'replyto','FROM'=>'from');
list($other_header_temp , $link ) = $this->keyUpper( $other_header );
foreach($other_header_temp as $key => $other_head){
if(isset($section[$key])){
$method = $section[$key];
$this -> {$method}( $other_head , null );
}else{
$this -> addHeader( $link[$key] , $other_head );
}
}
$this->subject( $subject );
$this->{$type}( $content );
if( isset( $attach ) ){
$this->attach( $attach , $add = false , $this->inline_mode );
}
return $this->send();
}
function easyText( $to , $subject , $content , $other_header = array() , $attach = null , $option = array() ){
return $this->easy( array('TYPE'=>'text','OPTION'=>$option) , $to , $subject , $content , $other_header , $attach );
}
function easyHtml( $to , $subject , $content , $other_header = array() , $attach = null , $option = array() ){
return $this->easy( array('TYPE'=>'html','OPTION'=>$option) , $to , $subject , $content , $other_header , $attach );
}
function easyReplace( $to , $subject , $content , $other_header = array() , $attach = null , $option = array() ){
$this->simpleReplace( true );
$type = 'text';
if(0!==count($option)){
$option = array_change_key_case( $option , CASE_UPPER );
$type = ( 'HTML' === strtoupper( $option['TYPE']) ) ? 'html' : $type ;
}
$this->easy( array('TYPE'=>$type,'OPTION'=>$option) , $to , $subject , $content , $other_header , $attach );
}
function easyDeco( $to , $subject , $content , $other_header = array() , $attach = null , $option = array() ){
if( isset( $attach ) ){
$this->inline_mode=true;
}
$this->autoDecoJudge( true );
$this->toSeparate( true );
return $this->easy( array('TYPE'=>'html','OPTION'=>$option) , $to , $subject , $content , $other_header , $attach );
}
function easyDecoTemplate( $to , $subject , $template , $other_header = array() , $attach = null , $option = array() ){
if(is_null($attach)){
$attach = array();
}
$DECO = new QdDeco;
$DECO -> template($template);
$DECO -> decode();
$content = $DECO -> get('HTML');
$text = $DECO -> get('PLAIN');
if(!empty($text)){
$this->text($text);
}
$att = $DECO ->get('ATTACH');
$attach = array_merge($att,$attach);
return $this->easyDeco( $to , $subject , $content , $other_header , $attach , $option );
}
function easyDecoRep( $to , $subject , $content , $other_header = array() , $attach = null , $option = array() ){
$this->simpleReplace( true );
return $this->easyDeco($to , $subject , $content , $attach , $option , $option);
}
function easyOption( $to , $subject = null , $content = null , $other_header = array() , $attach = null , $option = array() ){
if(!is_array($to)){
$option = array( $to => $subject );
}else{
$option = $to;
}
return $this->easy( array('TYPE'=>'option','OPTION'=>$option) , $to , $subject , $content , $other_header , $attach );
}
/*
* Notice: Before use $this->optionNameLink(); by Constractor
*/
//
//---------------------------------------
// something change mode
//---------------------------------------
// Keys must lowercase , because of PHP4's
var $property_type = array(
'auto_both' => 'bool' ,
'to_separate' => 'bool' ,
'simple_replace' => 'bool' ,
'auto_deco_judge' => 'bool' ,
'auto_ext' => 'bool' ,
'body_empty_allow' => 'bool' ,
'ignore_error' => 'bool' ,
'wrap_width' => 'bool' ,
'wordwrap_allow' => 'bool' ,
'wrap_prohibit_allow'=> 'bool' ,
'force_change_charset' => 'bool' ,
'error_display' => 'bool' ,
'sendmail' => 'bool' ,
'smtp' => 'bool' ,
'smtp_loglevel_link'=> 'bool' ,
'inline_mode' => 'bool' ,
'replace_with_to_priority'=> 'bool' ,
'attach_build_once' => 'bool' ,
'body_build_once' => 'bool' ,
'kana' => 'bool' ,
'render_mode' => 'bool' ,
'smime' => 'bool' ,
'pgp' => 'bool' ,
'simple_attach' => 'bool' ,
'message_id' => 'bool' ,
'allow_blank_header'=> 'bool' ,
'sign' => 'string' ,
'keep_parameter' => 'array' ,
'attach_path' => 'string' ,
'mta_option' => 'string' ,
'rep_prefix' => 'string' ,
'log_path' => 'string' ,
'errorlog_path' => 'string' ,
'log_filename' => 'string' ,
'errorlog_filename' => 'string' ,
'allways_bcc' => 'string' ,
'wrap_prohibit_top' => 'string' ,
'wrap_prohibit_end' => 'string' ,
'framework' => 'string' ,
'priority' => 'string' ,
'certificate_file' => 'string' ,
'certificate_file_path' => 'string' ,
'certificate_temp_path' => 'string' ,
'time_zone' => 'string' ,
'private_key_file' => 'string' ,
'certificate_pass' => 'string' ,
'message_id_right' => 'string' ,
'sendmail_path' => 'string' ,
'temporary_path' => 'string' ,
'united_charset' => 'string' ,
'varidate_address_regex'=> 'string' ,
'mb_strwidth_magni' => 'numeric' ,
'log_dateformat' => 'numeric' ,
'log_level' => 'numeric' ,
'errorlog_level' => 'numeric' ,
'mime_encode_max' => 'numeric' ,
'smtp_server' => 'array' ,
'address_validation_method'=> 'array',
);
var $method_property = array();
function optionNameLink(){
foreach($this->property_type as $prop => $type ){
$method_low = strtolower( str_replace( '_' , '' , $prop ) );
$this->method_property[$method_low] = $prop;
}
}
function option( $option , $line = null , $min = null , $max = null ){
$ret = array();
if( !is_null( $line ) ){
$line = '-' . $line ;
}
if(!is_array($option)){
return $this->errorSpecify( __FUNCTION__, __LINE__ );
}
foreach( $option as $key => $value ){
if( !isset( $this->method_property[strtolower($key)] ) ){
return $this->errorSpecify( __FUNCTION__ . '-' .$key , __LINE__ . $line );
}
$property_name = $this->method_property[strtolower($key)];
if( is_null( $value ) ){
$ret[] = $this->{$property_name} ;
continue ;
}
$err = false;
switch( $this->property_type[$property_name] ){
case 'bool':
if( is_bool( $value ) ){
$this->{$property_name} = $value ;
$ret[0] = true ;
}else{
return $this->errorSpecify( __FUNCTION__ . '-' .$key , __LINE__ . $line );
}
break;
case 'string':
if( '' === $value ){
$this->{$property_name} = null ;
$ret[0] = true ;
break ;
}
if( is_string( $value ) ){
$this->{$property_name} = $value ;
$ret[0] = true ;
}else{
return $this->errorSpecify( __FUNCTION__ . '-' .$key , __LINE__ . $line );
}
break;
case 'numeric':
if( !is_numeric( $value ) || ( isset( $min ) && ( $value < $min ) ) || ( isset( $max ) && ( $value > $max ) ) ){
return $this->errorSpecify( __FUNCTION__ . '-' .$key , __LINE__ . $line );
}else{
$this->{$property_name} = $value ;
$ret[0] = true ;
}
break;
case 'array':
if( !is_array( $value ) ){
$value = array( $value );
}
if( true===$min ){
$this->{$property_name} = array_merge( $this->{$property_name} , $value );
}else{
$this->{$property_name} = $value ;
}
$ret[0] = true ;
if( true === $max ){
$this->{$property_name} = array_change_key_case( $this->{$property_name} , CASE_UPPER );
}
break;
default:
return $this->errorSpecify( __FUNCTION__ . '-' .$key , __LINE__ . $line );
break;
}
}
if( 0 === count( $ret ) ){
return $this->errorSpecify( __FUNCTION__ , __LINE__ );
}elseif( 1 === count( $ret ) ){
return array_shift( $ret );
}else{
return $ret ;
}
}
function autoBoth( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function toSeparate( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function simpleReplace( $bool = null ){
$this->toSeparate( $bool );
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function autoDecoJudge( $bool = null ){
$this->attachBuildOnce( !$bool );
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function autoExt( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function bodyEmptyAllow( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function ignoreError( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function forceChangeCharset( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function errorDisplay( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function sendmail( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function smtp( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function smtpLoglevelLink( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function inlineMode( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function replaceWithToPriority( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function attachBuildOnce( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function bodyBuildOnce( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function kana( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function keepParameter( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function renderMode( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function simpleAttach( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function messageId( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function allowBlankHeader( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function smime( $bool = null ){
$fg = $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
if(!extension_loaded ( 'openssl' )){
$this->smime = false;
if(!$bool){
return false;
}
}
return $fg;
}
function pgp( $bool = null ){
// future
return true;
}
function sign( $string = null ){
if(false===$string){
$this->smime = false;
$this->pgp = false;
$this->sign = false;
return true;
}
if(empty($string)){
return $this->sign;
}
$string = strtoupper($string);
if('S/MIME'==$string){
$this->smime(true);
}elseif('PGP'==$string){
$this->pgp(true);
}else{
return false;
}
$fg = $this->option( array( __FUNCTION__ => $string ) ,__LINE__);
return $fg;
}
function size( $kind = null ){
if(empty($this->header_for_smtp)){
$stack = $this->render_mode;
$this->render_mode = true;
$fg = $this->send();
$this->render_mode = $stack;
}
$this->size['ALL'] = strlen( bin2hex( $this->header_for_smtp . $this->LFC . $this->content_for_mailfunction )) / 2;
$this->size['HEADER'] = strlen( bin2hex( $this->header_for_smtp )) / 2;
$this->size['BODY'] = strlen( bin2hex( $this->content_for_mailfunction )) / 2;
if(is_null($kind)){
return $this->size;
}
$kind = strtoupper( $kind );
if(isset($this->size[$kind])){
return $this->size[$kind];
}
return false;
}
function sizeAll(){
return $this->size('ALL');
}
function sizeHeader(){
return $this->size('HEADER');
}
function sizeBody(){
return $this->size('BODY');
}
function smtpData(){
if(empty($this->header_for_smtp)){
$stack = $this->render_mode;
$this->render_mode = true;
$fg = $this->send();
$this->render_mode = $stack;
}
return $this->header_for_smtp . $this->LFC . $this->content_for_mailfunction ;
}
function smtpDataBody(){
if(empty($this->content_for_mailfunction)){
$stack = $this->render_mode;
$this->render_mode = true;
$fg = $this->send();
$this->render_mode = $stack;
}
return $this->content_for_mailfunction ;
}
function isQmail(){
if(!is_null($this->is_qmail)){
return $this->is_qmail;
}
$this->is_qmail = false;
$ret = ini_get ( 'sendmail_path' );
if(false !== strpos($ret,'qmail')){
$this->is_qmail = true;
}
$sendmail_path = ini_get('sendmail_path');
if(false !== @system($sendmail_path.' -d0.1 < /dev/null > /dev/null',$ret)){
if(is_array($ret)){
$ret = reset($ret);
}
$code = (int) substr($ret,0,3);
if( 100 === $code || 111 === $code){
$this->is_qmail = true;
}
}
return $this->is_qmail ;
}
function lineFeed( $LFC = null ){
if(is_null($LFC)){
return $this->LFC;
}
if(preg_match('/[\r|\n|\r\n]/is',$LFC)){
$this->LFC = $LFC;
return true;
}else{
return false;
}
}
function isWin(){
return false!==strpos(PHP_OS,'WIN');
}
//---------------------------------------
// something change mode
//---------------------------------------
function whichTextHtml( $which ){
$which = strtoupper( $which );
if( 'TEXT' == $which ){
$this->is_html='TEXT';
}elseif( 'HTML' == $which ){
$this->is_html='HTML';
}elseif( 'BOTH' == $which ){
$this->is_html='BOTH';
}
}
function allwaysBcc( $option = null ){
if( is_null( $option ) ){
return $this->allways_bcc ;
}
if( $this->option( array( __FUNCTION__ => $option ) ,__LINE__) ){
$fg = $this->extractAddr( $this->allways_bcc ) ;
}
if( $this->errorGather() && $fg && !empty($this->allways_bcc) ){
return true ;
}else{
$this->allways_bcc = array();
return false ;
}
}
function priority( $option = null ){
$fg=$this->option( array( __FUNCTION__ => $option ) ,__LINE__);
$priority = strtoupper($option);
if(empty($priority)){
return $fg;
}
$kind = array('HIGH'=>1,'NORMAL'=>1,'LOW'=>1);
if( !isset( $kind[$priority] ) ){
return $this->errorGather('Illegal Priority Name \''.$option.'\'',__LINE__);
}
foreach($this->priority_def as $header_name => $values){
$this->addHeader($header_name,$values[$priority]);
}
return $this->errorGather();
}
function certificatePass( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function certificateFilePath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function certificateTempPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function certificateFile( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function privateKeyFile( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function framework( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function attachPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function timeZone( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function messageIdRight( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function mtaOption( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function unitedCharset( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function varidateAddressRegex( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function sendmailPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function temporaryPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function logPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function errorlogPath( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function logDateFormat( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function logFilename( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function errorlogFilename( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function logLevel( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__, 0 , $this->log_level_max );
}
function errorlogLevel( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__, 0 , $this->errorlog_level_max );
}
function mimeEncodeMax( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__);
}
function smtpServer( $array = null ){
return $this->option( array( __FUNCTION__ => $array ) ,__LINE__, true , true );
}
function addressValidationMethod( $array = null ){
return $this->option( array( __FUNCTION__ => $array ) ,__LINE__, false , true );
}
//------------------
//version
//------------------
function version(){
return $this->version;
}
//------------------
//mb_ wrapper
//------------------
function qd_detect_encoding( $word ){
if(!is_null($this->united_charset)){
return $this->united_charset;
}else{
return mb_detect_encoding( $word , mb_detect_order() , true );
}
}
function qd_convert_encoding( $word , $target_chrset , $org_charset = null ){
if(empty($org_charset)){
$org_charset = $this->qd_detect_encoding( $word );
}
if(empty($org_charset)){
return $word;
}
if( strtoupper( $target_chrset ) === strtoupper( $org_charset ) ){
return $word;
}
if('ASCII'===strtoupper( $target_chrset ) || 'ASCII'===strtoupper( $org_charset )){
return $word;
}
return mb_convert_encoding( $word , $target_chrset , $org_charset );
}
function qd_detect_order( $param=null ){
if(is_null($param)){
return mb_detect_order();
}else{
return mb_detect_order( $param );
}
}
//-----------------------------------------
// Address and Name Keys change Opiton
//-----------------------------------------
function addressField( $addr = null , $name = null ){
if( is_null($addr) && is_null($name) ){
return array( $this->tokey['_ADDR'] , $this->tokey['_NAME'] );
}
if( !is_null($addr) && is_array($addr) && 1 < count($addr) ){
$_addr = array_shift( $addr ) ;
$name = array_shift( $addr ) ;
$addr = $_addr;
}
if( (!is_null($addr) && !is_string( $addr )) || !is_null($name) && !is_string($name) ){
return $this->errorGather('Specify Error in addressField',__LINE__);
}
$addr = is_null( $addr ) ? $this->tokey['_ADDR'] : $addr ;
$name = is_null( $name ) ? $this->tokey['_NAME'] : $name ;
$this->tokey = array(
'_ADDR' => $addr,
'_NAME' => $name,
);
return true;
}
//-----------------------------------------------------------
// Wordwrap Opiton
// array( 'except word' => beginning flag )
// if beginning flag is true , beginning of a line is target
// if beginning flag is true , the word in line is target
//-----------------------------------------------------------
function wordwrapProhibitConstruct(){
$ret = $this->strToArrayKey( $this->wrap_prohibit_top , true );
$ret2 = $this->strToArrayKey( $this->wrap_prohibit_end , false );
$this->wrap_prohibit = array_merge( $ret , $ret2 );
}
function strToArrayKey( $word , $value ){
$ret = array();
$enc = $this->qd_detect_encoding( $word );
$length = mb_strlen( $word , $enc );
for( $i=0 ; $i < $length ; $i++ ){
$ret[ mb_substr( $word , $i , 1 , $enc ) ] = $value;
}
return $ret;
}
function wordwrapAllow( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function wrapProhibitAllow( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function wrapProhibitEnd( $option = null ){
$this->option( array( __FUNCTION__ => $option ) ,__LINE__);
$this->wordwrapProhibitConstruct();
return $this->errorGather();
}
function wrapProhibitTop( $option = null ){
$this->option( array( __FUNCTION__ => $option ) ,__LINE__);
$this->wordwrapProhibitConstruct();
return $this->errorGather();
}
function wrapWidth( $bool = null ){
return $this->option( array( __FUNCTION__ => $bool ) ,__LINE__);
}
function wordwrapLength( $length = null ){
if( is_null( $length ) ){
return $this->wordwrap_length;
}
if( !is_numeric( $length ) || ( is_numeric( $length ) && $length < 1 ) ){
return $this->errorGather('Wordwrap error , length is illegal' ,__LINE__) ;
}
$this->wordwrap_length = $length;
return $this->errorGather() ;
}
function mbStrwidthMagni( $option = null ){
return $this->option( array( __FUNCTION__ => $option ) ,__LINE__, 0 , 10 );
}
function wrapExcept( $array = null ){
if( null === $array ){
return $this->wrap_except;
}
if( is_string( $array ) || is_numeric( $array ) ){
$this->wrap_except = array( $array =>false );//default false
}
if( is_array( $array ) ){
if( 0 === count( $array ) ){
$this->wrap_except = array();
return $this->errorGather() ;
}
foreach( $array as $key => $value){
if( !is_bool( $value ) ){
$array[$key] = empty( $value ) ? false:true;
}else{
$array[$key] = $value ;
}
}
$this->wrap_except = $array;
return $this->errorGather() ;
}
return $this->errorSpecify(__FUNCTION__,__LINE__);
}
//------------------------------------------
// Charset Option
//------------------------------------------
function charsetHeader( $charset = null ){
if(is_null($charset)){
return $this->charset_header ;
}
$stack = $this->charset();
$stack['HEADER'] = $charset;
return $this->charset( $stack );
}
function charsetAttach( $charset = null ){
if(is_null($charset)){
return $this->charset_attach_filename ;
}
$stack = $this->charset();
$stack['HEADER'] = $charset;
return $this->charset( $stack );
}
function charsetBody( $charset = null , $enc = null ){
if( is_null($charset) && is_null($enc) ){
return array($this->charset_content , $this->content_transfer_enc_text , content_transfer_enc_html) ;
}
if(is_array($charset)){
$enc = isset($charset[1]) ? $charset[1]:null;
$charset = $charset[0];
}
$stack = $this->charset();
if( !is_null($charset) ){
$stack['BODY'] = $charset;
}
if( !is_null($enc) ){
$stack['HTML'] = $stack['TEXT'] = $enc;
}
return $this->charset( $stack );
}
function charset( $array = null , $op = null ){
if( is_null( $array ) && is_null( $op ) ){
foreach( $this->corres_charset as $key => $value ){
$ret[$key] = $this->{$value} ;
}
return $ret;
}
if( !is_null($op) && is_string($op) ){
$this->content_transfer_enc_text = $op ;
$this->content_transfer_enc_html = $op ;
return $this->charset( $array );
}elseif(!is_null($op) && !is_string($op)){
return $this->errorSpecify( __FUNCTION__ , __LINE__ );
}
if( is_array( $array ) ){
if( 2===count($array) && isset($array[0]) && isset($array[1])){
return $this->charset($array[0],$array[1]);
}
$array = array_change_key_case( $array , CASE_UPPER );
foreach( $array as $key => $value ){
if(isset($this->corres_charset[$key])){
if( is_string($this->corres_charset[$key]) ){
$this->{$this->corres_charset[$key]} = $value;
}else{
return $this->errorSpecify( __FUNCTION__ , __LINE__ );
}
}
}
}elseif( is_string($array) ){
$this->charset_header = $this->charset_content = $this->charset_attach_filename = $array;
}else{
return $this->errorSpecify( __FUNCTION__ , __LINE__ );
}
return $this->errorGather() ;
}
function encoding( $enc = null ){
if(is_null($enc)){
return $this->corres_charset['TEXT'];
}
$this->corres_charset['TEXT'] = $this->corres_charset['HTML'] = $enc;
return true;
}
//--------------------------
// set Mutibye Parameter
//--------------------------
function setMbParameter( $lang = null , $internal_enc = null , $detect = null ){
if(is_array($lang)){
mb_language( $lang[0] ) ;
mb_internal_encoding( $lang[1] ) ;
$this->qd_detect_order( $lang[2] );
}elseif( 'STACK'===strtoupper($lang) ){
$this->mb_parameter_stack = array(mb_language(),mb_internal_encoding(),$this->qd_detect_order());
mb_language( $this->lang_def );
mb_internal_encoding( $this->encoding_def );
$this->qd_detect_order( $this->detect_def );
}else{
if( !is_null( $lang ) ){
mb_language( $lang ) ;
}
if( !is_null( $internal_enc ) ){
mb_internal_encoding( $internal_enc ) ;
}
if( !is_null( $detect ) ){
$this->qd_detect_order( $detect );
}
}
}
//--------------------------------
// Decorationable HTML Mail Opiton
// ( Inline HTML , MHTML )
// See $this->deco_def Property
//--------------------------------
// Change decoration default along to each career
function decoDef( $value = null ){
if( is_null( $value ) ){
return $this->deco_def_default;
}
$this->deco_def_default = $value ;
return $this->errorGather() ;
}
// fix Decoration Pattern by STRING means CareerName
function decoFix( $cari = null ){
if(is_null($cari)){
return $this->deco_kind;
}
$this->deco_kind = $this->decoSelect( $cari );
return true;
}
function decoSelect( $deco_kind = null ){
if( is_null( $deco_kind ) ){
return $this->deco_def_default;//$this->deco_judge
}
$deco_kind = strtoupper( $deco_kind );
$ret = false ;
foreach( $this->deco_def as $key => $def ){
if( in_array( $deco_kind , $def['OPTION_NAME'] ) ){
$ret = $key ;
$this->inline_mode = true;
}
}
return $ret;
}
// Change Decoration Pattern by E-mail Address
function decoJudge( $addr_array ){
$addr=$addr_array[$this->tokey['_ADDR']];
$start = strrpos( $addr , '@');
if(empty($start)){
return $this->deco_def_default;
}
$right = trim(substr($addr , $start+1));
$parts = explode('.',$right);
$ct = count($parts);
if( 2 > $ct ){
return $this->deco_def_default;
}
$domains = array();
$domains[] = $parts[$ct-2] . '.' . $parts[$ct-1];
if( isset($parts[$ct-3]) ){
$domains[] = $parts[$ct-3] .'.'.$parts[$ct-2] . '.' . $parts[$ct-1];
}
if( isset($parts[$ct-3]) && isset($parts[$ct-4]) ){
$domains[] = $parts[$ct-4] .'.'. $parts[$ct-3] .'.'.$parts[$ct-2] . '.' . $parts[$ct-1];
}
$ct = count($domains);
$domain = reset($domains);
while( $ct-- > 0){
if(isset( $this->deco_judge[$domains[$ct]])){
$domain = $domains[$ct];
break;
}
}
return $this->decoSelect(isset( $this->deco_judge[$domain] ) ? $this->deco_judge[$domain]:null);
}
//------------------------------------
//
// Word Replace
//
// You can add prefix by $this->rep_prefix proparty
// OR $this->repPrefix() Method (Recommended)
// notice: this functino need on utf-8
// OR $this->qdmail_system_charset need utf-8
//------------------------------------
function replaceWord( $array = null , $add = false ){
if( is_null( $array ) ){
return $this->replace ;
}
if( !is_array( $array ) ){
$array = array( $array );
}
foreach($array as $key => $arr){
if( !is_array( $arr ) ){
$array[$key] = array( $arr );
}
}
if( $add ){
$this->replace = array_merge( $this->replace , $array );
}else{
$this->replace = $array ;
}
return $this->errorGather() ;
}
function replaceDef( $array = null ){
if(is_null($array)){
return $this->replace_def;
}
if(is_array($array)){
$this->replace_def = $array;
}else{
return false;
}
}
function repPrefix( $option = null ){
return $this->stringOption( __FUNCTION__ , $option , __LINE__ );
}
function replace( $cont , $rep ){
foreach($rep as $serch => $replace ){
if( '_' == mb_substr( $serch , 0 , 1 , $this->qd_detect_encoding($serch) ) ){
continue;
}
if( empty($replace) && !empty($this->replace_def[$serch]) ){
$replace = $this->replace_def[$serch];
}
$reg = '/%' . $this->rep_prefix . (string) $serch . '%/is' ;
$cont = $this->qdmail_preg_replace( $reg , $replace , $cont );
}
return $cont;
}
function qdmail_preg_replace( $reg , $rep , $cont ){
$enc = $this->qd_detect_encoding( $cont );
$_reg = $this->qd_convert_encoding( $reg , $this->qdmail_system_charset , $this->qd_detect_encoding( $reg ) );
$_rep = $this->qd_convert_encoding( $rep , $this->qdmail_system_charset , $this->qd_detect_encoding( $rep ) );
$_cont = $this->qd_convert_encoding( $cont , $this->qdmail_system_charset , $enc );
$cont = preg_replace( $_reg , $_rep , $_cont );
return $this->qd_convert_encoding($cont , $enc , $this->qdmail_system_charset );
}
//------------------------------------
// OOP User Interface (Recommended)
//------------------------------------
function to( $addr = null , $name = null , $add = false ){
return $this->addrs( 'TO' , $addr , $name , $add );
}
function cc( $addr = null , $name = null , $add = false ){
return $this->addrs( 'CC' , $addr , $name , $add );
}
function bcc( $addr = null , $name = null , $add = false ){
return $this->addrs( 'BCC' , $addr , $name , $add );
}
function from( $addr = null , $name = null ){
return $this->addrs( 'FROM' , $addr , $name , false );
}
function replyto( $addr = null , $name = null ){
return $this->addrs( 'REPLYTO' , $addr , $name , false );
}
function addHeader( $header_name = null , $value = null){
if('REPLY-TO'==strtoupper($header_name)){
$header_name = 'REPLYTO' ;
}
if(isset($this->addr_head_name[strtoupper($header_name)])){
return $this->{strtolower($header_name)}( $value , null , true );
} if(is_null($header_name)){
return $this->other_header;
}
if('clear'===strtolower($header_name) && is_null($value)){
$this->other_header=array();
return ;
}
$this->other_header[$header_name] = $value ;
}
function reset( $debugErase = false ){
if( !$debugErase ){
$stack_debug = $this->debug ;
}
$stack = $this->stack_construct;
$array = get_class_vars( $this->name ) ;
foreach($array as $key => $value){
$this->{$key} = $value ;
}
$this->__construct( $stack );
if( !$debugErase ){
$this->debug = $stack_debug ;
}
}
function resetHeader(){
$this->to = array();
$this->cc = array();
$this->bcc = array();
$this->from = array();
$this->replyto = array();
$this->other_header=array();
$this->subject = null;
}
function resetBody(){
$this->body('');
$this->is_html = null;
$this->deco_kind = null;
$this->inline_mode = false;
$this->attach = array();
}
function resetHeaderBody(){
$this->resetBody();
$this->resetHeader();
}
function _gatherFromArray( $array , $key ){
$ret = array();
foreach( $array as $ar ){
$ret[] = $ar[$key] ;
}
return $ret;
}
function done(){
return $this->_gatherFromArray( $this->done , $this->tokey['_ADDR'] );
}
function undone(){
return $this->_gatherFromArray( $this->undone , $this->tokey['_ADDR'] );
}
function subject( $subj = null ){
if( is_null($subj) ){
return $this->subject;
}
if( is_string( $subj ) || is_numeric( $subj ) ){
$this->subject['CONTENT'] = (string) $subj;
return $this->errorGather() ;
}elseif( is_array($subj) ){
$subj = array_change_key_case( $subj , CASE_UPPER );
if(isset($subj['CONTENT'])){
$this->subject = $subj;
}else{
$this->subject['CONTENT'] = (string) $subj[0];
$this->subject['_CHARSET'] = isset($subj[1]) ? $subj[1] : null ;
$this->subject['_ORG_CHARSET'] = isset($subj[2]) ? $subj[2] : null ;
}
return $this->errorGather() ;
}else{
return $this->errorSpecify(__FUNCTION__,__LINE__);
}
}
function body( $type =null , $cont = null , $length = null , $charset = null , $enc = null , $org_charset = null ){
if(is_null($type)){
return $this->content;
}
if(empty($type)){
$this->content = array(
'TEXT'=>array(
'CONTENT' => null,
'LENGTH' => null,
'_CHARSET' => null,
'ENC' => null,
'_ORG_CHARSET' => null,
),
'HTML'=>array(
'CONTENT' => null,
'ORG_CONTENT' => null,
'LENGTH' => null,
'_CHARSET' => null,
'ENC' => null,
'_ORG_CHARSET' => null,
),
);
return true;
}
$type = strtolower( $type );
if( 'text'!==$type && 'html'!==$type ){
return $this->errorGather('You must use \'text\' or \'html\'' ,__LINE__) ;
}
if( is_array( $cont ) ){
$def = array(
'CONTENT'=>null,
'LENGTH'=>null,
'_CHARSET'=>null,
'ENC'=>null,
'_ORG_CHARSET'=>null,
);
$temp = array_change_key_case( array_merge($def,$cont) , CASE_UPPER);
}else{
$temp = array(
'CONTENT'=>$cont,
'LENGTH'=>$length,
'_CHARSET'=>$charset,
'ENC'=>$enc,
'_ORG_CHARSET'=>$org_charset,
);
}
$this->content[strtoupper($type)] = array_merge( $this->content[strtoupper($type)] , $temp );
return $this->errorGather() ;
}
function text( $cont , $length = null , $charset = null , $enc = null , $org_charset = null ){
return $this->body('text', $cont , $length , $charset , $enc , $org_charset );
}
function html( $cont , $charset = null , $enc = null , $org_charset = null ){
return $this->body('html', $cont , null , $charset , $enc , $org_charset );
}
//--------------------------
// assist User Interface
//--------------------------
function addrs( $section , $addr = null , $name = null , $add = false ){
$section = strtolower( $section );
$ck = array('to'=>true,'from'=>true,'cc'=>true,'bcc'=>true,'replyto'=>true);
if(empty($ck[$section])){
return $this->errorGather('Illegal Section Name \''.$section.'\'' ,__LINE__) ;
}
if( is_null( $addr ) && is_null( $name )){
return $this->{$section} ;
}
if( false === $addr ){
$this->{$section} = array();
return $this->errorGather() ;
}
$addr = $this->analyzeAddr( $addr , $name );
if( !$this->allow_blank_header && empty($addr[0][$this->tokey['_ADDR']]) ){// if addres is empty , no set
return true;
}
if( !$add ){
$this->{$section} = $addr;
}else{
$this->{$section} = array_merge( $this->{$section} , $addr );
}
return ( 0 != count( $addr ) );
}
function analyzeAddr( $addr , $name ){
if( is_string( $addr ) ){
if( empty( $name ) ){
list( $name , $addr ) = $this->_extractNameAddr( $addr );
}else{
$addr = $this->extractAddr( $addr );
}
return array(array( $this->tokey['_ADDR'] => $addr , $this->tokey['_NAME'] => $name ));
}
// $addr is array
## list( $addr , $void ) = $this->keyUpper( $addr );
$ret = array();
if( empty( $name ) || !is_array( $name ) ){
if(isset($addr[$this->tokey['_ADDR']])){
$addr[$this->tokey['_NAME']] = isset($addr[$this->tokey['_NAME']]) ? $addr[$this->tokey['_NAME']]:null;
return array( $addr );//ver 0.7.3a
}elseif( isset( $addr[0] ) && is_array( $addr[0] ) ){
foreach($addr as $ad){
## list( $ad , $void ) = $this->keyUpper( $ad );
$_addr = isset( $ad[$this->tokey['_ADDR']] ) ? $this->extractAddr( $ad[$this->tokey['_ADDR']] ) : $this->extractAddr( $ad[0] ) ;
if(isset( $ad[$this->tokey['_NAME']] ) ){
$_name = $ad[$this->tokey['_NAME']];
}elseif( isset( $ad[1] ) ){
$_name = $ad[1];
}else{
$_name = null;
}
if( empty($_addr) ){
continue;
}else{
$ret[] = array_merge( $ad , array( $this->tokey['_ADDR'] => $_addr , $this->tokey['_NAME'] => $_name ) );
}
}
return $ret;
}else{
$_addr = $this->extractAddr( $addr[0] );
$_name = isset($addr[1]) ? $addr[1]:null;
$ret[] = array($this->tokey['_ADDR'] => $_addr , $this->tokey['_NAME'] => $_name);
}
return $ret; //fool proof
}else{
foreach( $addr as $key => $value ){
$_addr = $this->extractAddr( $value );
$_name = $name[$key] ;
if( empty( $_addr ) ){
continue;
}else{
$ret[] = array( $this->tokey['_ADDR'] => $_addr , $this->tokey['_NAME'] => $_name );
}
}
return $ret;
}
return $ret; // fool proof
}
//--------------------------------------------------------
// From MutibyteName<[email protected]> To MutibyteName
//--------------------------------------------------------
function _extractNameAddr( $addr ){
$formed_addr = $this->extractAddr( $addr );
if( empty( $formed_addr ) ){
return false;
}
$addr = trim($addr);
$addr = str_replace(array('<','>'),'',$addr);
$temp=strpos($addr,$formed_addr);
if( false === $temp ){
return null;
}
return array( substr( $addr , 0 , strpos( $addr , $formed_addr )) , $formed_addr );
}
function setContentArgs( $type , $param ){
$method_name = 'text';
if('HTML' == $type ){
$method_name = 'html';
}
$cont = null;
if(isset($param[$type])){
$cont = $param[$type];
}elseif(isset($param['CONTENT'])){
$cont = $param['CONTENT'];
}
return $this->{$method_name}(
$cont ,
isset($param['_CHARSET']) ? $param['_CHARSET']:null,
isset($param['ENC']) ? $param['ENC']:null,
isset($param['_ORG_CHARSET']) ? $param['_ORG_CHARSET']:null
);
}
//-------------------------------------------
// Main Routine Send()
// Option analyize
// Is To-Separate Mode ?
// loop:sendbase
// Already Created Mail?
// Create mail
// Additional Parameter(From User) Analyize (e.g. charset , subject etc...)
// (Not OOP MODE)
// Build Header(except Content-type etc) and Must Header Checking
// Both mode ? text only or html only or both ? or auto both
// Addition Attachment will do
// Select Body Structure by Decoration Pattern or else
// Build Body ( Recursive )
// Render Body with 'Content-type' Header and Boundary etc..
// + finalize( Recursive )
// Pass to the Header,first Content-type etc. that needs by Header Render Routine
// Set Default Header, MIME 1.0 etc
// Render Header and Render for SMTP Sender Text(Future)
// Debug Echo & log & error log will do if you want
//If error exsist , no sender(except ignore_error Property)
//-------------------------------------------
function headerDefault(){
$this->header['MIME-Version'] = '1.0';
if($this->debug > 0 ){
$this->header['X-QdmailDebug'] = trim(chunk_split ( base64_encode($this->iniGather()) , $this->mime_encode_max , $this->LFC."\t" ));
}
$this->header['X-'.$this->xmailer] = trim('version-'.$this->version . ' ' . $this->license .' http://hal456.net/qdmail PHPver '.PHP_VERSION);
if($this->smtp){
$sendby = 'SMTP';
}elseif($this->sendmail && !ini_get('SafeMode')){
$sendby = 'Sendmail';
}elseif($this->sendmail && ini_get('SafeMode')){
$sendby = 'MailFunction but Sendmail if no Safemode';
}else{
$sendby = 'MailFunction';
}
$this->header['X-'.$this->xmailer] .= $this->LFC . chr(9) . 'send-by '.$sendby;
}
function makeMessageId(){
$req_uri = empty($_SERVER['REQUEST_URI']) ? '':$_SERVER['REQUEST_URI'];
if(is_null($this->message_id_right)){
$right = 'hal456.net';
}else{
$right = $this->message_id_right;
}
$id = 'Qdmail.' . $this->version
. '_' . sha1( microtime() . $this->salt . mt_rand() . $req_uri )
. '@' . $right ;
return '<'.$id.'>';
}
function send( $option = null ){
if( is_null( $this->start_time )){
$this->start_time = microtime();
}
// mb language
if( 'neutral' === mb_language() ){
$this->setMbParameter('stack');
}
if( is_object( $option ) ){
$this->smtp_object = & $option;
$this->smtp = true;
$option = null ;
}
// Date: header
if( !is_null($this->time_zone) ){
$other = array_change_key_case($this->other_header,CASE_UPPER);
if( !isset($other['DATE']) ){
$this->other_header['Date'] = date('D, d M Y h:i:s ') . $this->time_zone;
}
}
$fg = true;
if( true === $this->toSeparate() ){
$stack_tos = array( $this->to , $this->cc , $this->bcc );
$tos = $this->to ;
# $this->cc( false ) ;
# $this->bcc( false ) ;
if( empty( $tos ) ){
$fg = $this->errorGather('recipient Header is not exsit line' ,__LINE__) ;
}else{
// To Separate mode
foreach($tos as $key => $to){
if( $this->simple_replace ){
if($this->replace_with_to_priority){
$to = array_merge( $this->selectReplace( $to , $key ) ,$to );
}else{
$to = array_merge( $to , $this->selectReplace( $to , $key ) );
}
}
$this->to( $to , null , false );
$this->debugEchoLf($this->to);
if( $this->auto_deco_judge ){
$this->deco_kind = $this->decoJudge( $this->to[0] );
}
if( $this->sendBase() ){
$this->is_create = false; // for next to
continue ;
}else{
$this->is_create = false; // for next to
$fg = $this->errorGather('Error \'TO\' Separate mode in Sendbase function , the Address is -> '.$this->to[0][$this->tokey['_ADDR']] ,__LINE__) ;
}
}
}
list( $this->to , $this->cc , $this->bcc ) = $stack_tos ;
}else{
// normal mode the end
$fg = $this->sendBase() ;
$this->is_create = false;
}
$this->setMbParameter($this->mb_parameter_stack);
$this->log();
//debug
$this->debugEcho('END');
if( $fg ){
return $this->errorGather();
}else{
return $this->errorGather('Send Error' ,__LINE__) ;
}
}
function selectReplace( $to , $key ){
$ret = array();
if( isset( $this->replace[$to[$this->tokey['_ADDR']]] ) ){
$ret = $this->replace[$to[$this->tokey['_ADDR']]];
}elseif( isset( $this->replace[$key] ) ){
$ret = $this->replace[$key];
}
return $ret ;
}
function sendBase(){
// stack bcc for allways bcc
unset( $stack_bcc ) ;
if( 0 != count( $this->allways_bcc ) ){
$stack_bcc = $this->bcc ;
$this->bcc( $this->allways_bcc , null , true );
}
// Message Id
if( $this->message_id){
$other = array_change_key_case($this->other_header,CASE_UPPER);
if(!isset($other['MESSAGE-ID'])){
$this->other_header['Message-Id'] = $this->makeMessageId();
}
}
if( !$this->is_create ){
$this->body = null;
$this->after_id = null;
$this->createMail();
}
if( isset($option) && !empty($option) ){
list( $option , $void ) = $this->keyUpper( $option );
}
// for smtp and sendmail
$this->extractrecipient() ;
$fg = true;
$fg_debug = ( 2 > $this->debug ) && !$this->render_mode;
if( $fg_debug && ( ( 0 === count( $this->error ) ) && ( 0 === count( $this->error_stack ) ) ) || $this->ignore_error ) {
//
// mail or SMTP or sendmail
//
if( $this->smtp ){
$fg = $this->sendBySmtp();
}elseif( $this->sendmail && !ini_get('safe_mode') ){
$fg = $this->sendBySendmail();
}elseif( ini_get('safe_mode') ){
$fg = mail(
trim( $this->header_for_mailfunction_to )
, trim( $this->header_for_mailfunction_subject )
, $this->content_for_mailfunction
, trim( $this->header_for_mailfunction_other )
);
}else{
$fg = mail(
trim( $this->header_for_mailfunction_to )
, trim( $this->header_for_mailfunction_subject )
, $this->content_for_mailfunction
, trim( $this->header_for_mailfunction_other )
, trim( $this->mta_option )
);
}
if( $fg ){
$this->done = array_merge( $this->done , $this->to , $this->cc , $this->bcc ) ;
}else{
$this->undone = array_merge( $this->undone , $this->to , $this->cc , $this->bcc ) ;
$err_mes = $this->smtp ? 'SMTP mail method':'PHP mail function';
$err_mes = $this->sendmail ? 'sendmail of localhost':$err_mes;
$fg =$this->errorGather('No send . Because '.$err_mes.' replied error' ,__LINE__);
}
}elseif( $fg_debug ){
$this->undone = array_merge( $this->undone , $this->to , $this->cc , $this->bcc ) ;
$fg = $this->errorGather('Error happen, see upper' ,__LINE__);;
}else{
$this->undone = array_merge( $this->undone , $this->to , $this->cc , $this->bcc ) ;
$fg = true ;
}
//debug
$bcc = null;
if( !empty($this->header_for_smtp_bcc )){
$bcc = '('.$this->header_for_smtp_bcc.')';
}
$this->debugEchoLf(
$bcc ,
$this->content_all_for_smtp,
// $this->header_for_smtp,
// $this->content_for_mailfunction,
$this->LFC.$this->LFC ,
date('Y-m-d H:i:s')
);
if($this->debug_report){
$this->debugReport('FILE');
}
if( isset( $stack_bcc ) ){
$this->bcc = $stack_bcc ;
}
return $this->errorGather() && $fg;
}
//-----------------
// checking
//-----------------
function mustCheck(){
if( 0 == count( $this->header_must ) ){
return $this->errorGather() ;
}
$must = true;
foreach( $this->header_must as $hdn ){
$header_upp = array_change_key_case( $this->header , CASE_UPPER );
if( ( !$this->smtp && empty( $header_upp[strtoupper($hdn)] ) ) || ( $this->smtp && empty( $header_upp[strtoupper($hdn)] ) && !isset( $this->smtp_server['FROM'] ) ) ){
$must = $this->errorGather('Must Header is not exist \''.$hdn.'\'' ,__LINE__) ;
}
}
return $must;
}
//-----------------------------------------------
// Create one mail
//-----------------------------------------------
function createMail( $boundary = null , $boundary_fix = false){
$this->_charsetDefFix();
//
// content(body) force convert to utf-8 ,
// because some system function can't do collectlly whitout utf-8,ex preg_replace,striptags
//
$this->content = $this->convertCharsetRecursive( $this->content , $this->qdmail_system_charset );
$this->buildHeader();
if(!$this->mustCheck()){
return false;
};
// Text only or Html Only or both ?
if( empty( $this->is_html ) ){
if( $this->issetContent( $this->content['HTML'] ) && $this->issetContent( $this->content['TEXT'] ) ){
$this->is_html = 'BOTH' ;
}elseif( $this->issetContent( $this->content['HTML'] ) && $this->auto_both ){
$this->content['TEXT'] = array(
'content'=>$this->htmlToText( $this->content['HTML']['CONTENT'] )
);
$this->is_html = 'BOTH';
}elseif( $this->issetContent( $this->content['HTML'] ) && !$this->auto_both ){
$this->is_html = 'HTML';
}else{
$this->is_html = 'TEXT';
}
}
// Select Body Structure
if( !isset( $this->deco_kind ) ){
$structure_no = 0 ;
}else{
$structure_no = $this->deco_def[$this->deco_kind]['STRUCTURE'];
}
// Short cut on many recipients , samebody
if( !$this->body_build_once && $this->attach_build_once && $this->attach_already_build){
//only text and html making
$this->replaceBodyStructure('TEXT');
$this->replaceBodyStructure('HTML');
}elseif(
($this->body_build_once && !$this->body_already_build)
||
( !$this->body_build_once && ( !$this->attach_build_once || ( $this->attach_build_once && !$this->attach_already_build ) ) )
){
$this->body_structure = $this->buildBody( $this->structure[$structure_no] ,$boundary, false , $boundary_fix );
}
if( !$this->body_build_once || ($this->body_build_once && !$this->body_already_build) ){
$this->renderBody();//including Content-type Header
}
$this->header = array_merge($this->header , $this->header_content_type);
// user added header
$this->headerDefault();
$this->renderHeader();
//
// signed
//
if( false===$this->sign ){
$this->content_all_for_smtp = $this->header_for_smtp . $this->LFC . $this->content_for_mailfunction;
}elseif($this->pgp){
// future PGP
}else{
// S/MIME
$this->content_all_for_smtp = $this->signSmime();
if(false===$this->content_all_for_smtp){
return $this->errorGather('Sign Error S/MIME',__LINE__);
}
}
$this->is_create=true;
}
function signSmime(){
if( !$this->smtp ){
return $this->errorGather('S/MIME needs SMTP Send,now You spcify no smtp',__LINE__);
}
// Path to certificate file , by Win or other OS
if(empty($this->certificate_file_path)){
$this->certificate_file_path = $this->isWin() ? $this->certificate_file_path_win : $this->certificate_file_path_unix;
}
if(empty($this->certificate_temp_path)){
$this->certificate_file_path = $this->isWin() ? $this->certificate_file_path_win : $this->certificate_file_path_unix;
}
$path = $this->certificate_file_path . QD_DS ;
if('PFX'===strtoupper(substr($this->certificate_file,-3))){
if(!function_exists('openssl_pkcs12_read')){
return $this->errorGather('You can not specify *.pfx type, please *.pem type becuase your PHP Version do not support \'openssl_pkcs12_read\'',__LINE__);
}
if(openssl_pkcs12_read(file_get_contents($path.$this->certificate_file),$ret,$this->certificate_pass)){
$private_key = $ret['pkey'];
$certificate = $ret['cert'];
}else{
return $this->errorGather('Illegal Certificate File \''.$path.$this->certificate_file.'\' or Incorrect Password ',__LINE__);
}
}else{
$private_key = file_get_contents( $path . $this->private_key_file );
$certificate = file_get_contents( $path . $this->certificate_file );
}
$temp = sha1($this->content_for_mailfunction).'.txt';
$temp_filename = $this->certificate_temp_path.QD_DS.'temp'.$temp;
$temp_signed_filename = $this->certificate_temp_path.QD_DS.'temp_signed'.$temp;
$fp = fopen( $temp_filename , "w" );
fputs( $fp , $this->content_for_mailfunction . $this->LFC );
fclose($fp);
unset($this->header_for_smtp_array['MIME-Version']);
openssl_pkcs7_sign(
$temp_filename,
$temp_signed_filename,
$certificate,
array($private_key, $this->certificate_pass),
$this->header_for_smtp_array
);
$ret = file_get_contents($temp_signed_filename);
unlink ( $temp_signed_filename );
unlink ( $temp_filename );
return $ret;
}
function replaceBodyStructure( $kind ){
$content_type = ( 'TEXT' === $kind ) ? 'text/plain':'text/html';
$false = false;
$rep = & $this->serchBodyStructure( $content_type , $this->body_structure , $false );
if( false === $rep ){
return false;
}
list( $content , $charset , $enc ) = $this->makeContentText( $this->content[$kind] , $kind );
$rep['CONTENT'] = $content;
$rep['HEADER']['Content-Type'] = $content_type.'; charset="' . $charset . '"';
$rep['HEADER']['Content-Transfer-Encoding'] = $enc ;
}
function & serchBodyStructure( $content_type , & $bbs , & $false ){
foreach($bbs as $fkey => $bs){
if( isset( $bs['HEADER']) && ( 0 < count($bs['HEADER']))) {
$len = strlen($content_type);
foreach( $bs['HEADER'] as $key => $cont ){
if( ('CONTENT-TYPE' === strtoupper($key)) && ($content_type === substr($cont,0,$len)) ){
return $bbs[$fkey];
}
}
}
if( !isset( $bs['CONTENT']) || ( isset( $bs['CONTENT']) && !is_array( $bs['CONTENT']))){
continue;
}
$ret = & $this->serchBodyStructure( $content_type , $bbs[$fkey]['CONTENT'] , $false );
return $ret;
}
return $false;
}
//except Content-type,user option
function buildHeader(){
$header = array();
foreach( $this->addr_many as $section => $many ){
if( 0 == count( $this->{strtolower( $section )} ) ){
continue;
}
foreach( $this->{strtolower($section)} as $one ){
$mime=$this->mimeEncode(
$one[$this->tokey['_NAME']],
isset($one['_CHARSET']) ? $one['_CHARSET'] : $this->charset_header,
isset($one['_ORG_CHARSET']) ? $one['_ORG_CHARSET'] : null,
strlen($section)+2
);
// bcc header is not allowed MimeName
if( empty( $mime ) || 'BCC'===strtoupper( $section ) ){
$header[$this->addr_head_name[$section]][] = $one[$this->tokey['_ADDR']];
}else{
$header[$this->addr_head_name[$section]][] = $mime.' <'.$one[$this->tokey['_ADDR']].'>';
}
}
if( !$many ){
$header[$this->addr_head_name[$section]] = array( array_pop( $header[$this->addr_head_name[$section]] ) );
}
}
if( !empty( $this->subject ) ){
//replace
if( $this->simple_replace ){
$subj = $this->replace( $this->subject['CONTENT'] , $this->to[0] );
}else{
$subj = $this->subject['CONTENT'] ;
}
$header['Subject']=$this->mimeEncode(
$subj ,
isset($this->subject['_CHARSET']) ? $this->subject['_CHARSET']:$this->charset_header,
isset($this->subject['_ORG_CHARSET']) ? $this->subject['_ORG_CHARSET'] : null,
9 //strlen(subject)+2
);
}
$this->header = array_merge( $header , $this->other_header ) ;
}
function renderHeader(){
if(isset($this->header['To'])){
$this->header_for_mailfunction_to = implode( ','.$this->LFC.' ' , $this->header['To'] );
unset( $this->header['To'] ) ;
}
if(isset($this->header['Subject'])){
$this->header_for_mailfunction_subject = $this->header['Subject'];
unset( $this->header['Subject'] ) ;
}
$this->header_for_mailfunction_other = null;
$header_for_smtp = array();
$this->header_for_smtp_bcc = null;
$header_for_smtp['To'] = $this->header_for_mailfunction_to;
$header_for_smtp['Subject'] = $this->header_for_mailfunction_subject;
foreach( $this->header as $key => $value ){
if( is_array( $value ) ){
$add = implode( ',' . $this->LFC . chr(9) , $value );
}else{
$add = $value;
}
if( 'BCC' !== strtoupper($key) ){
$header_for_smtp[$key] = $add ;
}else{
$this->header_for_smtp_bcc = $key . ': ' . $add . $this->LFC ;
}
$this->header_for_mailfunction_other .= $key . ': ' . $add . $this->LFC;
unset( $this->header[$key] );
}
$this->header_for_smtp = '';
foreach($header_for_smtp as $key => $value){
$this->header_for_smtp .= $key.': '.$value.$this->LFC;
}
if($this->smime){
$this->header_for_smtp_array = $header_for_smtp;
}
}
//-------------------------
// $ret = array(
// 'BOUNDARY' =>
// 'HEADER' =>
// 'CONTENT' =>array(
// (Recursive)
// )
// )
//-------------------------
function isInlineImage($filename){
if(!empty($this->content['HTML']['ORG_CONTENT'])){
$cont = $this->content['HTML']['ORG_CONTENT'];
}
if(!empty($this->content['HTML']['CONTENT'])){
$cont = $this->content['HTML']['CONTENT'];
}
if(empty($cont)){
return false;
}
$enc = $this->qd_detect_encoding($cont);
$cont = $this->qd_convert_encoding($cont,'UTF-8',$enc);
$name = $filename;
$enc = $this->qd_detect_encoding($name);
$name = $this->qd_convert_encoding($filename,'utf-8',$enc);
if( 0 < preg_match('/"cid:'.$name.'"/is' , $cont ) ){
return true;
}else{
return false;
};
}
function buildBody( $structure , $boundary = null , $rel = false , $boundary_fix = false){
$ret = array();
$one = array();
if( is_null( $boundary ) ){
$boundary = $this->makeBoundary();
}
$ret_boundary = $boundary ;
foreach($this->attach as $key => $att){
if($this->isInlineImage(basename($this->attach[$key]['PATH'])) && empty($this->attach[$key]['CONTENT-ID'])){
$this->attach[$key]['CONTENT-ID'] = basename($this->attach[$key]['PATH']);
}
}
foreach( $structure as $key => $value ){
$ret_header = array();
$ret_cont = array();
if( is_array( $value ) ){
$next_boundary = $boundary_fix ? $boundary:$this->makeBoundary();
$ret_header['Content-Type'] = strtolower($key).';' . $this->LFC
. ' boundary="' . $next_boundary . '"' ;
$rel = false;
$ret_cont = $this->buildBody( $value , $next_boundary , $rel);
if( 0 == count($ret_cont) && $structure['OMIT']){
continue;
}elseif( 1 == count($ret_cont) && $structure['OMIT']){
$one = null;
$ret_cont[0]['BOUNDARY'] = '--'.$boundary ;
$ret[] = $ret_cont[0];
continue;
}else{
$one = null;
$ret_cont[] = array( 'BOUNDARY' => null ,'HEADER' => array() ,'CONTENT' => '--' . $next_boundary . '--' );
$ret[] = array( 'BOUNDARY' => '--' . $ret_boundary , 'HEADER' => $ret_header , 'CONTENT' => $ret_cont );
continue;
}
}else{
switch( strtolower($key) ){
case 'image':
foreach( $this->attach as $att){
if( ( 'INLINE' === $value ) && $this->isSetCid( $att ) ){
$ret_cont[]= $this->buildAttach( $att , $boundary , true ) ;
}elseif( ( 'NOT_INLINE' === $value ) && !$this->isSetCid( $att )){
$ret_cont[] = $this->buildAttach( $att , $boundary , false ) ;
}if( 'BOTH' === $value ){
$ret_cont[] = $this->buildAttach( $att , $boundary , $this->isSetCid( $att ) ) ;
}
}
break;
case 'html':
$this->content['ORG_CONTENT'] = $this->content['HTML'];
list( $content , $charset , $enc ) = $this->makeContentText( $this->content['HTML'] , 'HTML' );
$ret_header['Content-Type'] = 'text/html; charset="' . $charset . '"';
$ret_header['Content-Transfer-Encoding'] = $enc ;
$ret_cont = $content ;
break;
case 'plain':
list( $content , $charset , $enc ) = $this->makeContentText( $this->content['TEXT'] , 'TEXT' );
$ret_header['Content-Type'] = 'text/plain; charset="' . $charset . '"';
$ret_header['Content-Transfer-Encoding'] = $enc ;
$ret_cont = $content ;
break;
case 'omit':
$one = null;
break;
}
if( !empty($ret_cont) ){
$ret[] = array( 'BOUNDARY' => '--' . $boundary , 'HEADER' => $ret_header , 'CONTENT' => $ret_cont );
}
}
}
return $ret ;
}
function renderBody(){
if( ( 0 === count( $this->body_structure ) ) && !$this->body_empty_allow ){
return $this->errorGather('Empty Body do not allowed. If you want to send empty Mail , use method -> bodyEmptyAllow(true)' ,__LINE__) ;
}elseif( 0 === count( $this->body_structure ) ){
$this->body_structure[0]['HEADER'] = array();
}
if( !$this->smime ){
foreach( $this->body_structure[0]['HEADER'] as $key => $value){
$this->header_content_type[$key]=$value;
}
$this->body_structure[0]['HEADER'] = array();
}
$this->body_structure[0]['BOUNDARY'] = null;
$this->content_for_mailfunction = rtrim($this->finalize( $this->body_structure )) ;
$this->body_already_build = true ;
}
function finalize( $array ){
foreach( $array as $ar ){
$header = $this->expandHeader( $ar['HEADER'] );
$bd = isset($ar['BOUNDARY']) ? trim($ar['BOUNDARY']) . $this->LFC : null ;
if(is_array($ar['CONTENT'])){
if( !empty( $header ) ){
$this->body = $this->body . $bd . $header . $this->LFC . $this->LFC ;
}
$this->finalize( $ar['CONTENT'] );
}else{
if( !empty( $header ) ){
$header .= $this->LFC . $this->LFC ;
}
$add = $bd . $header . $ar['CONTENT'] ;
$this->body = $this->body . $add . $this->LFC . $this->LFC ;
}
}
return $this->body;
}
function expandHeader( $hds ){
if(empty($hds)){
return null;
}
$header = null;
foreach( $hds as $key => $value ){
if( isset( $value ) ){
$header .= $key . ': ' . $value . $this->LFC;
}
}
return trim($header);
}
function makeBoundary(){
static $rec = 0 ;
$boundary = '__Next-' . $rec . '-' . $this->qdmail_md( null , 65 , 90 ) . 'UWRtYWlsIEFHUEx2Mw==' . base64_encode( $this->qdmail_md() ) . '__';
$rec ++ ;
return $boundary;
}
function makeContentText( $content , $is_text = 'TEXT' ){
$flag_wrp = ( 'TEXT' == $is_text ) ? true:false;
$enc = ( 'HTML' == $is_text ) ? $this->content_transfer_enc_html : $this->content_transfer_enc_text ;
if( is_array( $content ) ){
$content = array_change_key_case( $content , CASE_UPPER );
$_content = $content['CONTENT'];
$org_char = $this->qdmail_system_charset ; //already converted to system charaset
$target_char = isset($content['_CHARSET'])
? $content['_CHARSET'] : $this->charset_content;
$length = isset($content['LENGTH'])
? $content['LENGTH'] : $this->wordwrap_length;
$content_transfer_enc = !empty($content['ENC'])
? $content['ENC'] : $enc;
$content = $_content;
}else{
$org_char = $this->qdmail_system_charset ;
$target_char = $this->charset_content;
$length = $this->wordwrap_length;
$content_transfer_enc = $enc;
}
// fix crlf
list($content,$void) = $this->clean($content);
// Content_replace
if( $this->simple_replace ){
$content = $this->replace( $content , $this->to[0] );
}
// Content-id replace
if(!$this->content_id_fix){
$content = $this->replaceCid( $content );
}
// content modify by external function at HTML
if( 'HTML' == $is_text && isset($this->deco_kind) && isset($this->deco_def[$this->deco_kind]['HTML_EXTERNAL']) ){
$temp = $this->deco_def[$this->deco_kind]['HTML_EXTERNAL'];
if( is_array( $temp ) && 'this'==$temp[0]){
$content = $this->{$temp[1]}($content);
}elseif( !empty( $temp ) ){
$content = call_user_func( array($temp[0],$temp[1]) , $content);
}
}
if( $this->wordwrap_allow && $flag_wrp && false !== $length ){
$content = $this->mbWordwrap( $content , $length );
}
$enc_upp = strtoupper($content_transfer_enc);
if( $this->kana && 'ja'===$this->language && (('BASE64' === $enc_upp && $this->kana_content_relation) || 'BASE64' !== $enc_upp )){
$content = mb_convert_kana( $content , 'KV' , $org_char );
}
$content = $this->qd_convert_encoding( $content , $target_char , $org_char );
if( 'BASE64' == $enc_upp && !empty( $content ) ){
$content = chunk_split( base64_encode( $content ) );
}elseif( ( 'QUOTED-PRINTABLE' == $enc_upp || 'QP' == $enc_upp ) && !empty( $content ) ){
$content_transfer_enc = 'quoted-printable';
$content = $this->quotedPrintableEncode( $content );
}
return array( $content , $target_char , $content_transfer_enc );
}
//--------------
// html => text
// must utf-8 because of preg_replace & strip_tags function
//--------------
function htmlToText( $html ){
$_content = str_replace( array( "\r" , "\n" ) , '' , $html );
$_content = preg_replace( array( '/<br>/i','/<\/p>/i' , '/<br\s*\/>/i' , '/<\/div>/i' , '/<\/h[1-9]>/i' , '/<\/ol>/i' , '/<\/dl>/i' , '/<\/ul>/i' , '/<li>/i' , '/<\/li>/i' , '/<\/dd>/i' , '/<\/blockquote>/i' , '/<hr\s*\/?>/i' , '/<\/tr>/i' , '/<\/caption>/i' ), $this->LFC , $_content );
$_content = preg_replace( array( '/<\/td>/i' , '/<\/th>/i' ), ' ' , $_content );
$_content = preg_replace( "/\\r?\\n/", "\n" , $_content );
$_content = preg_replace( "/[\\n]+/", "\n" , $_content );
$_content = preg_replace( "/\\n/", $this->LFC , $_content );
return trim(strip_tags($_content));
}
function mimeEncode( $subject , $charset , $org_charset = null , $first_line_front_words_length = 12 ) {
$enc = isset($org_charset) ? $org_charset:$this->qd_detect_encoding($subject);
if( empty($subject) || ( strlen(bin2hex($subject))/2 == mb_strlen($subject,$enc) ) ){
return trim(chunk_split($subject, $this->mime_encode_max, "\r\n "));
}
if($this->kana && 'ja'===$this->language){
$subject = mb_convert_kana( $subject , 'KV' , $enc );
}
$subject = $this->qd_convert_encoding( $subject , $charset , $enc );
$start = "=?" . $charset . "?B?";
$end = "?=";
$spacer = $end . $this->LFC . chr(9) . $start;
$length = $this->mime_encode_max - strlen($start) - strlen($end);
$pointer = 1;
$cut_start = 0;
$line = null;
$_ret = array();
$max = mb_strlen( $subject ,$charset );
while( $pointer <= $max ){
$line = mb_substr( $subject , $cut_start , $pointer-$cut_start , $charset );
$bs64len = strlen(bin2hex(base64_encode($line)))/2;
if( (0!==count($_ret) && $bs64len <= $length) || (0===count($_ret) && $bs64len <= ($length-$first_line_front_words_length)) ){
$pointer ++;
}else{
$_ret[] = base64_encode($line) ;
$cut_start = $pointer;
}
}
if( strlen( trim( $line ) ) > 0){
$_ret[] = base64_encode( $line );
}
$ret = $start . implode( $spacer , $_ret ) . $end;
$ret = preg_replace(array('/\0/is','/\r[^\n]/is'),'',$ret);
return $ret ;
}
function extractAddr($addr_including_sclub){
if( preg_match( '/<([^>]+)>/' , $addr_including_sclub , $match ) == 0){
$addr = $addr_including_sclub;
}else{
$addr = $match[1];
}
$temp = $this->address_validation_method;
if( is_array( $temp ) && 'this'==$temp[0]){
$fg = $this->{$temp[1]}( $addr );
$mess ="System";
}elseif( !empty( $temp ) ){
$fg = call_user_func( array($temp[0],$temp[1]) , $addr );
$mess ="USER";
}
if( $fg ){
return $addr ;
}else{
return $this->errorGather('Illegal Mail Address'.$mess.'Validete Address Method' ,__LINE__) ;
}
}
//----------------------------------------------------------------
// Charset ReDecear - if Decoration Pattern needs anather charset
// (Overload)
//----------------------------------------------------------------
function _charsetDefFix(){
if( !isset( $this->deco_kind ) ){
return ;
}
if(isset($this->deco_def[$this->deco_kind]['_CHARSET'])){
$this->charset_content = $this->deco_def[$this->deco_kind]['_CHARSET'];
}
if(isset($this->deco_def[$this->deco_kind]['ENC_TEXT'])){
$this->content_transfer_enc_text = $this->deco_def[$this->deco_kind]['ENC_TEXT'];
}
if(isset($this->deco_def[$this->deco_kind]['ENC_HTML'])){
$this->content_transfer_enc_html = $this->deco_def[$this->deco_kind]['ENC_HTML'];
}
}
//------------------------------------------------------------
// Addition Header(in send( param ) ) set to $this->{to} etc.
// and return UpperCase keys
//------------------------------------------------------------
function setAddr( $header ){
if( empty( $header ) ){
return array( $header , array() );
}
list( $header , $link_hd )= $this->keyUpper( $header );
foreach( $this->addr_many as $section => $void){
if( !isset( $header[strtoupper($section)] ) ){
continue;
}
$this->{strtolower( $section )}( $header[strtoupper($section)] , null , true );
unset( $header[strtoupper( $section )] );
}
// TO Separate mode?
if( true === $this->toSeparate() ){
$this->cc(false);
$this->bcc(false);
}
return array( $header , $link_hd );
}
function convertCharsetRecursive( $array , $target_enc ){
if( is_array( $array ) && !empty( $array['_ORG_CHARSET'] ) ){
foreach($array as $key => $value){
if( false === strpos( $key , '_CHARSET' ) ){
$array[$key] = $this->qd_convert_encoding($value , $target_enc ,$array['_ORG_CHARSET'] );
}
}
}elseif( is_string( $array ) || is_numeric( $array ) ){
$enc = $this->qd_detect_encoding( $array );
$array = $this->qd_convert_encoding($array , $target_enc , $enc );
}elseif( is_array( $array ) ){
foreach( $array as $key => $value ){
$ret[$key] = $this->convertCharsetRecursive( $value , $target_enc );
}
$array = $ret ;
}elseif( empty( $array ) ){
$array = null ;
}else{
$this->error[]='Error convertCharsetRecursive, invalid type ,line->'.__LINE__;
}
return $array ;
}
function extractrecipient(){
$hd = array('to','cc','bcc') ;
$ret = array();
foreach( $hd as $hdn ){
foreach($this->{$hdn} as $addr ){
$ret[] = $addr[$this->tokey['_ADDR']] ;
}
}
if( 0 === count( $ret ) ){
return $this->errorGather('No recipient' ,__LINE__) ;
}else{
$this->recipient = $ret ;
return $this->errorGather();
}
}
//------------------------------------------------------------------------
// Attachment Routine
// attach - set to $this->attach array
// attach OneArray(1 array pattern array('path','attacheName'))
// attach Singe (2 string pattern ('path','attacheName') )
// attachFull - Base Routine allattch routine call him
// buildAttach - called buildBody method
//------------------------------------------------------------------------
//
//
//array('path_filename','attach_name','mime_type','target_charset','org_charset', );
//
//
//
function attach( $param , $add = false ){
list( $stack , $this->attach ) = array( $this->attach , array() );
if(is_string($param)){
$param = array($param);
}
if( ($this->inline_mode || $this->simple_attach) && !is_array($param[0])){
foreach($param as $one){
$param_temp[] = array( $one );
}
$param = $param_temp;
}
$te_st = reset($param);
if(!is_array($te_st)){
$param = array( $param );
}
foreach($param as $par){
if(empty($par)){
continue;
}
$path_filename = isset($par['PATH']) ? $par['PATH']:$par[0];
if(isset($par['NAME'])){
$attach_name = $par['NAME'];
}elseif(isset($par[1])){
$attach_name = $par[1];
}else{
$attach_name = basename( $path_filename ) ;
}
$mime_type = null;
if(isset($par['CONTENT-TYPE'])){
$mime_type = $par['CONTENT-TYPE'];
}elseif(isset($par['MIME-TYPE'])){
$mime_type = $par['MIME-TYPE'];
}elseif(isset($par[2])){
$mime_type = $par[2];
}
$content_id = null;
if(isset($par['CONTENT-ID'])){
$content_id = $par['CONTENT-ID'];
}elseif(isset($par[3])){
$content_id = $par[3];
}
$target_charset = null;
if(isset($par['_CHARSET'])){
$target_charset = $par['_CHARSET'];
}elseif(isset($par[4])){
$target_charset = $par[4];
}
$org_charset = null;
if(isset($par['_ORG_CHARSET'])){
$org_charset = $par['_ORG_CHARSET'];
}elseif(isset($par[5])){
$org_charset = $par[5];
}
$direct = null;
if(isset($par['DIRECT'])){
$direct = $par['DIRECT'];
}elseif(isset($par[6])){
$direct = $par[6];
}
$bare = false;
if(isset($par['BARE'])){
$bare = $par['BARE'];
}elseif(isset($par[7])){
$bare = $par[7];
}
$this->attach[] = array(
'PATH' => $path_filename,
'NAME' => $attach_name,
'CONTENT-TYPE' => $mime_type,
'CONTENT-ID' => $content_id,
'_CHARSET' => $target_charset,
'_ORG_CHARSET' => $org_charset,
'DATA' => $direct,
'DIRECT' => isset($direct) ,
'BARE' => $bare,
);
}
if($add){
$this->attach = array_merge( $stack , $this->attach );
}
$this->attach_already_build = false ;
return $this->errorGather() ;
}
//--------------------------------------------------------
// Build attachment one file , called by buildBody method
// $one is array , no recursive ,must ['PATH'] element
//--------------------------------------------------------
function buildAttach( $one , $boundary , $inline){
$ret_boundary = null;
$ret_header = array();
$ret_content = null;
$one = array_change_key_case( $one , CASE_UPPER);
if( !isset($one['NAME'] )){
$one['NAME'] = basename( $one['PATH'] );
}
//Content-Type
if( isset( $one['CONTENT-TYPE'] )){
$type = $one['CONTENT-TYPE'];
}elseif( 0 != preg_match( '/\.([^\.]+)$/' , $one['NAME'] , $matches )){
$type = isset( $this->attach_ctype[strtolower($matches[1])] )
? $this->attach_ctype[strtolower($matches[1])] : 'unkown';
}elseif(0 != preg_match( '/\.([^\.]+)$/' , $one['PATH'] , $matches )){
$type = isset( $this->attach_ctype[strtolower($matches[1])])
? $this->attach_ctype[strtolower($matches[1])] : 'unkown';
if( $this->auto_ext && 'unkown' != $type ){
$one['NAME'] .= '.'.$matches[1];
}
}else{
$type = 'unkown';
}
if( isset( $one['_CHARSET'] ) ){
$charset = $one['_CHARSET'];
}else{
$charset = $this->charset_attach_filename;
}
if( isset( $one['_ORG_CHARSET'] ) ){
$org_charset = $one['_ORG_CHARSET'];
}else{
$org_charset = null;
}
$filename = $this->mimeEncode( $one['NAME'] , $charset , $org_charset , 20 );
//is Inline ?
if( $inline ){
$id = $this->content_id_fix ? $one['CONTENT-ID']:$this->makeContentId($one['CONTENT-ID']);
$content_id = '<' . $id . '>' ;
$content_disposition = 'inline';//attachment for au?
}else{
$content_id = null ;
$content_disposition = 'attachment';
}
// do it need Disposition Heaer ?
if( isset( $this->deco_kind ) && false===$this->deco_def[$this->deco_kind]['DISPOSITION']){
$disposition = null;
}else{
$disposition = $content_disposition.';'.$this->LFC
.' filename="'.$filename.'"'
;
}
$ret_boundary = '--'.$boundary ;
$ret_header['Content-Type'] = $type.'; name="'.$filename.'"'
;
$ret_header['Content-Transfer-Encoding'] = 'base64' ;
$ret_header['Content-Id'] = isset($content_id) ? trim( $content_id ) : null ;
if(!empty($disposition)){
$ret_header['Content-Disposition'] = $disposition;
}
if( !empty( $one['DIRECT'] ) ){
$cont=$one['DATA'];
}else{
$path_filename = $this->attachPathFix( $one['PATH'] );
if( !file_exists ( $path_filename )){
$this->error[]='No attach file \''.$path_filename.'\' line->'.__LINE__;
return false;
}else{
$cont=file_get_contents( $path_filename );
}
}
if( isset( $one['BARE'] ) && true === $one['BARE'] ){
$ret_content = $one['DATA'];
}else{
$ret_content = trim(chunk_split(base64_encode($cont)));
}
$this->attach_already_build = true;
return array(
'BOUNDARY' =>$ret_boundary ,
'HEADER' =>$ret_header ,
'CONTENT' =>$ret_content
);
}
function isSetCid( $array ){
return isset( $array['CONTENT-ID'] ) && ( '' !== $array['CONTENT-ID'] ) ;
}
function makeContentId( $id ){
if( is_null( $this->after_id ) ){
$fromaddr = isset($this->header['From'][0]) ? $this->extractAddr($this->header['From'][0]):null;
$this->after_id = mt_rand() . '_'. str_replace(array('@','-','/','.'),'', $fromaddr .'_'. $this->xmailer.'_'.$this->version );
}
return str_replace(array('@','-','/','.'),'', 'id_'.$id ).'_@_'. $this->after_id ;
}
function replaceCid( $content ){
if( !isset( $this->deco_kind ) ){
return $content;
}
foreach($this->attach as $att){
if( $this->isSetCid( $att ) ){
$orig = preg_quote($att['CONTENT-ID'] ,'/');
$rep = $this->makeContentId( $att['CONTENT-ID'] );
$content = preg_replace('/(<\s*img[^>]+src\s*=\s*"cid:)' . $orig . '("[^>]*>)/is','${1}'.$rep.'${2}' ,$content);
}
}
return $content ;
}
function attachDirect( $attach_name , $data , $add = false , $mime_type = null , $content_id = null , $target_charset = null , $charset_org = null){
$_att=array();
$_att[0]['DIRECT'] = true;
$_att[0]['DATA'] = $data;
$_att[0]['PATH'] = null;
$_att[0]['NAME'] = $attach_name ;
$_att[0]['MIME_TYPE'] = $mime_type ;
$_att[0]['CONTENT-ID'] = $content_id ;
$_att[0]['_CHARSET'] = $target_charset;
$_att[0]['_ORG_CHARSET'] = $charset_org;
if( $add ){
$this->attach = array_merge( $this->attach , $_att );
}else{
$this->attach = $_att ;
}
return $this->errorGather() ;
}
function attachPathFix( $path_filename ){
$temp = substr($path_filename,0,1);
if( '/' != $temp && '\\' != $temp ){
return $this->attach_path . $path_filename;
}
return $path_filename;
}
//---------------------------------------
//
// Inteligent Multibyte Wordwrap
//
//---------------------------------------
function mbWordwrap( $word , $length ){
if( !is_numeric( $length ) ){
$length = $this->wordwrap_length;
}
if( 1 > $length ){
$this->error[]='Wordwrap length illegal , need more than 1 line->'.__LINE__;
}
$ret = array();
list( $word , $LFC ) = $this->clean( $word );
$lines = explode( $LFC , $word ) ;
foreach($lines as $line){
$ret []= $this->mbWordwrapLine( $line , $length );
}
return implode( $this->LFC , $ret );
}
function mbWordwrapLine( $line , $length ){
$skip = false;
if( 0 != count( $this->wrap_except ) ){
foreach($this->wrap_except as $word => $begin_flag ){
$fg = strpos( $line , $word );
if( ( ( 0 === $fg ) && $begin_flag) || ( ( false !== $fg ) && !$begin_flag) ){
$skip = true;
}
}
}
$enc = $this->qd_detect_encoding( $line );
$len = mb_strlen( $line , $enc );
if ( ( $len <= $length ) || $skip ) {
return $line;
}
if( $this->wrap_width ){
$method = 'widthSubStr';
}else{
$method = 'defMbSubStr';
}
$ret = array();
$ln = $length;
$j = 0;
for( $i=0; $i < $len ; $i += $ln ){
list( $r , $ln ) = $this->{$method}( $line , $i , $length , $enc );
if( 0 !== $j ){
list( $r , $no_top , $flag )=$this->mbProhibitTop( $r , $enc );
if( $flag ){
$ret[$j-1] .= $no_top ;
$i += mb_strlen( $no_top , $enc );
list( $r , $ln ) = $this->{$method}( $line , $i , $length , $enc );
}
}
if( ( $i + $ln ) < $len ){
list( $_r , $ret_count , $flag )=$this->mbProhibitEnd( $r , $enc );
if( $flag && ( $ret_count < ($length-1) ) ){
$i -= $ret_count;
$r = $_r;
}
}
$ret [$j++]= $r ;
}
return implode( $this->LFC , $ret ) ;
}
function defMbSubStr( $line , $start , $length , $enc ){
return array( mb_substr( $line , $start , $length , $enc ) ,$length );
}
function widthSubStr( $line , $start , $length , $enc ){
$ret = array();
$max = mb_strlen( $line , $enc ) ;
$target = mb_substr( $line , $start , $length , $enc ) ;
$point = $start + $length;
// mb_strwidth's lengh means ascii width
while( ( mb_strwidth( $target , $enc ) <= ( $length-1 ) * $this->mb_strwidth_magni ) && ( $point < $max ) ){
$target .= mb_substr( $line , $point++ , 1 , $enc ) ;
}
return array( $target , mb_strlen( $target , $enc ) ) ;
}
function mbProhibitTop( $line , $enc ){
$flag = false;
$ret = null;
$len = mb_strlen( $line , $enc );
$count = 0 ;
do{
$top = mb_substr( $line , $count++ , 1 , $enc );
}while( isset($this->wrap_prohibit[$top]) && $this->wrap_prohibit[$top] && ( abs($count) < $len ) );
-- $count ;
if( 0 < $count ){
$ret = mb_substr( $line , 0 , $count , $enc );
$line = mb_substr( $line , $count , $len - $count , $enc );
$flag = true;
}
return array( $line , $ret , $flag );
}
function mbProhibitEnd( $line , $enc ){
$flag = false;
$len = mb_strlen( $line , $enc );
$count = 0 ;
do{
$end = mb_substr( $line , --$count , 1 , $enc );
}while( isset($this->wrap_prohibit[$end]) && !$this->wrap_prohibit[$end] && ( abs($count) < $len ) );
$count = abs( ++$count );
if( 0 < $count ){
$line = mb_substr( $line , 0 , $len - $count , $enc );
$flag = true;
}
return array( $line , $count , $flag );
}
//------------------------
// utility
//------------------------
function issetContent( $array ){
if( !isset( $array ) ){
return false ;
}
if( isset( $array['CONTENT'] ) ){
return true ;
}
if( isset( $array ) && is_string( $array ) ){
return true ;
}
return false ;
}
function keyUpper( $array ){
$up_array = array_change_key_case( $array , CASE_UPPER );
$link = $this->qdmail_array_combine( array_keys( $up_array ) , array_keys( $array ));
return array( $up_array , $link );
}
function qdmail_array_combine( $keys , $values ){//for php4
if( !is_array( $keys ) || !is_array( $values ) ){
$this->error[]='array_conbine needs array line =>'.__LINE__;
}
$ret = array();
reset( $values );
foreach( $keys as $key ){
$ret[$key] = array_shift( $values ) ;
}
return $ret;
}
function qdmail_md( $col = null , $start = 33 , $end = 126 ){
if( is_null( $col ) ){
$col = $this->boundary_base_degit ;
}
$ret = null;
for( $i = 0 ; $i < $col ; $i++){
$ret .= chr( mt_rand( $start , $end ) ) ;
}
return $ret;
}
function clean( $content ){
if($this->smtp ){
$LFC = $this->LFC;
}else{
$LFC = chr(10);
}
return array(rtrim( preg_replace( '/\r?\n/' , $LFC , $content ) ),$LFC);
}
function quotedPrintableEncode( $word ){
if(empty($word)){
return $word;
}
$lines = preg_split("/\r?\n/", $word);
$out = array() ;
foreach ($lines as $line){
$one_line = null ;
for ($i = 0; $i <= strlen($line) - 1; $i++){
$char = substr ( $line, $i, 1 );
$ascii = ord ( $char );
if ( (32 > $ascii) || (61 == $ascii) || (126 < $ascii) ){
$char = '=' . strtoupper ( dechex( $ascii ) );
}
if ( ( strlen ( $one_line ) + strlen ( $char ) ) >= 76 ){
$out[]= $one_line . '=' ;
$one_line = null ;
}
$one_line .= $char;
}
$out[]= $one_line ;
}
return implode( $this->LFC , $out );
}
function time(){
list($start_usec, $start_sec) = explode(' ', $this->start_time );
list($end_usec, $end_sec) = explode(' ', microtime() );
return ($end_sec - $start_sec) + (float) ($end_usec - $start_usec);
}
//------------------
// error
//------------------
function errorStatment( $type = false , $lf = null ){
if( $type ){
return $this->errorRender( $this->error_stack , $lf , false );
}else{
return $this->error_stack;
}
}
function errorRender( $error = null , $lf = null , $display = true ){
if( is_null( $error ) ){
$error = $this->error;
}
if( is_null( $lf ) ){
$lf = $this->log_LFC ;
}
if( !is_array( $error ) ){
$error = array( $error );
}
$out = null ;
foreach($error as $mes){
$out .= $this->name . ' error: ' . trim( $mes ) . $lf ;
}
if( $this->error_display && $display ){
$_out = str_replace( $lf ,'<br>' . $lf , $out );
echo $_out ;
}
return $out ;
}
function errorGather( $message = null , $line = null){
if( !is_null( $message ) ){
if( !is_null( $line ) ){
$message .= ' line -> '.$line;
}
if(0 === count( $this->error_stack )){
$this->error[] = 'Qdmail Version '.$this->version.' ,PHP Version '.phpversion();
$this->error[] = $this->iniGather();
}
$this->error[] = $message ;
}elseif( 0 === count( $this->error )){
return true;
}
$er = $this->errorRender();
$this->error_stack = array_merge( $this->error_stack , $this->error );
$this->error = array();
if( !$this->logWrite( 'error' , $er ) ){
$this->error_stack = array_merge( $this->error_stack , $this->error );
}
return false;
}
function log( $mes = null ){
if( is_null( $mes )){
$addrs = $this->done() ;
// $this->done = array();
$spacer = null;
if( 0 != count( $addrs ) ){
$mes .= 'Send Success: '.implode(' ',$addrs) ;
$spacer = $this->log_LFC ;
}
$addrs = $this->undone() ;
// $this->undone = array();
if( 0 != count( $addrs ) ){
$mes .= $spacer . 'Send failure: '.implode(' ',$addrs);
}
}
return $this->logWrite( null , trim( $mes ) ) ;
}
function logWrite( $type , $message ){
$tp = ('error' == $type) ? false:true;
$level = $tp ? $this->log_level:$this->errorlog_level;
$fg_debug = ( 2 > $this->debug ) && !$this->render_mode;
if( 0 == $level || !$fg_debug){
return true;
}
$filename = $tp ? $this->log_filename:$this->errorlog_filename;
$path = $tp ? $this->log_path:$this->errorlog_path;
$ap = $tp ? $this->log_append:$this->errorlog_append;
$fp = fopen( $path.$filename , $ap );
if( !is_resource( $fp ) ){
$this->error[]='file open error at logWrite() line->'.__LINE__;
return false;
}
$spacer = $tp ? ' ' : $this->log_LFC ;
fwrite( $fp ,
date( $this->log_dateformat )
. $spacer
. trim( $message )
. $this->log_LFC
);
if( $level > 1 ){
fwrite( $fp , trim( $this->header_for_smtp ) . $this->log_LFC );
}elseif( $level > 2 ){
fwrite( $fp , $this->log_LFC . $this->content_for_mailfunction . $this->log_LFC );
}
fclose( $fp ) ;
return true ;
}
function errorSpecify( $func , $line , $add_message = null){
return $this->errorGather($add_message.'User Specify Error in Method of \''.$func.'\'' , $line ) ;
}
//-------------------------------------------
// MIME Content-type def
//-------------------------------------------
var $attach_ctype=array(
'txt'=>'text/plain',
'csv'=>'text/csv',
'xml'=>'text/xml',
'htm'=>'text/html',
'html'=>'text/html',
'gif'=>'image/gif',
'jpg'=>'image/jpeg',
'jpeg'=>'image/jpeg',
'png'=>'image/png',
'tif'=>'image/tiff',
'tiff'=>'image/tiff',
'bmp'=>'image/x-bmp',
'ps'=>'appilcation/postscript',
'eps'=>'appilcation/postscript',
'epsf'=>'appilcation/postscript',
'ai'=>'application/postscript',
'zip'=>'application/zip',
'lzh'=>'application/x-lzh',
'lha'=>'application/octet-stream',
'tar'=>'application/x-tar',
'gzip'=>'application/x-tar',
'cpt'=>'application/mac-compactpro',
'doc'=>'application/msword',
'xls'=>'application/vnd.ms-excel',
'ppt'=>'application/vnd.ms-powerpoint',
'rtf'=>'application/rtf',
'pdf'=>'application/pdf',
'css'=>'application/css',
'au'=>'audio/basic',
'rpm'=>'audio/x-pn-realaudio-plugin',
'swa'=>'application/x-director',
'mp3'=>'audio/mpeg',
'mp4'=>'audio/mp4',
'wav'=>'audio/x-wav',
'midi'=>'audio/midi',
'avi'=>'vide/x-msvideo',
'mpeg'=>'video/mpeg',
'mpg'=>'video/mpeg',
'wmv'=>'video/x-ms-wmv',
'flash'=>'application/x-shockwave-flash',
'mmf'=>'application/x-smaf ', //softbank chakumero
'smaf'=>'application/x-smaf', //softbank chakumero
'hdml'=>'text/x-hdml', // HDML au,docomo
'3gpp2'=>'video/3gpp2', // au chaku-uta,ez-movie
'3g2'=>'video/3gpp2', // au chaku-uta,ez-movie
'amc'=>'video/3gpp2', // au chaku-uta,ez-movie
'kjx'=>'application/x-kjx', // au ez-apri
'3gpp'=>'video/3gpp', // docomo chaku-uta,movie
'3gp'=>'video/3gpp', // docomo chaku-uta,movie
'amr'=>'video/3gpp', // docomo chaku-uta,movie
'asf'=>'video/3gpp', // docomo chaku-uta,movie
'jam'=>'application/x-jam', // docomo i-apri
'jar'=>'application/java-archive', // java apri
'jad'=>'text/vnd.sun.j2me.app-descriptor', // java apri
'exe'=>'application/octet-stream',
'khm'=>'application/x-kddi-htmlmail',// au decoration mail template
'dmt'=>'application/x-decomail-template',// nttdocomo decoration mail template
'hmt'=>'application/x-htmlmail-template',// softbank decoration mail template
'hqx'=>'application/mac-binhex40',
'cpt'=>'application/mac-compactpro',
'php'=>'application/x-httpd-php',
'php4'=>'application/x-httpd-php',
'php3'=>'application/x-httpd-php',
'phtml'=>'application/x-httpd-php',
'phps'=>'application/x-httpd-php-source',
'js'=>'application/x-javascript',
'swf'=>'application/x-shockwave-flash',
'eml'=>'message/rfc822',
);
//-------------------------------
// Debug
//-------------------------------
function iniGather(){
$ret = 'OS '.PHP_OS.' ; PHP Version '.PHP_VERSION.' ; '.$this->name.' version '.$this->version;
$ret .= $this->LFC.'php.ini status: mb_language = '.mb_language()
.' ; mb_internal_encoding = '.mb_internal_encoding()
.' ; mb_detect_order = '.implode(',',mb_detect_order());
$ret .= $this->LFC . $this->name .' Status debug: '.$this->debug().', log: '.$this->logLevel().', errorlog: '.$this->errorlogLevel();
return $ret;
}
function debug( $level=null ){
if( is_null( $level ) || !is_numeric($level) ){
return $this->debug;
}
$this->debug = $level ;
return true;
}
function debugEchoLine(){
$vars = func_get_args();
$this->debugEcho( false , $vars );
}
function debugEchoLf(){
$vars = func_get_args();
$this->debugEcho( true , $vars );
}
function debugEcho( $lf , $vars = null ){
static $already_header = false;
static $already_footer = false;
if( 1 > $this->debug ){
return;
}
if( true === $this->debug_echo_charset ){
$this->debug_echo_charset = $this->charset_content ;
}
if( !$already_header ){
$head='<html><head><meta http-equiv="content-type" content="text/html; charset='.$this->debug_echo_charset.'"></head><body>';
echo $head ;
echo '<pre>'.$this->name . ' Debug: '.$this->iniGather().'</pre>';
$already_header = true ;
}
if( $already_header && ( 'END' === $lf ) && !$already_footer){
$foot ='</body></html>';
echo $foot;
$already_footer = true;
return ;
}
$out = null;
if( !is_array( $vars ) ){
$vars =array( $vars );
}
foreach($vars as $var){
$_out = print_r( $var , true ) ;
$enc = $this->qd_detect_encoding( $_out );
if( ( strtoupper( $this->qdmail_system_charset ) !== strtoupper( $enc ) ) && ('ASCII'!==strtoupper( $enc ))){
$_out = $this->qd_convert_encoding( $_out , $this->qdmail_system_charset , $enc );
}
$out .= $_out . $this->LFC;
}
$spacer = $this->log_LFC ;
if( !$lf ){
$out = preg_replace("/\\r?\\n/",' ',$out);
$spacer = null ;
}
echo "<pre>";
$out = $this->name . ' Debug: ' . $spacer . trim( $out );
$out = htmlspecialchars( $out , ENT_QUOTES , $this->qdmail_system_charset);
$out = $this->qd_convert_encoding($out,$this->debug_echo_charset,$this->qdmail_system_charset);
echo $out;
echo "</pre>";
}
function debugReport( $var = null ){
if( is_null( $var ) ){
return $this->debug_report;
}
if( is_bool( $var ) ){
$this->debug_report = $var;
return true;
}
if( 'FILE' !== $var ){
return $this->errorSpecify(__FUNCTION__,__LINE__);
}
$fg= true;
$cont = print_r( $this , true );
$cont .= print_r( $_SERVER , true);
$date = date("Y_m_d_H_i_s");
$out = <<<EOF
Debug Report
date: {$date}
name: {$this->name}
version: {$this->version}
{$cont}
EOF;
$filename = $this->debug_report_path . $this->name.'_debug_report_'.date("Y_m_d_H_i_s") . '.txt';
if($fp = fopen( $filename , 'w' )){
fwrite( $fp , $out );
fclose( $fp );
}else{
$this->error[] = 'Can not open file \'' . $filename . '\' line-> ' . __LINE__ ;
$fg = false;
}
return $fg;
}
//--
// this path like this, /home/foo/bar/ or c\:htdocs\foo\bar\ or ./foo/bar/
// do not forget the last '/' or '\'
//--
function debugReportPath( $path = null ){
if( is_null( $path ) ){
return $path;
}
if( empty( $path ) ){
$this->debug_report_path = './';
return true;
}
if( is_string( $path ) ){
$this->debug_report_path = $path;
return true ;
}
return $this->errorSpecify(__FUNCTION__,__LINE__);
}
function sendBySmtp( $obj = null ){
if( !is_null( $obj ) ){
$this->smtp_object = $obj;
}
if( !isset( $this->smtp_object ) || !is_object( $this->smtp_object ) ){
if( false === ( $this->smtp_object = $this->smtpObject() ) ){
return $this->errorGather('SMTP Object make \'new\' error',__LINE__);
}
}
$this->smtp_server = array_change_key_case( $this->smtp_server , CASE_UPPER );
if( !isset( $this->smtp_server['HOST'] ) ){
$this->smtp_server = array_merge( $this->smtp_server , $this->smtp_object->server() );
}
if( !isset( $this->smtp_server['HOST'] ) ){
return $this->errorGather('No exist SMTP\'s Settings',__LINE__);
}
$this->smtp_server['CONTINUE'] = true;
if( !$this->smtp_object -> server( $this->smtp_server )){
return $this->errorGather('SMTP Object initialize error',__LINE__);
}
if( $this->smtp_loglevel_link ){
$this->smtp_object -> logLevel( $this->log_level );
$this->smtp_object -> errorlogLevel( $this->errorlog_level );
}
$this->smtp_object -> to( $this->recipient );
$this->smtp_object -> data( $this->content_all_for_smtp );
return $this -> smtp_object -> send();
}
function sendBySendmail(){
$temp_name = tempnam ( $this->temporary_path , 'qdmail' );
if(false===$temp_name){
return $this->errorGather('Can not make Temporary File ',__LINE__);
}
$fp = fopen($temp_name,'w');
if(false===$temp_name){
return $this->errorGather('Can not open Temporary File ',__LINE__);
}
fputs($fp,$this->content_all_for_smtp);
fclose($fp);
$recipient = implode(' ',$this->recipient);
$sendfg = exec($this->sendmail_path . ' '.$this->mtaOption().' '.$recipient.' < '.$temp_name,$ret);
$fg = unlink($temp_name);
if(false===$fg){
return $this->errorGather('Can not dellete Temporary File ',__LINE__);
}
return (false!==$sendfg && empty($sendfg)) || true === $sendfg;
}
//------------------------------------------
// expecting Override on the other FrameWork
//------------------------------------------
function & smtpObject( $null = false ){
if(is_null($null)){
$this->smtp_object = null;
return true;
}
if( isset( $this->smtp_object ) && is_object( $this->smtp_object ) ){
return $this->smtp_object;
}
if( !class_exists ( 'Qdsmtp' ) && file_exists( 'qdsmtp.php' ) ){
require_once( 'qdsmtp.php' );
}elseif( !class_exists ( 'Qdsmtp' ) && !file_exists( 'qdsmtp.php' )){
return $this->errorGather('Plese load SMTP Program - Qdsmtp http://hal456.net/qdsmtp',__LINE__);
}
$this->smtp_object = new Qdsmtp();
return $this->smtp_object;
}
function setSmtpObject( & $obj ){
if(is_object($obj)){
$this->smtp_object = & $obj;
return true;
}else{
return false;
}
}
}//the QdmailBase
class QdmailUserFunc extends QdmailBase{
function __construct( $param = null ){
parent::__construct( $param );
}
function validateAddr( $addr ){
if(0==preg_match( $this->varidate_address_regex , $addr , $match )){
$this->errorGather('Tyr Varidate Error by regex preg_match(\''.$this->varidate_address_regex . '\') the address is ->'.$addr,__LINE__);
}else{
return true;
}
}
function stripCrlf( $word ){
if( $this->force_change_charset ){
$enc = $this->qd_detect_encoding( $word ) ;
$word = $this->qd_convert_encoding( $word , $this->qdmail_system_charset , $enc );
}
$word = preg_replace( '/\r?\n/i' , '' , $word );
if( $this->force_change_charset ){
$word = $this->qd_convert_encoding( $word , $enc , $this->qdmail_system_charset );
}
return $word ;
}
}
class Qdmail extends QdmailUserFunc{
var $name ='Qdmail';
function __constructor( $param = null ){
if( !is_null($param)){
$param = func_get_args();
}
parent::__construct( $param );
}
}
//-------------------------------------------
// CakePHP Component
//-------------------------------------------
class QdmailComponent extends QdmailUserFunc{
var $framework = 'CakePHP';
var $view_dir = 'email';
var $layout_dir = 'email';
var $layout = 'default';
var $template = 'default';
var $view = null;
function __constructor( $param = null ){
if( !is_null($param)){
$param = func_get_args();
}
parent::__construct( $param );
}
function startup(&$controller) {
$this->Controller =& $controller;
if( defined( 'COMPONENTS' ) ){
$this->logPath(COMPONENTS);
$this->errorlogPath(COMPONENTS);
}
return;
}
//----------------------------
// Override Parent Method
//----------------------------
function & smtpObject( $null = false ){
if( isset( $this->Qdsmtp ) && is_object( $this->Qdsmtp ) ){
return $this->Qdsmtp;
}
if( !class_exists ( 'QdsmtpComponent' ) ){
if( !$this->import( 'Component' , 'Qdsmtp' ) ){
return $this->errorGather('Qdmail<->CakePHP Component Load Error , the name is Qdsmtp',__LINE__);
}
}
$this->Qdsmtp = new QdsmtpComponent();
if( !is_object( $this->Qdsmtp ) ){
return $this->errorGather('Qdmail<->CakePHP Component making Instance Error , the name is QdsmtpComponent',__LINE__);
}
$this->Qdsmtp -> startup( $this->Controller );
return $this->Qdsmtp;
}
//----------------------------
// Cake Interface
//----------------------------
function import( $kind , $name ){
if( 1.2 > (float) substr(Configure::version(),0,3) ){
$function_name = 'load' . $kind ;
if( function_exists( $function_name ) ){
return $function_name( $name ) ;
}else{
return $this->errorGather('Qdmail<->CakePHP ' .$kind .' Load Error , the name is \'' . $name . '\'',__LINE__);
}
}else{
return App::import( $kind , $name ) ;
}
}
function cakeText( $content , $template = null , $layout = null , $org_charset = null , $target_charset = null , $enc = null , $wordwrap_length = null ){
$this->template = is_null( $template ) ? $this->template : $template ;
$this->layout = is_null( $layout ) ? $this->layout : $layout ;
list( $cont , $target_charset , $org_charset ) = $this->cakeRender( $content , 'TEXT' , $org_charset = null , $target_charset );
return $this->text( $cont , $wordwrap_length , $target_charset , $enc , $org_charset );
}
function cakeHtml( $content , $template = null , $layout = null , $org_charset = null , $target_charset = null , $enc = null ){
$this->template = is_null( $template ) ? $this->template : $template ;
$this->layout = is_null( $layout ) ? $this->layout : $layout ;
list( $cont , $target_charset , $org_charset ) = $this->cakeRender( $content , 'HTML' , $org_charset = null , $target_charset );
return $this->html( $cont , null , $target_charset , $enc , $org_charset );
}
function cakeRender( $content , $type , $org_charset = null , $target_charset = null){
if( is_null( $target_charset ) ){
$target_charset = $this->charset_content;
}
if( !class_exists ( $this->Controller->view ) ){
if( !$this->import( 'View' , $this->view ) ){
return $this->errorGather('Qdmail<->CakePHP View Load Error , the name is \''.$this->view.'\'',__LINE__);
}
}
$type = strtolower( $type );
$view = new $this->Controller->view( $this->Controller , false );
$view->layout = $this->layout;
$mess = null;
$content = $view->renderElement( $this->view_dir . DS . $type . DS . $this->template , array('content' => $content ) , true );
if( 1.2 > (float) substr(Configure::version(),0,3) ){
$view->subDir = $this->layout_dir . DS . $type . DS ;
}else{
$view->layoutPath = $this->layout_dir . DS . $type;
}
$mess .= $view->renderLayout( $content ) ;
if( is_null( $org_charset ) ){
$org_charset = $this->qd_detect_encoding( $mess );
}
$mess = $this->qd_convert_encoding( $mess , $target_charset , $org_charset );
return array( $mess , $target_charset , $org_charset );
}
function CakePHP( $param ){
$param = array_change_key_case( $param , CASE_LOWER );
extract($param);
if( isset($type) || 'HTML' == $type ){
$type ='cakeHtml';
}else{
$type = 'cakeText';
}
return $this->{$type}( isset($content) ? $content:null, isset($template) ? $template:null , isset($layout) ? $layout:null , isset($org_charset) ? $org_charset: null , isset($target_charset) ? $target_charset:null , isset($enc) ? $enc:null , isset($wordwrap_length) ? $wordwrap_length:null );
}
}
//-------------------------------------------
// Symfony Addon
//-------------------------------------------
class sfQdmail extends QdmailUserFunc{
var $framework = 'Symfony';
function __construct( $param = null ){
if( !is_null($param)){
$param = func_get_args();
}
parent::__construct( $param );
}
function setBody( $body ){
if('HTML'===$this->is_html){
$this->html( $body );
}else{
$this->text( $body );
}
}
function getAltBody(){
if('HTML'===$this->is_html){
$content=$this->body();
return !empty($content['TEXT']['CONTENT']);
}else{
return false;
}
}
function setAltBody( $body ){
$this->text( $body );
}
function addStringAttachment($data, $attach_name , $mime_type){
$this->attachDirect( $attach_name , $data , $add = true , $mime_type );
}
function getRawHeader(){
return $this->header_for_smtp;
}
function getRawBody(){
return $this->$this->content_for_mailfunction;
}
function initialize(){
$this->reset();
}
function setCharset($charset){
$this->charset($charset);
}
function getCharset(){
$ret = $this->charset();
return $ret['TEXT'];
}
function setContentType($content_type){
if(false===strpos(strtoupper($content_type),'HTML')){
$this->is_html = 'TEXT';
}else{
$this->is_html = 'HTML';
}
}
function getContentType(){
if('HTML'===$this->is_html){
return 'text/html';
}else{
return 'text/plain';
}
}
function setPriority($priority){
$pri = array(1=>'high',3=>'normal',5=>'low');
if(isset($pri[$priority])){
$this->priority($pri[$priority]);
return true;
}else{
return false;
}
}
function getPriority(){
$pri = array('HIGH'=>1,'NORMAL'=>3,'LOW'=>5);
$now_priority = strtoupper($this->priority());
if(empty($now_priority)){
return null;
}
return $pri[$now_priority];
}
function setEncoding($encoding){
$this->encoding($encoding);
}
function getEncoding(){
return $this->encoding();
}
function setSubject($subject){
$this->subject($subject);
}
function getSubject(){
return $this->subject();
}
function getBody(){
$content=$this->body();
if('HTML'===$this->is_html){
return $content['HTML']['CONTENT'];
}else{
return $content['TEXT']['CONTENT'];
}
}
function setMailer($type = 'mail', $options = array()){
switch ($type){
case 'smtp':
$this->smtp = true;
$this->sendmail = false;
$this->mailer = 'smtp';
if (isset($options['keep_alive'])){
$this->keepParameter(true);
}
break;
case 'sendmail':
$this->sendmail = true;
$this->smtp = false;
$this->mailer = 'sendmail';
break;
default:
$this->smtp = false;
$this->sendmail = false;
$this->mailer = 'mail';
break;
}
}
function getMailer(){
return $this->mailer;
}
function setSender($address, $name = null){
$this->addHeader( 'Return-Path' , $address );
}
function getSender(){
return isset($this->other_header['Return-Path']) ? $this->other_header['Return-Path']:null;
}
function setFrom($address, $name = null){
$this->from( $address , $name );
}
function addAddresses($addresses){
$this->to( $addresses , null , true );
}
function addAddress($address, $name = null){
$this->to( $address , $name , true );
}
function addCc($address, $name = null){
$this->cc( $address , $name , true );
}
function addBcc($address, $name = null){
$this->cc( $address , $name , true );
}
function addReplyTo($address, $name = null){
$this->replyto( $address , $name , true );
}
function clearAddresses(){
$this->to =array();
}
function clearCcs(){
$this->cc =array();
}
function clearBccs(){
$this->bcc =array();
}
function clearReplyTos(){
$this->replyto =array();
}
function clearAllRecipients(){
$this->clearAddresses();
$this->clearCcs();
$this->clearBccs();
$this->clearReplyTos();
}
function addAttachment($path, $name = '', $encoding = 'base64', $type = 'application/octet-stream'){
return $this->attach(array('PATH'=>$path,'NAME'=>$name,'MIME-TYPE'=>$type),true);
}
function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = 'application/octet-stream'){
return $this->attach(array('PATH'=>$path,'NAME'=>$name,'MIME-TYPE'=>$type,'CONTENT-ID'=>$cid),true);
}
function setAttachments($attachments){}
function clearAttachments(){
$this->attach=array();
}
function addCustomHeader($name, $value){
$this->addHeader($name, $value);
}
function clearCustomHeaders(){
$this->other_header=array();
}
function prepare(){}
function smtpClose(){}
function setDomain($hostname){}
function getDomain(){}
function setHostname($hostname){}
function getHostname(){}
function setPort($port){}
function getPort(){}
function setUsername($username){}
function getUsername(){}
function setPassword($password){}
function getPassword(){}
function setWordWrap($wordWrap){}
function getWordWrap(){}
}
class QdDeco{
var $template = null;
var $data = array();
function template( $template = null ){
if(is_null($template)){
return $this->template;
}
$this->template = trim(preg_replace("/\\r?\\n/is","\r\n",$template));
return true;
}
function get( $kind ){
if(!empty($this->data[$kind])){
return $this->data[$kind];
}
if('ATTACH'===$kind){
return array();
}else{
return null;
}
}
function decode(){
if(!class_exists('QdmailReceiver')){
include('qd_mail_receiver.php');
}
$num_boundary = strpos(strtolower($this->template),'boundary');
$num_crlf = strpos($this->template,"\r\n\r\n");
$template = $this->template;
while((false!==$num_boundary)&&(false!==$num_crlf)&&($num_boundary > $num_crlf)){
$template = substr($template,$num_crlf+4);
$num_crlf = strpos($template,"\r\n\r\n");
$num_boundary = strpos(strtolower($template),'boundary');
}
$receiver = QdmailReceiver::start( 'direct' , $template );
$this->data['HTML'] = $receiver->bodyAutoSelect() ;
if(false===$this->data['HTML']){
$this->data['HTML'] = '';
}
$attach = $receiver->attach();
foreach($attach as $att){
if(isset($att['content-id'])){
$cid = rtrim($att['content-id'],'>');
$cid = ltrim($cid,'<');
}elseif(isset($att['content_id'])){
$cid = rtrim($att['content_id'],'>');
$cid = ltrim($cid,'<');
}else{
$cid = null;
}
$this->data['ATTACH'][]=array(
'PATH' => $att['filename_safe'],
'NAME' => $att['filename_safe'],
'CONTENT-TYPE' => $att['mimetype'],
'CONTENT-ID' => $cid,
'_CHARSET' => null,
'_ORG_CHARSET' => null,
'DIRECT' => $att['value'],
'BARE' => false,
);
}
return true;
}
}?>
<?php
/**
* Qdsmtp ver 0.2.0a
* SMTP Talker
*
* PHP versions 4 and 5 (PHP4.3 upper)
*
* Copyright 2008, Spok in japan , tokyo
* hal456.net/qdmail : http://hal456.net/qdsmtp/
* & CPA-LAB/Technical : http://www.cpa-lab.com/tech/
* Licensed under The MIT License License
*
* @copyright Copyright 2008, Spok.
* @link http://hal456.net/qdsmtp/
* @version 0.2.0a
* @lastmodified 2008-10-25
* @license http://www.opensource.org/licenses/mit-license.php The MIT License
*
* Qdsmtp is SMTP Taler library ,easy , quickly , usefull .
* Copyright (C) 2008 spok
*/
if ( defined('CAKE_CORE_INCLUDE_PATH') || defined('CAKE')) {
class QdsmtpBranch extends Object{}
}else{
class QdsmtpBranch{}
}
class QdsmtpError extends QdsmtpBranch{
var $name = 'QdsmtpError';
var $error_display = true;
var $errorlog_level = 0;
var $log_level = 0;
var $error = array() ;
var $error_stack = array();
var $log_LFC = "\r\n";
var $log_append = 'a';
var $errorlog_append = 'a';
var $log_filename ='qdsmtp.log';
var $errorlog_filename ='qdsmtp_error.log';
var $log_dateformat = 'Y-m-d H:i:s';
var $error_ignore = false;
function errorRender( $error = null , $lf = null , $display = true ){
if( is_null( $error ) ){
$error = $this->error;
}
if( is_null( $lf ) ){
$lf = $this->log_LFC ;
}
if( !is_array( $error ) ){
$error = array( $error );
}
$out = null ;
foreach($error as $mes){
$out .= $this->name . ' error: ' . trim( $mes ) . $lf ;
}
if( $this->error_display && $display ){
$_out = str_replace( $lf ,'<br>' . $lf , $out );
echo $_out ;
}
return $out ;
}
function errorGather( $message = null , $line = null){
if( !is_null( $message ) && !$this->error_ignore){
if( !is_null( $line ) ){
$message .= ' line -> '.$line;
}
$this->error[] = $message ;
}elseif( 0 === count( $this->error ) ){
return true;
}elseif( $this->error_ignore ){
return false;
}
$er = $this->errorRender();
$this->error_stack = array_merge( $this->error_stack , $this->error );
$this->error = array();
if( !$this->logWrite( 'error' , $er )){
$this->error_stack = array_merge( $this->error_stack , $this->error );
}
return false;
}
function logWrite( $type , $message ){
$tp = ('error' == $type) ? false:true;
$level = $tp ? $this->log_level:$this->errorlog_level;
if( 0 == $level ){
return true;
}
$filename = $tp ? $this->log_filename:$this->errorlog_filename;
$ap = $tp ? $this->log_append:$this->errorlog_append;
$fp = fopen( $filename , $ap );
if( !is_resource( $fp ) ){
$this->error[]='file open error at logWrite() line->'.__LINE__;
return false;
}
$spacer = $tp ? $this->log_LFC : $this->log_LFC ;
fwrite( $fp ,
date( $this->log_dateformat )
. $spacer
. trim( $message )
. $this->log_LFC
);
fclose( $fp ) ;
return true ;
}
function log(){
$mes = null;
foreach($this->smtp_log as $line){
$mes .= trim( $line ) . $this->log_LFC;
}
$this->logWrite( null ,$mes );
$this->smtp_log = array();
}
function logFilename( $data = null ){
if( is_null( $data ) ){
return $this->log_filename;
}
if( is_string( $data ) ){
$this->log_filename = $data;
return $this->errorGather();
}else{
return $this->errorGather('Data specified error',__LINE__);
}
}
function errorlogFilename( $data = null ){
if( is_null( $data ) ){
return $this->errorlog_filename;
}
if( is_string( $data ) ){
$this->errorlog_filename = $data;
return $this->errorGather();
}else{
return $this->errorGather('Data specified error',__LINE__);
}
}
}
class QdsmtpBase extends QdsmtpError{
var $name = 'QdSmtp';
var $smtpLFC ="\r\n";
var $smtp_param = array(
'HOST' => null,
'FROM' => null,
'USER' => null,
'PASS' => null,
'PORT' => 25,
'PROTOCOL' => array(
'SMTP_AUTH','POP_BEFORE','SMTP'
),
'POP_SERVER'=> null,
'POP_USER' => null,
'POP_PASS' => null,
'CONTINUE' => null,
);
var $protocol_def ='SMTP';
var $smtp_log = array();
var $smtp_auth_kind = array('PLAIN');
// var $smtp_auth_kind = array('CRAM-MD5','DIGEST-MD5','LOGIN','PLAIN');
var $data = null;
var $continue = false;
var $auto_kind = true;
var $rcpt = array();
var $rcpt_stack = array();
var $rcpt_undone = array();
var $rcpt_undone_stack = array();
var $smtp_limit = 1000;
var $sock = null;
var $already_auth = false;
// POP3
var $pop3_time_file = 'qdsmtp.time';
var $pop3_use_file = true;
var $pop3_connect_start = null;
var $pop3_valid_minute = 10;
var $time_out = 3 ;
var $always_notify_success = false;
function __constructor( $param = null ){
if( !is_null( $param[0] ) && is_bool( $param[0] ) ){
$this->continue = $continue;
}
if( is_array( $param[0] ) ){
$this->server( $param[0] );
}
}
//-----------------------------------------
// User Interface except POP3
//-----------------------------------------
function server( $param = null ){
if( is_null( $param ) ){
return $this->smtp_param;
}elseif( !is_array( $param ) ){
return $this->errorGather('Error Parameter type',__LINE__);
}
$param = array_change_key_case( $param , CASE_UPPER );
if( isset( $param['PROTOCOL'] ) && is_array($param['PROTOCOL'] ) ){
$param['PROTOCOL'] = array_change_key_case( $param['PROTOCOL'] , CASE_UPPER );
}
if( isset( $param['ALWAYS_NOTIFY'] ) && is_bool($param['ALWAYS_NOTIFY']) ){
$this->always_notify_success = $param['ALWAYS_NOTIFY'];
}
$this->smtp_param = array_merge( $this->smtp_param , $param );
if( isset( $this->smtp_param['CONTINUE'] ) ){
$this->continue = $this->smtp_param['CONTINUE'];
}
return true;
}
function data( $data = null ){
if( is_null( $data ) ){
return $this->data;
}
if( is_string( $data ) ){
$this->data = $data;
return $this->errorGather();
}else{
return $this->errorGather('Data specified error',__LINE__);
}
}
function to( $recip , $add = false ){
return $this->recipient( $recip );
}
function recipient( $recip , $add = false ){
if( !is_array( $recip ) ){
$recip = array( $recip );
}
if( $add ){
$this->recipient = array_merge( $this->recipient , $recip );
$this->recipient = array_unique( $this->recipient );
}else{
$this->recipient = $recip;
}
return $this->errorGather();
}
function addRecipient( $recip ){
return $this->recipient( $recip , true );
}
function addto( $recip ){
return $this->addRecipient( $recip );
}
function done( $stack = false ){
if( $stack ){
return $this->rcpt_stack;
}else{
return $this->rcpt;
}
}
function undone( $stack = false ){
if( $stack ){
return $this->rcpt_undone_stack;
}else{
return $this->rcpt_undone;
}
}
function continueConnect( $bool = null ){
if( is_null( $bool ) ){
return $this->continue;
}
if( is_bool( $bool ) ){
$this->continue = $bool;
return $this->errorGather();
}else{
return $this->errorGather('Connection Continue Mode specifed error',__LINE__);
}
}
function timeOut( $sec = null ){
if(is_null($sec)){
return $this->time_out;
}
if( is_numeric( $sec ) ){
$this->time_out = $sec;
return $this->errorGather();
}else{
return $this->errorGather(__FUNCTION__.' specifed error',__LINE__);
}
}
function errorlogLevel( $num = null ){
if( is_null( $num ) ){
return $this->errorlog_level;
}
if( is_numeric( $num ) ){
$this->errorlog_level = $num;
return $this->errorGather();
}else{
return $this->errorGather(__FUNCTION__.' specifed error',__LINE__);
}
}
function logLevel( $num = null ){
if( is_null( $num ) ){
return $this->log_level;
}
if( is_numeric( $num ) ){
$this->log_level = $num;
return $this->errorGather();
}else{
return $this->errorGather(__FUNCTION__.' specifed error',__LINE__);
}
}
function alwaysNotifySuccess( $bool = null ){
if(is_null($bool)){
return $this->always_notify_success;
}
if(is_bool($bool)){
$this->always_notify_success = $bool;
return true;
}else{
return false;
}
}
//------------------------------------------
// Sending Method
//------------------------------------------
// Qdsmtp ignore $option parameter
function mail( $to , $subject , $message , $header= null , $option = null ){
$this->makeData( $to , $subject , $message , $header , $option );
return $this->send();
}
function send( $data = null ){
if( !is_array($this->smtp_param['PROTOCOL'])){
$fg = $this->sendBase( $data , $this->smtp_param['PROTOCOL'] );
$this->log();
return $fg;
}
$stack = array( $this->error_display , $this->errorlog_level );
$this->error_display = false;
$this->errorlog_level= 0;
$ret = false;
foreach($this->smtp_param['PROTOCOL'] as $protocol ){
if( $this->sendBase( $data , $protocol ) ){
$ret = true;
$this->error_stack = array();
break;
}
}
list( $this->error_display , $this->errorlog_level ) = $stack;
if( !$ret ){
$fg = $this->errorGather( implode($this->smtpLFC , $this->error_stack) , __LINE__);
$this->log();
return $fg;
}
if( !$this->continue ){
$this->close();
}
$this->log();
return ( 0 === count( $this->error_stack ) ) && $this->errorGather();
}
function close(){
$items = array(
array( 'QUIT' , null ),
);
list( $st , $mes , $com ) = $this->communicate( $items );
if( !$st ){
return $this->errorGather('Error at QUIT',__LINE__);
}
fclose( $this->sock );
}
function sendBase( $data = null ,$protocol = null ){
if( !is_null( $data ) ){
$this->data = $data;
}
if( is_null( $protocol ) ){
$protocol = $this->protocol_def;
}
switch($protocol){
case 'POP_BEFORE'://POP3
if( !$this->pop3() ){
return $this->errorGather('POP failure',__LINE);
}
case 'SMTP':
if( !is_resource( $this->sock ) ){
$this->sock = $this->connect();
}
$this->sayHello();
if( !$this->sendData() ){
return false;
}
break;
case 'SMTP_AUTH':
if(!is_resource($this->sock)){
$this->sock = $this->connect();
}
if( !$this->already_auth ){
$this->sayHello();
if( 0 === preg_match('/[\s-]AUTH\s+([^\r\n]*)\r?\n/is', implode($this->smtpLFC,$this->smtp_log) , $matches)){
return $this->errorGather('HOST:'.$this->smtp_param['HOST'].' doesnot suppoted SMTP AUTH Protocol',__LINE__);
}
$mes = strtoupper( $matches[1] );
$decide = null;
foreach($this->smtp_auth_kind as $auth){
if( false !== strpos( $mes , $auth ) ){
$decide = $auth;
break;
}
}
if( is_null( $decide ) ){
return $this->errorGather('HOST:'.$this->smtp_param['HOST'].' doesnot suppoted MY Abalable SMTP AUTH Protocol '.implode(' or ',$this->smtp_auth_kind),__LINE__);
}
$decide = strtolower( str_replace( '-' , '_' ,$decide ) );
if( !$this->{$decide}() ){
return $this->errorGather('Auth Error',__LINE__);;
}
$this->already_auth = true;
}
if( !$this->sendData() ){
$this->already_auth = false;
return $this->errorGather('Send Data Error or Auth Error',__LINE__);
}
break;
case 'OVER_SSL':
break;
default:
break;
}
//debug
/*
if( 0==count($this->error_stack)){
$this->error_stack = 'no error';
}
echo "<pre>";
echo htmlspecialchars(print_r($this->smtp_log , true));
echo htmlspecialchars(print_r($this->error_stack , true));
echo "</pre>";
*/
return $this->errorGather();
}
//----------------------------------------------
// Comunication
//----------------------------------------------
//-------------------------------------------------------------------------
// see RFC821
// in japanese ->http://www.sea-bird.org/doc/rfc_doc/rfc821-jp.txt(not me)
//-------------------------------------------------------------------------
var $smtp_status100 = array(
1 => 4,
2 => 3,
3 => 2,
4 => 1,
5 => 0,
);
// 0 error
// 1 continue
// 2 final
var $smtp_status10 = array(
0 => 0,
1 => 5,
2 => 1,
3 => 0,
4 => 0,
5 => 5,
);
function sayHello(){
$items = array(
array( 'EHLO' , $this->smtp_param['HOST'] ),
array( 'HELO' , $this->smtp_param['HOST'] ),
);
if( !$this->tryUntilSuccess( $items ) ){
return $this->errorGather('HOST:'.$this->smtp_param['HOST'].' say no HELLO',__LINE__);
}
return $this->errorGather();
}
function sendData(){
$reci = array();
if( '<' == substr( $this->smtp_param['FROM'],0,1) ){
$from = 'FROM:' . $this->smtp_param['FROM'];
}else{
$from = 'FROM:<' . $this->smtp_param['FROM'] . '>';
}
$items = array(
array( 'MAIL' , $from ),
);
list( $st , $mes , $com ) = $this->communicate($items);
if( !$st ){
return $this->errorGather('Error From setting',__LINE__);
}
$this->rcpt = array();
$notify = $this->always_notify_success ? ' NOTIFY=SUCCESS,FAILURE':'';
foreach( $this->recipient as $recipi ){
$items = array(array( 'RCPT' , 'TO:<' . $recipi . '>' . $notify ));
list( $st , $mes , $com ) = $this->communicate($items);
if( !$st ){
$this->rcpt_undone[] = $recipi ;
$this->errorGather('Error RCPT setting',__LINE__);
}else{
$this->rcpt[] = $recipi ;
}
}
$this->rcpt_stack = array_merge( $this->rcpt_stack , $this->rcpt );
$this->rcpt_undone_stack = array_merge( $this->rcpt_undone_stack , $this->rcpt_undone );
$items = array();
$items[] = array( 'DATA' , null );
$items[] = array( 'DATA_CONTENT' , $this->smtpEscape($this->data).$this->smtpLFC . '.' );
$items[] = array( 'RSET' , null );
list( $st , $mes , $com ) = $this->communicate($items);
if( !$st ){
return $this->errorGather('Error Data sending',__LINE__);
}
return $this->errorGather();
}
function communicate( $items , $fp = null ){
if( is_null( $fp ) ){
$fp = $this->sock ;
}
$message = null ;
if( !is_resource( $fp ) ){
return array( $this->errorGather( 'Error Resouce or stop connect' ,__LINE__) , $message , false );
}
foreach( $items as $item ){
if( 'DATA_CONTENT' == $item[0] ){
$spacer = null ;
$item[0] = null ;
}elseif( 'DATA' == $item[0] || is_null($item[1]) ){
$spacer = null;
}else{
$spacer = ' ';
}
$put_message = rtrim( $item[0] . $spacer . $item[1] ) . $this->smtpLFC;
if( !fputs( $fp , $put_message ) ){
return array( $this->errorGather('SMTP can not fputs',__LINE__), $message , false );
}
$this->smtp_log[] = $this->name . ' ' . $put_message ;
do{
list( $st , $_message ) = $this->getMessage( $fp );
$message .= trim( $_message ) . $this->smtpLFC;
if( !$st ){
return array( $this->errorGather('getMessage error',__LINE__), $message , $st );
}
$branch = isset($this->smtp_status[$item[0]][$st]) ? $this->smtp_status[$item[0]][$st] : null;
switch( $branch ){
case 'S': // Success
$contine = false ;
break;
case 'F': // Failure
return array( $this->errorGather('Failure :status'.$st.' message:'.htmlspecialchars($_message).' on '.htmlspecialchars($put_message),__LINE__) , $message , $st );
break;
case 'E': // Error
return array( $this->errorGather('Error :status'.$st.' message:'.htmlspecialchars($_message).' on '.htmlspecialchars($put_message),__LINE__) , $message , $st );
break;
default:
$s100 = (int) substr( $st , 0 , 1 );
$s10 = (int) substr( $st , 1 , 1 );
$s = $this->smtp_status100[$s100] * $this->smtp_status10[$s10];
switch($s){
case 0: // Error
return array( $this->errorGather('Unkown Error :status'.$st.' message:'.htmlspecialchars($_message).' on '.htmlspecialchars($put_message),__LINE__) , $message , $st );
break;
case 3: //22X,220
$contine = true ;
break;
case 10: //35X,354
$contine = false ;
break;
case 15: //25X,250 Sucsess
$contine = false ;
break;
default:
$contine = false;
break;
}
break;
}
}while($contine);
}
return array($this->errorGather() , $message , $st );
}
function getMessage( $fp = null ){
if( is_null( $fp ) ){
$fp = $this->sock ;
}
if( !is_resource( $fp ) ){
return array( $this->errorGather( 'Error Resouce or stop connect' ,__LINE__) , null );
}
$status = array();
$status[-1] = null;
$message = array();
$count = 0;
do{
$mes = fgets( $fp , 512 );
if( false === $mes ){
$er = stream_get_meta_data ( $fp );
$er_mes = null;
if( true === $er ['timed_out'] ){
$er_mes = ' SYSTEM TIME OUT ';
}
return array( $this->errorGather('No Responce' . $er_mes,__LINE__) , null );
}
$status[$count] = substr( $mes , 0 , 3 );
$_continue = substr( $mes , 3 , 1 );
$message[] = trim( $mes );
$this->smtp_log[] = 'Server '.$mes ;
if( '-' == $_continue && ( ($status[$count] == $status[$count-1]) || (0 == $count)) ){
$continue = true ;
}else{
$continue = false ;
}
$count ++;
}while($continue);
return array( $status[0] , implode( $this->smtpLFC , $message ) );
}
function connect( $host = null , $port = null , $status = 220 ){
if(is_null($host)){
$host = $this->smtp_param['HOST'];
}
if(is_null($port)){
$port = $this->smtp_param['PORT'];
}
$sock = fsockopen( $host , $port , $err , $errst , $this->time_out );
if( !is_resource( $sock ) ){
return $this->errorGather('Connection error HOST: '.$host.' PORT: ' . $port ,__LINE__);
}
stream_set_timeout ( $sock , $this->time_out );
return $sock;
}
function tryUntilSuccess( $items ){
$try = false;
$err_mes = array();
foreach( $items as $item ){
$err_mes[] = $item[0];
$this->error_ignore = true;
list( $st , $mes , $com ) = $this->communicate( array( $item ) );
$this->error_ignore = false;
if( true === $st ){
$try = true;
$this->error = array();
break;
}
}
if( !$try ){
return $this->errorGather( 'Tyr Error ->' . implode( ' ' , $err_mes ) ,__LINE__);
}
return $this->errorGather();
}
//--------------------------
// AUTH
//--------------------------
function plain(){
$plain = $this->makePlain();
$items = array();
foreach($plain as $pn ){
$items[] = array( 'AUTH PLAIN' , $pn );
}
return $this->tryUntilSuccess( $items );
}
function makePlain(){
$plain[0] = base64_encode($this->smtp_param['USER']."\0".$this->smtp_param['USER']."\0".$this->smtp_param['PASS']);
$plain[1] = base64_encode($this->smtp_param['USER']."\0".$this->smtp_param['PASS']);
return $plain;
}
//-----------------------------------
// Utility
//-----------------------------------
function makeData( $to , $subject , $message , $header=null , $option=null ){
$recip = array();
$recip = array_merge( $recip , $this->extractAddr( $to ) );
$recip = array_merge( $recip , $this->extractAddr( $this->extractHeader('CC' , $header) ) );
$recip = array_merge( $recip , $this->extractAddr( $this->extractHeader('BCC' , $header) ) );
$this->recipient( $recip );
$head = trim( 'To: ' . $to . $this->smtpLFC . 'Subject: ' . trim( $subject ) . $this->smtpLFC . trim($header) );
return $this->data = $head . $this->smtpLFC . $this->smtpLFC . $message ;
}
function extractAddr( $line ){
if(0===preg_match_all('/<?([^<,]+@[^>,]+)>?\s*,?\s*/',$line,$matches)){
return array();
}else{
return $matches[1];
}
}
function extractHeader( $section , $header){
if( 0===preg_match('/'.$section.': (.*)\r?\n[^\s]/is' , $header , $matches ) ){
return null;
}else{
return str_replace( array( "\r" , "\n" , "\t" , ' ' ) , null , $matches[1] );
}
}
function smtpEscape( $mes ){
$mes = preg_replace( '/\r?\n\.\r?\n/is' , $this->smtpLFC . '..' . $this->smtpLFC , $mes );
if( 0 !== preg_match( '/\r?\n[^\r\n]{'.$this->smtp_limit.',}\r?\n/is' , $mes ) ){
return $this->errorGather('SMTP Overfllow '.$this->smtp_limit.' chars in one line.',__LINE__);
}
return $mes;
}
//----------------------------------------------------
// POP3
//----------------------------------------------------
function pop3(){
if( $this->pop3_use_file ){
if( !file_exists( $this->pop3_time_file ) ){
$this->writePop3Time();
}
$this->pop3_connect_start = file_get_contents( $this->pop3_time_file );
}elseif( is_null( $this->pop3_connect_start ) ){
$this->pop3_connect_start = time();
}
if( ( $this->pop3_connect_start + $this->pop3_valid_minute * 60 ) > time() ){
return $this->errorGather();
}
if( $this->pop3_use_file ){
$this->writePop3Time();
}
$fp = $this->connect( $this->smtp_param['POP_HOST'] , 110 , '+OK' );
if( false === $fp ){
return $this->errorGather('Can not connect POP3 Sever' ,__LINE__);
}
$items = array(
array( 'USER' , $this->smtp_param['POP_USER'] ),
array( 'PASS' , $this->smtp_param['POP_PASS'] ),
);
$this->communicate( $items , $fp );
fclose( $fp );
return $this->errorGather();
}
function pop3UseFile( $bool = null ){
if( is_null($bool)){
return $this->pop3_use_file;
}
if( is_bool( $bool ) ){
$this->pop3_use_file = $bool;
return $this->errorGather();
}else{
return $this->errorGather('POP3 UseFile specifed error',__LINE__);
}
}
function pop3TimeFilename( $filename = null ){
if(is_null($filename)){
return $this->pop3_time_file;
}
if( is_string( $filename ) && !empty( $filename ) ){
$this->pop3_time_file = $filename;
return $this->errorGather();
}else{
return $this->errorGather('POP3 Filename specifed error',__LINE__);
}
}
function pop3ValidMinute( $min = null ){
if(is_null($min)){
return $this->pop3_valid_minute;
}
if( is_numeric( $min ) ){
$this->pop3_valid_minute = $min;
return $this->errorGather();
}else{
return $this->errorGather('POP3 Valid Minute specifed error',__LINE__);
}
}
function writePop3Time(){
$fp_time = fopen($this->pop3_time_file,'w');
fputs( $fp_time , time() );
fclose($fp_time);
}
//--------------------------------
// Result Colleciton
//--------------------------------
var $smtp_status= array(
'USER' => array(
'+OK' => 'S', // for pop3
),
'PASS' => array(
'+OK' => 'S', // for pop3
),
'HELO' => array(
'250' => 'S',
'500' => 'E',
'501' => 'E',
'504' => 'E',
'421' => 'E',
),
'EHLO' => array(
'250' => 'S',
'500' => 'E',
'501' => 'E',
'504' => 'E',
'421' => 'E',
),
'MAIL' => array(
'250' => 'S',
'500' => 'E',
'501' => 'E',
'421' => 'E',
'552' => 'E',
'451' => 'E',
'452' => 'E',
),
'RCPT' => array(
'250' => 'S',
'251' => 'S',
'550' => 'F',
'551' => 'F',
'552' => 'F',
'553' => 'F',
'450' => 'F',
'451' => 'F',
'452' => 'F',
'500' => 'E',
'501' => 'E',
'503' => 'E',
'421' => 'E',
),
'DATA' => array(
'354' => 'S',
'250' => 'S',
'451' => 'F',
'554' => 'F',
'500' => 'E',
'501' => 'E',
'503' => 'E',
'421' => 'E',
),
'AUTH PLAIN' => array(
'235' => 'S',
'503' => 'S', //503 5.5.0 Already Authenticated
'501' => 'E',
'535' => 'E',
),
'STARTTLS' => array(
'220' => 'S',
),
'RSET' => array(
'250' => 'S',
),
'QUIT' => array(
'221' => 'S',
'500' => 'E',
'501' => 'E',
'504' => 'E',
),
);
}
class Qdsmtp extends QdsmtpBase{
function __constructor( $param = null ){
if( !is_null($param)){
$param = func_get_args();
}
parent::QdsmtpBase( $param );
}
}
//-------------------------------------------
// CakePHP Component
//-------------------------------------------
class QdsmtpComponent extends QdsmtpBase{
var $layout = 'default';
var $view_dir = 'email';
var $layout_dir = 'email';
var $template = 'default';
var $view = null;
function __constructor( $param = null ){
if( !is_null($param)){
$param = func_get_args();
}
parent::QdsmtpBase( $param );
}
function startup(&$controller) {
$this->Controller =& $controller;
if( defined( 'COMPONENTS' ) ){
$this->logFilename(COMPONENTS.$this->name.'.log');
$this->errorlogFilename( COMPONENTS . '_error' . $this->name . '.log' );
}
return;
}
}?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment