View source
<?php
abstract class RateWidget {
protected $type;
protected $mode;
protected $entity_type;
protected $entity_id;
protected $value_type;
protected $field_name;
protected $tag;
protected $account;
protected $elements;
protected $displayed;
protected $displayed_just_voted;
protected $just_voted;
protected $results;
protected $rating;
protected $count;
protected $voted;
public function __construct($attributes) {
global $user;
$this->type = $attributes['type'];
$this->entity_type = $attributes['entity_type'];
$this->entity_id = $attributes['entity_id'];
$this->mode = $attributes['mode'];
$this->field_name = $attributes['field_name'];
$this->account = empty($attributes['account']) ? $user : $attributes['account'];
$this->displayed = empty($attributes['displayed']) ? RATE_AVERAGE : $attributes['displayed'];
$this->displayed_just_voted = empty($attributes['displayed_just_voted']) ? RATE_USER_OR_AVERAGE : $attributes['displayed_just_voted'];
$this->elements = array();
$this->just_voted = FALSE;
$this->tag = isset($attributes['tag']) ? $attributes['tag'] : 'vote';
$this
->load();
$this
->processVote();
if ($this->just_voted) {
$this->displayed = $this->displayed_just_voted;
}
$this->results = $this
->getAverageResults();
$user_vote = $this
->getUserResults();
if ($user_vote) {
$this->voted = TRUE;
$this->results[] = array(
'function' => 'user',
'value' => $user_vote,
);
}
else {
$this->voted = FALSE;
}
$average_rating = NULL;
$user_rating = NULL;
$this->rating = 0;
$this->count = 0;
foreach ($this->results as $result) {
switch ($result['function']) {
case 'average':
$average_rating = $result['value'];
case 'user':
$user_rating = $result['value'];
break;
case 'count':
$this->count = $result['value'];
break;
}
}
switch ($this->displayed) {
case RATE_USER_OR_AVERAGE:
case RATE_USER:
if (!is_null($user_rating)) {
$this->rating = $user_rating;
$this->displayed = RATE_USER;
break;
}
case RATE_AVERAGE:
$this->rating = $average_rating;
break;
}
$this
->calculateResults();
$this
->init();
}
protected abstract function load();
protected function init() {
}
public abstract function __toString();
public function getJS() {
return array();
}
public function getCSS() {
return array();
}
public function clickButton($value) {
}
public function viewAccess() {
return TRUE;
}
protected final function getToken($value = '') {
global $user;
$value .= $this->entity_type;
$value .= $this->entity_id;
return drupal_hmac_base64($value, $user->uid . drupal_get_private_key() . drupal_get_hash_salt());
}
protected function clickedButton() {
foreach ($this->elements as $element) {
if ($element instanceof RateButton && $element
->hasClicked()) {
return $element;
}
}
return FALSE;
}
public function processVote() {
if ($button = $this
->clickedButton()) {
$this->just_voted = TRUE;
$this
->vote($button
->getValue());
}
}
public function vote($value) {
$votes = array(
'entity_type' => $this->entity_type,
'entity_id' => $this->entity_id,
'value_type' => $this->value_type,
'value' => $value,
'tag' => $this->tag,
);
$criteria = NULL;
$redirect = FALSE;
$save = TRUE;
$context = array(
'redirect' => &$redirect,
'save' => &$save,
'criteria' => &$criteria,
'widget' => &$this,
);
drupal_alter('rate_vote', $votes, $context);
if ($save) {
votingapi_set_votes($votes, $criteria);
}
}
protected function getAverageResults() {
$criteria = array(
'entity_type' => $this->entity_type,
'entity_id' => $this->entity_id,
'tag' => $this->tag,
'value_type' => $this->value_type,
);
return votingapi_select_results($criteria);
}
protected function getUserResults() {
$criteria = array(
'entity_type' => $this->entity_type,
'entity_id' => $this->entity_id,
'tag' => $this->tag,
'value_type' => $this->value_type,
'uid' => $this->account->uid,
);
if (!$this->account->uid) {
$criteria += array(
'vote_source' => ip_address(),
);
}
if ($results = votingapi_select_votes($criteria)) {
$anonymous_window = variable_get('votingapi_anonymous_window', 86400);
$anonymous_window = max(5, $anonymous_window);
if ($this->account->uid || $user_vote[0]['timestamp'] > REQUEST_TIME - $anonymous_window || $anonymous_window == -1) {
return $results[0]['value'];
}
}
return NULL;
}
protected function calculateResults() {
$this->elements['rating'] = round($this->rating);
$this->elements['count'] = $this->count;
if ($this->value_type == 'points') {
$up = NULL;
$down = NULL;
foreach ($this->elements as $name => $element) {
if ($element instanceof RateButton) {
if ($element
->getValue() == 1) {
$up = $name;
}
if ($element
->getValue() == -1) {
$down = $name;
}
}
}
if ($up && $down) {
$down_count = (int) ($this->count - $this->rating) / 2;
$up_count = $this->count - $down_count;
if ($up_count == $down_count) {
$up_percent = 50;
$down_percent = 50;
}
else {
$up_percent = $up_count / $this->count * 100;
$down_percent = 100 - $up_percent;
}
$this->elements['up_count'] = $up_count;
$this->elements['up_percent'] = $up_percent;
$this->elements['down_count'] = $down_count;
$this->elements['down_percent'] = $down_percent;
}
}
foreach ($this->elements as $name => $element) {
if ($element instanceof RateButton) {
$value = $element
->getValue();
foreach ($this->results as $result) {
if ($result['function'] == 'option-' . $value) {
$this->elements["{$name}_count"] = $result['value'];
}
}
}
}
}
protected function getButtonLabelByValue($value) {
foreach ($this->elements as $element) {
if ($element instanceof RateButton && $element
->getValue() == $value) {
return $element
->getLabel();
}
}
}
}