<?php
//v1.0.4 www.bcoos.net 2006/10 GPL
//v1.3 www.exoops.info 2006/03 
// $Id: xoopsmailer.php,v 1.23 2003/07/07 05:36:10 half-dead Exp $
// ------------------------------------------------------------------------- //
//               E-Xoops: Content Management for the Masses                  //
//                       < http://www.e-xoops.com >                          //
// ------------------------------------------------------------------------- //
// Original Author: Kazumi Ono
// Author Website : http://www.mywebaddons.com/ , http://www.myweb.ne.jp
// License Type   : GPL: See /manual/LICENSES/GPL.txt
// ------------------------------------------------------------------------- //
if (!defined("XOOPS_XOOPSMAILER_INCLUDED")) {
	define("XOOPS_XOOPSMAILER_INCLUDED", 1);
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
class XoopsMailer {
	var $fromEmail;
	var $fromName;
	var $toUsers;
	var $toEmails;
	var $subject;
	var $body;
	var $errors;
	var $success;
	var $isMail;
	var $isPM;
	var $assignedTags;
	var $template;
	var $templatedir;
	var $useToggle;
	var $type;
	function XoopsMailer() {
		$this->reset();
	}
//---------------------------------------------------------------------------------------//
/**
* reset all properties to default
*/
function reset() {
	$this->fromEmail    = '';
	$this->fromName     = '';
	$this->toUsers      = array();
	$this->toEmails     = array();
	$this->headers      = array();
	$this->subject      = '';
	$this->body         = '';
	$this->errors       = array();
	$this->success      = array();
	$this->isMail       = false;
	$this->isPM         = false;
	$this->assignedTags = array();
	$this->template     = '';
	$this->templatedir  = '';
	$this->isToggle     = false;
	$this->type         = 'plain';
	$this->boundary     = '----'.md5(uniqid(mt_rand(), TRUE));
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function assign($tag, $value=NULL) {
if ( is_array($tag) ) {
	foreach ($tag as $k => $v) {
		$this->assign($k, $v);
	}
	} else {
		if ( !empty($tag) && isset($value) ) {
			$tag = strtoupper(trim($tag));
				if ( substr($tag, 0, 2) != 'X_' ) {
					$this->assignedTags[$tag] = $value;
				}
		}
	}
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function attachFile($file, $type='application/x-unknown-content-type', $disposition='attachment') {
if ( empty($type) ) {
	$type = 'application/x-unknown-content-type';
}
if ( preg_match("'(audio|application|image|video)/'i", $type) ) {
	$mode = 'b';
}
if ($fp = @fopen($file, 'r'.$mode)) {
	$attachment = fread($fp, filesize($file));
	fclose($fp);
}
if ($attachment) {
	if ($disposition != 'inline') { $disposition = 'attachment'; }
	$this->attachments[] = '--'.$this->boundary;
	$this->attachments[] = 'Content-Type: '.$type.'; name="'.basename($file).'"';
	$this->attachments[] = 'Content-Transfer-Encoding: base64';
	$this->attachments[] = 'Content-Disposition: '.$disposition.'; filename="'.basename($file).'"'."\n";
	$this->attachments[] = chunk_split(base64_encode($attachment));
	return(TRUE);
}
return(FALSE);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setTemplateDir($value) {
if ( @is_dir($value) ) {
	if (substr($value, -1) == '/') {
		$value = substr($value, 0, -1);
	}
	$this->templatedir = $value;
	}
}
//---------------------------------------------------------------------------------------//
/**
* Sets path to the root of the module containing the template
* Do NOT set the path to the language dir
* Templates are always in <path>/language/(lang)/mail_template/<files>
*
* @param string $value full path to directory
*/
function setTemplate($value) {
	$this->template = $value;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setFromEmail($value) {
	$this->fromEmail = trim($value);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setFromName($value) {
	$this->fromName = trim($value);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setSubject($value) {
	$this->subject = trim($value);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setBody($value) {
	$this->body = trim($value);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function useMail() {
	$this->isMail = true;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function usePM() {
	$this->isPM = true;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function useToggle($value=false) {
	$this->useToggle = ($value == false) ? false : true;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setToEmails($email) {
if (!is_array($email) && preg_match('#(,|;| )#', $email)) {
	$email = preg_split('#(,|;| )#', $email);
}
if ( !is_array($email) ) {
	$email = trim($email);
	if ( checkEmail($email) ) {
		array_push($this->toEmails, $email);
	}
	} else {
		foreach ($email as $e) {
			$this->setToEmails($e);
		}
	}
$this->toEmails = array_unique($this->toEmails);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setToUsers($user) {
if ( !is_array($user) ) {
	if ( strtolower(get_class($user)) == 'xoopsuser' ) {
		array_push($this->toUsers, $user->getVar('uid'));
		} elseif ( XoopsUser::getUnameFromId($user) ) {
			array_push($this->toUsers, $user);
		}
	} else {
		foreach ($user as $u) {
			$this->setToUsers($u);
		}
	}
$this->toUsers = array_unique($this->toUsers);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setToGroups($group) {
if ( !is_array($group) ) {
	if ( strtolower(get_class($group)) != 'xoopsgroup' ) {
		$group = new XoopsGroup($group);
	}
	$this->setToUsers($group->getMembers());
	} else {
		foreach ($group as $g) {
			$this->setToGroups($g);
		}
	}
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setType($type='text/plain') {
	$this->addHeader('Content-Type:', $type);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setPriority($priority=3) {
switch($priority) {
	case 1:
		$this->addHeader('X-Priority:', '1 (Highest)');
		break;
	case 2:
		$this->addHeader('X-Priority:', '2 (High)');
		break;
	case 3:
		$this->addHeader('X-Priority:', '3 (Normal)');
		break;
	case 4:
		$this->addHeader('X-Priority:', '4 (Low)');
		break;
	case 5:
		$this->addHeader('X-Priority:', '5 (Lowest)');
		break;
	}
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function setReciept($email='') {
	$email = checkEmail($email) ? $email : $this->fromEmail;
	$this->addHeader('Disposition-Notification-To:', $email);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function addHeader($type, $value) {
$type = trim($type);
if (substr($type, -1) != ':') {
	$type .= ':';
}
$this->headers[$type] = trim($value);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function removeHeader($value) {
$value = trim($value);
if (substr($value, -1) != ':') {
	$value .= ':';
}
unset($this->headers[$value]);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function getHeaders() {
foreach ($this->headers as $key => $value) {
	if (substr($key, -1) != ':') {
		$key .= ':';
	}
	$header[] = trim($key).' '.trim($value);
}
return join("\n", $header);
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function send() {
global $xoopsUser, $bcoosConfig;
if ( !empty($this->template) ) {
	if ( !empty($this->templatedir) ) {
		if ( @file_exists($this->templatedir.'/language/'.$bcoosConfig['language'].'/mail_template/'.$this->template) ) {
			$path = $this->templatedir.'/language/'.$bcoosConfig['language'].'/mail_template/'.$this->template;
		} elseif( @file_exists($this->templatedir.'/language/english/mail_template/'.$this->template) ) {
			$path = $this->templatedir.'/language/english/mail_template/'.$this->template;
		} else {
			$this->errors[] = sprintf(_XM_FAILOPTPL, $this->templatedir.$this->template);
			return false;
		}
		} else {
			if ( @file_exists(XOOPS_ROOT_PATH.'/language/'.$bcoosConfig['language'].'/mail_template/'.$this->template) ) {
				$path = XOOPS_ROOT_PATH.'/language/'.$bcoosConfig['language'].'/mail_template/'.$this->template;
			} elseif ( @file_exists(XOOPS_ROOT_PATH.'/language/english/mail_template/'.$this->template) ) {
				$path = XOOPS_ROOT_PATH.'/language/english/mail_template/'.$this->template;
			} else {
				$this->errors[] = sprintf(_XM_FAILOPTPL, $this->templatedir.$this->template);
				return false;
			}
		}
	if ($fp = @fopen($path, 'r')) {
		$this->setBody(fread($fp, filesize($path)));
		fclose($fp);
		if ( stristr($this->body, '{X_ISHTML}') ) {
			$this->body = str_replace('{X_ISHTML}', '', $this->body);
			$this->setType('text/html');
		}
		} else {
			$this->errors[] = sprintf(_XM_FAILOPTPL, $path);
			return false;
		}
	} elseif ( empty($this->body) ) {
		$this->errors[] = _XM_MSGBODY;
		return false;
	}
// replace tags with actual values
foreach ( $this->assignedTags as $k => $v ) {
	$this->body = str_replace("{".$k."}", $v, $this->body);
}
$this->body = str_replace("\r\n", "\n"  , $this->body);
$this->body = str_replace("\r"  , "\n"  , $this->body);
if ($this->isMail || $this->toEmails) {
	if ( empty($this->fromName) && $xoopsUser ) {
		$this->setFromName($xoopsUser->uname());
		} elseif ( empty($this->fromName) ) {
			$this->setFromName($bcoosConfig['title']);
		}
	if ( empty($this->fromEmail) && $xoopsUser ) {
		$this->setFromEmail($xoopsUser->email());
		} elseif ( empty($this->fromEmail) ) {
			$this->setFromEmail($bcoosConfig['adminmail']);
		}
	$this->addHeader('From:', $this->fromEmail);
	$this->addHeader('Reply-To:', $this->fromEmail);
	$this->addHeader('Return-Path:', $this->fromEmail);
	$this->addHeader('Error-To:', $this->fromEmail);
	$this->addHeader('Return-Errors-To:', $this->fromEmail);
	$this->addHeader('X-Mailer:', XOOPS_VERSION);
	if ( !empty($this->attachments) ) {
		$body = "\n".'--'.$this->boundary."\n";
		if ( isset($this->headers['Content-Type:']) ) {
			$body .= 'Content-Type: '.$this->headers['Content-Type:']."\n\n";
			} else {
				$body .= 'Content-Type: text/plain'."\n\n";
			}
		$body       .= $this->body."\n\n";
		$body       .= join("\n", $this->attachments);
		$body       .= '--'.$this->boundary.'--';
		$this->body  = $body;
		$this->addHeader('Content-Type:', 'multipart/mixed; boundary="'.$this->boundary.'"');
	}
// RFC 822 compliency :: need to test header/attachments
$this->body = str_replace("\n", "\r\n", trim($this->body));
}
$headers = $this->getHeaders();
/*
echo "<pre>".$headers."</pre>";
exit();
*/
// send mail to specified mail addresses, if any
foreach ($this->toEmails as $mailaddr) {
	if ( !$this->sendMail($mailaddr, $this->subject, $this->body, $headers) ) {
		$this->errors[] = sprintf(_XM_SENDMAILNG, $mailaddr);
		} else {
			$this->success[] = sprintf(_XM_MAILGOOD, $mailaddr);
		}
}
// send message to specified users, if any
foreach ($this->toUsers as $uid) {
	$user = new XoopsUser($uid);
	// set some user specific variables
	$subject = str_replace("{X_UNAME}", $user->getVar("uname"), $this->subject );
	$text    = str_replace("{X_UID}", $user->getVar("uid"), $this->body );
	$text    = str_replace("{X_UEMAIL}", $user->getVar("email"), $text );
	$text    = str_replace("{X_UNAME}", $user->getVar("uname"), $text );
	$text    = str_replace("{X_UACTLINK}", XOOPS_URL."/user.php?op=actv&id=".$user->getVar("uid")."&key=".$user->getVar("actkey")."", $text );
// send mail
if ($this->isMail) {
	if (
		checkEmail($user->getVar("email")) &&
		$this->sendMail($user->getVar("email"), $subject, $text, $headers)
		) {
		$this->success[] = sprintf(_XM_MAILGOOD, $user->getVar("uname"));
		} else {
			$this->errors[] = sprintf(_XM_SENDMAILNG, $user->getVar("uname"));
		}
}
// send private message
if ($this->isPM) {
	if ( !$this->sendPM($user->getVar("uid"), $subject, $text) ) {
		$this->errors[] = sprintf(_XM_SENDPMNG, $user->getVar("uname"));
		} else {
			$this->success[] = sprintf(_XM_PMGOOD, $user->getVar("uname"));
		}
}
} // END FOREACH
if ( count($this->errors) > 0 ) {
	return false;
}
return true;
} // END SEND
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function sendMail($to, $subject, $body, $headers) {
global $myts, $bcoosConfig;
$subject = trim($myts->oopsStripSlashesGPC($subject));
$body    = trim($myts->oopsStripSlashesGPC($body));
$headers = trim($myts->oopsStripSlashesGPC($headers));
if ($bcoosConfig['mail_function'] == 'email') {
	if ( !email($this->fromEmail, $to, $subject, $body, $this->fromEmail, $headers) ) {
		return false;
	}
	} else {
		if ( !mail($to, $subject, $body, $headers) ) {
			return false;
		}
	}
sleep(1);
return true;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function sendPM($uid, $subject, $body) {
global $xoopsUser;
include_once(XOOPS_ROOT_PATH."/class/xoopspm.php");
$pm = new XoopsPM();
$pm->setVar("subject"    , $subject);
$pm->setVar("msg_text"   , $body);
$pm->setVar("to_userid"  , $uid);
$pm->setVar("from_userid", $xoopsUser->getVar("uid"));
if ( !$pm->store() ) {
	return false;
}
return true;
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function getErrors($ashtml=true) {
if ( !$ashtml ) {
	return $this->errors;
	} else {
		if ( !empty($this->errors) ) {
			$ret = "<h6>"._ERROR."</h6>";
			foreach ($this->errors as $error) {
				$ret .= $error.'<br />';
				}
		} else {
			$ret = "";
		}
	return $ret;
	}
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function getSuccess($ashtml = true) {
if ( !$ashtml ) {
	return $this->success;
	} else {
		$ret = "";
			if ( !empty($this->success) ) {
				foreach ( $this->success as $suc ) {
					$ret .= $suc."<br />";
				}
			}
	return $ret;
	}
}
//---------------------------------------------------------------------------------------//
/**
* Description
*
* @param type $var description
* @return type description
*/
function toggle($trigger=5) {
$toUsers  = count($this->toUsers);
$toEmails = count($this->toEmails);
if ( ($this->useToggle == 1) && ($this->isMail || $toEmails) && (($toEmails+$toUsers) > $trigger) ) {
	$this->useToggle = 0;
	?>
	<form action="<?php echo XOOPS_URL;?>/include/mailtoggle.php" method="post" id="toggle" name="toggle" target="mailer">
	<input type="hidden" name="mail" value="<?php echo urlencode(serialize($this));?>" />
	<input type="image" class="image" src="<?php echo XOOPS_URL;?>/images/pixel.gif" />
	</form>
	<script type="text/javascript">
		mailer = window.open("", "mailer", "width=300, height=150, location=no, menubar=no, resizable=no, scrollbars=yes, status=no, titlebar=no, toolbar=no, directories=no");
		mailer.moveTo(((screen.availWidth/2)-(300/2)), ((screen.availHeight/2)-(150/2)));
		xoopsGetElementById("toggle").submit();
	</script>
	<?php
	echo "<h4>"._XM_BATCH."</h4>"._XM_LEAVE;
	return(TRUE);
	}
return(FALSE);
}
//---------------------------------------------------------------------------------------//
} // END CLASS
//---------------------------------------------------------------------------------------//
}
?>
