11 Dec 2013

The purpose of this theme is creation of multi-axis rating system in Drupal 7, which uses drupal comment system and fivestar rating. And most important is that we will calculate average vote from several fivestar fields (in our case they are 3: Taste, Price, Quality)

This works with Drupal 7

First you have to install Fivestar and VotingAPI modules.
In fivestar options (which you can find at admin/config/content/fivestar) type so many axis as you need. In our case they are 4 (3+1): vote,quality,price,taste

Next in your content type ( i assume that you will make Review content type) you have to create 4 (3+1) fields (or as many as you wish)
field_rating (for average overall) select voting tag: vote
field_rating_quality (for quality vote) select voting tag: quality
field_rating_price (for price vote) select voting tag: price
field_rating_taste (for taste vote) select voting tag: taste

It's important that all four fields must be : Stars (rated while viewing).

Also it's important that in Manage Display you must uncheck Expose this Fivestar field for voting on the @type type for all Four fields.

Next Step: Go to Comment Fields:
Add above four existing fields, but this time you must select widget Stars (rated while editing). And in settings for each field you must set Voting Target : Parent Node

Above steps are usual for fivestar and comments system, but we need Average Overall field, which to collect average user voting from other 3 fields. So here are next steps:

We have selected field_rating in comments with widget type Stars (rated while editing), but we don't want to expose this field for users. We don't want to allow the to voting on this field. So we must hide it with CSS code:
.comment-form .field-name-field-rating{display:none;}

Next we must create custom module, here are the code:

<?php
/**
* Implements hook_form_alter().
*
* Hide average fivestar field from review edit/create form.
*/
function fivestar_multiaxis_overall_form_alter(&$form, &$form_state, $form_id) {
  if (
$form_id == 'comment_node_review_form') {
   
// Hide average field, this field is calculated upon node_presave.
   
$form['field_rating']['#access'] = FALSE;
  }
}
/**
* Implements hook_comment_presave().
*
* Calculates average vote rating.
*/
function fivestar_multiaxis_overall_comment_presave($comment) {
 
$parent_node = node_load($comment->nid);
  if (
$parent_node->type == 'review') {
   
// Get values from 3 axis.
   
$vote_axis_one      = entity_metadata_wrapper('comment', $comment)->field_ratring_quality->value();
   
$vote_axis_two      = entity_metadata_wrapper('comment', $comment)->field_rating_taste->value();
   
$vote_axis_three    = entity_metadata_wrapper('comment', $comment)->field_rating_price->value();
   
// Calculate and set average axe.
   
$votes_average      = ($vote_axis_one + $vote_axis_two + $vote_axis_three) / 3;
   
// @info: Can't use entity_metadata_wrapper, because '->set' not supported on this field.
    //entity_metadata_wrapper('node', $node)->field_review_votes_average->set($votes_average);
   
$comment->field_rating['und'][0]['rating'] = $votes_average;
  }
}
?>

If you are using another content type you must change 'comment_node_review_form' и type == 'review' with your value. If you are using Article content type,change with these 'comment_node_article_form' и type == 'article'

The code is tested and works properly.

If you cant create custom module you can download my. But you need to change some of variables if you are using different ones.

Category: 

Contact

Contact with me

You can use contact form or skype:irgnet.

Connect with me