В этой публикации мы расскажем о том, как среднестатистический ведущий программист 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 интегрированных в систему шаблонов, наиболее часто используемых в работе сайта:
- регистрация пользователя;
- восстановление пароля;
- изменение пароля;
- уведомление покупателя о совершении заказа;
- смена статуса заказа;
- уведомление о появлении.
Были применены неймспейсы, что позволяет вызывать метод с любого места:
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-адресе администратора и теме письма. Также имеются стандартные настройки, и если необязательные поля не заполнены, то данные будут взяты именно оттуда.
Для еще большего удобства администратора предусмотрена проверка на сервере возможности отправки оповещения. Отправитель будет уверен в том, что получатель уведомлен о событии:
ссылка на оригинал статьи http://habrahabr.ru/company/imagecms/blog/203274/
Добавить комментарий