StudioForty9 | Search Engine Marketing, E-Commerce, Web Design, Web Development, Magento, ExpressionEngine

  • Home
  • Products
  • Our Work
  • Our Team
  • Blog
  • Contact Us

Restricting Product Purchase to Authorised Users in Magento

Quick ways to exend Magento's default functionality

  • Date 7th February, 2011
  • Author Alan Morkan
  • Category Magento

I haven't written about e-commerce for quite a while now. Magento has been keeping me busy and now I've a list of thoughts and insights that I hope to share in the coming weeks.

So first off, I'd like to describe a recent module I wrote that might seem reasonably complex. However, I'd like to show how easy it can be when taking advantage of Magento's features.

The idea behind the module is that a customer may only purchase a particular product by entering a code. There's 4 parts to the module:

  • The product view page where the customer can enter their code.
  • An override of the default Add to Cart functionality in Magento to validate the given Code
  • A section in the Magento backend for managing Codes.
  • An event listener to observe when a customer places an order so that the code can be marked as "used".

The basics of the module can be setup using ModuleCreator (http://www.magentocommerce.com/magento-connect/Daniel+Nitz/extension/1108/modulecreator). The module doesn't really install properly in Magento 1.4.x but I've used it enough times at this stage to be able to copy the files over manually and do some search and replace over them to get it the way I want it.

Once the files, are in place, the most important thing is to design the table structure in the database and write the SQL installation script. The fields I needed were:

  • code_id
  • country_id
  • customer_ip
  • valid_to
  • valid_from
  • used_timestamp
  • status

Once installed in Magento, you can start fixing up the grid and add/edit screens to show you the fields for your particular module (rather than the default ModuleCreator fields). Having useful field types in the grid is a topic I intend to return to in a future post.

After that, it's just a matter of creating a test product and giving it a custom option where the customer can enter the code.

We then override the Add to Cart functionality. So I override /app/code/core/Mage/Checkout/Model/Cart.php. To do this I add the following lines to the config.xml file of my module:

<models>
	   ...
	   <checkout>
	      <rewrite>
	         <cart>SF9_Codes_Model_Cart</cart>
	      </rewrite>
	   </checkout>
	</models>

and I create my own Cart.php file

class SF9_Codes_Model_Cart extends Mage_Checkout_Model_Cart
{
     public function addProduct($product, $info=null){
        $code_title = Mage::getStoreConfig('codes/codes/custom_option_title', 1);
        $error_message = Mage::getStoreConfig('codes/codes/invalid_code_error_message', 1);
    
          $options = array();
         
          foreach ($product->getOptions() as $_option) {
               $options[$_option->getId()] = $_option->getTitle();
          }
         
          if(!in_array($code_title, $options)){
               parent::addProduct($product, $info);
               return;
          }         
         
          foreach($info['options'] as $key => $value){
               if(in_array($key, array_keys($options)) ){
                    $code = $value;
               }
          }         
    
          $timestamp = date('Y-m-d H:i:s');
         
          $codes = Mage::getModel('codes/codes')->getCollection()
                         ->addFieldToSelect('*')
                         ->addFieldToFilter('code', $code)
                         ->addFieldToFilter('status', 0)
                         ->addFieldToFilter('valid_from', array('date' => true, 'to' => $timestamp))
                         ->addFieldToFilter('valid_to', array('date' => true, 'from' => $timestamp))
                         ->setPageSize(1);
         
          if(count($codes) > 0){
               parent::addProduct($product, $info);    
          }else{
               Mage::throwException($error_message);
          }
         
     }
}

Finally, I create an observer for the order_placed event. To do this, I add the following lines to config.xml

<events>
	   <checkout_type_onepage_save_order_after>
	      <observers>
	         <sf9_codes_observer>
	            <type>singleton</type>
	            <class>SF9_Codes_Model_Observer</class>
	            <method>update_used_codes</method>
	         </sf9_codes_observer>
	      </observers>
	   </checkout_type_onepage_save_order_after>
	</events>

and create the following Observer.php file

class SF9_Codes_Model_Observer{
        
          //runs when order is saved in Onepage Checkout
          public function update_used_codes($observer){
               $event = $observer->getEvent();
               $order = $event->getOrder();
              
               $code_title = Mage::getStoreConfig('codes/codes/custom_option_title', 1);
              
               $items = $order->getAllItems();
               foreach($items as $item){
                    $_options = $item->getProductOptions();
                    foreach($_options['options'] as $_option){
                         $options[$_option['label']] = $_option['value'];
                    }
                    if(isset($options[$code_title])){
                         $code = $options[$code_title];
                         $codes = Mage::getModel('codes/codes')->getCollection()
                                             ->addFieldToSelect('*')
                                             ->addFieldToFilter('code', $code)
                                             ->setPageSize(1);
              
                         $update = $codes->getFirstItem();
                         $timestamp = date('Y-m-d H:i:s');                             
                         $update->setStatus(1)
                                   ->setUsername($order->getBillingAddress()->getName())
                                   ->setUserIp($_SERVER['REMOTE_ADDR'])
                                   ->setUsedTimestamp($timestamp)
                                   ->save();
                    }
               }
          }
     }

What's nice about the module is how it exemplifies in a very succinct way the different ways to extend Magento's core functionality. You can extend a core PHP file when you want to alter the default behaviour or create an observer that listens to one of the approximately 280 events that Magento fires off when you want to do something extra at a particular time (in this case, update the code's status to "used" and write its "used timestamp".

Now, let's hope I can make blogging about Magento more of a habit!!

Subscribe to Our Blog
Recent Posts Toggle
  • As consumers flock online, Irish businesses need to follow
  • E-commerce fund a welcome development
  • An Irish Module for Magento
  • Taking Control of Product Options in Magento
  • jQuery in Magento made easy
  • Restricting Product Purchase to Authorised Users in Magento
  • West Cork Homeless
  • Fota Wildlife wins Best Tourism & Travel Website… and also takes the Eircom Spiders Grand Prix
  • Realex Redirect with PHP
  • Blinds & Magento
Categories Toggle
  • Expression Engine (2)
  • General (8)
  • Magento (7)
  • PHP (1)
  • Portfolio (2)
  • Realex (1)
  • SEO (1)
  • We are now getting twice as many hits as we were in the past and the numbers are growing by the week. StudioForty9 are innovative, well organised, knowledgeable, flexible and very easy to deal with.
    Stephen RyanFotawildlife.ie
  • I have been working closely with StudioForty9 for over a year now. They are a key part of my online strategy and I can recommend them without hesitation.
    Brendan O'SullivanMyBlinds.ie
  • I have no hesitation in recommending StudioForty9. I now regard them as critical partners in my business.
    Fred CroweSpeech-Writers.com
  • As a business development consultant I understand what it takes to build and expand a business and when it comes to the online business sector, this company has what it takes to deliver.
    Billy O'ConnorThe Discovery Partnership

MyMailCampaign Client Login StudioForty9 Lite

Copyright © 2006 - 2012 StudioForty9. 2nd Floor, 34 Grand Parade, Cork City, Ireland. Phone: +353 87 225 1250