<?php
/*
 * framework-spider
 * util/Mail.class.php
 * 
 * CopyRight(C)Framework-Spider Developer Team. 2010. All Right Reserved. 
 * URL				 : http://sourceforge.jp/projects/frameworkspider/
 * Mail				: frameworkspider-dev@lists.sourceforge.jp
 * Auther			: Masanori Nakashima
 * Modifier		: Masanori Nakashima
 * Last Updated: 2010.06.23
 * 
 */
/**
 * メール送信基底クラス
 * @package util ユーティリティパッケージ
 * @version 1.0.0
 * @copyright Copyright &copy; 2008, <info@md-systems.net> http://www.md-systems.net/
 * @author  m.nakashima <m_nakashima@md-systems.net>
 * @since PHP 4.3
 */
class util_Mail {
	
	/** 送信設定オプション	*/
	var $options	= array();
	/** 初期化済みフラグ	*/
	var $is_init	= false;
	
	// 送信項目
	/** subject	*/
	var $subject;
	/** text body	*/
	var $text_body;
	/** html body	*/
	var $html_body;
	/** attachement	*/
	var $attachements	= array();
	/** html inline images	*/
	var $inline_images	= array();
	
	/** To	*/
	var $to;
	/** From	*/
	var $from;
	/** Cc	*/
	var $cc		= array();
	/** Bcc	*/
	var $bcc	= array();
	/** reply to	*/
	var $reply_to;
	/** return path	*/
	var $return_path;
	
	// option
	var $boundary;
	var $x_mailer			= 'MDS.Co.,Ltd./Web Mailer v1.0.0/www.md-systems.net';
	var $charset_header		= 'ISO-2022-JP';
	var $charset_body		= 'ISO-2022-JP';
	var $charset_filename	= 'Shift_JIS';
	var $replace_words	= array();
		
	/**
	 * コンストラクタ
	 */
	function util_Mail() {
	}
	/**
	 * 送信メソッドクラス定義に合わせたインスタンスを生成します。
	 * $class_name: SendMail / SMTP /PHP
	 * $options:	  送信オプション
	 */
	function get_instance( $class_name='SendMail', $options=array() ) {
		$send_class_path	= dirname(__FILE__)
			.DIRECTORY_SEPARATOR.'mail'
			.DIRECTORY_SEPARATOR.$class_name.'.class.php';
		if( !file_exists( $send_class_path ) ) {
			return false;
		} else {
			require_once($send_class_path);
			$send_class_name	= 'util_mail_' . $class_name;
			$send_object		= new $send_class_name;
			if( count($send_object->validate_options( $options )) == 0 ) {
				$send_object->init( $options );
				return $send_object;
			} else {
				return false;
			}
		}
	}
	/**
	 * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。
	 * エラーがない場合は要素0の配列を返します。
	 */
	function validate_options( & $options ) {
		return array();
	}
	/**
	 * 指定された送信設定オプションで送信オブジェクトを初期化します。
	 */
	function init( $options = array() ) {
		$this->options	= $options;
		$this->is_init	= true;
	}
	/**
	 * 件名を設定します。
	 * @param $subject string
	 */
	function setSubject( $subject ) {
		$this->subject	= $subject;
	}
	/**
	 * テキスト本文を設定します。
	 * @param $body string
	 */
	function setTextBody( $body ) {
		$this->text_body	= $body;
	}
	/**
	 * HTML本文を設定します。
	 * @param $body string
	 */
	function setHtmlBody( $body ) {
		$this->html_body	= $body;
	}
	/**
	 * テンプレートから件名と本文を設定します。
	 * @param $file_path テンプレートファイルパス
	 */
	function setTemplateFile( $file_path, $toEncoding=null, $fromEncoding='auto', $convertKana=null ) {
		if( file_exists( $file_path ) ) {
			if( $lines = @file( $file_path ) ) {
				$this->subject		= array_shift( $lines );
				$this->subject		= str_replace("\r\n","",$this->subject);
				$this->subject		= str_replace("\r","",$this->subject);
				$this->subject		= str_replace("\n","",$this->subject);
				$this->text_body	= implode("",$lines);
				$this->text_body	= str_replace("\r\n","\n",$this->text_body);
				$this->text_body	= str_replace("\r","\n",$this->text_body);
				if( !is_null($toEncoding) && $toEncoding != $fromEncoding ) {
					if( !is_null($fromEncoding) ) {
						$this->subject		= mb_convert_encoding($this->subject,$toEncoding,$fromEncoding);
						$this->text_body	= mb_convert_encoding($this->text_body,$toEncoding,$fromEncoding);
					} else {
						$this->subject		= mb_convert_encoding($this->subject,$toEncoding);
						$this->text_body	= mb_convert_encoding($this->text_body,$toEncoding);
					}
				}
				if( !is_null($convertKana) ) {
					$this->subject		= mb_convert_kana($this->subject,$convertKana,$toEncoding);
					$this->text_body	= mb_convert_kana($this->text_body,$convertKana,$toEncoding);
				}
			} else {
				return false;
			}
		} else {
			return false;
		}
		return true;
	}
	/**
	 * Fromアドレスを設定します。
	 * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。
	 * 例) MDS <info@md-systems.net>
	 * @param $address string
	 */
	function setFrom( $address ) {
		$this->from	= $address;
	}
	function setReplyTo( $address ) {
		$this->reply_to	= $address;
	}
	function setReturnPath( $address ) {
		$this->return_path	= $address;
	}
	/**
	 * Ccアドレスを配列で設定します。
	 * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。
	 * 例) MDS <info@md-systems.net>
	 * @param $address_array string
	 */
	function setCc( $address_array ) {
		if( is_array( $address_array ) ) {
			$this->cc	= $address_array;
		} else if( strlen(trim($address_array)) > 0 ) {
			$this->cc	= array();
			array_push( $this->cc, $address_array );
		}
	}
	/**
	 * Ccアドレスを追加します。
	 * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。
	 * 例) MDS <info@md-systems.net>
	 * @param $address string
	 */
	function addCc( $address ) {
		if( !is_array( $this->cc) ) {
			$this->cc	= array();
		}
		array_push( $this->cc, $address );
	}
	/**
	 * Bccアドレスを配列で設定します。
	 * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。
	 * 例) MDS <info@md-systems.net>
	 * @param $address_array string
	 */
	function setBcc( $address_array ) {
		if( is_array( $address_array ) ) {
			$this->bcc	= $address_array;
		} else if( strlen(trim($address_array)) > 0 ) {
			$this->bcc	= array();
			array_push( $this->bcc, $address_array );
		}
	}
	/**
	 * Bccアドレスを追加します。
	 * メールアドレス RFC 2822を満たしていればアドレスに名前を付加することもできます。
	 * 例) MDS <info@md-systems.net>
	 * @param $address string
	 */
	function addBcc( $address ) {
		if( !is_array( $this->bcc) ) {
			$this->bcc	= array();
		}
		array_push( $this->bcc, $address );
	}
	/**
	 * 添付ファイルを追加します。
	 * @param $address string
	 */
	function addAttachement( $file_path, $name=null, $type="application/octet-stream" ) {
		if( !is_array( $this->attachements ) ) {
			$this->attachements	= array();
		}
		if( is_null( $name ) || strlen(trim($name)) == 0 ) {
			$name	= basename( $file_path );
		}
		$file_info	= array(
			'name'	=> $name,
			'path'	=> $file_path,
			'type'	=> $type
		);
		array_push( $this->attachements, $file_info );
	}
	/**
	 * 添付ファイルを追加します。
	 * @param $address string
	 */
	function addInlineImage( $content_id, $file_path, $name=null, $type="application/octet-stream" ) {
		if( !is_array( $this->inline_images ) ) {
			$this->inline_images	= array();
		}
		if( is_null( $name ) || strlen(trim($name)) == 0 ) {
			$name	= basename( $file_path );
		}
		$file_info	= array(
			'name'	=> $name,
			'path'	=> $file_path,
			'type'	=> $type
		);
		$this->inline_images[$content_id]	= $file_info;
	}

	/**
	 * メールを送信します
	 */
	function send( $to, $subject=null, $body=null, $from=null, $reply_to=null, $return_path=null, $cc=null, $bcc=null, $add_header_crlf=false, $convert_encoding=true ) {
		$this->to	= $to;
		if( !is_null($subject) && strlen(trim($subject)) > 0 ) {
			$this->subject	= $subject;
		}
		if( !is_null($body) && strlen(trim($body)) > 0 ) {
			$this->text_body	= $body;
		}
		if( !is_null($from) && strlen(trim($from)) > 0 ) {
			$this->from	= $from;
		}
		if( !is_null($reply_to) && strlen(trim($reply_to)) > 0 ) {
			$this->reply_to	= $reply_to;
		}
		if( !is_null($return_path) && strlen(trim($return_path)) > 0 ) {
			$this->return_path	= $return_path;
		}
		if( is_array( $cc ) ) {
			$this->setCc( $cc );
		} else if( strlen(trim($cc)) > 0 ) {
			$this->addCc( $cc );
		}
		if( is_array( $bcc ) ) {
			$this->setBcc( $bcc );
		} else if( strlen(trim($bcc)) > 0 ) {
			$this->addBcc( $bcc );
		}
		return $this->send_execute( $add_header_crlf, $convert_encoding );
	}
	/**
	 * 送信処理を行う抽象メソッド
	 */
	function send_execute( $add_header_crlf=false, $convert_encoding=true ) {
		return false;
	}
	/**
	 * メールヘッダ用にエンコードした件名を取得します
	 */
	function get_encoded_subject( $add_header_crlf=false, $convert_encoding=true ) {
		// 置換文字列の処理を行う
		$subject	= $this->subject;
		$subject	= $this->getReplacedStrings( $subject, $this->getHeaderEncoding(), $convert_encoding );
		// 改行とMIME円コーディング処理
		if( $add_header_crlf ) {
			if( $convert_encoding ) {
				return mb_encode_mimeheader($subject,$this->getHeaderEncoding());
			} else {
				return mb_encode_mimeheader($subject);
			}
		} else {
			if( $convert_encoding && mb_detect_encoding($subject) != 'ascii' ) {
				$subject	= mb_convert_encoding($subject,$this->getHeaderEncoding(),'auto');
			}
			$subject					= base64_encode( $subject );
			return '=?'.$this->getHeaderCharset().'?B?'.$subject.'?=';
		}
	}
	/**
	 * 設定されたメールヘッダーをヘッダー文字列として取得します。
	 */
	function _get_header_part_strings( $include_to=false, $include_subject=false, $include_bcc=false, $add_header_crlf=false, $convert_encoding=true ) {
		$header_hash	= $this->_get_header_hash( $include_to, $include_subject, $include_bcc, $add_header_crlf, $convert_encoding );
		$header_strings	= '';
		foreach( $header_hash as $key => $value ) {
			$header_strings	.= $key . ': ' . $value . "\r\n";
		}
		return $header_strings . "\r\n";
	}
	/**
	 * 設定されたメールヘッダーをエンコード済みのハッシュで取得します。
	 */
	function _get_header_hash( $include_to=false, $include_subject=false, $include_bcc=false, $add_header_crlf=false, $convert_encoding=true ) {
		$return_hash	= array();
		$return_hash['MIME-Version']					= '1.0';
		$return_hash['Content-Transfer-Encoding']	= '7bit';
		$return_hash['X-Mailer']						= $this->x_mailer;
		
		if( strlen(trim($this->reply_to)) == 0 ) {
			$this->reply_to	= $this->from;
		}
		if( strlen(trim($this->return_path)) == 0 ) {
			$this->return_path	= $this->getFromAddress();
		}
		
		// メールアドレス RFC 2822を満たすことを前提としてユーザ名をエンコードする
		if( $include_to ) {
			$return_hash['To']				= $this->convertHeaderAddress( $this->to );
		}
		$return_hash['From']			= $this->convertHeaderAddress( $this->from );
		$return_hash['Reply-To']		= $this->convertHeaderAddress( $this->reply_to );
		$return_hash['Return-Path']	= $this->convertHeaderAddress( $this->return_path );
		$new_cc_array	= array();
		foreach( $this->cc as $address ) {
			if( strlen(trim($address)) > 0 ) {
				// RFC 2822を満たすことを前提としてユーザ名をエンコードする
				array_push( $new_cc_array, $this->convertHeaderAddress( $address ) );
			}
		}
		if( count($new_cc_array) > 0 ) {
			$return_hash['Cc']				= implode(", ", $new_cc_array );
		}
		if( $include_bcc ) {
			$new_bcc_array	= array();
			foreach( $this->bcc as $address ) {
				if( strlen(trim($address)) > 0 ) {
					// RFC 2822を満たすことを前提としてユーザ名をエンコードする
					array_push( $new_bcc_array, $this->convertHeaderAddress( $address ) );
				}
			}
			if( count($new_bcc_array) > 0 ) {
				$return_hash['Bcc']				= implode(", ", $new_bcc_array );
			}
		}
		// 件名の処理
		if( $include_subject ) {
			$return_hash['Subject']	= $this->get_encoded_subject( $add_header_crlf, $convert_encoding );
		}
		// 現在の日時を追加
		$return_hash['Date']	= date('r');

		// 添付ファイルの確認
		if( !is_array( $this->attachements) ){ $this->attachements		= array(); }
		if( !is_array( $this->inline_images) ){ $this->inline_images	= array(); }
		if(  $this->isMobile() ) {
			$this->boundary = substr(uniqid("b"),0,10);
			if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) {
				// HTMLメールで添付ファイルとインライン画像両方がある場合
				$return_hash['Content-Type']	= 'multipart/Related; boundary="'.$this->boundary.'"';
			} else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) {
				// HTMLメールで添付ファイルのみある場合
				$return_hash['Content-Type']	= 'multipart/Mixed; boundary="'.$this->boundary.'"';
			} else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) {
				// HTMLメールでインライン画像のみある場合
				$return_hash['Content-Type']	= 'multipart/Related; boundary="'.$this->boundary.'"';
			} else if( strlen($this->html_body) > 0 ) {
				// HTMLメールで添付もインライン画像もない場合
				$return_hash['Content-Type']	= 'multipart/Mixed; boundary="'.$this->boundary.'"';
			} else if( count($this->attachements) > 0 ) {
				// プレーンテキストで添付ファイルがある場合
				$return_hash['Content-Type']	= 'Multipart/Mixed; boundary="'.$this->boundary.'"';
			} else {
				// プレーンテキストのみの場合
				$return_hash['Content-Type']	= 'text/plain; charset='.$this->getBodyCharset();
			}
		} else {
			$this->boundary = "bnd" . uniqid("b");
			if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) {
				// HTMLメールで添付ファイルとインライン画像両方がある場合
				$return_hash['Content-Type']	= 'Multipart/Mixed; boundary="'.$this->boundary.'"';
			} else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) {
				// HTMLメールで添付ファイルのみある場合
				$return_hash['Content-Type']	= 'Multipart/Mixed; boundary="'.$this->boundary.'"';
			} else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) {
				// HTMLメールでインライン画像のみある場合
				$return_hash['Content-Type']	= 'Multipart/Related; boundary="'.$this->boundary.'"; type="Multipart/Alternative"';
			} else if( strlen($this->html_body) > 0 ) {
				// HTMLメールで添付もインライン画像もない場合
				$return_hash['Content-Type']	= 'Multipart/Alternative; boundary="'.$this->boundary.'"';
			} else if( count($this->attachements) > 0 ) {
				// プレーンテキストで添付ファイルがある場合
				$return_hash['Content-Type']	= 'Multipart/Mixed; boundary="'.$this->boundary.'"';
			} else {
				// プレーンテキストのみの場合
				$return_hash['Content-Type']	= 'text/plain; charset='.$this->getBodyCharset();
			}
		}

		return $return_hash;
	}
	/**
	 * Toのアドレス部分のみを抜き出したメールアドレスのみを取得します。
	 */
	function getToAddress() {
		$to	= $this->to;
		if( preg_match('/\\s/',$to) > 0 ) {
			$params = explode(' ', $to );
			$to		= array_pop($params);
		}
		$to	= trim($to);
		$to	= preg_replace('/^</','',$to);
		$to	= preg_replace('/>$/','',$to);
		return $to;
	}
	/**
	 * Fromのアドレス部分のみを抜き出したメールアドレスのみを取得します。
	 */
	function getFromAddress() {
		$from	= $this->from;
		if( preg_match('/\\s/',$from) > 0 ) {
			$params 	= explode(' ', $from );
			$from		= array_pop($params);
		}
		$from	= trim($from);
		$from	= preg_replace('/^</','',$from);
		$from	= preg_replace('/>$/','',$from);
		return $from;
	}
	/**
	 * Ccのアドレス部分のみを抜き出したメールアドレスのみの配列を取得します。
	 */
	function getCcAddresses() {
		$addresses	= array();
		if( is_array($this->cc) ) {
			foreach( $this->cc as $address ) {
				if( strlen(trim($address)) > 0 ) {
					if( preg_match('/\\s/',$address) > 0 ) {
						$params 	= explode(' ', $address );
						$address	= array_pop($params);
					}
					$address	= trim($address);
					$address	= preg_replace('/^</','',$address);
					$address	= preg_replace('/>$/','',$address);
					if( strlen(trim($address)) > 0 ) {
						array_push( $addresses, $address );
					}
				}
			}
		}
		return $addresses;
	}
	/**
	 * Bccのアドレス部分のみを抜き出したメールアドレスのみの配列を取得します。
	 */
	function getBccAddresses() {
		$addresses	= array();
		if( is_array($this->bcc) ) {
			foreach( $this->bcc as $address ) {
				if( strlen(trim($address)) > 0 ) {
					if( preg_match('/\\s/',$address) > 0 ) {
						$params 	= explode(' ', $address );
						$address	= array_pop($params);
					}
					$address	= trim($address);
					$address	= preg_replace('/^</','',$address);
					$address	= preg_replace('/>$/','',$address);
					if( strlen(trim($address)) > 0 ) {
						array_push( $addresses, $address );
					}
				}
			}
		}
		return $addresses;
	}
	/**
	 * 
	 */
	function convertHeaderAddress( $address, $convert_encoding = true ) {
		// to RFC 2822を満たすことを前提としてユーザ名をエンコードする
		$name	= '';
		if( preg_match('/\\s/',$address) > 0 ) {
			$params		= explode(' ', $address );
			$address	= array_pop( $params );
			$name		= implode( ' ', $params );
			if( $convert_encoding && mb_detect_encoding($address) != 'ascii' ) {
				$name	= mb_convert_encoding($name,$this->getHeaderEncoding(),'auto');
			}
			$name	= base64_encode( $name );
			$name	= '=?'.$this->getHeaderCharset().'?B?'.$name.'?=';
			$address	= $name.' '.$address;
		}
		return $address;
	}
	/**
	 * メールのボディパート文字列を取得します。
	 */
	function _get_body_part_strings( $convert_encoding=true ) {
		// text_bodyのみ置換文字列の処理を行う
		$text_body	= $this->text_body;
		$text_body	= str_replace("\r\n","\n",$text_body);
		$text_body	= str_replace("\r","\n",$text_body);
		$text_body	= str_replace("\n","\r\n",$text_body);
		$text_body	= $this->getReplacedStrings( $text_body, $this->getBodyEncoding(), $convert_encoding );
		$html_body	= $this->html_body;
		$html_body	= str_replace("\r\n","\n",$html_body);
		$html_body	= str_replace("\r","\n",$html_body);
		$html_body	= str_replace("\n","\r\n",$html_body);
		$html_body	= $this->getReplacedStrings( $html_body, $this->getBodyEncoding(), $convert_encoding );
		if( !is_array( $this->attachements) ){ $this->attachements		= array(); }
		if( !is_array( $this->inline_images) ){ $this->inline_images	= array(); }
		
		if( $convert_encoding ) {
			$text_body	= mb_convert_encoding($text_body,$this->getBodyEncoding(),'auto');
			$html_body	= mb_convert_encoding($html_body,$this->getBodyEncoding(),'auto');
		}
		
		// リターンするbody文字列を作成する
		$return_body	= '';
		if( $this->isMobile() ) {
			// 添付とデコメールのパターン判断
			if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) {
				// HTMLメールで添付ファイルとインライン画像両方がある場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "" . substr(uniqid("b"),0,8);
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
//				$return_body	.= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n";
//				$return_body	.= $text_body;
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// インラインファイル添付
				foreach( $this->inline_images as $content_id => $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Id: <'.$content_id.'>'."\r\n\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) {
				// HTMLメールで添付ファイルのみある場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "" . substr(uniqid("b"),0,8);
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
//				$return_body	.= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n";
//				$return_body	.= $text_body;
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) {
				// HTMLメールでインライン画像のみある場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "" . substr(uniqid("b"),0,8);
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
//				$return_body	.= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n";
//				$return_body	.= $text_body;
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// インラインファイル添付
				$num	= 1;
				foreach( $this->inline_images as $content_id => $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Id: <'.$content_id.'>'."\r\n\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
					$num++;
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( strlen($this->html_body) > 0 ) {
				// HTMLメールで添付もインライン画像もない場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "" . substr(uniqid("b"),0,8);
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
//				$return_body	.= 'Content-Transfer-Encoding: 7bit'."\r\n\r\n";
//				$return_body	.= $text_body;
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( count($this->attachements) > 0 ) {
				// プレーンテキストで添付ファイルがある場合
				// textパート
				$return_body	= '--' . $this->boundary . "\r\n\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n\r\n";
				$return_body	.= $text_body;
				$return_body	.= "\r\n\r\n";
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
	
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else {
				// プレーンテキストで添付ファイルもない bodyの改行コードはLFに統一する
				$return_body	= str_replace("\r\n","\n",$text_body);
				$return_body	= str_replace("\r","\n",$return_body);
			}
		} else {
			// 添付とHTMLのパターン判断
			if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) > 0 ) {
				// HTMLメールで添付ファイルとインライン画像両方がある場合
				// multipart/relatedパート
				$return_body	.= '--' . $this->boundary . "\r\n";
				$related_boundary = "*-bndd" . uniqid("b");
				$return_body	.= 'Content-Type: Multipart/Related; type="multipart/alternative"; boundary="'.$related_boundary.'"' ."\r\n\r\n";
				// multipart/alternativeパート
				$return_body	.= '--' . $related_boundary . "\r\n";
				$alternative_boundary = "*-bndd" . uniqid("b");
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"'."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"'."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// インラインファイル添付
				foreach( $this->inline_images as $content_id => $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $related_boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Id: <'.$content_id.'>'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// multipart/relatedパート終了
				$return_body	.= '--' . $related_boundary . '--'."\r\n\r\n";
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n\r\n";
			} else if( strlen($this->html_body) > 0 && count($this->attachements) > 0 && count($this->inline_images) == 0 ) {
				// HTMLメールで添付ファイルのみある場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "*-bndd" . uniqid("b");
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( strlen($this->html_body) > 0 && count($this->attachements) == 0 && count($this->inline_images) > 0 ) {
				// HTMLメールでインライン画像のみある場合
				// multipart/alternativeパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$alternative_boundary = "*-bndd" . uniqid("b");
				$return_body	.= 'Content-Type: Multipart/Alternative; boundary="'.$alternative_boundary.'"' ."\r\n\r\n";
				// textパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $alternative_boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// multipart/alternativeパート終了
				$return_body	.= '--' . $alternative_boundary . '--'."\r\n\r\n";
				// インラインファイル添付
				foreach( $this->inline_images as $content_id => $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Id: <'.$content_id.'>'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( strlen($this->html_body) > 0 ) {
				// HTMLメールで添付もインライン画像もない場合
				// textパート
				$return_body	.= '--' . $this->boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($text_body);
				$return_body	.= $text_body;
				$return_body	.= "\r\n\r\n";
				// htmlパート
				$return_body	.= '--' . $this->boundary . "\r\n";
				$return_body	.= 'Content-Type: text/html; charset="'.$this->getBodyCharset().'"' ."\r\n";
				$return_body	.= 'Content-Transfer-Encoding: quoted-printable'."\r\n\r\n";
				$return_body	.= $this->quoted_printable_encoding($html_body);
				$return_body	.= "\r\n\r\n";
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else if( count($this->attachements) > 0 ) {
				// プレーンテキストで添付ファイルがある場合
				// textパート
				$return_body	= '--' . $this->boundary . "\r\n";
				$return_body	.= 'Content-Type: text/plain; charset="'.$this->getBodyCharset().'"' ."\r\n\r\n";
				$return_body	.= $text_body;
				$return_body	.= "\r\n\r\n";
				// ファイルパート
				foreach( $this->attachements as $file_info ) {
					$file_path	= $file_info['path'];
					$file_type	= $file_info['type'];
					$file_name	= $file_info['name'];
					$contents	= file_get_contents( $file_path );
					$attach		= chunk_split(base64_encode($contents));
					$file_name	= mb_convert_encoding( $file_name, $this->getFileNameEncoding(), 'auto');
					$file_name	= base64_encode($file_name);
					$file_name	= '=?'.$this->getFileNameCharset().'?B?'.$file_name.'?=';
	
					$return_body	.= '--' . $this->boundary . "\r\n";
					$return_body	.= 'Content-Type: '.$file_type.'; name="'.$file_name.'"'."\r\n";
					$return_body	.= 'Content-Transfer-Encoding: base64'."\r\n";
					$return_body	.= 'Content-Disposition: attachment; filename="'.$file_name.'"'."\r\n";
					$return_body	.= "\r\n";
					$return_body	.= $attach . "\r\n";
					$return_body	.= "\r\n\r\n";
				}
				// マルチパート終了
				$return_body	.= '--' . $this->boundary . '--'."\r\n";
			} else {
				// プレーンテキストで添付ファイルもない bodyの改行コードはLFに統一する
				$return_body	= str_replace("\r\n","\n",$text_body);
				$return_body	= str_replace("\r","\n",$return_body);
			}
		}
		
		return trim($return_body);
	}
	/**
	 * 本文と件名の特定置き換えワードを設定します。
	 */
	function addReplaceWord( $name, $value ) {
		$this->replace_words[$name]	= $value;
	}
	/**
	 * 本文と件名の特定置き換えワードをハッシュで設定します。
	 */
	function addReplaceWordByHash( $prefix_name, $hash ) {
		foreach( $hash as $key=>$val ) {
			if( gettype( $val ) != 'object'
				&& gettype( $val ) != 'array'
				&& gettype( $val ) != 'resource'
			) {
				$this->addReplaceWord( $prefix_name."::".$key, $val );
			}
		}
	}
	/**
	 * 本文と件名の特定置き換えワードをオブジェクトで設定します。
	 */
	function addReplaceWordByObject( $prefix_name, $object ) {
		$vars	= get_object_vars( $object );
		foreach( $vars as $key=>$val ) {
			if( gettype( $val ) != 'object'
				&& gettype( $val ) != 'array'
				&& gettype( $val ) != 'resource'
			) {
				$this->addReplaceWord( $prefix_name."::".$key, $val );
			}
		}
	}
	/**
	 * メールヘッダの文字コードを指定します。
	 */
	function setHeaderCharset( $charset ) {
		$this->charset_header	= $charset;
	}
	/**
	 * 設定されているメールヘッダ文字コードを取得します
	 */
	function getHeaderCharset() {
		return $this->charset_header;
	}
	/**
	 * 設定されているメールヘッダ文字コードで利用するPHPコード変換ルールを取得します
	 */
	function getHeaderEncoding() {
		$key	= strtoupper($this->charset_header);
		if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) {
			return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key];
		} else {
			return $this->charset_header;
		}
	}
	/**
	 * テキストボディの文字コードを指定します。
	 */
	function setBodyCharset( $charset ) {
		$this->charset_body	= $charset;
	}
	/**
	 * 設定されているテキストボディ文字コードを取得します
	 */
	function getBodyCharset() {
		return $this->charset_body;
	}
	/**
	 * 設定されているテキストボディ文字コードで利用するPHPコード変換ルールを取得します
	 */
	function getBodyEncoding() {
		$key	= strtoupper($this->charset_body);
		if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) {
			return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key];
		} else {
			return $this->charset_body;
		}
	}
	/**
	 * 添付ファイル名の文字コードを指定します。
	 */
	function setFileNameCharset( $charset ) {
		$this->charset_filename	= $charset;
	}
	/**
	 * 設定されている添付ファイル名文字コードを取得します
	 */
	function getFileNameCharset() {
		return $this->charset_filename;
	}
	/**
	 * 設定されている添付ファイル名文字コードで利用するPHPコード変換ルールを取得します
	 */
	function getFileNameEncoding() {
		$key	= strtoupper($this->charset_filename);
		if( isset( $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key]) ) {
			return $GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP'][$key];
		} else {
			return $this->charset_filename;
		}
	}
	/**
	 * 文字列をquoted printableエンコードして返します。
	 * @param string $str エンコード前文字列
	 * @return string エンコード後文字列
	 */
	function quoted_printable_encoding($str){
		if( !defined('CRLF') ) {
			define('CRLF', "\r\n");
		}
		$str		= trim($str);
		$str		= str_replace("\r\n","\n",$str);
		$lines		= preg_split("/\r?\n/", $str);
		$retStrings	= '';
		foreach ( $lines as $line ) {
			$lineDec	= '';
			for( $i=0; $i < strlen($line); $i++ ) {
				$char	= substr( $line, $i, 1 );
				$ascii	= ord( $char );
				if ( $ascii < 32 || $ascii == 61 || $ascii > 126 ) {
					$char	= '='.strtoupper( dechex( $ascii ) );
				}
				if ( ( strlen ( $lineDec ) + strlen ( $char ) ) >= 76 ) {
					$retStrings .= $lineDec.'='.CRLF;
					$lineDec	= '';
				}
				$lineDec	.= $char;
			}
			if( strlen(trim($lineDec)) > 0 ) {
				$retStrings	.= $lineDec.CRLF;
			} else {
				$retStrings	.= '=0A=0D='.CRLF;
			}
		}
		return trim($retStrings);
	}
	/**
	 * 携帯電話メール宛か確認します
	 */
	function isMobile() {
		foreach( $GLOBALS['MOBILE_MAIL_DOMAIN_ARRAY'] as $fqdn ) {
			$fqdn_regx	= str_replace('.','\\.',$fqdn );
			if( preg_match('/\\@'.$fqdn_regx.'$/',$this->to) > 0 ) {
				return true;
			}
		}
	}
	/**
	 * 件名の特定置き換えワードを設定した文字列を返す。
	 */
	function getReplacedTextSubject( $convert_encoding=true ) {
		$subject = $this->subject;
		$subject = $this->getReplacedStrings( $subject );
		return $subject;
	}
	/**
	 * 本文の特定置き換えワードを設定した文字列を返す。
	 */
	function getReplacedTextBody( $convert_encoding=true ) {
		$text_body = $this->text_body;
		$text_body = $this->getReplacedStrings( $text_body );
		return $text_body;
	}
	/**
	 * 本オブジェクトに設定された置換ハッシュを元に対象文字列を置換して取得
	 * @param $targetStrings 置き換え元文字列
	 * @param $toEncoding 文字セット
	 * @param $convert_encoding 強制文字エンコード変換
	 * @return 変換後の文字列
	 */
	function getReplacedStrings( $targetStrings, $toEncoding='UTF-8', $convert_encoding=true ) {
		return util_Mail::replaceFormatStrings( $targetStrings, $this->replace_words, $toEncoding, $convert_encoding );
	}
	/**
	 * 置き換え文字列を置換ワードハッシュで置換した文字列を取得する静的メソッド
	 * @param $targetStrings 置き換え元文字列
	 * @param $replaceHash 置換ワードハッシュ
	 * @param $toEncoding 文字セット
	 * @param $convert_encoding 強制文字エンコード変換
	 * @return 変換後の文字列
	 */
	function replaceFormatStrings( $targetStrings, $replaceHash=array(), $toEncoding='UTF-8', $convert_encoding=true, $request=null ) {
		if( mb_detect_encoding($targetStrings) != 'UTF-8' ) {
			$targetStrings	= mb_convert_encoding($targetStrings,'UTF-8','auto');
		}
		// writeタグの置換
		foreach( $replaceHash as $repKey => $repValue ){
			if( is_object($repValue) ){
				// $repValueがオブジェクトの場合
				if( is_a($repValue,'system_AbstractData') ){
					$targetStrings	= $repValue->convertTextValues( $request, $targetStrings, $repKey );
				} else {
					// system_AbstractData以外のクラスは置換しない
				}
			} else if( is_array($repValue) ){
				// $repValueが配列の場合
				$targetStrings = util_Mail::_replaceArrayValue( $targetStrings, $repKey, $repValue, $request );
			} else if( is_null($repValue) || is_scalar($repValue) ){
				// $repValueがスカラー値の場合はそのまま置換
				$targetStrings = util_Mail::_replaceScalarValue( $targetStrings, $repKey, $repValue );
			}
		}
		// 一通り変換したらcalcタグ計算
		$regx		= '/<calc=([^>]+)>/';
		if( preg_match_all($regx,$targetStrings,$matches,PREG_PATTERN_ORDER) > 0 ) {
			if(is_array($matches[0])&&is_array($matches[1])){
				foreach($matches[0] as $num => $tagAllStr ){
					if( isset($matches[1][$num]) && preg_match('/^[0-9\\-\\+\\*\\/\\(\\)\\s]*$/',$matches[1][$num])>0 ){
						$value	= 0;
						$eValue	= '$value = ('.$matches[1][$num].');';
						eval($eValue);
						$targetStrings	= str_replace($tagAllStr,$value,$targetStrings);
					}
				}
			}
		}
		// ifタグの置換
		$targetStrings	= preg_replace('/\\{if\\:\\}(.*)\\{\\/if\\}/','',$targetStrings);
		$targetStrings	= preg_replace('/\\{if\\:0\\}(.*)\\{\\/if\\}/','',$targetStrings);
		$targetStrings	= preg_replace('/\\{if\\:\\\'0\\\'\\}(.*)\\{\\/if\\}/','',$targetStrings);
		$targetStrings	= preg_replace('/\\{if\\:([^\\}])+}/','',$targetStrings);
		$targetStrings	= preg_replace('/\\{\\/if\\}/','',$targetStrings);
		// 文字コード変換
		if( !$convert_encoding && $toEncoding != 'UTF-8' ) {
			$targetStrings	= mb_convert_encoding($targetStrings,$toEncoding,'UTF-8');
		}
		return $targetStrings;
	}
	/**
	 * 渡された―を含むタグを配列で変換します
	 */
	function _replaceArrayValue( $targetStrings, $key, $val, $request=null ){
		if( strlen($targetStrings)==0 || strlen($key)==0 || is_null($val) ){
			return $targetStrings;
		} else if( !is_array($val) ){
			return $targetStrings;
		}
		foreach( $val as $repKey => $repValue ){
			if( is_object($repValue) ){
				// $repValueがオブジェクトの場合
				if( is_a($repValue,'system_AbstractData') ){
					$targetStrings	= $repValue->convertTextValues( $request, $targetStrings, $repKey );
				} else {
					// system_AbstractData以外のクラスは置換しない
				}
			} else if( is_array($repValue) ){
				// $repValueが配列の場合
				$targetStrings = util_Mail::_replaceArrayValue( $targetStrings, $repKey, $repValue, $request );
			} else if( is_scalar($repValue) ){
				// $repValueがスカラー値の場合はそのまま置換
				$targetStrings = util_Mail::_replaceScalarValue( $targetStrings, $repKey, $repValue );
			}
		}
		return $targetStrings;
	}
	/**
	 * 渡されたキーを含むタグをスカラー値に変換します
	 */
	function _replaceScalarValue( $targetStrings, $key, $val ){
		if( strlen($targetStrings)==0 || strlen($key)==0 ){
			return $targetStrings;
		}
		// そのまま変換
		$targetStrings	= str_replace( '{'.$key.'}', $val, $targetStrings );
		$targetStrings	= str_replace( '{write:'.$key.'}', $val, $targetStrings );
		$targetStrings	= str_replace( '{if:'.$key.'}', '{if:'.$val.'}', $targetStrings );
		// オプション付きタグ変換
		$targetStrings = util_Mail::_replaceOptionScalarValue( $targetStrings, $key, $val );
		return $targetStrings;
	}
	/**
	 * オプション付きタグ変換
	 */
	function _replaceOptionScalarValue( $targetStrings, $key, $val ){
		$regx		= '/\\{write\\:'.util_CharUtility::escapeRegxStr($key).'(\\s[^\\}]+)\\}/';
		if( preg_match_all($regx,$targetStrings,$matches,PREG_PATTERN_ORDER) > 0 ) {
			if( is_array($matches[0]) ) {
				foreach( $matches[0] as $matchNum => $allStr ) {
					$convertedValue	= $val;
					$paramStr	= '';
					if( is_array($matches[1]) && isset($matches[1][$matchNum]) ) {
						$paramStr	= $matches[1][$matchNum];
						$params		= explode(' ',$paramStr);
						foreach($params as $str) {
							if( 'number_format' == trim($str) ) {
								$convertedValue	= number_format($convertedValue);
							} else if( 'jpy' == trim($str) ) {
								$convertedValue	= '￥'.number_format($convertedValue);
							} else if( preg_match('/^right\\(([0-9]{1,6})\\)$/',$str,$subMatchs) > 0 ) {
								$length	= trim($subMatchs[1]);
								if( strlen($convertedValue) < $length ) {
									$spaces	= '';
									for( $i=0; $i<$length-strlen($convertedValue); $i++ ) {
										$spaces	.= ' ';
									}
									$convertedValue	= $spaces.$convertedValue;
								}
							} else if( preg_match('/^left\\(([0-9]{1,6})\\)$/',$str,$subMatchs) > 0 ) {
								$length	= trim($subMatchs[1]);
								if( strlen($convertedValue) < $length ) {
									$spaces	= '';
									for( $i=0; $i<$length-strlen($convertedValue); $i++ ) {
										$spaces	.= ' ';
									}
									$convertedValue	= $convertedValue.$spaces;
								}
							} else if( preg_match('/^center\\(([0-9]{1,6})\\)$/',$str,$subMatchs) > 0 ) {
								$length	= trim($subMatchs[1]);
								if( strlen($convertedValue) < $length ) {
									$spaces	= '';
									for( $i=0; $i<floor(($length-strlen($convertedValue))/2); $i++ ) {
										$spaces	.= ' ';
									}
									$convertedValue	= $spaces.$convertedValue;
								}
							}
						}
					}
					$targetStrings	= str_replace( $allStr, $convertedValue, $targetStrings );
				}
			}
		}
		return $targetStrings;
	}
	/**
	 * カンマ区切りに分割されたメールアドレスを配列で取得します
	 */
	function divideCsvEmail( $mailCsvString ) {
		$addressArray	= array();
		if( strpos($mailCsvString,',') !== false ) {
			$tmpArray	= explode(',',trim($mailCsvString));
			foreach( $tmpArray as $address ) {
				$address	= trim($address);
				if( strlen($address) > 0 ) {
					array_push($addressArray,$address);
				}
			}
		} else if( strlen(trim($mailCsvString)) > 0 ) {
			array_push($addressArray,trim($mailCsvString));
		}
		return $addressArray;
	}
}
// 本クラスで利用するグローバル変数定義
/** 文字コード変換ルール	*/
$GLOBALS['UTIL_MAIL_CHARSET_CODE_MAP']	= array(
	'JIS'			=> 'ISO-2022-JP',
	'SHIFT_JIS'	=> 'SJIS-win',
	'Shift_JIS'	=> 'SJIS-win',
	'SHIFT-JIS'	=> 'SJIS-win',
);
?>