После того, как почтовые сервисы перешли на свою строгую политику, многие клиенты стали жаловаться, что письма с интернет-магазина падают как минимум в спам, а в худшем случае, хостинг просто блочит письмо и не отправляет клиенту. В связи с этим, мы стали прикручивать на сайты популярную библиотеку PHPMailer, которая позволяет гибко настроить отправку почты. Как оказалось, в рамках простой CMS данная библиотека выглядит «мини-монстром» так как содержала в себе файлов больше, чем папка со всеми контроллерами системы.

В итоге мы составили кое-какой алгоритм подключения этого дела к системе Okay.

Итак, шаг номер раз: скачиваем библиотеку PHPMailer с гита.
Шаг номер два: загружаем папку библиотеки в папку api самой системы и подключаем ее к ней.

Для этого нам надо сделать вот такие манипуляции:

В классе Notify.php подключаем библиотеку вот таким образом:

require('PHPMailer/class.phpmailer.php');
include('PHPMailer/class.smtp.php');

После этого меняем стандартную функцию mail на вот такую:

public function SMTP($to, $subject, $message,$headers){
        $mail = new PHPMailer();

        $mail->IsSMTP(); // telling the class to use SMTP
        $mail->Host       = ''.$this->settings->smtp_server.''; // SMTP server
        $mail->SMTPDebug  = 0;                     // enables SMTP debug information (for testing)
        $mail->SMTPAuth   = true;                  // enable SMTP authentication
        $mail->Port       = $this->settings->smtp_port;                    // set the SMTP port for the GMAIL server
        $mail->Username   = ''.$this->settings->smtp_user.''; // SMTP account username
        $mail->Password   = ''.$this->settings->smtp_pass.'';        // SMTP account password
        $mail->SetFrom($this->settings->smtp_user, $this->settings->user_pseudo);
        $mail->AddReplyTo($this->settings->smtp_user,$this->settings->user_pseudo);
        $mail->Subject    = $subject;
     
        $mail->MsgHTML($message);
        $mail->addCustomHeader("MIME-Version: 1.0\n");

        $recipients = explode(',',$to);
        if(!empty($recipients)){
            foreach($recipients as $i=>$r){
                $mail->AddAddress($r);
            }
        }
        else{
            $mail->AddAddress($to);
        }


        if(!$mail->Send()) {
            @file_put_contents('error_log.txt',$mail->ErrorInfo);
        }
    }

    
    function email($to, $subject, $message, $from = '', $reply_to = '')
    {
    	$headers = "MIME-Version: 1.0\n" ;
    	$headers .= "Content-type: text/html; charset=UTF-8; \r\n";
    	$headers .= "From: $from\r\n";
    	if(!empty($reply_to))
	    	$headers .= "reply-to: $reply_to\r\n";
    	
    	$subject = "=?utf-8?B?".base64_encode($subject)."?=";
        
        if($this->settings->use_smtp){
            $this->SMTP($to, $subject, $message, $headers);
        }
        else{
            @mail($to, $subject, $message, $headers);
        }

    }

И по факту, исполняющая часть у вас готова. Здесь добавлен регулятор в виде конструкции if, который позволит админу самому переключать способ отправки, это либо функиция mail, либо протокол SMTP.

После этого «допилим» административную часть, и добавим поля:

Идем в папку backend/design/html и открываем файл settings.tpl, в конец которого добавляет вот такой кусок кода:

<div class="block layer">
       <h2>Настройки SMTP почты</h2>
        <ul>
            <li>

                <label class="property" >SMTP Почта</label>
                <select name="use_smtp">
                    <option value="1" {if $settings->use_smtp == 1}selected=""{/if}>Да</option>
                    <option value="0" {if $settings->use_smtp == 0}selected=""{/if}>Нет</option>
                </select>

                <label class="property" >SMTP Server</label>
                <input name="smtp_server" class="okay_inp" value="{$settings->smtp_server}" type="text" />

                <label class="property" >SMTP Port</label>
                <input name="smtp_port" class=" okay_inp " value="{$settings->smtp_port}" type="text" />

                <label class="property" >SMTP Пользователь</label>
                <input name="smtp_user" class=" okay_inp " value="{$settings->smtp_user}" type="text" />

                <label class="property" >SMTP Пароль</label>
                <input name="smtp_pass" class=" okay_inp " value="{$settings->smtp_pass}" type="text" />

                <label class="property" >Имя отправителя</label>
                <input name="user_pseudo" class=" okay_inp " value="{$settings->user_pseudo}" type="text" />
            </li>
        </ul>
    </div> 

После чего получаем вот такой вид внешне:

И добавляет обработчик данных полей в файл backend/SettingsAdmin.php

   $this->settings->smtp_server = $this->request->post('smtp_server');
            $this->settings->smtp_port = $this->request->post('smtp_port');
            $this->settings->smtp_user = $this->request->post('smtp_user');
            $this->settings->smtp_pass = $this->request->post('smtp_pass');
            $this->settings->use_smtp = $this->request->post('use_smtp');
            $this->settings->user_pseudo = $this->request->post('user_pseudo');


На этой программная часть закончилась, и все бы хорошо, но настройка этого дела требует иногда нервных усилий.

Краткий список действий будет таков:

1. Зарегистрировать почту для домена (например на яндексе)
2. Переключить MX записи почтовой службы на хостинге
3. Узнать у хостинга, открыт ли 465-й порт на сервере, иначе смысла отправлять письма не будет
4. Указать логин и пароль в админке
5. Пользоваться подписанным ящиком, и отправлять письма от «подписанного» отправителя
Поделиться с друзьями
-->

Комментарии (24)


  1. oxidmod
    13.01.2017 12:52
    +1

    composer? система модулей? что ж єто за CMS, в которой надо лезть в кор, чтобы чтото подключить… а да, подключение инклудом? хоть какойто бы автолоад сделали


    1. ustasby
      13.01.2017 15:15

      Это симпла, которая тоже из г@вна и палок, внутри ад, лучше даже не глядеть.


    1. m1hasik
      14.01.2017 14:34

      CMS не модульная, и делая ее модульной, мы ее только дороже сделаем. Я понимаю что с точки зрения «сегодня» это очень устаревший кодинг, но поверьте, не на каждом рынке разработке это даже нужно.
      Работая в среднем с клиентами, которые готовы платить 1000-2000 usd за интернет магазин (OkayCMS — платформа чисто для магазинов), этого вполне достаточно.


      1. oxidmod
        14.01.2017 17:12

        А обновлять вы как будете с правками в ядре?


        1. m1hasik
          14.01.2017 17:37

          Да, сейчас так и делается https://github.com/OkayCMS/Okay/commits/master
          по сути как такового ядра нет, ну образно. Есть просто главный класс, в котором определяются все другие.
          Я понимаю, что может такая система и устаревшая, но спросом пользуется, и самое в ней интересное то, что она по себе очень легкая, ведь чистый php и знания ООП позволяют даже начинающему программисту на ней делать допилы. Хотелось когда сделать модульность, но все застопорилось из за одного момента. Как расширить существующий класс при это не делая переопределения его.
          сразу приведу типичную задачу, которую выполняю раз в неделю как минимум.

          Есть сущность товар с n полей. Нужно к ней добавить еще пару полей в БД, которые будут влиять на цену товара.

          Вот такие мелкие задачи не позволяют разгуляться при модульности, и лучше залезть в готовый класс и добавить в выборку еще пару полей


          1. oxidmod
            14.01.2017 22:03

            Для атрибутов товаров давно придумали EAV


          1. Fortop
            17.01.2017 00:23

            Как расширить существующий класс при это не делая переопределения его.

            Например так:
             // extend Gettext\Translation to find translation by id
            $findById = function ($id) {
                return $this->offsetExists($id) ? $this[$id] : false;
            };
            $findByIdBinded = \Closure::bind($findById, $translations[$lang], \Gettext\Translation::class);
            $translationEntity = $findByIdBinded($id);
            
            


            1. m1hasik
              17.01.2017 14:23

              возьмем во внимание, таким еще не пользовались, спасибо. А такой вопрос, будет ли дружить модульность с шаблонизатором? или нужно писать файлы с чистыми вставками на php?


              1. Fortop
                17.01.2017 14:26

                Вопрос очень странный.

                модульность дружит с модульностью.
                Большинство современных шаблонизаторов отлично с этим живет.


      1. xoma
        16.01.2017 14:16

        за 1000 долларов можно купить битрикс в «топовой» комплектаци. Или имелось ввиду 100?


        1. m1hasik
          16.01.2017 14:19

          За 1000 долларов вы не сделаете на битриксе магазин под ключ, с дизайном и доделками.
          Я имел в виду что 1000 usd это готовый проект, в который входит лицензия, шаблон, переделка шаблона под клиента, 10-15 модулей сторонних.
          Самый минимум на этой cms это лицензия + шаблон, и это выйдет в 280 usd
          Или же вообще бесплатная версия с дефолтным шаблоном. Есть и такая там


          1. xoma
            16.01.2017 14:21

            Чем это отлчается от того, что я возьму PrestaShop/Opencart и докуплю модулей?


            1. m1hasik
              16.01.2017 14:29

              Ничем, это просто другая CMS. У каждой есть свои минусы и плюсы. Конкретно эта система делается «простой» для разработчиков. Есть свой малый(специфический) рынок, где сайты делаются за неделю, и по быстрому.
              Ну и раз уж сравнивать с другими CMS, то в Okay есть классный ЧПУ фильтр, для «самопродвижения» товаров по низкочастотке. ну и вообще много SEO-фич присутствует


              1. ET-NiK
                16.01.2017 19:57

                Опять же, возвращаемся к первому комменту.
                Простой система для разработчиков будет с composer, системой модулей, автолоадом.
                Разве, что для новичка, который первый день на PHP кодит и не знает этих вещей.


                1. m1hasik
                  16.01.2017 20:00

                  Тогда вопрос как к специалисту. Стоит ли реально переводить систему на модульность и устанавливать composer? Откроет ли это больше функций для разработчиков.
                  Ну и вопрос ко всем программистам: будет ли вам лучше и удобнее работать с модульной системой?
                  На данный момент, например, от composer не будет толку вообще, так как все что через него можно скачать в систему это PHPMailer либо же новая версия Smarty.


                  1. oxidmod
                    16.01.2017 22:20

                    или любую другую библиотеку, для чего угодно, что взбредет в голову заказчику. При этом не нужно искать куда добавить инклуд, а просто пишешь use VendorName/PackageName/ClassName; и вперед покорять вершины))


                    1. m1hasik
                      16.01.2017 22:23

                      Раз этим пользуются многие, то это очень удобно значит. Я рад что обсуждение данного поста открыло много вещей и новых идей. Думаю мы в своей системе вернемся к разработке модульности)


                      1. ustasby
                        21.01.2017 03:10

                        Много идей в пустой голове, вашанедосимпла ломается за 5 минут, а еще за час хостер отключит любой сайт, если она сама через 5 минут сама работать не перестанет. Дыра на дыре и дырой погоняет.


  1. ainu
    13.01.2017 12:57

    Лучше бы рассказали, как отправлять письма так, чтобы и без SMTP, и доходили при этом.
    Обращаясь к коллективно-сознательному разуму: написать статью?


    1. Boomburum
      13.01.2017 13:12

      Полезная информация лишней не бывает :)


      1. ainu
        13.01.2017 15:11

        Значит, замётано. Бумбурум, я считаю, достоин считаться голосом коллективно-сознательного=)


        1. Boomburum
          13.01.2017 18:55

          Ну, я точно не замена коллективному разуму, но если говорить о полезности Хабра, то чем больше, тем лучше ) Поэтому рады любому технически-полезному посту )


  1. ainu
    13.01.2017 12:59
    +1

    @mail(...)

    Так делать нельзя. Подавление ошибок значительно замедляет время отработки кода.


  1. MaZaNaX
    13.01.2017 14:43
    +1

    Такое ощущение, что вернулся в 2008й.

    $mail->Host       = ''.$this->settings->smtp_server.'';
    

    Что это за жесть?

     if(!empty($recipients)){
     }
    

    if(!$mail->Send()) {
    }
    

    Код-стайл тоже не?

        function email($to, $subject, $message, $from = '', $reply_to = '')
    

    а модификатор доступа? Ну кмон