rate.module in Rate 8.2
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\Session\AccountInterface;
use Drupal\Core\Template\Attribute;
use Drupal\node\NodeInterface;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\core\Entity\EntityTypeInterface;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\views\ViewExecutable;
use Drupal\field\Entity\FieldConfig;
/**
* Implements hook_entity_extra_field_info().
*/
function rate_entity_extra_field_info() {
$extra = [];
// Rate widgets pseudo fields definitions.
$widgets = \Drupal::service('entity_type.manager')
->getStorage('rate_widget')
->loadMultiple();
$field_manager = \Drupal::service('entity_field.manager');
// No need to continue without widgets.
if (empty($widgets)) {
return $extra;
}
$comment_module_enabled = \Drupal::service('module_handler')
->moduleExists('comment');
if ($comment_module_enabled) {
/** @var \Drupal\comment\CommentManagerInterface $comment_manager */
$comment_manager = \Drupal::service('comment.manager');
}
foreach ($widgets as $widget => $widget_variables) {
$entities = $widget_variables
->get('entity_types');
$comments = $widget_variables
->get('comment_types');
if ($entities && count($entities) > 0) {
foreach ($entities as $id => $entity) {
$parameter = explode('.', $entity);
$widget_name = 'rate_' . $widget;
$widget_label = 'Rate ' . $widget_variables
->label();
$extra[$parameter[0]][$parameter[1]]['display'][$widget_name] = [
// Create a label based on the rate widget name (duplicates are OK).
'label' => $widget_label,
'description' => t('Displays the rate voting widget assigned to this entity.'),
'weight' => 100,
'visible' => TRUE,
];
}
}
if ($comment_module_enabled && $comments && count($comments) > 0) {
foreach ($comments as $id => $comment) {
$parameter = explode('.', $comment);
$fields = $comment_manager
->getFields($parameter[0]);
$field_definitions = $field_manager
->getFieldDefinitions($parameter[0], $parameter[1]);
foreach ($fields as $fid => $field) {
if (in_array($parameter[1], $field['bundles'])) {
$comment_settings = $field_definitions[$fid]
->getFieldStorageDefinition()
->get('settings');
$comment_type = $comment_settings['comment_type'];
$widget_name = 'rate_comment_' . $widget;
$widget_label = 'Rate comment ' . $widget_variables
->label();
$extra['comment'][$comment_type]['display'][$widget_name] = [
// Create a label from the rate widget name (duplicates are OK).
'label' => $widget_label,
'description' => t('Displays the rate voting widget assigned to this entity.'),
'weight' => 100,
'visible' => TRUE,
];
}
}
}
}
}
return $extra;
}
/**
* Implements hook_entity_view().
*/
function rate_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
// Rate widgets definitions.
$display_components = $display
->getComponents();
$widgets = \Drupal::service('entity_type.manager')
->getStorage('rate_widget');
$rate_widget_base_service = \Drupal::service('rate.vote_widget_base');
$entity_type = $entity
->getEntityTypeId();
$entity_bundle = $entity
->bundle();
$entity_id = $entity
->id();
foreach ($display_components as $component => $component_settings) {
// Check if we have a comment or node related widget.
if (substr($component, 0, 5) == 'rate_') {
if (substr($component, 0, 13) == 'rate_comment_') {
// This is for comments.
$widget_name = substr($component, 13);
}
elseif (substr($component, 0, 5) == 'rate_') {
// This is for nodes.
$widget_name = substr($component, 5);
}
else {
return;
}
// Generate the voting form for each widget.
$generate_widget = FALSE;
$widget = $widgets
->load($widget_name);
// Leftover rate extra field - core issue in #2903746 and #2903745.
if (!$widget) {
// Delete the leftover rate extra field.
$display
->removeComponent($component)
->save();
}
else {
$entities_enabled = $widget
->get('entity_types');
$comments_enabled = $widget
->get('comment_types');
}
// Generate the form only if the widget is enabled in the config entity.
if (isset($entities_enabled) && count($entities_enabled) > 0 && $entity_type != 'comment') {
if (in_array($entity_type . '.' . $entity_bundle, $entities_enabled)) {
$generate_widget = TRUE;
}
}
if (isset($comments_enabled) && count($comments_enabled) > 0 && $entity_type == 'comment') {
if (in_array($entity
->getCommentedEntityTypeId() . '.' . $entity
->getCommentedEntity()
->bundle(), $comments_enabled)) {
$generate_widget = TRUE;
}
}
if ($widget && $generate_widget === TRUE) {
$widget_template = $widget
->get('template');
$value_type = $widget
->get('value_type') ? $widget
->get('value_type') : 'percent';
$settings = $widget;
$vote_type = $widget_template == 'fivestar' ? $widget_template : 'updown';
$form = $rate_widget_base_service
->getForm($entity_type, $entity_bundle, $entity_id, $vote_type, $value_type, $widget_name, $settings);
$form_container = [
'rating' => [
'#theme' => 'container',
'#attributes' => [
'class' => [
'rate-widget',
$widget_template,
],
],
'#children' => [
'form' => $form,
],
],
'#attached' => [
'library' => [
'rate/unvote-helper',
'rate/w-' . $widget_template,
],
],
];
if (isset($build[$component])) {
array_unshift($build[$component], $form_container);
}
else {
$build[$component][] = $form_container;
}
$build['#cache']['tags'][] = 'vote:' . $entity
->bundle() . ':' . $entity
->id();
// Create a date field in each linked content entity (node).
// This field allows voting until the date set by the user.
// "Use deadline" must be checked in the widget voting settings.
$voting_settings = $widget
->get('voting');
$use_deadline = isset($voting_settings['use_deadline']) ? $voting_settings['use_deadline'] : 0;
if ($entity_type == 'node' && $use_deadline == 1) {
$field_name = 'field_rate_vote_deadline';
// Create the field to hold the date, if it does not exist yet.
if (empty($rate_date_storage = FieldStorageConfig::loadByName($entity_type, $field_name))) {
$rate_date_storage = FieldStorageConfig::create([
'field_name' => $field_name,
'langcode' => 'en',
'status' => TRUE,
'dependencies' => [
'module' => [
'datetime',
$entity_type,
],
],
'entity_type' => $entity_type,
'type' => 'datetime',
'settings' => [
'datetime_type' => 'date',
],
'module' => 'datetime',
'locked' => FALSE,
'cardinality' => 1,
'translatable' => TRUE,
'persist_with_no_fields' => TRUE,
'custom_storage' => FALSE,
])
->save();
}
// Add the field to the entity, which has the rate widget enabled.
if (empty($rate_date_field = FieldConfig::loadByName($entity_type, $entity_bundle, $field_name))) {
$rate_date_field = FieldConfig::create([
'field_name' => $field_name,
'field_type' => 'datetime',
'langcode' => 'en',
'status' => TRUE,
'dependencies' => [
'config' => [
'field.storage.' . $entity_type . '.' . $field_name,
$entity_type . '.type.' . $entity_bundle,
],
'module' => [
'datetime',
],
],
'entity_type' => $entity_type,
'bundle' => $entity_bundle,
'label' => 'Rate vote deadline',
'description' => '',
'required' => FALSE,
'translatable' => FALSE,
'default_value' => [
'default_date_type' => 'now',
'default_date' => 'now',
],
])
->save();
}
// Add the rate date field to the form mode of the entity in question.
/** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $display_repository */
$display_repository = \Drupal::service('entity_display.repository');
// Assign widget settings for the default form mode.
$display_repository
->getFormDisplay($entity_type, $entity_bundle)
->setComponent($field_name, [
'weight' => 300,
])
->save();
}
}
}
}
}
/**
* 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);
}
// Rate widgets settings - disable results if no widgets enabled on node.
$entity_type_id = $node
->getEntityTypeId();
$bundle = $node
->bundle();
$widgets = \Drupal::service('entity_type.manager')
->getStorage('rate_widget')
->loadMultiple();
if (!empty($widgets)) {
$enabled_widgets = 0;
foreach ($widgets as $widget => $widget_variables) {
$entities = $widget_variables
->get('entity_types');
$comments = $widget_variables
->get('comment_types');
if ($entities && count($entities) > 0) {
foreach ($entities as $id => $entity) {
// Check if at least one widget is enabled.
if ($entity == $entity_type_id . '.' . $bundle) {
$enabled_widgets++;
}
}
}
}
// Unset the results tab if no widgets linked to this node bundle.
if ($enabled_widgets == 0) {
unset($data['tabs'][0]['rate.node_results_page']);
}
}
}
}
/**
* Implements hook_theme().
*/
function rate_theme($existing, $type, $theme, $path) {
return [
// Rate widgets theme.
'rate_widgets_summary' => [
'variables' => [
'results' => [],
'vote' => NULL,
'rate_widget' => NULL,
'widget_template' => NULL,
'disabled' => FALSE,
'deadline_disabled' => FALSE,
],
],
'rate_widget' => [
'template' => 'rate-widget',
'render element' => 'form',
],
'form_element__rating' => [
'base hook' => 'form_element',
],
];
}
/**
* 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();
}
}
/**
* Implements hook_entity_type_build().
*/
function rate_entity_type_build(array &$entity_types) {
// Enables the RateWidgetBaseForm for the vote entity.
$entity_types['vote']
->setFormClass('rate_vote', 'Drupal\\rate\\Form\\RateWidgetBaseForm');
}
/**
* Implements hook_entity_base_field_info().
*/
function rate_entity_base_field_info(EntityTypeInterface $entity_type) {
// Add the rate_widget as a base field.
// @ToDo: Need to run drush entity:update - update rate.install instead.
if ($entity_type
->id() == 'vote') {
$fields = [];
$fields['rate_widget'] = BaseFieldDefinition::create('string')
->setLabel(t('Rate widget'))
->setName('rate_widget')
->setRevisionable(FALSE)
->setCustomStorage(FALSE)
->setRequired(FALSE)
->setDescription(t('Holds the Rate field name.'))
->setPropertyConstraints('value', [
'Length' => [
'max' => FieldStorageConfig::NAME_MAX_LENGTH,
],
]);
return $fields;
}
}
/**
* Implements hook_theme_suggestions_alter().
*/
function rate_theme_suggestions_alter(array &$suggestions, array $variables, $hook) {
if ($hook == 'rate_widgets_summary') {
$entity = $variables['vote'];
$content = \Drupal::service('entity_type.manager')
->getStorage($entity
->getVotedEntityType())
->load($entity
->getVotedEntityId());
$plugin = \Drupal::service('entity_type.manager')
->getStorage('rate_widget')
->load($entity->rate_widget->value)
->get('template');
$suggestions[] = $hook . '__' . $plugin;
$suggestions[] = $hook . '__' . $plugin . '__' . $entity->rate_widget->value;
// During undo we don't have the entity anymore that the vote was cast on.
if (isset($content)) {
$suggestions[] = $hook . '__' . $plugin . '__' . $content
->getEntityTypeId();
$suggestions[] = $hook . '__' . $plugin . '__' . $content
->getEntityTypeId() . '__' . $content
->bundle() . '__' . $entity->rate_widget->value;
$suggestions[] = $hook . '__' . $plugin . '__' . $content
->getEntityTypeId() . '__' . $content
->bundle();
}
}
}
/**
* Implements hook_preprocess_HOOK() for rate-widget.html.twig.
*/
function template_preprocess_rate_widget(&$variables) {
$variables['widget_template'] = $variables['form']['#widget_template'];
$variables['display_settings'] = $variables['form']['#display_settings'];
$variables['results_settings'] = $variables['form']['#results_settings'];
$label_class = isset($variables['display_settings']['label_class']) ? $variables['display_settings']['label_class'] : '';
$description_class = isset($variables['display_settings']['description_class']) ? $variables['display_settings']['description_class'] : '';
$variables['label_attributes'] = new Attribute();
$variables['label_attributes']['class'] = [];
$variables['label_attributes']['class'][] = $label_class;
if (isset($variables['display_settings']['label_position']) && $variables['display_settings']['label_position'] == 'above') {
if ($variables['display_settings']['description_position'] == 'right' && $variables['results_settings']['result_position'] == 'right') {
$variables['label_attributes']['colspan'] = [];
$variables['label_attributes']['colspan'][] = 3;
}
elseif ($variables['display_settings']['description_position'] == 'right' || $variables['results_settings']['result_position'] == 'right') {
$variables['label_attributes']['colspan'] = [];
$variables['label_attributes']['colspan'][] = 2;
}
}
$variables['description_attributes'] = new Attribute();
$variables['description_attributes']['class'] = [];
$variables['description_attributes']['class'][] = $description_class;
if (isset($variables['results_settings']['result_position']) && $variables['results_settings']['result_position'] == 'below') {
if ($variables['display_settings']['description_position'] && $variables['display_settings']['description_position'] == 'right') {
$variables['result_attributes'] = new Attribute();
$variables['result_attributes']['colspan'] = [];
$variables['result_attributes']['colspan'][] = 2;
}
}
}
/**
* Implements hook_theme_suggestions_HOOK_alter().
*/
function rate_theme_suggestions_form_element_alter(array &$suggestions, array $variables) {
if ($variables['element']['#type'] == 'radio' && isset($variables['element']['#attributes']['twig-suggestion'])) {
if ($variables['element']['#attributes']['twig-suggestion'] == 'rating-input') {
$suggestions[] = 'form_element__rating';
}
}
}
/**
* Implements hook_preprocess_HOOK() for form-element--rating.html.twig.
*/
function template_preprocess_form_element__rating(&$variables) {
$element = $variables['element'];
$variables['option_result'] = isset($element['#option_result']) ? $element['#option_result'] : '';
$variables['label_attributes'] = isset($element['#label_attributes']) ? $element['#label_attributes'] : '';
$variables['title'] = isset($element['#title']) ? $element['#title'] : '';
$variables['children'] = isset($element['#children']) ? $element['#children'] : '';
}
/**
* Implements hook_views_pre_render().
*/
function rate_views_pre_render(ViewExecutable $view) {
// Used for the blocks, which show the results of rate widget votings.
// Currently used for nodes.
if (in_array($view
->id(), [
'rate_widgets_results',
])) {
if (in_array($view->current_display, [
'node_summary_block',
])) {
$widget_id = $view->args[2];
$widget = \Drupal::service('entity_type.manager')
->getStorage('rate_widget')
->load($widget_id);
$options = isset($widget) ? $widget
->get('options') : [];
$template = isset($widget) ? $widget
->get('template') : '';
$labels = [];
// Add missing options if not all options were used to vote.
if (isset($view->total_rows) && $view->total_rows < count($options) && $view->total_rows > 0) {
$options = $template == 'fivestar' ? array_reverse($options) : $options;
foreach ($options as $key => $option) {
$new_row = new $view->result[0]();
$new_row->_entity = $view->result[0]->_entity;
// Set the variables.
$new_row->index = $key;
$new_row->votingapi_vote_value = $options[$key]['value'];
$new_row->votingapi_vote_value_1 = 0;
$new_row->node_field_data_votingapi_vote_nid = $view->result[0]->node_field_data_votingapi_vote_nid;
$temp[$key] = $new_row;
}
foreach ($view->result as $key => $value) {
$vote_value = $value->votingapi_vote_value;
$temp_key = array_search($vote_value, array_column($temp, 'votingapi_vote_value'));
if (isset($temp_key)) {
$temp[$temp_key] = $value;
}
}
$view->result = $temp;
}
foreach ($view->result as $row_num => $row_data) {
// Remove the empty rows.
$vote_value = $row_data->_entity
->getValue();
if ($vote_value == 0) {
unset($view->result[$row_num]);
$view->total_rows = $view->total_rows - 1;
}
else {
$vote_value = $row_data->votingapi_vote_value;
$option_key = array_search($vote_value, array_column($options, 'value'));
$row_data->votingapi_vote_value = (string) $options[$option_key]['label'];
}
}
}
}
}
/**
* Implements hook_rate_templates().
*/
function rate_rate_templates() {
$templates = [];
$templates['custom'] = new stdClass();
$templates['custom']->value_type = '';
$templates['custom']->options = [
[],
];
$templates['custom']->customizable = TRUE;
$templates['custom']->translate = TRUE;
$templates['custom']->template_title = t('Custom');
$templates['thumbsup'] = new stdClass();
$templates['thumbsup']->value_type = 'points';
$templates['thumbsup']->options = [
[
'value' => 1,
'label' => 'up',
],
];
$templates['thumbsup']->customizable = FALSE;
$templates['thumbsup']->translate = TRUE;
$templates['thumbsup']->template_title = t('Thumbs up');
$templates['thumbsupdown'] = new stdClass();
$templates['thumbsupdown']->value_type = 'points';
$templates['thumbsupdown']->options = [
[
'value' => 1,
'label' => 'up',
],
[
'value' => -1,
'label' => 'down',
],
];
$templates['thumbsupdown']->customizable = FALSE;
$templates['thumbsupdown']->translate = TRUE;
$templates['thumbsupdown']->template_title = t('Thumbs up / down');
$templates['numberupdown'] = new stdClass();
$templates['numberupdown']->value_type = 'points';
$templates['numberupdown']->options = [
[
'value' => 1,
'label' => 'up',
],
[
'value' => -1,
'label' => 'down',
],
];
$templates['numberupdown']->customizable = FALSE;
$templates['numberupdown']->translate = TRUE;
$templates['numberupdown']->template_title = t('Number up / down');
$templates['fivestar'] = new stdClass();
$templates['fivestar']->value_type = 'percent';
$templates['fivestar']->options = [
[
'value' => 0,
'label' => '1',
],
[
'value' => 25,
'label' => '2',
],
[
'value' => 50,
'label' => '3',
],
[
'value' => 75,
'label' => '4',
],
[
'value' => 100,
'label' => '5',
],
];
$templates['fivestar']->customizable = TRUE;
$templates['fivestar']->translate = FALSE;
$templates['fivestar']->template_title = t('Fivestar');
$templates['emotion'] = new stdClass();
$templates['emotion']->value_type = 'option';
$templates['emotion']->options = [
[
'value' => 1,
'label' => 'funny',
],
[
'value' => 2,
'label' => 'mad',
],
[
'value' => 3,
'label' => 'angry',
],
];
$templates['emotion']->customizable = TRUE;
$templates['emotion']->translate = TRUE;
$templates['emotion']->template_title = t('Emotion');
$templates['yesno'] = new stdClass();
$templates['yesno']->value_type = 'option';
$templates['yesno']->options = [
[
'value' => 1,
'label' => 'yes',
],
[
'value' => 2,
'label' => 'no',
],
];
$templates['yesno']->customizable = TRUE;
$templates['yesno']->translate = TRUE;
$templates['yesno']->template_title = t('Yes / No');
return $templates;
}
/**
* Implements hook_library_info_alter().
*/
function rate_library_info_alter(&$libraries, $extension) {
if ($extension === 'rate') {
$config = \Drupal::config('rate.settings');
if ($config
->get('disable_fontawesome')) {
foreach ($libraries as $library_key => $library) {
if (isset($library['dependencies'])) {
foreach ($library['dependencies'] as $key => $dependency) {
if ($dependency === 'rate/fontawesome') {
unset($libraries[$library_key]['dependencies'][$key]);
}
}
}
}
}
}
}
Functions
Name![]() |
Description |
---|---|
rate_entity_base_field_info | Implements hook_entity_base_field_info(). |
rate_entity_extra_field_info | Implements hook_entity_extra_field_info(). |
rate_entity_type_build | Implements hook_entity_type_build(). |
rate_entity_view | Implements hook_entity_view(). |
rate_library_info_alter | Implements hook_library_info_alter(). |
rate_menu_local_tasks_alter | Implements hook_menu_local_tasks_alter(). |
rate_rate_templates | Implements hook_rate_templates(). |
rate_theme | Implements hook_theme(). |
rate_theme_suggestions_alter | Implements hook_theme_suggestions_alter(). |
rate_theme_suggestions_form_element_alter | Implements hook_theme_suggestions_HOOK_alter(). |
rate_views_pre_render | Implements hook_views_pre_render(). |
rate_vote_type_access | Implements hook_ENTITY_TYPE_access(). |
template_preprocess_form_element__rating | Implements hook_preprocess_HOOK() for form-element--rating.html.twig. |
template_preprocess_rate_widget | Implements hook_preprocess_HOOK() for rate-widget.html.twig. |