3

I am building an MVC application (using the Zend Framework).

When users first register, the applicaiton sends them an email. My question is, where should I trigger this email from? The model or the controller? My thoughts are as follows:

  • In some ways, the model makes sense, since sending a registration email is part of my business logic. Users must click the link in the mail to validate their email address.

  • But by putting it in the model, I am 'encumbering' the model. The model's registerUser action is then only useful within the context of an application that needs emails sent for every registration.

  • Instead, by triggering the email from within the controller, my controller would be a litter 'fatter', but my model a little more 'fine grained'.

I have written an email service which actually configures and sends the email, and I think this is a good design decision. I am really just asking where I should be calling this service from.

Your thoughts are most appreciated!

DatsunBing
  • 8,684
  • 17
  • 87
  • 172

3 Answers3

2

According to Zend Framework's definition of MVC, you should put send the email from the controller:

Controllers...decide which view to display based on the user's request.

Models, on the other hand, contain:

...basic functionality behind a set of abstractions.

An email may be considered a "view" in that it displays information to the user. It is the controller's job to activate this "view."

George Cummins
  • 28,485
  • 8
  • 71
  • 90
  • Allow me to play devil's advocate, but wouldn't a model be just as good? $user = new User(); $user->sendEmail("Welcome!"); Just point out, this is really up for debate and will really depend on programmer preference and ultimate goal. Whatever you choose, just be consistent. – brady.vitrano Jul 06 '11 at 21:48
  • @brady.vitrano Thanks for your comments. As you say, preference certainly plays a role, and there are no hard-and-fast rules. However, when the ZF document references "basic functionality" I assume it is referring to processes such as add/delete/update. If the model can send email, why not HTML output (views) as well? As a side note, this question has been addressed on SO before: http://stackoverflow.com/questions/5017369/mvc-php-sending-mail-from-model and elsewhere, with no clear consensus. – George Cummins Jul 06 '11 at 21:57
  • @brady. Your sugestion violates a clean Seperation of Concerns. A user is a user, they shouldn't also be in charge of sending emails. If anything, at the very least, there should be something in charge of email sending that isn't tied into some other type in the system like you've presented. – Jamie Dixon Jul 06 '11 at 21:58
  • 1
    @jamie and @george Thanks for the replies. I couldn't agree more. – brady.vitrano Jul 06 '11 at 23:12
2

In my opinion, I would want this in the model, as I would consider this an assumed process of the create user method, rather than any specific interaction with the user making the request.

In other words, since I would always want this email sent, regardless of the source of the request, I would identify this as a natural byproduct of the create user action, similar to a record being saved in a database.

0

You might want to look into using something like NServiceBus to queue messages to be sent to your Email Service.

This way you can have NServiceBus subscribe to an event that occurs and omit any manual firing of the email service etc.

Ultimately you want a failsafe way of ensuring your messages get to the intended people. This kind of framework will greatly help you ensure that this happens.

Alternatively you could store the emails to be sent inside your database and have your email service check the database queue every x minutes for new emails to send and omit the need for triggering the email sending.

Again, doing it this way will ensure at the least that the emails get sent. Should the network go down or some other disruption occur during the sending of each email you can simply leave them in the queue until the network comes back up.

Jamie Dixon
  • 53,019
  • 19
  • 125
  • 162
  • This does not answer the question. Even if the OP decides to use your product, he will still need to know when to call it. – George Cummins Jul 06 '11 at 21:30
  • That's my point - he wouldn't need to call it. The bus (whatever bus framework he might be) would be configured with an event that would fire when something happens, such as a user being inserted into the database. This omits the need to manually go about triggering emails. Also in my second sugestion, again there's no need to call anything. The service would be in charge of looking up emails to be sent from the database. What he might need in that case is a custom event setup that listens for new items being inserted into the database and generates the relevent email message into the database – Jamie Dixon Jul 06 '11 at 21:34
  • Perhaps you are making a point that is beyond my grasp. However, when you say "The bus...would be configured with an event" you seem to be describing precisely what the OP has referenced: the time/event/action/whatever that the email service should be activated. It really doesn't matter if the email sender is an external service or built into the framework; the task to trigger it is the same. As to your second point, the external service is unnecessary overhead. The OP did not ask for the extra email-related features, so configuring a listener just for this seems like overkill. – George Cummins Jul 06 '11 at 21:49
  • Hey George. I think we're just thinking about things a little differently here. With regard to the second portion of your comment, the OP says they've already written an email service. My sugestion is that instead of triggering the email service from the website code, the service should instead check the database every x minutes for new emails to send. This is how I would do it. – Jamie Dixon Jul 06 '11 at 21:55