Drupal 7 Module Development Part 4 - Cron and sending email

By shane
Mon, 2012-10-01 23:54
8 comments
Daily Dose of Drupal Episode #19

Share with Others

This continues on the module we started last time and shows how to implement hook_cron to run periodic tasks on your Drupal website. Also goes over hook_mail and the drupal_mail function for creating and sending email messages within your Drupal 7 module.

In this episode you will learn:

  • How to implement hook_cron in a Drupal 7 module
  • How to implement hook_mail to set up email messages in your Drupal 7 module
  • How to trigger the sending of email in a Drupal 7 module with the drupal_mail function
  • How to retrieve Drupal variables using the Drupal variable_get function

Welcome to another Daily Dose of Drupal this is Episode Number 19. Last time we’ve talked about building the Drupal 7 Cron Monitor Module which is essentially just a simple demonstration module that is going to allow you to learn how to build an administration form which is what we did last time and you can see on the screen here as well as today learn how to implement hook_cron and how to send e-mails from within a Drupal Module.

So as you can see before; we’ve created this Administration Form and you go on and look at Episode Number 18 for how to actually do that and here’s the code that we ended up with and today we’re going to start by implementing a very simple hook called hook_cron.

All hook_cron does is it allows you to perform periodic actions; so Cron is set up on your Drupal site and you can configure it to run a specific intervals depending on Service Settings and also … I believe you can set up from the administration interface as well. So hook_cron; we’re going to go ahead and grab this example; Ours is going to be much simpler than this but we’ll use that as a starting point; so we’re going to add our Comment Block and paste in the code, I was just going to go ahead and start by getting rid of all that and as I’ve mentioned before, our Drupal module is called cron_monitor so we’ll place hook with that and basically anything you run here will be run periodically anytime Cron is run on a Drupal site, this could be running some database queries or in this case sending an e-mail, pretty much anything that you would need to do, any task that you would need to perform on a periodic basis.

The important thing to know is that new users is certainly causing this; this is something could be caused by the server or run at periodic interval. So we’re going to go ahead and get started; we only want to run or send this e-mail if this checkbox here is checked and that’s a setting in the variables table and you can see we created this checkbox using the Form API and we saved it in this variable called cron_monitor_enable. So what I’m going to do is a simple If statement.

If cron_monitor_enable then we’re going to send the Cron Monitor e-mail and that’s all that needs to happen with our Cron. We could set it up to run once a day for instance using some PHP Dates functions but in this case we’re just going to have it run every single time that Cron is run.

As mentioned before and not necessarily the most practical example but it is going to demonstrate a few major points. The next thing we’re going to look at is hook_mail and anytime you want your module to be able to send e-mail, you’re going to create a hook_mail implementation.

We’re going to go ahead and start same as before, copying this and we’ll be getting rid of most of it but use it as a good baseline to make sure we get all the correct parameters for the function, we’ll go ahead and paste that in there, as I mentioned before I’m just going to get rid of this, we’ll start with pretty much a blank function here, add our module name and you can see there are three parameters here; the first one is the Key and this allows us to implement multiple e-mail templates within our module so we could have a key for multiple different messages that our module may need to send out.

In this case we’re only going to have one and add the message and that’s where you can actually add the subject and body fields to the e-mail and params are variables that can be passed in. We’re not going to use any … in this case we just note that extra variables could pass in here and use for replacement patterns or to trigger different actions to happen in your hook_mail function.

The first thing that we’re going to do is just write a simple Switch Statement on the Key Variable and in this case we’re going to call … we’re going to assume our key is cron_monitor_email, we can call this anything we wanted, just keeping it relatively straight forward, we’re going to add a subject, we’re going to wrap everything in the T Function which is just a good best practice to follow.

So the subject is going to be this is the Cron Monitor Report, we need you to add a body and this can be just an Array so you can add additional lines that are going to be appended onto the end of this e-mail body. Okay I’ll go over what I’m doing here; basically I’m adding a line at the of the e-mail that’s says “this is a report from Cron Monitor on @site name” and this @site name is going to get replaced; using the T Function you can have replacement patterns so in this case it’s going to replace @site name with this variable which is going to pull from the variable’s table.

So it’s going to pull the site name; that means when you drop this module on any site, it should pull whatever the actual site name of your website is or it will fall back to test.codekarate.com, you can add one more piece to the body and in this case we’re going to want to add the variable that we set here; this cron_monitor_email_text, so I’m just going to grab this and go ahead and paste this in.

One thing to know is you probably going to want to read up on the hook_mail documentation more, I’m not doing anything with translation really right now even though it’s something that you should pay attention to especially if there’s a chance that you’re going to need to make the site multi-lingual. In this case it’s just a simple admin e-mail, I’m running it through the T Function which is the best practice but I’m not actually ensuring that it’s getting properly translated here.

So now we actually need … now that we have this set up we have to actually call this and in order to trigger this in any of the e-mail we’re going to use the drupal_mail function; you can see there’s some documentation on what drupal_mail does, it’s pretty extensive but it tells you all the different things that you can do with it, in our case this is going to be very simple; the first parameter is the Module; so our module is cron_monitor then it’s the key which is going to match this down here, so it’s cron_monitor_email, let’s go ahead and copy that in, paste it there, and so the next one is who this is going to send to, you could make this dynamic, you can make it a variable, I’m just going to go ahead and hard code this in for now, the language; I’m just going to use the language default and you could also go ahead and add extra parameters, as I mentioned before: who the e-mail should be from, if you leave it null it should default through whatever the site e-mail address is and if you actually want to trigger the sending but that will default to True.

So this is all we need to get a very basic e-mail send using Drupal. So assuming I didn’t mistyped anything there, everything looks good, I can come over here, I’m going to go to the Status Report, that will tell me the last time Cron was run and I will go ahead and make sure I run Cron again, you could also run Cron through Drush; just use Drush Cron, it’s taking it’s time here.

As you can see it’s not a lot of code to get a basic e-mail working but it does get a little more sensitive if you want to add all the translation, functions and if you really want to make the e-mail configurable. So the last time Cron was run was 15 minutes ago so I’m going to go ahead and run Cron manually and if all goes well I should receive an e-mail.

As you can see I received an e-mail and it says “this is a Cron Monitor Report” as a subject, it says it’s a report from Cron Monitor on test.codekarate.com, it says Cron has run on your Drupal site. I could of course go back change that message in the Administration Settings so I could change this settings section here and I change that and resend it, it’s going to then print out the new message, if I go ahead and disable setting I’ll go ahead and do that just so I can show that it works, if I disable it and I run Cron, I can refresh my inbox just as much as I want and nothing is coming through.

So it’s all working, as you can see it’s very simple to get set up, the documentation is a little overwhelming if you just really get it into Drupal but there are a lot of good examples out there so you can read the documentation, look at some of the examples in the comments and really learn from there on how to get your module to send e-mails.

Thank you for watching the Daily Dose of Drupal, this has been brought to you by codekarate.com, you can follow me on Twitter @smthomas3 and you can sign up for the Code Karate Newsletter. Until next time thanks for watching.

Comments

It is very useful and interesting, i have watched a couple of videos.

My query/issue
i am developing a website where in two types of profile are there 1. casual user/visitor may or may not register in the site 2. are professionals/consultants who will give suggestions to query also they will display their products.

now i need to understand two things
one the visitor is able to send a mail just by click a button (that will be in each product ) a add to cart type. a mail should be sent to admin, ofcourse the visitor will give email detail.
two is on a periodic system should send a mail to all the members who has not completed profile

I am not sure exactly what you need to do, however it sounds like you need two things.

The first is a form that sounds like it will be attached to the products. If a user completes this form it will send out an email.

The second is to use hook_cron to periodically check if a member has not completed their profile. You should be able to just run a database query to see if the profile information exists. If the information does not exist, trigger the sending of the email to the user.

If you can provide more information, I may be able to better help you out.

Sorry that i was not making myself clear.

the first one is : just like a shopping cart but difference here is on click of button it should send the user to a contact form where in the id of this product is taken by the system and here the user will enter his/her email id and some body matter.

if you get time you may visit a url : www.connect2clients.in go to any menu you will see a yellow button on click it will take you to contact form.

second one is exactly what have mentioned.

would like to intoduce my self i am new to drupal though i have been into software developement for 7years dotnot basically.

regards

That is a little tricky to do. You may be able to do something using the webform module. This would allow you to build out the form, you would then maybe just need to add a hidden field and populate it using hook_form_alter.

I did something similar on a site recently (alquilerio.com/ this site is no longer active), if you go to any property you will see a "contact" link that opens up in a modal popup window. In this case I used the PrivateMsg module to allow users to send a message to a property owner. This required some coding though to get around limitations and allow an anonymous user to send a private message to the property owner user.

I hope that helps.

Thank you for that,
so basically will need to understanding drupal coding do the work,
regards
thanks once again

Hello Shane,

I am too a drupal developer. Recently started getting my hands dirty in custom module development. I am using Eclipse PDT for the module development. Its able to understand the color codes and the .module & .theme files. Even I had installed the hooks template for Eclipse. But still the intelli-sense is not working variable_get() and system_settings_form() functions. How can I get it working?

hello shane,
first off many thanks for your great drupal "doses".

I have just 1 quick question:
every time you recall the variable_get function to access its value you always include the default value again.
What I mean is: you define the default form field using
'#default_value' => variable_get('foo_var', 0)

When, later, you need to access this variable you put again the default value:
variable_get('foo_var', 0).
My question is: is it necessary? or it is just a good practice? and if yes, why?

Thanks again,
guidout

Adding the default value is not absolutely necessary and if you don't add it, it will default the value to NULL if the variable does not exist.

I would suggest using it though, especially in the case above where you are looking for the value to be a number. This way you can guarantee that even if something happened to the variable (perhaps it got deleted from the database for some reason), your code will still run without any errors.

So while it's not necessary, if you do not want the default value to be NULL, it is best to define a specific default when using the variable_get function.

Post new comment