Wednesday, 10th of March 2010

Established in 2007 RVstudio provides premier
Web 2.0 services based on the world-famous
Drupal platform. We have developed a large
scale of customized web-systems for clients
based in USA, Canada, France, UK and Hungary

How to create a fancy pay-per-view content using Drupal 6?

In this post we’ll explain how to create a pay-per-view content in Drupal 6 using Ubercart 2 and a custom module. Our goal is to create a special content type that is available for everyone in a teaser format, but users need to pay an amount to view the full node.

Modules needed

  • Ubercart 2
  • Cart links (part of Ubercart)

So first of all, we install Ubercart (an open source shopping cart solution for Drupal). We create a new Product class, which will give us a new content type with all possibilities from both Drupal's and Ubercart's point of view. This means that the content type is expandable (by CCK) and also, we can use the Ubercart product features as well.
So let's call our product class "Premium content". When done, go to create a new Premium content. We'll see that the general node form is extended by Ubercart's various fields. This means we can give a price to our premium content. This looks all good. When our node is created, we'll see that there's an "Add to cart" button appears, together with a few additional fields, like SKU. We don't want these there, luckily we can get rid of them by modifying the Product fields to display in Ubercart's settings.
At this point the content is still accessible for everyone. So let's create our small module that will help us determine who has access to the content.

We'll need to create an additional table in our database, so we create the custom.install file, that looks like this:

<?php

/**
* Implementation of hook_install().
*/
function custom_install() {
 
drupal_install_schema('custom');
}

/**
* Implementation of hook_schema().
*/
function custom_schema() {
 
$schema['custom'] = array(
   
'description' => 'For storing per-node access details.',
   
'fields' => array(
     
'user_id' => array(
       
'description' => 'The user ID.',
       
'type' => 'varchar',
       
'length' => 100,
       
'not null' => TRUE,
      ),
     
'node_id' => array(
       
'description' => 'The node ID.',
       
'type' => 'varchar',
       
'length' => 200,
       
'not null' => TRUE,
      ),
     
    ),
   
  );
  return
$schema;
}


/*
* Implementation of hook_uninstall
*/
function custom_uninstall() {
 
drupal_uninstall_schema('custom');
}
?>

So we created a very simple table with only 2 fields, the user ID and node ID. Let's create our custom.module:

<?php


function custom_check_user_access($user, $node){
//Check if this user has access to this node
   
   
$sql = db_result(db_query("SELECT * FROM custom WHERE user_id = %d AND node_id = %d", $user->uid, $node->nid));
       
    return
$sql;
}

function
custom_grant_user_access($user, $node_id){
//Function for granting a user access to a particular node, we'll use this later
   
db_query("INSERT INTO custom VALUES(%d, %d)", $user->uid, $node_id);

}

function
custom_theme() {
  return array(
   
'custom_body' => array(
     
'arguments' => array('node' => NULL),
    ),
  );
}

function
theme_custom_body($user, $node) {
//Theming function that we'll use in a template file
   
$true = custom_check_user_access($user, $node);

    if(
$true){
       
//If the user has access to this node, output the whole node
       
$output = $node->body;
    }

    else{
       
//If the user doesn't have access to this node, output the teaser only and a cart link to purchase the access

       
$db = db_query("SELECT * FROM node_revisions WHERE nid = %d", $node->nid);
        while (
$result = db_fetch_array($db)){

           
$teaser = $result['teaser'];

        }

       
$output = $teaser .' ... ';
       
$output .= '<br /><p><div class="pay-per-view-msg"> <a href=
        "/cart/add/e-p'
. $node->nid .'?destination=/cart/checkout">Purchase this premium content.</a>
        </p></div>'
;

    }

return
$output;
}
?>

We're quite close now. The next thing is to make use of our theming function and use it in our node-premium_content.tpl.php file. Depending on what theme we're using, the default node template file can be different. The only thing we'll need to modify in our new template file is to change the content variable to our theming function created in our module:

<div class="content">
    <?php print $content ?>
</div>

To be changed to:

<div class="content">
    <?php global $user; ?>
    <?php print theme('custom_body',$user, $node); ?>
</div>

The last thing we need to do is add a new Conditional action to Ubercart. It's simple, when a customer completes checkout, grant access to the purchased node. This is what we'll use in our action (PHP code):

<?php
//Get the product node's ID
foreach ($order->products as $product){
$nids[] = $product->nid;
}

//Grant access to the node using our function
custom_grant_user_access($account, $product->nid);

//Redirect back to the original page with full content
$path = 'node/'.$product->nid;
$goto = drupal_get_path_alias($path);
drupal_goto($goto);
?>

And we should have a pay-per-view solution using Ubercart, a custom module and a little theming.