<?php
/*
 * framework-spider
 * util/mail/SMTP.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
 * 
 */
require_once( dirname(dirname(__FILE__)).DIRECTORY_SEPARATOR.'Mail.class.php');
/**
 * メール送信ユーティリティ拡張クラス：SMTP接続による送信の実装クラス
 * 
 * ※ 本クラスはPEAR/Mailパッケージを利用します。
 * 
 * @version 1.0.0
 * @copyright Copyright &copy; 2008, <m_nakashima@users.sourceforge.jp> http://sourceforge.jp/projects/shopformer/
 * @author  m.nakashima <m_nakashima@users.sourceforge.jp>
 * @since PHP 4.3
 */
class util_mail_SMTP extends util_Mail {
	function util_mail_SMTP() {
	}
	/**
	 * メールを送信します
	 */
	function send_execute( $add_header_crlf=false, $convert_encoding=true ) {
		
		$header_hash	= $this->_get_header_hash(true,true,false,$add_header_crlf,$convert_encoding);
		$body_strings	= $this->_get_body_part_strings($convert_encoding);

		// 最初にそのままPEARを要求してみる
		$is_exist_pear_mail	= false;
		if( @require_once('PEAR.php') ) {
			// pearが存在するならMailパッケージの確認
			if( @require_once('Mail.php') ) {
				// pear mailパッケージインストール済み
				$is_exist_pear_mail	= true;
			}
		}
		if( !class_exists('PEAR') || !class_exists('Mail') ){
			// デフォルトのインクルードパスに存在しないなら設定された追加パスを確認
			// 区切り文字の決定
			$separator = ":";
			if( PHP_OS == "WINNT" ){
				$separator = ";";
			}
			$pathArray	= explode($separator,$this->options['pear_path'].$separator.get_include_path());
			foreach( $pathArray as $rPath ){
				if( !class_exists('PEAR') ){
					$pPath	= $rPath.DIRECTORY_SEPARATOR.'PEAR.php';
					if( file_exists($pPath) ){
						@require_once($pPath);
					}
				}
				if( !class_exists('Mail') ){
					$mPath	= $rPath.DIRECTORY_SEPARATOR.'Mail.php';
					if( file_exists($mPath) ){
						@require_once($mPath);
					}
				}
			}
		}
		if( !class_exists('PEAR') || !class_exists('Mail') ){
			return false;
		}
		$mailSendObj	= null;
		if( preg_match('/^[fF](|[aA][lL][sS][eE])$/',$this->options['smtp_auth']) > 0
			|| strlen($this->options['smtp_auth']) == 0 ) {
			$this->options['smtp_auth']	= false;
		}
		if( preg_match('/^[pP][oO][pP][bB][eE][fF][oO][rR][eE]$/',$this->options['smtp_auth']) > 0 ) {
			if( $this->connectPopBeforeSmtp() ) {
				$params = array(
					"host" => $this->options['smtp_host'],
					"port" => $this->options['smtp_port'],
					"localhost" => $_SERVER['HOST_NAME']
				);
				$mailSendObj = & Mail::factory( 'smtp', $params );
			} else {
				return false;
			}
		} else {
			$params = array(
				"host" => $this->options['smtp_host'],
				"port" => $this->options['smtp_port'],
				"auth" => $this->options['smtp_auth'],
				"username" => $this->options['smtp_auth_user'],
				"password" => $this->options['smtp_auth_pass'],
				"localhost" => $_SERVER['HOST_NAME']
			);
			$mailSendObj = & Mail::factory( 'smtp', $params );
		}
		
		// 送信を実行する
		$result = $mailSendObj->send( $this->getToAddress(), $header_hash, $body_strings );
		if ( PEAR::isError( $result ) ) {
			return false;
		} else {
			// Ccにメール送信する
			$cc_array	= $this->getCcAddresses();
			foreach( $cc_array as $address ) {
				$mailSendObj->send( $address, $header_hash, $body_strings );
			}
			// Bccにメール送信する
			$bcc_array	= $this->getBccAddresses();
			foreach( $bcc_array as $address ) {
				$mailSendObj->send( $address, $header_hash, $body_strings );
			}
			return true;
		}
	}
	/**
	 * 送信設定オプションの妥当性検査を行いエラーメッセージの配列を返します。
	 * エラーがない場合は要素0の配列を返します。
	 */
	function validate_options( & $options ) {
		$error_messages	= array();
		if( !is_array($options) ) {
			array_push($error_messages,'util.mail.optionrequired');
		} else {
			if( !isset($options['pear_path']) && isset($options[0]) ) {
				$options['pear_path']	= trim(stripslashes($options[0]));
				unset( $options[0] );
			}
			if( !isset($options['smtp_host']) && isset($options[1]) ) {
				$options['smtp_host']	= trim(stripslashes($options[1]));
				unset( $options[1] );
			}
			if( !isset($options['smtp_port']) && isset($options[2]) ) {
				$options['smtp_port']	= trim(stripslashes($options[2]));
				unset( $options[2] );
			}
			if( !isset($options['smtp_auth']) && isset($options[3]) ) {
				$options['smtp_auth']	= trim(stripslashes($options[3]));
				unset( $options[3] );
			}
			if( !isset($options['smtp_auth_user']) && isset($options[4]) ) {
				$options['smtp_auth_user']	= trim(stripslashes($options[4]));
				unset( $options[4] );
			}
			if( !isset($options['smtp_auth_pass']) && isset($options[5]) ) {
				$options['smtp_auth_pass']	= trim(stripslashes($options[5]));
				unset( $options[5] );
			}
		}
		
		$pear_path		= trim($options['pear_path']);
		$smtp_host		= trim($options['smtp_host']);
		$smtp_port		= trim($options['smtp_port']);

		// pear mailの存在確認
		$is_exist_pear_mail	= false;
		if( @require_once ( 'PEAR.php' ) ) {
			if( @require_once ( 'Mail.php' ) ) {
				$is_exist_pear_mail	= true;
			}
		}
		if( !$is_exist_pear_mail ) {
			// デフォルトにないならオプションを確認
			if( strlen($pear_path) == 0 ) {
				array_push($error_messages,'util.mail.smtp.requirepear');
			} else if( !file_exists($pear_path) ) {
				array_push($error_messages,'util.mail.smtp.pearnotexists');
			} else {
				$separator = ":";
				if( PHP_OS == "WINNT" ){
					$separator = ";";
				}
				$includePath	= get_include_path();
				$includePath	.= $separator . $options['pear_path'] . $separator;
				set_include_path( $includePath );
				if( @require_once ( 'PEAR.php' ) ) {
					if( @require_once ( 'Mail.php' ) ) {
					} else {
						array_push($error_messages,'util.mail.smtp.requirepearmail');
					}
				} else {
					array_push($error_messages,'util.mail.smtp.pearnotexists');
				}
			}
		}
		if( strlen($smtp_host) == 0 ) {
			array_push($error_messages,'util.mail.smtp.nohost');
		} else {
			// ホスト存在確認
			$ipAddress	= gethostbyname($smtp_host);
			if( preg_match('/^[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}/',$ipAddress) == 0 ) {
				array_push($error_messages,'util.mail.smtp.hostnotfound');
			}
		}
		if( strlen($smtp_port) == 0 ) {
			array_push($error_messages,'util.mail.smtp.noport');
		} else if( preg_match('/^[0-9]+$/',$smtp_port) == 0 ) {
			array_push($error_messages,'util.mail.smtp.invalidport');
		}
		$smtp_auth			= trim($options['smtp_auth']);
		$smtp_auth_user		= trim($options['smtp_auth_user']);
		$smtp_auth_pass		= trim($options['smtp_auth_pass']);
		
		if( preg_match('/^[fF](|[aA][lL][sS][eE])$/',$smtp_auth) > 0
			|| strlen($smtp_auth) == 0 ) {
			$smtp_auth		= false;
		}
		if( $smtp_auth === false ) {
			// 認証なし
		} else if( preg_match('/^[pP][oO][pP][bB][eE][fF][oO][rR][eE]$/',$smtp_auth) > 0 ) {
			// pop before smtp
			if( strlen(trim($options['pop_host'])) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nopophost');
			}
			if( strlen(trim($options['pop_port'])) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nopopport');
			}
			if( strlen($smtp_auth_user) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nouser');
			}
			if( strlen($smtp_auth_pass) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nopassword');
			}
		} else {
			if( strlen($smtp_auth_user) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nouser');
			}
			if( strlen($smtp_auth_pass) == 0 ) {
				array_push($error_messages,'util.mail.smtp.nopassword');
			}
		}
		return $error_messages;
	}
	/**
	 * pop before smtpのためpopサーバーに接続して切断します
	 */
	function connectPopBeforeSmtp() {
		$socket = fsockopen($this->options['pop_host'], $this->options['pop_port'], $errorNumber, $errorMessage, 10);
		if( $socket !== false ) {
			$buffer = fgets($socket, 512);
			if (substr($buffer, 0, 3) != '+OK') {
				fputs($socket, "QUIT \r\n");
				fclose($socket);
			} else {
				fputs($socket, "USER ".$this->options['smtp_auth_user']."\r\n ");
				$buffer = fgets($socket, 512);
				if (substr($buffer, 0, 3) != '+OK') {
					fputs($socket, "QUIT \r\n");
					fclose($socket);
				} else {
					fputs($socket, "PASS ".$this->options['smtp_auth_pass']."\r\n");
					$buffer = fgets($socket, 512);
					if (substr($buffer, 0, 3) != '+OK') {
						fputs($socket, "QUIT \r\n");
						fclose($socket);
					} else {
						fputs($socket, "QUIT \r\n");
						fclose($socket);
						return true;
					}
				}
			}
		}
		return false;
	}
}
?>