<?php
/*
Класс рассыльщика почты с вложениями.
1. Письма в тектовом и html форматах.
2. Присоединение любого количества вложений.
3. Реализация прямого соединения с smtp сервером.
Автор: Denvas
*/
class SendMailClass{
var $boundary = "--------SCS-2006-07-31-i-solutions"; //разделитель
var $priority=3;//приоритет
var $charset="";
var $from; //Отправитель
var $to; //Получатель
var $subj; //Тема письма
var $replyto;//Кому отвечать
var $body_plain; //текст письма
var $attach=array();//вложенные файлы
var $SMTPhost;
var $SMTPlogin;
var $SMTPpwd;
var $sd;//хэнд сокета
var $Error="";
var $endline;//конец строки
//==================================================//
/*
Конструктор
*/
function SendMailClass(){
$this->Clear();
$this->endline="\n";//концом строки у нас будет просто перевод
}
//==================================================//
/*
Установка кодировки для письма
*/
function SetCharset($charset){
$this->charset=$charset;
}
//==================================================//
function Clear(){
$this->Error="";
$this->from="";
$this->replyto="";
$this->to="";
$this->subj="";
$this->body_plain="";
$this->attach=array();
}
//==================================================//
/*
Действие: генерация заголовка
*/
function Header(){
$header="Reply-To: ".(($this->replyto)?(substr($this->replyto,0,strpos($this->replyto,"@"))." <".$this->replyto.">"):$this->from).$this->endline;
$header.="From: ".$this->from.$this->endline;
$header.="MIME-Version: 1.0".$this->endline;
if(count($this->attach)>0){//письмо с аттачами
$header.="Content-Type: multipart/mixed; boundary=\"".$this->boundary."\"".$this->endline;
}
else{//простое письмо
if(!empty($this->charset))$charset="; charset=".$this->charset; else $charset="";
$header.="Content-Type: text/plain".$charset.$this->endline;
};
$header.="X-Priority: ".$this->priority.$this->endline;
return $header;
}//function Header()
//==================================================//
/*
Действие: присоедининие данных
*/
function Attach($name, $type, $data){
$this->attach[]=array($name, $type, $data);
}//function Attach($name, $type, $data)
//==================================================//
/*
Действие: присоединение файла
*/
function FileAttach($namefile, $type, $name=""){
$fd=@fopen($namefile,'r');
if(!$fd)return false;
if(!$name)
$name=basename($namefile);
if(!$type)$type=mime_content_type($namefile);//автоопределение не работает, но если не оставлять пустым $type, то ошибку выдавать не будет
$this->Attach($name, $type, fread($fd,filesize($namefile)));
fclose($fd);
return true;
}//function FileAttach($namefile, $type)
//==================================================//
/*
Действие: генерация тела письма
*/
function Body(){
$body="";
$nattach=count($this->attach);
//письмо без вложений
if($nattach==0){
$body.=$this->body_plain.$this->endline;
return $body;
};
//письмо с вложениями
if(!empty($this->charset))$charset="; charset=".$this->charset; else $charset="";
$body.="--".$this->boundary.$this->endline;
if($this->body_plain){
$body.="Content-Type: text/plain".$charset.$this->endline;
$body.="Content-Transfer-Encoding: quoted-printable".$this->endline.$this->endline;
$body.=$this->body_plain.$this->endline.$this->endline;
$body.="--".$this->boundary.$this->endline;
};//if(empty($this->body_plain))
//вложения
for($j=0;$j<$nattach;$j++){
list($name, $type, $data)=$this->attach[$j];
//файлы для ссылок из html
if(($name)&&(strpos($type,"text/")!==0)){
$body.="Content-Type: ".$type.$this->endline;
$body.="Content-Transfer-Encoding: base64".$this->endline;
$body.="Content-Location: ".$name.$this->endline;
$body.="Content-ID: <".$name.">".$this->endline;
$body.="Content-Disposition: attachment; filename=\"".$this->EncodeBQ($name)."\"".$this->endline.$this->endline;
$body.=chunk_split(base64_encode($data)).$this->endline;
}
else{//нельзя выставлять Content-Disposition, т.к. Outlook начнет считать его вложением и не будет открывать
$body.="Content-Type: ".$type.$charset.$this->endline;
$body.="Conent-Transfer-Encoding: quoted-printable".$this->endline.$this->endline;
$body.=$data.$this->endline.$this->endline;
};
$body.= "--".$this->boundary;
if($j==($nattach-1))$body.="--";
$body.=$this->endline;
};//for($j=0;$j<$nattach;$j++)
return $body;
}//function Body()
//==================================================//
/*
закодировать русские буквы
*/
function EncodeBQ($str){
if($this->charset){
$str="=?".$this->charset."?B?".base64_encode($str)."?=";
};
return $str;
}//function EncodeBQ($str)
//==================================================//
/*
Действие: данные для письма
*/
function Mail($from,$to,$subj,$text="",$html=""){
$this->body_plain=$text;
if(is_array($from)){
list($this->from, $this->replyto)=$from;//первое от кого отсылать, второе кому ответить
}
else{
$this->from=$from;
$this->replyto=$from;
};
$this->to=$to;
$this->subj=(strlen($subj)>0)?$this->EncodeBQ($subj):"";
if($html)
$this->Attach("", "text/html", $html);
}//function Mail($from,$to,$subj,$text,$html="")
//==================================================//
/*
Дальше идет реализация отсылки почты
*/
//==================================================//
/*
Действие: настройка smtp для отправки почты и соединение с сервером
*/
function SMTPConf($host,$login="",$password=""){
global $CONF;
$this->Error="";
//если хост такойже как и был, то не переконективатся
if(strcmp($this->SMTPhost,$host)==0){
return true;
}
else{
if(!empty($this->SMTPhost))$this->SMTPclose();
};
$this->SMTPhost=$host;
$this->SMTPlogin=$login;
$this->SMTPpwd=$password;
if(!$host)return true;//отсылка с помощью sendmail
$port="25";
$myhost=isset($CONF['domain'])?$CONF['domain']:@$_SERVER['HTTP_HOST'];
$this->sd = @fsockopen($this->SMTPhost, $port, $errno, $errstr, 30);
if($this->sd===false){
$this->Error="SMTP: ERROR CONNECT ".$errstr;
return false;
};
$res=fgets($this->sd, 512);
//print "S: ".trim($res)."\n";
//авторизация если задан логи
if($this->SMTPlogin){
$this->mess("AUTH LOGIN".$this->endline);
$this->mess(base64_encode($this->SMTPlogin).$this->endline);
$this->mess(base64_encode($this->SMTPpwd).$this->endline);
};//if($login)
$this->mess("HELO ".$myhost.$this->endline);
return true;
}
//==================================================//
/*
Действие: сгенерировать и послать письмо
*/
function Send(){
if(!empty($this->SMTPhost)){
return $this->SendSMTP("To: ".$this->to.$this->endline."Subject: ".$this->subj.$this->endline.$this->Header(), $this->Body());
}
else{
return mail($this->to,$this->subj,$this->Body(),$this->Header());
};
}//function Send()
//==================================================//
/*
Действие: послать письмо c уже сформированным заголовком и телом
*/
function SendHB($head,$body){
if(!empty($this->SMTPhost)){
return $this->SendSMTP("To: ".$this->to.$this->endline."Subject: ".$this->subj.$this->endline.$head, $body);
}
else{
return mail($this->to,$this->subj,$body,$head);
};
}//function Send()
//==================================================//
/*
Действие: посылка порции данных в сокет
*/
function mess($str){
//print "C: ".trim($str)."\n";
$res="";
//исправить конец строки
$str=str_replace("\r","",$str);
$str=str_replace("\n","\r\n",$str);
//записать в сокет
$rw=fwrite($this->sd, $str);
if(strlen($str)!=$rw){
$this->Error="Send 0";
return false;
};
$res=fgets($this->sd, 512);//fread не работает. а fgets работает получив конец строки
//print "S: ".trim($res)."\n";
return $res;
}//function mess($str)
//==================================================//
/*
Действие: отсылка письма через SMTP протокол
Возвращает: истину есил отсылка прошла успешно
*/
function SendSMTP($head,$body){
if($this->Error)return false;
$this->mess("MAIL FROM: ".$this->from.$this->endline);
$res=$this->mess("RCPT TO: ".$this->to.$this->endline);
if(!strstr($res,"250")){
$this->Error="SMTP ERROR: $res\n";
return false;
};
$this->mess("DATA".$this->endline);
//эти данные нужно добавить, т.к. используя sendmail они подставятся, а напрямую по протоколу нет.
//отсылка данных
$this->mess($head.$this->endline.$body.$this->endline.".".$this->endline);
return true;
}//function SendSMTP($host,$login="",$password="")
//==================================================//
/*
Закрыть smtp соединение
*/
function SMTPclose(){
//завершение
if(!$this->sd)return;
$this->mess("QUIT".$this->endline);
//print "Mail send\n";
fclose($this->sd);
unset($this->sd);
}
//==================================================//
};
?>