Stuff & Nonsense

Magento: Block users using a group

One of the most glaring omissions of magento is a way of blocking users. Currently your only option when faced with a user you wish to ban from the site is to do some kind of IP blocking in your web server configuration, or delete the user account. Neither of those options is really useful, IP blocks are difficult to maintain and if you delete a user account there’s nothing to stop the miscreant just creating a new account.

Here’s how you can create a simple module that allows you to set up a ‘blocked’ group. When customers are placed in this group they can still log in, however they’re not able to add anything to their cart and thus can’t actually place an order.

First up we need to create our module folder structure. Here I’m using a namespace of ‘Tallpaul’ and a module name of ‘bangroup’, but you can change these according to your requirements (just make sure you change them throughout, or you’ll get missing classpaths and all sorts of fun).

 

 

 

 

 

 

You can see we only have a couple of files in here.  ‘Config.xml’ is a configuration file that defines how our module is going to behave, and’CartController.php’ is our code that’s going to stop blocked users from adding items to their cart.

Lets take a look at ‘config.xml’ first.

<config>
 <modules>
 <Tallpaul_Bangroup>
 <version>0.1.0</version>
 </Tallpaul_Bangroup>
 </modules>
 <frontend>
 <routers>
 <checkout>
 <args>
 <modules>
 <tallpaul_bangroup before="Mage_Checkout_CartController">Tallpaul_Bangroup_Frontend_Checkout</tallpaul_bangroup>
 </modules>
 </args>
 </checkout>
 </routers>
 </frontend>
</config>

After the usual configuration stuff of defining a version for our module, there’s only one line here that does anything.  We’re defining that our module (tallpaul_bangroup) is overriding a specific controller (Mage_Checkout_CartController) with a new controller (Tallpaul_Bangroup_Frontend_Checkout).  And that’s pretty much it.  You can see here that controller overrides are dfined in a different way to bloc / helper / etc overrides.  I’m not entirely sure why, but this is just the way magento does it.  It usually takes me a bit of trial and error to work out how to override a specific controller, but once you’ve done it a few times it becomes second nature to map these files to a classpath.

Anyway, now we’ve got our configuration out of the way, lets have a look at CartController.php.  In here we’re going to extend the magento checkout controller class, and override a couple of functions.

/**
 * Shopping cart controller
 */
require_once Mage::getModuleDir('controllers', 'Mage_Checkout').DS.'CartController.php';

class Tallpaul_Bangroup_Frontend_Checkout_CartController extends Mage_Checkout_CartController
{

  /**
   * Check if user is blocked (ie: if they're in the 'Blocked' group)
   */
  public function isBlocked(){
  		if(Mage::getSingleton('customer/session')->isLoggedIn())
		{
  			$groupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
			$group = Mage::getModel('customer/group')->load($groupId);
			$groupName = $group->getCode();
			if ($groupName == "Blocked"){
				return true;
			}
		}
		return false; //user can't be blocked if they're not logged in
  }

  /**
   * Empty current user cart
   */
  public function emptyCart(){
  		$cartHelper = Mage::helper('checkout/cart');
     	$items = $cartHelper->getCart()->getItems();
        foreach ($items as $item) {
            	$itemId = $item->getItemId();
            	$cartHelper->getCart()->removeItem($itemId)->save();
        }
  }

   /**
     * Shopping cart display action
     */
   public function indexAction()
   {
   		if ($this->isBlocked()){
   			$this->emptyCart();
		}
		parent::indexAction();
   }

    /**
     * Add product to shopping cart action
     */
    public function addAction()
    {
			if ($this->isBlocked()){
				$this->emptyCart();
				$this->_goBack();
                return;
			}
		parent::addAction();

    }

}

 

The actions we’re overriding are ‘indexAction’ (which is used to display a user’s cart) and ‘addAction’ (called whenever an item is added to the cart.  The other 2 functions here ‘isBlocked’ and ’emptyCart’ are simple helper functions I’ve defined to keep things tidy.

The basic logic here is that when a user adds an item to their cart we first check if they’re in a specific group (here I’ve used ‘Blocked’ as the name of the group, but you can call it something else as long as you update the code in ‘isBlocked’).  If they are we empty their cart, and then return.  The effect of this is to take the user to an empty cart with nothing added to it and no error message to indicate what the problem might be.

As a doublecheck against a user who already has items in their cart when they’re placed in the ‘Blocked’ group, we also add a check to the ‘indexAction’ to empty their cart when they view it.

At the end of our indexAction and addAction we use the nifty trick of calling the relevant method in the ‘parent’ class.  This means our code remains clean and simple, while allowing requests that we don’t want to block using our code to ‘fall through’ to the parent implementation and be dealt with by the standard Magento logic.

Now all that’s required is an ‘activation’ xml file in app/code/etc and we’re good to go.  Create a group called ‘Blocked’, add your rogue users to it and laugh as you imagine their confusion at being unable to add items to their basket.

You can download the code for this article here: [wpdm_file id=8]

 

3 thoughts on “Magento: Block users using a group

  1. Hi, great idea and the code works great, too. However if someone in the Blocked customer group adds items to their cart while not logged in and then logs in on the checkout page then their cart will not be emptied and they will be able to check out. What code could be added to also empty the cart from the checkout page? Thanks!

    1. Actually, if things are added to the cart before logging in then the only way the cart will be cleared after the customer logs in is if they either add something else or visit the Cart page. Otherwise the items will remain in their cart and they will be able to check out – as long as they just steer clear of the cart page. Is there a way to just empty the cart on any page load rather than only when the cart page is visited? I’m worried that this would not work well with AJAX cart modules, too (though I don’t have one installed to test it). Thanks again!

      1. Hi Todd,

        I’ve changed jobs since writing this code and I no longer use Magento, however one of the last things I did was fix this very issue.

        I added code that emptied the cart of user in the blocked group as soon as they hit the checkout page and (if I remember correctly) also when they logged in. Unfortunately I don’t have access to that code now, and no real interest in magento anymore so I’ll leave it as an exercise for the reader 😀

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.