Extending “Contact us” functionality in Magento

contact_us-featured

One of the most important aspects of any business is customer support. It is important to enable your customers to easily reach to you if they need to contact you.

Out of the box Magento offers nice form on “Contact us” page where customers can enter their info and submit support request without opening their email client and searching for your customer service email.

However, sometimes that’s not enough. Depending of your business type and size, you may want to split your customer support into departments to improve your efficiency of solving support requests.

Luckily, it’s not complicated so let’s start!

Registering our module

Note: I’m working with fresh install of latest Magento CE 1.9.2.3 with sample data

We will override core Magento module called Contacts so we’ll also name our module Contacts and add it to the Inchoo vendor map in local code pool. First step is to register our module in Magento by creating Inchoo_Contacts.xml in app/etc/modules folder of our project. Our file should look something like this:

<?xml version="1.0"?>
<config>
    <modules>
        <Inchoo_Contacts>
            <active>true</active>
            <codePool>local</codePool>
        </Inchoo_Contacts>
    </modules>
</config>

Now, let’s make our modules directory structure in app/code/local directory. First we create Inchoo directory and then add child directory named Contacts. Now we have directory structure like this: app/code/local/Inchoo/Contacts. Next step is to make our modules configuration file, where we define all models, helpers, events etc. Make etc directory in app/code/local/Inchoo/Contacts and create config.xml file. We will add some basic information in that file, our module name and version, so config.xml should look like this:

<?xml version="1.0"?>
<config>
    <modules>
        <Inchoo_Contacts>
            <version>1.0.0</version>
        </Inchoo_Contacts>
    </modules>
</config>

Now our extension should be registered in Magento and listed in administration in Configuration→Advanced under “Disable Modules Output” group, but it doesn’t do anything, so let’s change that.

Creating backend logic

Next step is to enable administration users to define new emails that should be available for “Contact us” page, and add “Available on contact us page” setting for existing emails. Unfortunately, in order to administrators dynamically add new emails we should create slightly complicated logic and implement grid in admin so we won’t do that now. Instead we will add new email fields in our system.xml file where we can modify our Configuration page in administration panel. So, in etc directory of our module create system.xml file and copy following code:

<?xml version="1.0" encoding="UTF-8"?>
<config>
    <sections>
        <trans_email>
            <groups>
                <ident_sales>
                    <fields>
                        <contact_us>
                            <label>Available on contact us page</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                        </contact_us>
                    </fields>
                </ident_sales>
                <ident_support>
                    <fields>
                        <contact_us>
                            <label>Available on contact us page</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                        </contact_us>
                    </fields>
                </ident_support>
                <ident_repair>
                    <label>Repair</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>9</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <name translate="label">
                            <label>Name (Label)</label>
                            <frontend_type>text</frontend_type>
                            <backend_model>adminhtml/system_config_backend_email_sender</backend_model>
                            <validate>validate-emailSender</validate>
                            <sort_order>10</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </name>
                        <email translate="label">
                            <label>Email</label>
                            <frontend_type>text</frontend_type>
                            <validate>validate-email</validate>
                            <backend_model>adminhtml/system_config_backend_email_address</backend_model>
                            <sort_order>20</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </email>
                        <contact_us>
                            <label>Available on contact us page</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                        </contact_us>
                    </fields>
                </ident_repair>
                <ident_returns>
                    <label>Returns</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>10</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    <fields>
                        <name translate="label">
                            <label>Name (Label)</label>
                            <frontend_type>text</frontend_type>
                            <backend_model>adminhtml/system_config_backend_email_sender</backend_model>
                            <validate>validate-emailSender</validate>
                            <sort_order>1</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </name>
                        <email translate="label">
                            <label>Email</label>
                            <frontend_type>text</frontend_type>
                            <validate>validate-email</validate>
                            <backend_model>adminhtml/system_config_backend_email_address</backend_model>
                            <sort_order>20</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                        </email>
                        <contact_us>
                            <label>Available on contact us page</label>
                            <frontend_type>select</frontend_type>
                            <sort_order>30</sort_order>
                            <show_in_default>1</show_in_default>
                            <show_in_website>1</show_in_website>
                            <show_in_store>1</show_in_store>
                            <source_model>adminhtml/system_config_source_yesno</source_model>
                        </contact_us>
                    </fields>
                </ident_returns>
            </groups>
        </trans_email>
    </sections>
</config>

In this code we added several groups to section <trans_emails> which references to “Store Email Addresses” page in Admin→Configuration. Every group represents information about single email address that our site uses. Out of the box there are several groups already added in Magento, for instance there are <ident_support>, <ident_sales> etc.

They represent customer support email and sales representative email, respectively. Let’s say you want those emails to be listed on “Contact us” page as departments so we need additional field where we can set availability of those emails on “Contact us” page. We added new field to every email group and called it <contact us> and set it’s label to “Available on contact us page”. It’s a simple “Yes/No” select field with several other options, If you’re little confused you can read more about fields and system.xml here. As you can see, we added two new groups called <ident_repair> and <ident_returns> which represents our Repair and Returns departments. Each of them has three fields, “Name (Label)”, “Email” and “Available on contacts us page” which we can modify in administration.

Now if we go to administration configuration and open “Store Email Addresses” section we can see that there are two new groups of emails. However, their fields are empty so let’s set default values in our config.xml file. Add these lines to your config.xml:

<?xml version="1.0"?>
<config>
    <!-- This comment represents other config nodes we set earlier -->
    <default>
        <trans_email>
            <ident_sales>
                <contact_us>1</contact_us>
            </ident_sales>
            <ident_support>
                <contact_us>1</contact_us>
            </ident_support>
            <ident_repair>
                <name>Repair</name>
                <email>repair@example.com</email>
                <contact_us>1</contact_us>
            </ident_repair>
            <ident_returns>
                <name>Returns</name>
                <email>returns@example.com</email>
                <contact_us>1</contact_us>
            </ident_returns>
        </trans_email>
    </default>
    <!-- This comment represents other config nodes we set earlier -->
</config>

As you can recognize, these nodes that we added follow section/group/field structure and values we add under the field nodes (in this case “name”, “email” and “contact_us” are field nodes) will be displayed in configuration settings.

Next thing is to write some code where we fetch emails that are available on “Contact us” page. Since “Contact us” page is core Magento functionality, we should override some of the Magento classes. To be more specific, we will override Data helper of Contacts core module. You can read more about overriding helpers in this article but basically we add following lines in our config.xml:

<?xml version="1.0"?>
<config>
    <!-- This comment represents other config nodes we set earlier -->
    <global>
        <helpers>
            <contacts>
                <rewrite>
                    <data>Inchoo_Contacts_Helper_Data</data>
                </rewrite>
            </contacts>
        </helpers>
    </global>
    <!-- This comment represents other config nodes we set earlier -->
</config>

Now we must create Helper directory in our modules directory and create file Data.php. Content of that file should be like this:

<?php
 
class Inchoo_Contacts_Helper_Data extends Mage_Contacts_Helper_Data
{
    /**
     * Get emails for "Contact us" page
     *
     * @return mixed
     */
    public function getContactEmails()
    {
        $allowedEmails = array();
        $emails = Mage::getStoreConfig('trans_email');
 
        foreach ($emails as $email) {
            if (isset($email['contact_us']) && $email['contact_us'] == 1) {
                $allowedEmails[] = $email;
            }
        }
 
        return $allowedEmails;
    }
}

We extended core Contacts helper class and just added one method which returns emails that will be listed on “Contact us” page. First we initialize an empty array, secondly we fetch all of the email groups that are located in <trans_email> section. Then in foreach loop we are checking whether every email has set “contact_us” field value to 1 (that is “Yes” in configuration). If it’s set we are storing it in our array and finally return that array.

Displaying departments on “Contact us” page

Now that we made logic for getting emails, we should display them on “Contact us” page. First we need to find template file that we’ll override.

To do so, we must look under <contacts_index_index> layout handle in app/design/frontend/rwd/default/layout/contacts.xml layout file. There we can see that template file we need is “contacts/form.phtml”. I presume you are using custom theme, but if not, you should always make your custom theme if you’re planning to modify and override Magento templates. You can read more about creating custom themes here.

Now add these lines to your custom theme “contacts/form.phtml” file:

<?php
    $emails = Mage::helper('contacts')->getContactEmails();
?>
<!-- Other markup →
 
<!-- Other form fields -->
 
<div class="field">
    <label for="department"><?php echo Mage::helper('contacts')->__('Department') ?></label>
    <div class="input-box">
        <select name="department" id="department" class="input-select validate-select">
            <option value="">Select Department</option>
            <?php foreach($emails as $email): ?>
                <option value="<?php echo $email['email'] ?>"><?php echo $email['name'] ?></option>
            <?php endforeach ?>
        </select>
    </div>
</div>
<!-- Other form fields →

If we refresh our “Contact us” page we should see nice new Department dropdown with labels that can be changed in our admin configuration.

Final step is to modify controller which is handling this request. As you can guess, we must override core Magento controller and that is IndexController of core Contacts module. Add following lines to config.xml file of our module:

<?xml version="1.0"?>
<config>
    <!-- This comment represents other config nodes we set earlier -->
    <frontend>
        <routers>
            <contacts>
                <args>
                    <modules>
                        <Inchoo_Contacts before="Mage_Contacts">Inchoo_Contacts</Inchoo_Contacts>
                    </modules>
                </args>
            </contacts>
        </routers>
    </frontend>
    <!-- This comment represents other config nodes we set earlier -->
</config>

Now in app/code/local/Inchoo/Contacts/controllers directory create file IndexController.php and add the following content:

<?php
require_once(Mage::getModuleDir('controllers','Mage_Contacts').DS.'IndexController.php');
 
class Inchoo_Contacts_IndexController extends Mage_Contacts_IndexController
{
    public function postAction()
    {
        $post = $this->getRequest()->getPost();
        if ( $post ) {
            $translate = Mage::getSingleton('core/translate');
            /* @var $translate Mage_Core_Model_Translate */
            $translate->setTranslateInline(false);
            try {
                $postObject = new Varien_Object();
                $postObject->setData($post);
                // get emails enabled for Contact us page
                $allowedEmails = Mage::helper('contacts')->getContactEmails();
 
                $error = false;
 
                if (!Zend_Validate::is(trim($post['name']) , 'NotEmpty')) {
                    $error = true;
                }
 
                if (!Zend_Validate::is(trim($post['comment']) , 'NotEmpty')) {
                    $error = true;
                }
 
                if (!Zend_Validate::is(trim($post['email']), 'EmailAddress')) {
                    $error = true;
                }
 
                if (Zend_Validate::is(trim($post['hideit']), 'NotEmpty')) {
                    $error = true;
                }
 
                // validate department email
                if (!Zend_Validate::is(trim($post['department']), 'EmailAddress')) {
                    $error = true;
                }
 
                // check whether submitted emails is enabled in configuration
                $foundEmail = false;
                foreach($allowedEmails as $email)
                {
                    if($email['email'] == $post['department']){
                        $foundEmail = true;
                    }
                }
                // if email is in allowed emails set error to false, if it's not
                // in allowed emails set error to true
                $error = ! $foundEmail;
 
                if ($error) {
                    throw new Exception();
                }
                $mailTemplate = Mage::getModel('core/email_template');
                /* @var $mailTemplate Mage_Core_Model_Email_Template */
                $mailTemplate->setDesignConfig(array('area' => 'frontend'))
                    ->setReplyTo($post['email'])
                    ->sendTransactional(
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_TEMPLATE),
                        Mage::getStoreConfig(self::XML_PATH_EMAIL_SENDER),
                        // send to selected department email
                        $post['department'],
                        null,
                        array('data' => $postObject)
                    );
 
                if (!$mailTemplate->getSentSuccess()) {
                    throw new Exception();
                }
 
                $translate->setTranslateInline(true);
 
                Mage::getSingleton('customer/session')
                    ->addSuccess(Mage::helper('contacts')->__('Your inquiry was submitted and will be responded to as soon as possible. Thank you for contacting us.'));
                $this->_redirect('home');
 
                return;
            } catch (Exception $e) {
                $translate->setTranslateInline(true);
 
                Mage::getSingleton('customer/session')->addError(Mage::helper('contacts')->__('Unable to submit your request. Please, try again later'));
                $this->_redirect('*/*/');
                return;
            }
 
        } else {
            $this->_redirect('*/*/');
        }
    }
}

We’ve overridden postAction() method and actually copied most of the code from parent class. We just added additional validation for our department email and checked whether it’s enabled in our configuration. I added some comments above lines I added because it’s easier to follow everything in code.

Conclusion

And that’s it folks, with just a little effort you can extend your “Contact us” page by splitting your customer service into departments which should speed up handling of support request.

And of course, it’s much easier for your customers to send you support requests because there’s no need for turning on email clients and searching for your emails.

Thanks for reading, let me know in the comments if you have any questions. Enjoy coding!


6 comments

  1. Great article, all coding easily understand. Thank you very much 😀

    Please answer my question
    1. How to add and Displaying NUMBER HANDPHONE on “Contact us”.
    2. How displaying data contact us from customer in Admin page magento.
    Thank you

  2. Our form currently redirects to a page with the URL /contacts/index/post. This results in a 404 page.

    Is this normal behaviour for this form? Ideally, I’d like to stay on this page and just show a confirmation that the email has been sent.

  3. The programming was very easily understand and more important coding are provided on this post and this is very valuable in my studies,all coding easily understand and develop more skills,thanks for sharing this post.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.