Customers who bought this item also bought

17 replies [Last post]
Joined: 01/23/2008
Juice: 185

Hi

I have added this feature to the shop i am developing and I wanted to share it with you, maybe someone finds it useful

Ingredients
Drupal + Ubercart Eye-wink
CRE module -> http://drupal.org/project/cre
VotingApi module -> http://www.drupal.org/project/votingapi
Workflow-NG module and UI activated -> http://drupal.org/project/workflow_ng

You will need to create a custom module (or use any "auxiliar" modules you have). The code uses workflow-ng & votingapi hooks. It creates an action and a block.

After creating and activating the module, you should create a new configuration from workflow-ng UI screen, with the event set to Customer completes checkout, with no condition and with the action defined by the module (for the example below 'Vote the items'), so whenever a customer completes the checkout, a custom vote is issued.
The block is restricted to show 5 elements by the db_query_range.
Then you activate the block in the block administer settings wherever you want it.

Here is the code

<?php

/**
* Implementation of hook_action_info().
*/
function customer_related_action_info(){
  $actions = array();
  $actions['customer_related_vote_item'] = array(
    '#label' => t('Vote the items'),
    '#arguments' => array(
      'order' => array('#entity' => 'order', '#label' => t('Order')),
    ),
    '#module' => t('Name of the module'),
  );
  return $actions;
}

function customer_related_vote_item ($order) {

  $products = $order->products;
  foreach ($products as $product) {
    $votes->value = 1;
    $votes->value_type = 'points';
    $votes->tag = 'customer_related';
    $test = votingapi_set_vote('product',$product->nid,$votes,$order->uid);
  }
}

/**
* Hook block
*/
function customer_related_block($op = 'list', $delta = 0, $edit = array()) {
 
    switch ($op) {
      case 'list':
        $blocks[0]['info'] = t('Customers that bought this item also bought');
        return $blocks;
       
      case 'view':
        $block['subject'] = t('Customers that bought this item also bought');
        $block['content'] = _calculate_other_items();
        break;
    }
    return $block;
}

function _calculate_other_items() {

  $sql = "SELECT d.content_id1 as 'content_id',sum(d.sum+d.count*r.value)/sum(d.count) as 'score',n.title
    FROM {cre_similarity_matrix} d,{votingapi_vote} r,{node} n
    WHERE d.content_type1='product'
    AND d.content_id1<>r.content_id
    AND d.content_id2=r.content_id
    AND n.nid=d.content_id1
    AND r.tag = 'customer_related'
    AND n.type = 'product'
    AND n.nid<> %d
    AND d.content_id2 = %d
    GROUP BY d.content_id1 ORDER BY score DESC";
 
  $result = db_query_range ($sql,arg(1),arg(1),0, 5);
  $data_array = array();
  while ($data = db_fetch_object($result)) {
    $rows[] = array(l($data->title,'node/'.$data->content_id));
  }
  if (count($rows)) {
    return theme('table', array(), $rows, array(), NULL);
  }
  else {
    return NULL;
  }
}

Any comments or modifications are welcome!!!

TR
TR's picture
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3221

Very nice!

If you could turn it into a module, you could add the dependencies on the other modules and implement the workflow hook to automatically generate the configuration - that way someone could install your contribution just by enabling it.

<tr>.
Joined: 01/23/2008
Juice: 185

Thanks! I will work on that.

Joined: 08/14/2007
Juice: 3864

Sounds like it'd be an awesome feature to add to my Upsell Contrib. It's one of those things I intended to include, but haven't gotten around to yet.

If you'd like to work on combining them, that'd be awesome, or I could give it a shot in the coming days.

Unless others think these two are better off separate?

Help directly fund development: Donate via PayPal!

TR
TR's picture
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3221

I would keep them as separate modules, to fit with the Drupal philosophy, but certainly group them into the same package so they show up together at admin/build/modules. Also goes well with the stuff Lyle moved to the Marketing contrib.

<tr>.
Joined: 08/14/2007
Juice: 3864

Actually you're right, after thinking about it, I feel like the "Customers also bought..." seems more suited for a product detail page, whereas mine is fine for the Cart screen.

Help directly fund development: Donate via PayPal!

Joined: 01/23/2008
Juice: 185

Hi

Yes, is a block thought for product details page. I've adapted the code for being a module under your suggestions, it has a configuration for workflow by default and it is "part" of the package "Ubercart - extra".

I don't know where should I include the module for being a contribution, so I upload the module here until I discover that! Smiling

Thanks to both!

AttachmentSize
custom_like.zip 1.73 KB
TR
TR's picture
Bug FinderFAQ ModeratorGetting busy with the Ubercode.
Joined: 11/05/2007
Juice: 3221

You can use the "Create Content" menu link to submit your contribution. Here's the direct link: http://www.ubercart.org/node/add/contrib

<tr>.
Joined: 01/23/2008
Juice: 185

I am pending of a "feature" I've request to CRE module support, as they are not supporting (from my point of view) different tags for votingapi, because the queries don't restrict only to the custom tags when a node is voted by more than a voting-module.

here is the request: http://drupal.org/node/245349

Until this is fixed, the module i've posted only works if you don't have another module that uses votingapi or if you have one, but the content type "product" is not voted.

I'll keep you informed about this

Thanks!

Joined: 03/06/2009
Juice: 9

Hi pcambra, I'm the developer for Recommender API http://drupal.org/project/recommender. It implements the algorithm used in Amazon. It should be quite easy to write a module that generate recommendation based on order history. An example that uses Recommender API is here http://drupal.org/project/uurec.

If you want to write the module, I can provide supports. Let me know!

Joined: 08/14/2007
Juice: 3864

Revisiting this as per a convo with mattyt on #drupal-ubercart. I like the idea of an Order History-based recommendation as well. I'm thinking the best way to accomplish this is to build another db table that will be populated with a hook_order. Each node will have an array that gets updated whenever an order is completed. Since these aren't really "related" we can consider them to be more based on user similarities.

I think the main issue with the code that was provided above is caching - that query doesn't seem very light, and so it's not the kind of thing you'd want getting fired on every page view (of course block-level caching would have this). Which is why I consider just creating a table to keep track of these relationships, and this way we can further modularize the way uc_upsell works - "get the products" block can be agnostic with regard to which table it's pulling from, whether it's "similar" based on user purchases or "related" based on admin selection. I can provide another block for Similar products.

Help directly fund development: Donate via PayPal!

Joined: 03/16/2009
Juice: 2

To torgosPizza's point yes that query is aweful. I am the author of CRE and I eliminated the need for that query. I developed a seperate module which I am looking to integrate with Ubercart for this specific purpose, its called Similarity Objects. It is a module that provides ways to customize how you find 'similar' nodes, users and taxonomy terms. I am hoping to take a look at this tonight, but would really love someone that has developed against Ubercart to take a look. It will only work against Ubercart 2.0 as it will be Drupal 6 only unless someone else wants to back port it. It does require php 5.

I will be integrating in the next few hours the Recommender API Dan talked about above into this module. He and I talked over at DrupalCon DC and that is the goal. Plz take a look I want this to be a part of this module in a big way.

Joined: 08/14/2007
Juice: 3864

Hi Scott,

That would be perfect. If you'd like, feel free to look at the Upsell module at http://drupal.org/project/uc_upsell and if you'd like, write an file that can be included with the original module (and then called as an include). That way we can keep the functionality separate.

I would love to find a way to add Similarity Objects' functionality to uc_upsell.

Help directly fund development: Donate via PayPal!

Joined: 01/23/2008
Juice: 185

You are probably right, for hight traffic sites, my query maybe won't performance well, best solution would be a "programmatic" action, but this worked for me, anyway, CRE module never implemented the suggestion I made (as fas as I know) for including voting tags of Voting API, so I haven't worked on this feature since I published here last year.

Joined: 03/06/2009
Juice: 9

Hi, I started a new thread discussing my Google Summer of Code '09 project here:
http://www.ubercart.org/forum/ideas_and_suggestions/10727/gsoc_ubercart_...

Comments are much welcome~

Joined: 03/06/2009
Juice: 9

"Ubercart Products Recommender" http://drupal.org/project/uc_rec

Feedback please go to http://drupal.org/node/510252

Joined: 08/14/2007
Juice: 3864

No response to my comments?

Help directly fund development: Donate via PayPal!

Joined: 01/24/2010
Juice: 2

Hi I created a module using the above code.But no result.I saw a table named cre_similarity_matrix.what are fields of this table.If any know please help me?