A commonly used Magento feature is the ability to place customers into different customer groups. These customer groups can then be used in a number of ways, such as tiered pricing where each customer group may have different pricing applied. By default, Magento does not include a means of automatically sorting customers into different groups when the customer account is created; instead they must be assigned manually. This post follows on from our creating custom customer attributes post and shows how to automate customers being assigned to groups based upon information they have provided when signing up, whether from a custom or default customer attribute.

In the previous post, we added a new attribute called flavour to our customer and made it compulsory. For the purposes of this article, let's say that if a customer's favourite ice-cream flavour is Caramel, we want them to be eligible for discounts across some of our products. The first step is to create the customer group. This can be done from the admin panel by choosing CustomersCustomer Groups and clicking on the 'Add New Customer Group' button. When you do this, take note of the new id assigned to this group, as we are going to need it later.

Now, we have to add in our custom module. I am calling my module Customer and it is part of the Fontis group. So, the file should be named app/etc/modules/Fontis_Customer.xml. Add the following code into this file:

<config>
 <modules>
 <Fontis_Customer>
 <active>true</active>
 <codePool>local</codePool>
 </Fontis_Customer>
 </modules>
</config>

Next, we need to create the code for the module. The idea behind our code is that we are going to create an observer on the customer_save_before event. Magento has a number of events that we can observe but most are beyond the scope of this article. What is useful is that the customer_save_before event is called both when a customer is created and when a customer makes changes to their account. This means that the one observer will be able to do the work for both events.

All of the code we are writing for our module will be located inside the app/code/local/Fontis/Customer/ directory. The first file is etc/config.xml:

<?xml version="1.0"?>
<config>
 <modules>
 <Fontis_Customer>
 <version>1.0</version>
 </Fontis_Customer>
 </modules>
 <global>
 <events>
 <customer_save_before>
 <observers>
 <fontis_customer_save_observer>
 <type>singleton</type>
 <class>Fontis_Customer_Model_Customer_Observer</class>
 <method>customer_save_before</method>
 </fontis_customer_save_observer>
 </observers>
 </customer_save_before>
 </events>
 </global>
</config>

The next step is to create the class that we have just told Magento we are going to use, and should be defined in the file Model/Customer/Observer.php:

<?php

class Fontis_Customer_Model_Customer_Observer extends Mage_Core_Model_Abstract
{
 /*
 * observer for the customer saved event
 */
 public function customer_save_before( $observer )
 {
 try {
 $customer = $observer->getCustomer();
 
 if( strtolower( $customer->getFlavour() ) == "caramel" ) {
 $customer->setData( 'group_id', 5 ); // Set the new customer group
 } else {
 $customer->setData( 'group_id', 1); // Set to the default customer group
 }
 } catch ( Exception $e ) {
 Mage::log( "customer_save_before observer failed: " . $e->getMessage() );
 }
 }
}

?>

Customers are now automatically assigned to your new group if they supply caramel as their favourite ice cream flavour.

I should mention a number of caveats regarding this last snippet. First, it is important to enclose everything in your observers with try ... catch blocks. Without this precaution, if your script causes an exception then the customer's information won't be saved. It is also very important not to call the $customer->save() method. If you do this, it will cause your observer to be called again, which will call the save method again and loop until you run out of memory. The reason that you don't need to call the save method is that the customer object you are working on is the same object that Magento is partway through saving when your observer gets called. Once your observer finishes, the customer object finishes saving (and then the customer_save_after event is fired).

Another thing to mention is the if ... else statement in the observer. In the true case, we set the customers group to be ID 5. This is likely the group ID of your new group, if it is the first group that you have created in your Magento install. The else statement handles the case where a customers edits their account and changes their favourite flavour, in which case you may want to set their group back to a default.

To conclude, you can use this same method to add observers to a large number of events. You can also use the observer we have used here to change anything about your customers. Remember to enclose anything in an observer with try ... catch statements.


Magento Compatibility

Post originally written for Magento version:1.3.2.4
Tested with Magento versions:1.3.2.4, 1.4.0.1