We’ve all been to websites that endlessly redirect us to either a sign-up page or a membership purchase page before viewing the rest of the website. Perhaps you’ve wondered how to set this up in Magento for your own business. Creating a restricted store or a membership only store is actually fairly easy to do.
Click here to download the source code for this article.
Recently, we built such a system on Magento by using the controller_action_predispatch observer. In this post we’ll walk you through the code that we used to create this restricted store. This example assumes the following:
You have a membership product, e.g., “Lifetime Membership” a customer must purchase before being allowed to browse the rest of the store.
There are essentially 2 major files in this module, the Observer.php and, as with all Magento modules, the config.xml. Starting from the Magento directory we place these two files in
app/code/local/Cadence/Vip/etc/config.xml
and
app/code/local/Cadence/Vip/Model/Observer.php.
The key part of setting up this module is setting up the event observer. Before touching the observer we need to first get our config.xml in order (anything in square brackets is a variable).
<?xml version="1.0" encoding="utf-8"?>
<config>
<!--other stuff-->
<global>
<!--other stuff-->
<events>
<controller_action_predispatch>
<observers>
<cadence_vip>
<class>Cadence_Vip/observer</class>
<method>vipCheck</method>
</cadence_vip>
</observers>
</controller_action_predispatch>
<sales_order_place_after>
<observers>
<cadence_vip>
<class>Cadence_Vip/observer</class>
<method>updateCustomerGroup</method>
</cadence_vip>
</observers>
</sales_order_place_after>
</events>
<!--other stuff-->
</global>
<!--other stuff-->
</config>
Depending on how much you know about Magento observers you may realize that we’ve actually set two observers up. The first of these observers, controller_action_predispatch, will allow us to redirect any requests we don’t want back to the page we do want them to see. The second observer, sales_order_place_after, will move the customer into a different customer group so that they can move about the website without the interference of our first observer. This brings us to the observer file itself.
<?php
class Cadence_Vip_Model_Observer extends Varien_Event_Observer
{
public function vipCheck(Varien_Event_Observer $observer)
{
$vipGroupId = 6;
$customer = Mage::getSingleton('customer/session');
$isLoggedIn = $customer->isLoggedIn();
$customerGroup = $customer->getCustomerGroupId();
if ($isLoggedIn && $customerGroup == $vipGroupId) {
return;
}
$request = Mage::app()->getRequest();
$requestId = $request->getParam('id');
$requestController = $request->getControllerName();
$requestModule = $request->getModuleName();
$vipProductId = 906;
if ($requestModule==='catalog' && $requestId != $vipProductId) {
$controller = $observer->getControllerAction();
$controller->getRequest()->setDispatched(true);
$controller->setFlag('', Mage_Core_Controller_Front_Action::FLAG_NO_DISPATCH, true);
Mage::getSingleton("core/session")->addError("You must purchase the lifetime membership before viewing another product");
Mage::app()->getResponse()->setRedirect('/catalog/product/view/id/906');
}
}
public function updateCustomerGroup(){
//...detailed below
}
}
Our first function checks to see if the person currently looking at the store is a “vip” member. Before we even check this you need to first go into Magento’s admin panel and got to Customers->Customer Groups. In the top right corner of the page there’s a button that says add new customer group. Click on the button and you can customize the name and tax class of the customer group. Afterwards you’re returned to the customer groups page where you’ll be able to find the id number of your group to the left of the name.
Now our first function checks to see if the customer is already part of our “vip” group. In the example code above the customer group number was 6, hence we have the function check if the customer belongs to group $vipGroupId = 6. If the customer belongs to $vipGroupId and is logged in then we get ‘return’ and don’t need to worry about any of the checks that come later.
The next part of the function is another if/then statement to check if the customer is using the catalog module and also check which product the customer is viewing. Before jumping into the code we need to sidetrack again to setup our membership product (the “vip membership” in the above example). In order to create a new product go to the admin panel and under the “Catalog” tab click “Manage Products” and add a new product for the membership. We set the product type to virtual, which we expect will be the correct product type for most projects of this nature since there is no physical product to deliver, just the membership. Set all the required fields for the product and save. After finishing return to the “Manage Products” grid. To the left of your product’s name will be the product ID# that you’ll need for the next part.
Go back to the Observer.php file, we’ll take a look at the second check run in the function (everything below the line making an if/then statement on $requestModule and $requestId). The conditions of the if statement between the parentheses check if the ‘catalog’ module is being called. If the catalog module is being called the function gathers the controller and stops the dispatch action (in this case taking you to a product page or list). In the final two lines with content we put an error message into the system so that customers know why they’ve been redirected and don’t assume there was a mistake. Finally we put the redirect in place and send them to our preferred product page. Replace the number in $vipProductId = 906 in the above example with the product ID# of the new product you created. This part of the module is ready to go.
Now onto the second part of the observer file.
class Cadence_Vip_Model_Observer extends Varien_Event_Observer
{
public function vipCheck(Varien_Event_Observer $observer)
{
//detailed above...
}
public function updateCustomerGroup()
{
$vipProductId = 906;
$vipGroupId = 6;
$cart = Mage::getSingleton('checkout/cart');
$cartIds = $cart->getProductIds();
foreach ($cartIds as $id) {
if ($id == $vipProductId) {
$customerId = Mage::getSingleton("customer/session")->getCustomerId();
$customer = Mage::getModel("customer/customer")->load($customerId);
$customer->setGroupId($vipGroupId);
$customer->save();
return;
}
}
}
}
The updateCustomerGroup() function is initiated by the sales_order_place_after event that’s listed in the config.xml code higher up. Again we see the variables $vipProductId = 906 for the product ID# and $vipGroupId = 6 for the customer group. These need to be replaced with the group ID# and product ID# of the group and product you’ve created for this project.
The purpose of this function is to change the group membership of a customer once they’ve finished purchasing the vip membership. After their membership status is changed they’ll be able to access the rest of the products and buy whatever they like inside the store.
To break the code down further we see a call to mage::getSingleton(‘checkout/cart’) that loads the recently used shopping cart. We then use it to call getProductIds() to get the ids of all the products. Last, a foreach loop looks for the id of our vip membership product. If the product is found then the four lines of code load the current customer and automatically change their group to the vip group. The customer can then look through the rest of the store.
Finally, we have one more admin panel issue to tackle. We must update the setting in system -> configuration -> checkout that requires a user be logged in to checkout. That way you can be 100% sure anyone checking out is logged in, otherwise guests will still not have access to your other items.
Let us know what you think of this solution for creating a Membership Only Store in Magento in the comments below.