<?php

#	$f = file_get_contents('log_send/9163_0c9006a0ff96f050968fb87d1398e276_2013-06-19_20-22-18.xml');
#	$_POST['data'] = base64_encode($f);


	if (!empty($_POST['data']))
	{
		$e = new Email();
		$e->set_message($_POST['data']);
		$e->send();
		
		#
		$xml = $e->response->asXML();
		echo base64_encode($xml);
	}
	else
	{
		phpinfo();
		check_fsockopen();
	}


class Email {

	public $message;
	public $response;
	public $macros     = array();
	public $recipients = array();
	public $boundary;
	public $type;

	#
	function set_message($str)
	{
		#
		$str = str_replace(' ', '+', $str);
		$xml_str = base64_decode($str);
		$this->message = simplexml_load_string($xml_str);

		#
		$this->boundary = '--'.md5(uniqid(time()));

		#
		$this->type = $this->message->template['type'] == 'html' ? 'text/html' : 'text/plain';

		#
#		$this->logger();

		#
		foreach ($this->message->macros->macro as $m)
		{
			$name = (string) $m['name'];
			$this->macros[$name] = array();
			foreach($m->item as $item)
			{
				$this->macros[$name][] = (string) $item;
			}
		}

		#
		foreach ($this->message->recipients->email as $email)
		{
			$this->recipients[] = (string) $email;
		}

		#
		$this->response = new SimpleXMLElement('<response />');
		$this->response->addAttribute('mailing_id', $this->message['mailing_id']);
		$this->response->addAttribute('base_piece', $this->message->recipients['base_piece']);
		$this->response->addChild('recipients');
		$this->response->recipients->addAttribute('ok', 0);
		$this->response->recipients->addAttribute('err', 0);
	}


	#
	function show_xml()
	{
		header("Content-Type: text/xml");
		echo $this->message->asXML();
	}


	#
	function logger()
	{
		$fn = 'log_'.md5(microtime()).'.xml';
		file_put_contents($fn, $this->message->asXML());
	}


	#
	function send()
	{
		#
		while ($this->recipients)
		{
			#
			$email  = array_shift($this->recipients);
			#
			$subj   = $this->replace_macros_in_text($this->message->template->subject);
			$subj   = '=?utf-8?B?'.base64_encode($subj).'?=';
			#
			$text   = $this->make_body();
			
			#
			$header = $this->make_header();
			
			#
			$result = mail($email, $subj, $text, $header) ? 'OK' : 'NO';
			
			#
			$rr = $this->response->recipients->addChild('email', $email);
			$rr->addAttribute('result', $result);
			if ($result == 'OK') $this->response->recipients['ok']+=1;
			if ($result == 'NO') $this->response->recipients['err']+=1;
		}
		
		#
#		header($bad_result ? 'HTTP/1.1 201 OK' : 'HTTP/1.1 200 OK');
		# список мыл
#		echo implode("\n", $report);
	}


	#
	function make_header()
	{
		$headers = array();
		
		$from_mail = $this->replace_macros_in_text((string)$this->message->template->email);
		$from_name = $this->replace_macros_in_text((string)$this->message->template->sender);
		$from_name = '=?utf-8?B?'.base64_encode($from_name).'?=';
		
		$headers[] = 'From: '.$from_name.' <'.$from_mail.'>';
		$headers[] = 'Message-ID: '.$this->replace_macros_in_text($this->message->template->mesid);
		$headers[] = 'MIME-Version: 1.0'; 
		
		#
		if (!empty($this->message->attaches))
			$headers[] = 'Content-Type: multipart/mixed; boundary="'.$this->boundary.'"'; 
		#
		else
			$headers[] = 'Content-Type: '.$this->type.'; charset=utf-8';
		
		$header = implode("\r\n", $headers);
		return $header;
	}


	#
	function make_body()
	{
		$text = (string) $this->message->template->body;
		$text = $this->replace_macros_in_text($text);
		
		#
		if (!empty($this->message->attaches))
		{
			$multipart = array();
			
			#
			$multipart[] = '--'.$this->boundary; 
			$multipart[] = 'Content-Type: '.$this->type.'; charset=utf-8';
			$multipart[] = 'Content-Transfer-Encoding: base64';
			$multipart[] = '';
			$multipart[] = chunk_split(base64_encode($text));
			
			#
			foreach ($this->message->attaches->attach as $attach)
			{
				$mime = (string) $attach->mime;
				$name = (string) $attach->name;
				$url  = (string) $attach->url;
				$file = file_get_contents($url);
				
				$multipart[] = '--'.$this->boundary; 
				$multipart[] = 'Content-Type: '.$mime.'; name = "'.$name.'"';
				$multipart[] = 'Content-Transfer-Encoding: base64';
				$multipart[] = '';
				$multipart[] = chunk_split(base64_encode($file));
			}
			$multipart[] = '--'.$this->boundary.'--';
			$body = implode("\r\n", $multipart);
			echo "\n".$body."\n";
		}
		#
		else
			$body = $text;
		
		return $body;
	}

# ======================================================================

	#
	function replace_macros_in_text($text)
	{
		#
		if (preg_match_all("|{(.*)}|U", $text, $out))
		{
			#
			foreach ($out[1] as $m)
			{
				#
				$dm = $this->macros_data($m);

				#
				if ($dm['type'] == 'let') $values = $this->macros_values_let($dm['name']);
				#
				else $values = $this->macros_values($dm['name']);

				#
				$value = $values ? $values[array_rand($values)] : '['.$dm['name'].']';

				#
				if ($dm['type'] == 'let')    $dm['name'] = 'LET:'.$dm['name'];
				if ($dm['type'] == 'unique') $dm['name'] = '$'.$dm['name'];
				if ($dm['type'] == 'static') $dm['name'] = '_'.$dm['name'];
				
				#
				$text = preg_replace('/{'.preg_quote($dm['name']).'}/is', $value, $text, 1);
			}
			
			#
			return $this->replace_macros_in_text($text);
		}
		#
		else return $text;
	}


	#
	function macros_data($macros)
	{
		$data = array();
		
		#
		if (!strncasecmp($macros, 'LET:', 4))
		{
			$data['type'] = 'let';
			$data['name'] = substr($macros, 4);
		}
		#
		elseif ($macros[0]=='_')
		{
			$data['type'] = 'static';
			$data['name'] = substr($macros, 1);
		}
		#
		elseif ($macros[0]=='$')
		{
			$data['type'] = 'unique';
			$data['name'] = substr($macros, 1);
		}
		#
		else
		{
			$data['type'] = 'dynamic';
			$data['name'] = $macros;
		}
		#
		return $data;
	}


	#
	function macros_values($name)
	{
		#
		if (array_key_exists($name, $this->macros))
		{
			return $this->macros[$name];
		}
		else return null;
	}


	#
	function macros_values_let($str)
	{
		return explode(',',$str);
	}

}


	function check_fsockopen()
	{
		#
		if (!function_exists('fsockopen'))
		{
			echo '<span style="color:red">fsockopen не работает!</span>'; 
			return;
		}

		#
		$tests = array(25 => 'localhost');

		#
		foreach ($tests as $port => $server)
		{
			#
			$fp = @fsockopen($server, $port, $errno, $errstr, 5);

			#
			if ($fp)
			{
				echo '<br/><span style="color:green" >Порт '.$port.' открыт на вашем сервере!</span>';
				fclose($fp);
			}

			#
			else
			{
				echo '<br/><span style="color:red" >Порт '.$port.' не открыт на вашем сервере!</span>';
				#
				echo " error num: ".$errno.' : '.$errstr;
			}
		}
	}


?>

