Откуда отправлять почту в рамках MVC, чтобы не было дублирования кода? - PullRequest
4 голосов
/ 10 мая 2010

Это вопрос MVC. Вот ситуация:

  1. Я пишу приложение, в котором у меня есть «группы».
  2. Чтобы пригласить других людей в свои группы, введите их адрес электронной почты и нажмите «пригласить».
  3. Существует два способа вызова этой функциональности: а) веб-интерфейс и б) API
  4. После того, как отправка почты завершена, я хочу сообщить пользователю, какие письма были успешно отправлены (то есть, если отправка SMTP прошла успешно. В настоящее время я не заинтересован в сообщении о возврате почты). *

Итак, я думаю, как мне проектировать, чтобы не было дублирования кода. То есть API и веб-интерфейс должны разделять основную часть кода.

Для этого я могу создать метод "пригласить" внутри модели "группа". Итак, API и веб-интерфейс могут просто вызывать: группы-> приглашать ($ адресов электронной); Этот метод может отправлять электронные письма. Но проблема в том, что мне нужно получить доступ к почтовым шаблонам, создать представления для писем, а затем отправлять письма. Который на самом деле должен быть в части «Просмотр» или, по крайней мере, в части «Контроллер».

Какой самый элегантный дизайн в этой ситуации?

Примечание: я действительно думаю написать это в Модели. Мое единственное сомнение: раньше я думал об отправке почты также как «презентация». Так как это может рассматриваться как другая форма генерирования продукции.

Добавлено после редактирования

Я понимаю, что просмотр не обязательно должен выводиться в браузер. И в этом мое сомнение. Теперь проблема, скажем, в моем приложении есть «список задач». Мы можем назначить задачу для некоторых людей. Теперь метод assignTo можно вызывать в двух ситуациях: 1) при создании задачи 2) переназначить задачу кому-либо еще.

В обоих случаях новый уполномоченный должен получить уведомление по электронной почте. Таким образом, если метод «assignTo» не отправляет почту, мы должны продублировать почтовую часть в двух местах: «задача создать контроллер» и «задача переназначить контроллер».

Я хотел избежать этого дублирования.

Ответы [ 3 ]

2 голосов
/ 10 мая 2010

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

Просмотр : нажмите «пригласить» (или для API: отправить команду приглашения);
Контроллер : пользователь нажал «пригласить», получить данные из модели;
Модель : Контроллер запрашивает данные (электронные письма для определенных людей или еще что-то), возврат;
Контроллер : получает данные от модели, данные настройки для представления (шаблон) и отправляет по электронной почте сообщение «View».

После этого верните что-то в API или попросите контроллер вывести представление для веб-интерфейса, которое сообщает пользователю, что приглашение обработано.

1 голос
/ 10 мая 2010

У меня были те же сомнения с почтовой системой в Кохане, в конце концов, я понял, что лучший способ сделать это был так:

Иметь один основной класс 'mailer' (упаковщик), который будет содержать методы для отправки писем, расширять его для каждого отдельно используемого класса (почтовых фабрик) Mailer;

применение / классы / mailer.php:

abstract class Mailer {

        protected $from;
        protected $to;
        protected $cc;
        protected $bcc;
        protected $subject;
        protected $body;
        protected $reply_to;
        protected $sent_on;
        protected $content_type = 'text/html';
        protected $headers;

        protected $template;

        public static function factory($name)
        {       
            $class = 'Mailer_'.$name;

            return new $class();
        }

        public function __construct()
        {
            return $this;
        }

        public function send($save = FALSE)
        {
            // send the email using swift mailer, zend_mail, phpmailer, whatever..
        }

        protected function save($to, $subject, $body, $headers)
        {

        }
    }

Приложение / классы / почтовик / user.php

class Mailer_User extends Mailer {

        // Who is sending the mail
        protected $from         = "users@domain.com";

    // Content type of the email
    protected $content_type = 'text/html';

    public function email_activated($name, $email)
    {
        $this->to      = $email;
        $this->subject = 'Your email has been verified';
        $this->body    = View::factory('mailer/user/email_verified')
                           ->set('name', $name)
                           ->render();

        return $this;
    }
}

и позже в коде используйте его как фабрику;

Mailer::factory('user')
    ->email_activated( $user->username, $user->email)
    ->send();

отправка электронного письма из любого места.

0 голосов
/ 10 мая 2010

Сам API является группой всех открытых методов в модели - никакой дополнительной оболочки не требуется, потому что модель выполняет всю обертку самостоятельно (и делает другие методы закрытыми). Само приложение не должно использовать другой API, отличный от официального (так что вы предотвращаете дублирование).

Я бы сделал что-то вроде:

sendMail(array $recipients);
sendGroupMail($group_id) not{
    sendMail(/*get recipients by group_id*/);
};
...