Information

Founded
Location
Украина
Website
www.imagecms.net
Employees
11–30 employees
Registered
Pull to refresh
0
Rating

Реализация e-mail-оповещений в ImageCMS

ImageCMS corporate blogCMSWebsite development

В этой публикации мы расскажем о том, как среднестатистический ведущий программист ImageCMS Андрюша реализовал удобную систему e-mail-оповещений пользователей Интернет-магазина. Сам он теперь утверждает, что не программист, а фея.

В чем заключалась проблема до реализации нового функционала?
Немало огорчало, что отправка e-mail пользователям не имела централизованного места управления, ведь это создавало определенные неудобства администратору и наличие множества лишнего кода, который дублировался.
Смотрим-с:

/**
 * Send email to user.
 *
 * @param SOrders $order
 * @return bool
 */
protected function _sendMail(SOrders $order)
{
    //Check setting to send message
    if (ShopCore::app()->SSettings->ordersSendMessage == 'false')
        return;
    //Array of parameters to send
    $replaceData = array(
        '%userName%' => $order->getUserFullName(),
        '%userEmail%' => $order->getUserEmail(),
        '%userPhone%' => $order->getUserPhone(),
        '%userDeliver%' => $order->getUserDeliverTo(),
        '%orderId%' => $order->getId(),
        '%orderKey%' => $order->getKey(),
        '%orderLink%' => shop_url('cart/view/' . $order->getKey()),
    );

    //Use function encode for every element from $replaceData
    $replaceData = array_map('encode', $replaceData);

    //Get settings for sending
    $fromEmail = ShopCore::app()->SSettings->ordersSenderEmail;
    $shopName = ShopCore::app()->SSettings->ordersSenderName;
    $theme = ShopCore::app()->SSettings->ordersMessageTheme;
    //Formating message
    $message = str_replace(array_keys($replaceData), $replaceData, ShopCore::app()->SSettings->ordersMessageText);

    //Load CodeIgniter Email library
    $this->load->library('email');
    $config['mailtype'] = ShopCore::app()->SSettings->ordersMessageFormat;
    //Initialize library configurations
    $this->email->initialize($config);

    //Sending message	
    $this->email->from($fromEmail, $shopName);
    $this->email->to($order->getUserEmail());
    $this->email->subject($theme);
    $this->email->message($message);
    $this->email->send();
}

protected function _sendNewMail(SOrders $order)
{
    //Check setting to send message
    if (ShopCore::app()->SSettings->ordersSendMessage == 'false')
        return;

    //Array of parameters to send
    $replaceData['variables'] = array(
        '%userName%' => $order->getUserFullName(),
        '%userEmail%' => $order->getUserEmail(),
        '%userPhone%' => $order->getUserPhone(),
        '%userDeliver%' => $order->getUserDeliverTo(),
        '%orderId%' => $order->getId(),
        '%orderKey%' => $order->getKey(),
        '%orderLink%' => shop_url('cart/view/' . $order->getKey()),
    );

    $replaceData['to'] = $order->getUserEmail();

    //Load CodeIgniter Email library
    $this->load->library('email');

    //Sending message	
    $this->email->sendMail('toUserOrderNotification', $replaceData);
}



Что предпринял Андрюша?

Для централизации всей системы создания и отправки оповещений, Фея написал отдельный модуль. Изначально вместе с модулем идет 6 интегрированных в систему шаблонов, наиболее часто используемых в работе сайта:
  1. регистрация пользователя;
  2. восстановление пароля;
  3. изменение пароля;
  4. уведомление покупателя о совершении заказа;
  5. смена статуса заказа;
  6. уведомление о появлении.



Были применены неймспейсы, что позволяет вызывать метод с любого места:
        namespace cmsemail\classes;


Главное препятствие на пути к достижению цели Андрея заключалось далеко не в количестве кода, а именно в необходимости найти все места в коде, где идет отправка e-mail, и заменить их новым методом. Наш герой не отчаивался… Фея заткнул уши группой Korn и абстрагировал обработку всей логики отправки писем пользователю и администратору в небольшой метод, что можно увидеть на следующем полотне.
Смотрим-с:

//Creatind link to check for administrator
$checkLink = site_url() . "admin/components/run/shop/orders/createPdf/" . trim($order->getId());
//Array of parameters to send
$emailData = array(
    'userName' => $order->user_full_name,
    'userEmail' => $order->user_email,
    'userPhone' => $order->user_phone,
    'userDeliver' => $order->user_deliver_to,
    'orderLink' => shop_url('cart/view/' . $order->key),
    'products' => $productsForEmail,
    'deliveryPrice' => $deliveryPrice,
    'checkLink' => $checkLink,
);

//Sending emeils
\cmsemail\email::getInstance()->sendEmail($order->user_email, 'make_order', $emailData);


Так этот метод выглядит внутри:

/**
 * send email
 *
 * @param string $send_to - recepient email
 * @param string $patern_name - email patern  name
 * @param array $variables - variables to raplase in message:
 *   $variables = array('$user$' => 'UserName')
 * @return bool
 */
public function sendEmail($send_to, $patern_name, $variables)
{
    //loading CodeIgniter Email library 
    $this->load->library('email');

    //Getting settings 
    $patern_settings = $this->cmsemail_model->getPaternSettings($patern_name);
    $default_settings = $this->cmsemail_model->getSettings();

    //Prepare settings into correct array for initialize library
    if ($patern_settings)
    {
        foreach ($patern_settings as $key => $value)
        {
            if (!$value)
            {
                if ($default_settings[$key])
                {
                    $patern_settings[$key] = $default_settings[$key];
                }
            }
        }
    }
    $default_settings['type'] = strtolower($patern_settings['type']);

    //Initializing library settings
    $this->_set_config($patern_settings);

    //Sending user email if active in options
    if ($patern_settings['user_message_active'])
    {
        $this->from_email = $patern_settings['from_email'];
        $this->from = $patern_settings['from'];
        $this->send_to = $send_to;
        $this->theme = $patern_settings['theme'];
        $this->message = $this->replaceVariables($patern_settings['user_message'], $variables);
        if (!$this->_sendEmail())
        {
            $this->errors[] = lang('User message doesnt send', 'cmsemail');
        }
        else
        {
            //Registering event if success
            \CMSFactory\Events::create()->registerEvent(
                    array(
                'from' => $this->from,
                'from_email' => $this->from_email,
                'send_to' => $this->send_to,
                'theme' => $this->theme,
                'message' => $this->message
                    ), 'ParentEmail:userSend');
            \CMSFactory\Events::runFactory();
        }
    }

    //Sending administrator email if active in options
    if ($patern_settings['admin_message_active'])
    {
        $this->from_email = $patern_settings['from_email'];
        $this->from = $patern_settings['from'];

        if ($patern_settings['admin_email'])
        {
            $this->send_to = $patern_settings['admin_email'];
        }
        else
        {
            $this->send_to = $default_settings['admin_email'];
        }

        $this->theme = $patern_settings['theme'];
        $this->message = $this->replaceVariables($patern_settings['admin_message'], $variables);

        if (!$this->_sendEmail())
        {
            $this->errors[] = lang('User message doesnt send', 'cmsemail');
        }
        else
        {
            //Registering event if success
            \CMSFactory\Events::create()->registerEvent(
                    array(
                'from' => $this->from,
                'from_email' => $this->from_email,
                'send_to' => $this->send_to,
                'theme' => $this->theme,
                'message' => $this->message
                    ), 'ParentEmail:adminSend');
            \CMSFactory\Events::runFactory();
        }
    }

    //Returning status 
    if ($this->errors)
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}



Так среднестатистический ведущий программист сделал централизацию всей системы оповещения пользователей. Кода стало меньше, он стал изящнее, управление оповещениями — проще.



Какие проблемы решает данный функционал?

Обновленная система оповещений, локализованная в едином интерфейсе, значительно упрощает работу, особенно неопытному пользователю, поскольку весь функционал собран в администраторской панели ImageCMS.
На следующем скриншоте изображена панель приборов настройки шаблонов писем, которое получает пользователь и администратор.

Пример настройки письма пользователю о сделанном заказе


Пример настройки письма администратору магазина о сделанном заказе.


Можно ли создавать свои шаблоны уведомлений?
Более опытные юзеры ImageCMS Shop могут создавать собственные шаблоны оповещений, а также интегрировать их в систему. Гибкая система настроек позволяет варьировать компоненты отправки в разных комбинациях. Каждое оповещение имеет свои отдельные настройки адреса отправки, данных об отправителе, e-mail-адресе администратора и теме письма. Также имеются стандартные настройки, и если необязательные поля не заполнены, то данные будут взяты именно оттуда.
Для еще большего удобства администратора предусмотрена проверка на сервере возможности отправки оповещения. Отправитель будет уверен в том, что получатель уведомлен о событии:
Tags:cmsинтернет-магазинсайтысайтостроениеImageCMSImageCMS Shope-mailphpnotifications
Hubs: ImageCMS corporate blog CMS Website development
Rating -10
Views 3.7k Add to bookmarks 12
Comments
Comments 8