Where should I send letters in the MVC environment so that there is no code duplication?

This is a MVC question. Here is the situation:

  • I am writing an application where I have β€œgroups”.
  • You can invite others to your groups by typing their email and clicking "Invite."
  • There are two possibilities that can be called this functionality: a) a web interface and b) an API
  • Upon completion of sending the mail, I want to inform the user which letters were sent successfully (that is, if the SMTP transmission was successful. At present, I am not interested in reporting mail errors).

So, I’m thinking how can I design so that there is no duplication of code. That is, the API and the web interface must share the bulk of the code.

To do this, I can create an invite method inside the group model. Thus, the API and web interface can simply call: groups-> invite ($ email addresses); This method can send emails. But the problem is that I have to access the mail templates, create submissions for letters, and then send letters. In fact, it should be in the "View" part, or at least in the "Controller" part.

What is the most elegant design in this situation?

Note. I really think to write this in Model. My only doubt is that I used to think that sending emails was also a "presentation". Since this can be considered as another form of output generation.

Added after editing.

I understand that View does not have to be displayed in the browser. And I doubt it. Now the problem is that I have a "task list" in my application. We can assign a task to some people. Now the "assignTo" method can be called in two situations: 1) When creating a task 2) reassign the task to someone else.

In both cases, the new assignee must receive an email notification. Therefore, if the "assignTo" method does not send mail, we must duplicate the mail part in two places: "task create controller" and "task reassign controller".

I wanted to avoid this duplication.

+4
source share
3 answers

I had the same doubts about the Cohan mailing system, in the end it turned out that the best way to do this was as follows:

There is one main class "mail program" (wrapper), which will contain methods for sending letters, expand them for each class of mailboxes (factories) used separately;

Application / classes / 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) { } } 

Application / classes / mailer / 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; } } 

and then in code use it as a factory;

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

sending email to where you want.

+1
source

Viewing does not have to be the output to the browser that the user sees. It can also be a template that is emailed. The controller receives input about what to do, requests the necessary information from the Model and View users to display this information. In this case, the view will be an email template, and the controller has the task of sending this output by email.

Show : click "Invite" (or for API: send an invitation command); Controller : user clicked β€œinvite”, get data from the model.
Model . The controller requests data (emails for specific people or much more), return; Controller : receives data from the model, settings data for the presentation (template), and sends "View" by e-mail.

After that, return something to the API or inform the controller about the View exit for the web interface, which tells the user that the invitation has been processed.

+2
source

The API itself is a group of all public methods in the model - no additional shell is required, because the model itself does all the packaging (and keeps other methods non-public). The application itself should not use a different api than the official one (so you prevent duplication).

I would do something like:

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

Source: https://habr.com/ru/post/1309304/


All Articles