rate.module in Rate 8
Same filename and directory in other branches
Hook implementation code for the Rate module.
File
rate.moduleView source
<?php
/**
* @file
* Hook implementation code for the Rate module.
*/
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Link;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Template\Attribute;
use Drupal\Core\Url;
use Drupal\node\NodeInterface;
/**
* Implements hook_entity_extra_field_info().
*/
function rate_entity_extra_field_info() {
$extra = [];
$config = \Drupal::config('rate.settings');
$enabled_types_widgets = $config
->get('enabled_types_widgets');
if (!empty($enabled_types_widgets)) {
foreach ($enabled_types_widgets as $entity_type_id => $entities) {
foreach ($entities as $bundle => $settings) {
$extra[$entity_type_id][$bundle]['display']['rate_vote_widget'] = [
'label' => t('Rate Vote Widget'),
'description' => t('Displays the rate voting widget selected from the settings page.'),
'weight' => 100,
'visible' => TRUE,
];
}
}
}
return $extra;
}
/**
* Implements hook_entity_view().
*/
function rate_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
if (($widget_config = $display
->getComponent('rate_vote_widget')) && $view_mode == 'full') {
$vote_widget_service = \Drupal::service('rate.entity.vote_widget');
$vote_widget = $vote_widget_service
->buildRateVotingWidget($entity
->id(), $entity
->getEntityTypeId(), $entity
->bundle());
if (isset($vote_widget['rate_vote_widget'])) {
$vote_widget['rate_vote_widget']['#weight'] = isset($widget_config['weight']) ? $widget_config['weight'] : 2;
}
$build = array_merge($build, $vote_widget);
}
}
/**
* Implements hook_menu_local_tasks_alter().
*
* This unsets Voting Results tab for non-voting-enabled node types.
*/
function rate_menu_local_tasks_alter(&$data, $route_name) {
if (isset($data['tabs'][0]) && isset($data['tabs'][0]['entity.node.canonical'])) {
$node = Drupal::request()->attributes
->get('node');
if (!$node instanceof NodeInterface) {
$node = Drupal::entityTypeManager()
->getStorage('node')
->load($node);
}
if ($node) {
$config = \Drupal::config('rate.settings');
$enabled_types_widgets = $config
->get('enabled_types_widgets');
if (!empty($enabled_types_widgets)) {
foreach ($enabled_types_widgets as $entity_type_id => $entity_types) {
foreach ($entity_types as $bundle => $settings) {
if ($entity_type_id !== 'node') {
continue;
}
if (!in_array($node
->bundle(), array_keys($entity_types))) {
unset($data['tabs'][0]['rate.results_page']);
break;
}
}
}
}
elseif (isset($data['tabs'][0]['rate.results_page'])) {
unset($data['tabs'][0]['rate.results_page']);
}
}
}
}
/**
* Implements hook_theme().
*/
function rate_theme($existing, $type, $theme, $path) {
return [
// Templates for default widget types.
'rate_template_info_description' => [
'variables' => [
'info' => '',
'description' => '',
],
'template' => 'rate-template-info-description',
],
'rate_template_thumbs_up' => [
'variables' => [
'results' => 0,
'use_ajax' => FALSE,
'can_vote' => FALSE,
'has_voted' => FALSE,
'user_voted' => NULL,
'entity_id' => NULL,
'entity_type_id' => NULL,
'widget_type' => NULL,
],
'template' => 'rate-template-thumbs-up',
],
'rate_template_thumbs_up_down' => [
'variables' => [
'results' => 0,
'use_ajax' => FALSE,
'can_vote' => FALSE,
'has_voted' => FALSE,
'user_voted' => NULL,
'entity_id' => NULL,
'entity_type_id' => NULL,
'widget_type' => NULL,
],
'template' => 'rate-template-thumbs-up-down',
],
'rate_template_number_up_down' => [
'variables' => [
'results' => 0,
'use_ajax' => FALSE,
'can_vote' => FALSE,
'has_voted' => FALSE,
'user_voted' => NULL,
'entity_id' => NULL,
'entity_type_id' => NULL,
'widget_type' => NULL,
],
'template' => 'rate-template-number-up-down',
],
'rate_template_fivestar' => [
'variables' => [
'results' => 0,
'use_ajax' => FALSE,
'can_vote' => FALSE,
'has_voted' => FALSE,
'user_voted' => NULL,
'entity_id' => NULL,
'entity_type_id' => NULL,
'widget_type' => NULL,
],
'template' => 'rate-template-fivestar',
],
'rate_template_yesno' => [
'variables' => [
'results' => 0,
'use_ajax' => FALSE,
'can_vote' => FALSE,
'has_voted' => FALSE,
'user_voted' => NULL,
'entity_id' => NULL,
'entity_type_id' => NULL,
'widget_type' => NULL,
],
'template' => 'rate-template-yesno',
],
];
}
/**
* Implements hook_preprocess_HOOK() for rate-template-number-up-down.html.twig.
*/
function template_preprocess_rate_template_number_up_down(&$variables) {
$vote_types = [
'up',
'down',
];
foreach ($vote_types as $vote_type) {
$variables[$vote_type . '_attributes'] = new Attribute();
$variables[$vote_type . '_attributes']['class'] = [];
$variables[$vote_type . '_attributes']['class'][] = 'rate-number-up-down-btn-' . $vote_type;
if ($variables['use_ajax'] && !$variables['has_voted'] && $variables['can_vote']) {
$variables[$vote_type . '_attributes']['class'][] = 'use-ajax';
}
}
$score = isset($variables['results']['updown']['vote_sum']) ? $variables['results']['updown']['vote_sum'] : 0;
if ($score > 0) {
$score = '+' . $score;
$score_class = 'positive';
}
elseif ($score < 0) {
$score_class = 'negative';
}
else {
$score_class = 'neutral';
}
$variables['score'] = $score;
$variables['score_attributes'] = new Attribute();
$variables['score_attributes']['class'] = [];
$variables['score_attributes']['class'][] = 'rate-number-up-down-rating';
$variables['score_attributes']['class'][] = $score_class;
$variables['up_votes'] = isset($variables['results']['updown']['rate_count_up']) ? $variables['results']['updown']['rate_count_up'] : 0;
$variables['down_votes'] = isset($variables['results']['updown']['vote_count']) ? $variables['results']['updown']['vote_count'] - $variables['up_votes'] : 0;
_rate_set_common_theme_variables($variables);
_rate_get_undo_link($variables);
$variables['#attached']['library'][] = 'rate/number-up-down';
}
/**
* Implements hook_preprocess_HOOK() for rate-template-fivestar.html.twig.
*/
function template_preprocess_rate_template_fivestar(&$variables) {
$variables['stars'] = [];
// Calculate the score.
$score = isset($variables['results']['fivestar']['vote_average']) ? $variables['results']['fivestar']['vote_average'] : 0;
// Set up the links.
for ($counter = 1; $counter < 6; $counter++) {
$variables['stars'][$counter]['star_attributes'] = new Attribute();
$variables['stars'][$counter]['star_attributes']['class'] = [];
if ($counter <= $score) {
$variables['stars'][$counter]['star_attributes']['class'][] = 'rate-fivestar-btn-filled';
}
else {
$variables['stars'][$counter]['star_attributes']['class'][] = 'rate-fivestar-btn-empty';
}
$variables['stars'][$counter]['star_attributes']['class'][] = ' rate-fivestar-' . $counter;
if ($variables['use_ajax'] && !$variables['has_voted'] && $variables['can_vote']) {
$variables['stars'][$counter]['star_attributes']['class'][] = 'use-ajax';
}
if ($variables['entity_id']) {
$variables['stars'][$counter]['star_link'] = Url::fromRoute('rate.vote', [
'entity_type_id' => $variables['entity_type_id'],
'vote_type_id' => 'fivestar',
'value' => $counter,
'entity_id' => $variables['entity_id'],
'widget_type' => $variables['widget_type'],
'destination' => \Drupal::destination()
->getAsArray()['destination'],
]);
}
}
_rate_set_common_theme_variables($variables, FALSE);
_rate_get_undo_link($variables);
$variables['#attached']['library'][] = 'rate/fivestar';
}
/**
* Implements hook_preprocess_HOOK() for rate-template-thumbs_up_down.html.twig.
*/
function template_preprocess_rate_template_thumbs_up_down(&$variables) {
$vote_types = [
'up' => '1',
'down' => '-1',
];
foreach ($vote_types as $vote_type => $value) {
$variables[$vote_type . '_li_attributes'] = new Attribute();
$variables[$vote_type . '_li_attributes']['class'] = [];
$variables[$vote_type . '_li_attributes']['class'] = 'thumb-' . $vote_type;
$variables[$vote_type . '_attributes'] = new Attribute();
$variables[$vote_type . '_attributes']['class'] = [];
$variables[$vote_type . '_attributes']['class'][] = 'rate-thumbs-up-down-btn-' . $vote_type;
// Add a class if the current user has voted on this item.
if ($variables['user_voted'] === $value) {
$variables[$vote_type . '_li_attributes']['class'][] = 'rate-voted';
}
if ($variables['use_ajax'] && !$variables['has_voted'] && $variables['can_vote']) {
$variables[$vote_type . '_attributes']['class'][] = 'use-ajax';
}
}
$variables['percent_attributes'] = new Attribute();
$variables['percent_attributes']['class'] = [];
$variables['percent_attributes']['class'][] = 'percent';
$total_votes = isset($variables['results']['updown']['vote_count']) ? $variables['results']['updown']['vote_count'] : 0;
$variables['up_votes'] = isset($variables['results']['updown']['rate_count_up']) ? $variables['results']['updown']['rate_count_up'] : 0;
$variables['down_votes'] = $total_votes - $variables['up_votes'];
if (!empty($total_votes)) {
$variables['up_percent'] = round($variables['up_votes'] / $total_votes * 100);
$variables['down_percent'] = round($variables['down_votes'] / $total_votes * 100);
}
else {
$variables['up_percent'] = 0;
$variables['down_percent'] = 0;
}
_rate_set_common_theme_variables($variables);
_rate_get_undo_link($variables);
$variables['#attached']['library'][] = 'rate/thumbs-up-down';
}
/**
* Implements hook_preprocess_HOOK() for rate-template-thumbs_up.html.twig.
*/
function template_preprocess_rate_template_thumbs_up(&$variables) {
$variables['up_attributes'] = new Attribute();
$variables['up_attributes']['class'] = [];
$variables['up_attributes']['class'][] = 'rate-thumbs-up-btn-up';
if ($variables['use_ajax'] && !$variables['has_voted'] && $variables['can_vote']) {
$variables['up_attributes']['class'][] = 'use-ajax';
}
$variables['score_attributes'] = new Attribute();
$variables['score_attributes']['class'] = [];
$variables['score_attributes']['class'][] = 'rate-score';
$variables['up_votes'] = isset($variables['results']['updown']['rate_count_up']) ? $variables['results']['updown']['rate_count_up'] : 0;
_rate_set_common_theme_variables($variables);
_rate_get_undo_link($variables);
$variables['#attached']['library'][] = 'rate/thumbs-up';
}
/**
* Implements hook_preprocess_HOOK() for rate-template-yes_no.html.twig.
*/
function template_preprocess_rate_template_yesno(&$variables) {
$vote_types = [
'yes' => '1',
'no' => '-1',
];
foreach ($vote_types as $vote_type => $value) {
$variables[$vote_type . '_li_attributes'] = new Attribute();
$variables[$vote_type . '_li_attributes']['class'] = [];
$variables[$vote_type . '_li_attributes']['class'][] = 'rate-' . $vote_type;
$variables[$vote_type . '_attributes'] = new Attribute();
$variables[$vote_type . '_attributes']['class'] = [];
$variables[$vote_type . '_attributes']['class'][] = 'rate-yesno-btn';
$variables[$vote_type . '_attributes']['class'][] = 'rate-' . $vote_type . '-btn';
// Add a class if the current user has voted on this item.
if ($variables['user_voted'] === $value) {
$variables[$vote_type . '_li_attributes']['class'][] = 'rate-voted';
}
if ($variables['use_ajax'] && !$variables['has_voted'] && $variables['can_vote']) {
$variables[$vote_type . '_attributes']['class'][] = 'use-ajax';
}
}
$variables['up_votes'] = isset($variables['results']['updown']['rate_count_up']) ? $variables['results']['updown']['rate_count_up'] : 0;
$variables['down_votes'] = isset($variables['results']['updown']['vote_count']) ? $variables['results']['updown']['vote_count'] - $variables['up_votes'] : 0;
$variables['score_attributes'] = new Attribute();
$variables['score_attributes']['class'] = [];
$variables['score_attributes']['class'][] = 'rate-yesno-votes';
_rate_set_common_theme_variables($variables, TRUE);
_rate_get_undo_link($variables);
$variables['#attached']['library'][] = 'rate/yesno';
}
/**
* Helper function to return an undo link.
*/
function _rate_get_undo_link(&$variables) {
if (!$variables['entity_id']) {
$variables['can_vote'] = FALSE;
return;
}
$variables['undo'] = '';
$variables['undo_attributes'] = new Attribute();
$variables['undo_attributes']['class'] = [];
$variables['undo_attributes']['class'][] = 'rate-undo-vote';
$undo_link_class = 'rate-undo';
if ($variables['use_ajax']) {
$undo_link_class .= ' use-ajax';
}
if ($variables['has_voted']) {
$variables['undo'] = Link::fromTextAndUrl(t('Undo'), Url::fromRoute('rate.undo_vote', [
'entity_type_id' => $variables['entity_type_id'],
'entity_id' => $variables['entity_id'],
'widget_type' => $variables['widget_type'],
'destination' => \Drupal::destination()
->getAsArray()['destination'],
], [
'attributes' => [
'class' => $undo_link_class,
],
]));
}
}
/**
* Helper function to set common themeing variables.
*/
function _rate_set_common_theme_variables(&$variables, $generate_links = TRUE) {
$destination = \Drupal::destination()
->getAsArray();
if (!$variables['entity_id']) {
$variables['can_vote'] = FALSE;
return;
}
if ($generate_links) {
$variables['up_url'] = Url::fromRoute('rate.vote', [
'entity_type_id' => $variables['entity_type_id'],
'vote_type_id' => 'updown',
'value' => 1,
'entity_id' => $variables['entity_id'],
'widget_type' => $variables['widget_type'],
'destination' => $destination['destination'],
]);
$variables['down_url'] = Url::fromRoute('rate.vote', [
'entity_type_id' => $variables['entity_type_id'],
'vote_type_id' => 'updown',
'value' => -1,
'entity_id' => $variables['entity_id'],
'widget_type' => $variables['widget_type'],
'destination' => $destination['destination'],
]);
}
$output['info_description'] = [
// @Todo: Add info and description to to settings form.
'#theme' => 'info_description',
'#info' => '',
'#description' => '',
];
$variables['destination'] = $destination['destination'];
$variables['widget_attributes'] = new Attribute();
$variables['widget_attributes']['data-drupal-selector'] = 'rate-' . $variables['entity_type_id'] . '-' . $variables['entity_id'];
$variables['widget_attributes']['class'] = [];
$class = str_ireplace('rate_template_', '', $variables['theme_hook_original']);
$variables['widget_attributes']['class'][] = 'rate-widget-' . str_ireplace('_', '-', $class);
}
/**
* Implements hook_ENTITY_TYPE_access().
*/
function rate_vote_type_access(EntityInterface $vote_type, $operation, AccountInterface $account) {
// If the user has the 'view rate results page' permission, we grant 'view'
// access to all of the vote_type configuration entities defined
// by the Rate module.
$rate_types = [
'updown',
'fivestar',
];
// Allow users with the permission 'view rate results page' to view metadata
// about any of the vote types provided by this module.
if (in_array($vote_type
->id(), $rate_types)) {
switch ($operation) {
case 'view':
return AccessResult::allowedIf($account
->hasPermission('view rate results page'))
->cachePerPermissions()
->cachePerUser();
default:
return AccessResult::neutral();
}
}
else {
return AccessResult::neutral();
}
}