onPHP / onphp-framework

onPHP is the mature GPL'ed multi-purpose object-oriented PHP framework.
85 stars 52 forks source link

Отправка писем #235

Open DeryabinSergey opened 9 years ago

DeryabinSergey commented 9 years ago

Друзья!

Дайте пример отправки письма с вложением (картика в частности). Простые письма отправляю не вопрос. Посмотрел все что с mail связано, видел MimeMail, но как пользоваться не понял

dewid1985 commented 9 years ago

Посмотри, вот тут: https://pear.php.net/manual/en/package.mail.mail-mime.example.php

DeryabinSergey commented 8 years ago

Друзья, я тут вернулся к вопросу почты, и методом проб и ошибок выяснил что наш MimeMail немного не допиленный, а так же есть в MimePart заложены вложения, но они не реализованы. Например сейчас можно отправить письмо (текстовую или HTML версию) и вложение (вложения), но нельзя отправить и текстовую и HTML версию, добавить вложение и что бы в HTML версии были подцеплены изображения.

Пример простого письма - две версии и вложение ниже:

$mail = 
    MimeMail::create()->
        addPart(
            MimeMail::create()->setContentType('multipart/alternative')->
                addPart(MimePart::create()->setBody('Text body')->setContentType('text/plain')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))->
                addPart(MimePart::create()->setBody('<html><body><p>HTML <strong>body</strong></p></body></html>')->setContentType('text/html')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))->
                build()
        )->
        addPart(MimePart::create()->setBody(file_get_contents($image->getThumbPath().$image->FileName))->setContentType(getimagesize($image->getThumbPath().$image->FileName)['mime'])->setEncoding(MailEncoding::base64())->setFilename($image->FileName)->setContentId(md5($image->getThumbPath().$image->FileName)))->
        build();

Mail::create()->
    setFrom(MailAddress::create()->setAddress('noreply@example.ru')->setPerson('Отправитель')->toString())->
    setTo('web-qOjOcA@mail-tester.com')->
    setSubject('Проверочное письмо')->
    setHeaders($mail->getHeaders())->
    setText($mail->getEncodedBody())->   
    send();

А что бы это чудо заработало необходима возможность указания Content-Type в MimeMail:

svd@dsergey:/var/www/onPHP$ git diff main/Net/Mail/MimeMail.class.php
diff --git a/main/Net/Mail/MimeMail.class.php b/main/Net/Mail/MimeMail.class.php
index bfeb2ca..1773580 100644
--- a/main/Net/Mail/MimeMail.class.php
+++ b/main/Net/Mail/MimeMail.class.php
@@ -23,6 +23,32 @@
                private $headers        = null;

                private $boundary       = null;
+                
+               private $contentType    = null;
+               
+               /**
+                * @return MimeMail
+               **/
+               public static function create()
+               {
+                       return new self;
+               }
+               
+               public function __construct()
+               {
+                       // useful defaults
+                       $this->contentType      = 'multipart/mixed';
+               }
+               
+               /**
+                * @return MimeMail
+               **/
+               public function setContentType($type)
+               {
+                       $this->contentType = $type;
+                       
+                       return $this;
+               }

                /**
                 * @return MimeMail
@@ -34,17 +60,20 @@
                        return $this;
                }

+               /**
+                * @return MimeMail
+               **/
                public function build()
                {
                        if (!$this->parts)
                                throw new UnimplementedFeatureException();

                        if (!$this->boundary)
-                               $this->boundary = '=_'.md5(microtime(true));
+                               $this->boundary = '=_'.md5(microtime(true)*rand(1, 1000));

                        $mail =
                                MimePart::create()->
-                               setContentType('multipart/mixed')->
+                               setContentType($this->contentType)->
                                setBoundary($this->boundary);

                        $this->headers =
@@ -59,6 +88,8 @@
                                        .$part->getEncodedBody()."\n";

                        $this->body .= '--'.$this->boundary."--"."\n\n";
+                        
+                        return $this;
                }
dewid1985 commented 8 years ago

$mail = MimeMail::create()-> addPart( MimeMail::create()->setContentType('multipart/alternative')-> addPart(MimePart::create()->setBody('Text body')->setContentType('text/plain')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))-> addPart(MimePart::create()->setBody('

HTML body

')->setContentType('text/html')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))-> build() )-> addPart(MimePart::create()->setBody(file_get_contents($image->getThumbPath().$image->FileName))->setContentType(getimagesize($image->getThumbPath().$image->FileName)['mime'])->setEncoding(MailEncoding::base64())->setFilename($image->FileName)->setContentId(md5($image->getThumbPath().$image->FileName)))-> build();

Mail::create()-> setFrom(MailAddress::create()->setAddress('noreply@example.ru')->setPerson('Отправитель')->toString())-> setTo('web-qOjOcA@mail-tester.com')-> setSubject('Проверочное письмо')-> setHeaders($mail->getHeaders())-> setText($mail->getEncodedBody())->
send();

Метод addPart в классе MimeMail явно ожидает объект MimePart , для и этого предусмотрен contentType в MimePart объекте.

А в остальном не чего не изменилось возьмите почитайте RFC, если вы отправляете html с картинкой то лучше использовать 'multipart/related' а во всем остальном вам сюда https://github.com/onPHP/onphp-framework/blob/master/test/main/Net/MailTest.class.php

DeryabinSergey commented 8 years ago

Метод addPart в классе MimeMail явно ожидает объект MimePart , для и этого предусмотрен contentType в MimePart объекте.

Так я с этим и не спорю. Только в самом MimeMail при формировании письма первоначальный content-type захардкожен: https://github.com/onPHP/onphp-framework/blob/master/main/Net/Mail/MimeMail.class.php#L47

dewid1985 commented 8 years ago

Тогда уже так! 2016-02-26 16 52 59

DeryabinSergey commented 8 years ago

если вы отправляете html с картинкой то лучше использовать 'multipart/related'

Это если картинка предполагается использоваться в теле письма, если просто вложением - то нет Вот например письмо, где две версии - текстовая и HTML, в HTML версии используется картинка и есть просто картинка, которая прицеплена к письму:


$mp2 = 
    MimePart::create()->
        loadBodyFromFile($image2->getThumbPath().$image2->FileName)->
        setContentType(getimagesize($image2->getThumbPath().$image2->FileName)['mime'])->
        setEncoding(MailEncoding::base64())->
        setContentId(md5($image2->getThumbPath().$image2->FileName).image_type_to_extension(getimagesize($image2->getThumbPath().$image2->FileName)[2]))->
        setInline();
$mail = 
    MimeMail::create()->
        addPart(
            MimeMail::create()->setContentType('multipart/alternative')->
                addPart(MimePart::create()->setBody('Text body')->setContentType('text/plain')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))->
                addPart(
                    MimeMail::create()->setContentType('multipart/related')->
                        addPart(MimePart::create()->setBody('<html><body><p>HTML <strong>body</strong><br /><img src="cid:'.$mp2->getContentId().'" alt="" /></p></body></html>')->setContentType('text/html')->setCharset("UTF-8")->setEncoding(MailEncoding::base64()))->
                        addPart($mp2)->
                        build()
                )->
                build()
        )->
        addPart(MimePart::create()->loadBodyFromFile($image->getThumbPath().$image->FileName)->setContentType(getimagesize($image->getThumbPath().$image->FileName)['mime'])->setEncoding(MailEncoding::base64())->setFilename($image->FileName))->
        build();