Magento – Custom email contact form with notification system

In this article, hopefully, you will learn how to create a module that uses its own controller, programatically creates a block based on core template and assigned via file, handles form submission and utilizes Magento notification system to output the notifications to user.
Although the module it self might look relatively simple in the end, keep in mind that these are powerful concepts that you can latter reuse for much more complex requirements.
file 1:
/app/etc/modules/Inchoo_SimpleContact.xml
content of file 1:
<?xml version="1.0"?>
<config>
<modules>
<Inchoo_SimpleContact>
<active>true</active>
<codePool>local</codePool>
</Inchoo_SimpleContact>
</modules>
</config>
file 2: app/code/local/Inchoo/SimpleContact/etc/config.xml
content of file 2:
<?xml version="1.0"?>
<config>
<modules>
<Inchoo_SimpleContact>
<version>0.1.0</version>
</Inchoo_SimpleContact>
</modules>
<frontend>
<routers>
<JustSomeFreeRouterNameHereNo1>
<use>standard</use>
<args>
<module>Inchoo_SimpleContact</module>
<frontName>inchoo-simplecontact</frontName>
</args>
</JustSomeFreeRouterNameHereNo1>
</routers>
</frontend>
</config>
As we dissect our module, the first thing that pops up is the “frontend” element. We can see it has lot of sub-elements of which “routers” is first. In order for something in Magento to be accessible on certain url, that something needs to have controller, like all Zend powered applications. Unlike pure Zend apps, Magento has its own way of mapping controllers, trough xml definitions.
I intentionally used “JustSomeFreeRouterNameHereNo1” for element name making it self explanatory. You can freely assign name to a router wheres “use” and “args” are two parameters each router should have. Parametar “module” if the full name of your module and “frontName” is the actual url path trough which you acccess your controller. In example above I would access my controller indexAction() method trough url like http://shop.local/index.php/inchoo-simplecontact/index/ or http://shop.local/index.php/inchoo-simplecontact/. In case we have url rewrite set up we can even access it by omitting the “index.php” part from url.
Now we will look into the content of IndexController.php.
file 3: app/code/local/Inchoo/SimpleContact/controllers/IndexController.php
content of file 3:
<?php
class Inchoo_SimpleContact_IndexController extends Mage_Core_Controller_Front_Action
{
public function indexAction()
{
//Get current layout state
$this->loadLayout();
$block = $this->getLayout()->createBlock(
'Mage_Core_Block_Template',
'inchoo.simple_contact',
array(
'template' => 'inchoo/simple_contact.phtml'
)
);
$this->getLayout()->getBlock('content')->append($block);
//$this->getLayout()->getBlock('right')->insert($block, 'catalog.compare.sidebar', true);
$this->_initLayoutMessages('core/session');
$this->renderLayout();
}
public function sendemailAction()
{
//Fetch submited params
$params = $this->getRequest()->getParams();
$mail = new Zend_Mail();
$mail->setBodyText($params['comment']);
$mail->setFrom($params['email'], $params['name']);
$mail->addTo('somebody_else@example.com', 'Some Recipient');
$mail->setSubject('Test Inchoo_SimpleContact Module for Magento');
try {
$mail->send();
}
catch(Exception $ex) {
Mage::getSingleton('core/session')->addError('Unable to send email. Sample of a custom notification error from Inchoo_SimpleContact.');
}
//Redirect back to index action of (this) inchoo-simplecontact controller
$this->_redirect('inchoo-simplecontact/');
}
}
?>
Above file, although simple, demonstrates two powerful concepts. First we have an example of creating a block “on the fly”. There are several ways one can add an output block to be shown in Magento, this is the “hardest” way. Most of the materials you will find on the web will show you how to do it from xml files. However, I want you to know how to do it from code.
There is one important reason why you should now how to do this from code: Simplicity! If you were to output the block from layout files then you are adding at leas one more file to your module. The more files you have in your module, bigger the chance for bugs. This is really something you should consider and keep in mind for modules who actually require controllers and are not very user centric.
When I say “not very user centric” I think in terms where designer needs to have full control of layout and the way it is arranged. However in cases where not much layout modifications will be required on custom made controller output I believe that “saving yourself” from writing another layout file is the right way to go.
Note that inside the method call createBlock i use ‘Mage_Core_Block_Template’ as one of the parameters. This is the block class. In this example core block template is used. However, you can freely use one of your own declared blocks (will be shown in latter modules). Created block is appended (inserted actualy) in existing block named “content”. Block “content” is one that is almost always present in the output.
Inside the sendemailAction method we have another important concept, the notification system example. Catch exception block triggers the “adding in the notification message” to the session storage. There are few different storage mechanism inside the Magento. Most of them simply extend core/session without any noticeable diference, therefore unles you wish to extend the existing and write your own, you can use the Mage::getSingleton(‘core/session’). You can use 4 diferent types of notification messages: error, warning, notice, success. Which you can call respectively like trough methods addError(’Custom error here’), addWarning(’Custom warning here’), addNotice(’Custom notice here’), addSuccess(’Custom success here’) as shown above.
Any notifications added to ‘core/session’ storage are outputted to frontend trough view files. For instance one such example is app/design/frontend/default/default/template/page/3columns.phtml file. Inside the file there is the < ?php echo $this->getChildHtml(‘global_messages’) ?> line of code that outputs all global notifications. Note that the “global_messages” referes to block name from within the page.xml layout file, which in turn referes to Magento “core/messages” (Mage_Core_Block_Messages) class type.
Final file for our module is the view file itself. As you might notice from the IndexController, we are using the ‘inchoo/simple_contact.phtml’ as one of the parameters passed to createBlock method. What this means is that our module is going to look for app/design/frontend/default/default/template/inchoo/simple_contact.phtml file. Note that if we were to assign diferent template then “default” to be used for our site then ‘inchoo/simple_contact.phtml’ would refer to folder and file from within that template. If that file is not find in this “other” template then the system would look for one in default template.
file 4: app/design/frontend/default/default/template/inchoo/simple_contact.phtml
content of file 4:
<div class="box simple_contact">
<form id="simple_contact_form" name="simple_contact_form" action="<?php echo $this->getUrl('inchoo-simplecontact/') ?>index/sendemail" method="post">
<fieldset class="group-select">
<h4 class="legend">Inchoo_SimpleContact module sample</h4>
<ul>
<li>
<div class="input-box">
<label for="name">Gimme your name <span class="required">*</span></label><br />
<input name="name" id="name" title="Name" value="" class="required-entry input-text" type="text" />
</div>
<div class="input-box">
<label for="email">And your email <span class="required">*</span></label><br />
<input name="email" id="email" title="Email" value="" class="required-entry input-text validate-email" type="text" />
</div>
<div class="clear"></div>
<div class="input-box">
<label for="comment">Some comment?</label><br />
<textarea name="comment" id="comment" title="Comment" class="required-entry input-text" style="height:100px;" cols="50" rows="3"></textarea>
</div>
</li>
</ul>
</fieldset>
<div class="button-set">
<p class="required">* Required Fields</p>
<button class="form-button" type="submit"><span>Submit</span></button>
</div>
</form>
</div>
Content of above file is mostly HTML related so there is not much to talk about it.
That’s it, the end.
60 comments
i am using magento 1.9
when submit page always get 404 error message
please help
How can i see in front-end
Custom form works perfectly on other versions of magento. But when I upgraded, it stopped working.
Mail not send . Display always error “Unable to send email. Sample of a custom notification error from Inchoo_SimpleContact.”.
Please help me.
Thanks
I’m getting the same error. How do I debug it?
{{block type=”core/template” template=”inchoo/simple_contact.phtml”}}
this block code not working in CMS page on magento 1.9.2.4. any one help me
There seems to be a difference in the form action:
This does not work:
getUrl('inchoo-simplecontact/') ?>index/sendemail
This does work:
getUrl('inchoo-simplecontact/index/sendemail') ?>
class Bleacherbum_AddDealer_IndexController extends Mage_Core_Controller_Front_Action
{
public function sendemailAction()
{
//Fetch submited params
$params = $this->getRequest()->getParams();
$mail = new Zend_Mail();
$bodytext = ‘
Dealer Name: ‘ . $params[‘dealer_name’] . ‘
Address Line 1: ‘ . $params[‘address1’] . ‘
Address Line 2: ‘ . $params[‘address2’] . ‘
City: ‘ . $params[‘city’] . ‘
State: ‘ . $params[‘state’] . ‘
Zip/Postal Code: ‘ . $params[‘zip’] . ‘
Contact Email: ‘ . $params[’email’] . ‘
Phone #: ‘ . $params[‘phone’] . ‘
Website URL: ‘ . $params[‘url’] . ‘
Notes:
‘ . $params[‘notes’];
$mail->setBodyText( $bodytext );
$mail->setFrom( $params[’email’], $params[‘dealer_name’] );
// $mail->addTo( ‘addadealer@streetfxseries.com’, ‘Add A StreetFX Dealer’ );
$mail->addTo( ‘mwilliams@buztronics.com’, ‘Add A StreetFX Dealer’ );
$mail->setSubject( ‘New Request to Add Dealer to Locator on StreetFXSeries.com’ );
try {
$mail->send();
}
catch(Exception $ex) {
Mage::getSingleton( ‘core/session’ )->addError( ‘Unable to send email. Please make sure all required fields are filled out properly.’ );
}
//Redirect to success message of (this) add-dealer controller
$this->_redirect( ‘add-dealer-success/’ );
}
}
I tried this , i got blank page on url http://happygroups.co/inchoo-simplecontact/
Where’s the layout xml file? Where can I access the form and test it?
if we submit the form who can able to receive the mail? it take it from store general contact or contact us email?
HI, this is really nice article.
I did not understand what is the use of . Can you please explain it.
I also want to know why form validation is not working.
Here I have asked about JustSomeFreeRouterNameHereNo1, which is not shown in my first comment..
When i click submit it doesnt send me an email!
Iam new to magento and i want to add custom code in magento.
I place the same content with tags whatever you given.Just i want to know, how to access that page in browser? my website is : magento.2muchstore.com
Anybody tell that thing is very greatful for me.Thanks in advance.
Works great
what does the line
getUrl(‘inchoo-simplecontact/’) ?>index/sendemail”
mean cos i am trying to creating a Question form so i have changed a few names and references however when i change this line it does not send the email or do anything.
Thanks very much! Works beautifully!!
Thank you, very useful.
Great tutorial!
But what if I want this contact form not on http://shop.local/index.php/inchoo-simplecontact/ but in my right sidebar on all the pages that do have that sidebar.
HI,
How to call custom form in the template…. some 404 error is coming.
Need your support.
Thanks
Thank you for the Script. I’ve the problem that I don’t got the success message. I received the mail, but got no message on the frontend?! Any idea? Thanks.
Hello,
Thanks for sharing all this amazing knowledge!
I have got the form to work and send emails. However, I am unable to get the success message to work by using:
Mage::getSingleton(‘core/session’)->addSuccess(‘success message’);
I have tried adding this piece of code before the redirect and after it. In both cases, the submit button just gives me a blank page!
what could possibly be wrong with that :/ ?
Hey,
How could I add this custom form to a cms page and get it working.
I’ve added {{block type=”core/template” template=”inchoo/simple_contact.phtml”}} to my cms page but the form action /index/sendemail returns to a 404 page, hence the email is not sent?
Thanks
Stefan
i am always getting 404 error what am doing wrong please help me ASAP…..
Turn your caching off and refresh the page.
Hi,
Is there any way to implement a simple WYSIWYG editor into the contact form to allow for formatting such as line breaks, etc? All of the emails that come through from this form offer no formatting whatsoever and it would be great to figure out how to implement a very light WYSIWYG editor like Redactor (http://imperavi.com/redactor/).
Hi,
I want to change the sender address from “website8@box867.bluehost.com” to “customercare@somewebsite.com”.
still i can’t receive contact us mail in my magento 1.7 site if anybody knows solution for this issue please help me!
https://inchoo.net/magento/index.php/inchoo-simplecontact
i can’t able to access form
i m getting following error on submitting the data.how can i solve it?
“Unable to send email. Sample of a custom notification error from Inchoo_SimpleContact.”
works 100%, my fault
…always redirected to 404, not able send message, could be routers config.xml ?
How did you solved the 404 problem?
Hello, i loved your tutorial i was able to create a custom form and access it on the local server using the url format that you showed.
https://inchoo.net/website/index.php/contest
but when i uploaded the module on to the server i cannot access it using the URL format
http://www.website.org/index.php/contest
it gives me 404 not found error . what am i doing wrong
Hello, great tuto thx !!
By the way i have a problem when posting my form, i get a 404. Event hough i get the url in the action parameter (http://myDomain.com/inchoo-simplecontact/index/sendemail/).
I really don’t see what’s going wrong.
If anybody have some feedback 🙂
Thx in advance.
Hi the form seems to be working fine which is great however how do i define the template of the “success page” to 1column?
i want to create prescription form for every product and save it in backend with the ordered product . how can i achieve this in magento please answer ASAP.
Hi,
How to add captcha to this form. Please help me
how to add additional fields along with this
@Alan:
The easiest way to do what you are describing is to use a slightly different method than described here. This article was written some time ago, and Magento has other ways of completing this task now.
First off, inside config.xml, we are going to define a new email template, then an event that will listen for a specific event. Add the following inside the ‘global’ section of config.xml:
* Note: the email template is an HTML file and NOT a PHTML file.
Next, inside your the action you are calling when the form is submitted, process your info as necessary and then make a call to Mage::dispatchEvent() before you redirect to the next page. This will dispatch the event that we set up in our config, and trigger our listener to fire the method we assigned to it. Example:
* Note: ‘your_event_name’ will be whatever you defined inside the first tag inside of the events tag in config.xml. The array in the second argument is the array of values you want to pass to the listener function.
Next, create a file called Observer.php inside your Model folder. Inside Observer.php:
Finally, create your email template file. You will be creating it inside magentoRoot/app/locale/en_US/template/email/. Your template will be just regular HTML, but you can call the variables that you passed like so:
I hope this helps. Let me know if you have any questions!
How can i get some variable of my groupon deal to the form?
@Erin:
Check out this link for more thorough instructions:
http://fishpig.co.uk/blog/magento-forms-prototype-javascript-validation.html
The most important part is creating the form as a form in the form’s JS. Add this below your form:
Insert the ID you assigned to the form in the ‘form_id’ spot. You can name the var anything you want as long as it is not used in other places. There are multiple classes that you can assign to individual form elements that will interact with the JS validation assuming you have your form set up.
How about Field validation?
Is it possible to call a Transactional email when processing the form?
@Christopher,
thanks for your reply
@Rohan
Just add the following underneath the frontend in your config.xml file and add the file customform.xml to your layout files.
customform.xml
Sorry i didn’t get your code visible on screen. Stuck in the same problem kindly guide me through. I also want the template to be empty.
how to change the layout of this form page by default its 3-column
I want it as Empty
Hi Neetesh,
it very simple just goto the cms page find your home page and change the URL enter your form URL it will work…
how to call this custom contact form in home page
It’s a nice guide to understand a little bit more on how to create your own Magento’s plugins. This gives you not only how to create a custom form but also a way to understand how an app works on Magento’s framework.
I would, however explain it a little different, in fact, I would do steps backwards as I think they are more understandable that way, but still it has been a great help.
I am using this for a custom form on my site and it works like a charm. There is only one problem…after clicking “submit” button, it takes a very long time to submit, send the email, and redirect.
It is currently taking about 50-55 seconds after clicking submit to send the email and move on to the next page.
Can anyone help me understand why this is taking so long?
Here is my sendemailAction() code:
I have not any access to my module with the url
http://exampl.com/index.php/inchoo-simplecontact/index.
What is the problem?
I follow your post but when I click on the submit button on the form it redirects me to the 404 not found page.
hi, how to avoid spam on this custom contact form?
i keep receiving spam using this custom contact form.
can you help me?thanks
Hi! Great tutorial, I’ve created my own form that works great. However, I’m getting a lot of spam through the form and I need a way to eliminate this. I saw a neat security feature called MathGuard (www.codegravity.com/projects/mathguard) but I’m having a bear of a time implementing it. At this point, I’d settle for a simple security question like “What color is grass?” and if they get it right, the form can process… Please help!
If i wanted the ability to upload a file using the contact page, how would i go about doing this?
leas ,
least*
Thanks, I got some ideas after reading this article.