You are here

class Fivestar in Fivestar 8

Provides a fivestar form element.

Plugin annotation

@FormElement("fivestar");

Hierarchy

Expanded class hierarchy of Fivestar

2 string references to 'Fivestar'
fivestar.info.yml in ./fivestar.info.yml
fivestar.info.yml
FivestarTestCase::getInfo in test/fivestar.field.test
2 #type uses of Fivestar
FivestarForm::buildForm in src/Form/FivestarForm.php
Form constructor.
StarsWidget::formElement in src/Plugin/Field/FieldWidget/StarsWidget.php
Returns the form for a single field widget.

File

src/Element/Fivestar.php, line 14

Namespace

Drupal\fivestar\Element
View source
class Fivestar extends FormElement {

  /**
   * {@inheritdoc}
   */
  public function getInfo() {
    $class = get_class($this);
    return [
      '#input' => TRUE,
      '#stars' => 5,
      '#allow_clear' => FALSE,
      '#allow_revote' => FALSE,
      '#allow_ownvote' => FALSE,
      '#ajax' => NULL,
      '#show_static_result' => FALSE,
      '#process' => [
        [
          $class,
          'process',
        ],
        [
          $class,
          'processAjaxForm',
        ],
      ],
      '#theme_wrappers' => [
        'form_element',
      ],
      '#widget' => [
        'name' => 'default',
      ],
      '#values' => [
        'vote_user' => 0,
        'vote_average' => 0,
        'vote_count' => 0,
      ],
      '#settings' => [
        'display_format' => 'average',
        'text_format' => 'none',
      ],
    ];
  }

  /**
   * Process callback: process fivestar element.
   */
  public static function process(array &$element, FormStateInterface $form_state, &$complete_form) {
    $settings = $element['#settings'];
    $values = $element['#values'];
    $class[] = 'clearfix';
    $title = 'it';
    if (isset($settings['entity_id']) && isset($settings['entity_type'])) {
      $entity_id = $settings['entity_id'];
      $entity_type = $settings['entity_type'];
      $entity_manager = \Drupal::entityTypeManager();
      $entity = $entity_manager
        ->getStorage($entity_type)
        ->load($entity_id);
      $title = $entity
        ->label();
    }
    elseif (isset($complete_form['#node'])) {
      $title = $complete_form['#node']->title;
    }
    $options = [
      '-' => t('Select rating'),
    ];
    for ($i = 1; $i <= $element['#stars']; $i++) {
      $this_value = ceil($i * 100 / $element['#stars']);
      $options[$this_value] = t('Give @title @star/@count', [
        '@title' => $title,
        '@star' => $i,
        '@count' => $element['#stars'],
      ]);
    }

    // Display clear button only if enabled.
    if ($element['#allow_clear'] == TRUE) {
      $options[0] = t('Cancel rating');
    }
    if (self::userCanVote($element)) {
      $element['vote'] = [
        '#type' => 'select',
        '#description' => self::getElementDescription($element),
        '#options' => $options,
        '#rating' => $values['vote_average'],
        '#required' => $element['#required'],
        '#attributes' => $element['#attributes'],
        '#default_value' => self::getElementDefaultValue($element),
        '#weight' => -2,
        '#ajax' => $element['#ajax'],
        '#parents' => isset($element['#parents']) ? $element['#parents'] : [],
      ];
    }
    else {
      $renderer = \Drupal::service('renderer');
      $static_stars = [
        '#theme' => 'fivestar_static',
        '#rating' => self::getElementDefaultValue($element),
        '#stars' => $element['#stars'],
        '#vote_type' => $element['#vote_type'],
        '#widget' => $element['#widget'],
      ];
      $element_static = [
        '#theme' => 'fivestar_static_element',
        '#star_display' => $renderer
          ->render($static_stars),
        '#title' => '',
        '#description' => self::getElementDescription($element),
      ];
      $element['vote_statistic'] = [
        '#type' => 'markup',
        '#markup' => $renderer
          ->render($element_static),
      ];
    }
    $class[] = "fivestar-{$settings['text_format']}-text";
    switch ($settings['display_format']) {
      case 'average':
        $class[] = 'fivestar-average-stars';
        break;
      case 'user':
        $class[] = 'fivestar-user-stars';
        break;
      case 'smart':
        $class[] = 'fivestar-smart-stars ' . ($values['vote_user'] ? 'fivestar-user-stars' : 'fivestar-average-stars');
        break;
      case 'dual':
        $class[] = 'fivestar-combo-stars';
        $static_average = [
          '#type' => 'fivestar_static',
          '#rating' => $values['vote_average'],
          '#stars' => $settings['stars'],
          '#vote_type' => $settings['vote_type'],
          '#widget' => $settings['widget'],
        ];
        if ($settings['text_format'] != 'none') {
          $static_description = [
            '#type' => 'fivestar_summary',
            '#average_rating' => $settings['text_format'] == 'user' ? NULL : (isset($values['vote_average']) ? $values['vote_average'] : 0),
            '#votes' => isset($values['vote_count']) ? $values['vote_count'] : 0,
            '#stars' => $settings['stars'],
          ];
        }
        else {
          $static_description = '&nbsp;';
        }
        $element_static = [
          '#type' => 'fivestar_static_element',
          '#title' => '',
          '#star_display' => $static_average,
          '#description' => $static_description,
        ];
        $element['average'] = [
          '#type' => 'markup',
          '#markup' => $element_static,
          '#weight' => -1,
        ];
        break;
    }
    $widget_name = mb_strtolower($element['#widget']['name']);
    $widget_name_kebab = str_replace('_', '-', $widget_name);
    $class[] = 'fivestar-form-item';
    $class[] = 'fivestar-' . $widget_name_kebab;
    if ($widget_name != 'default') {
      $element['#attached']['library'][] = \Drupal::service('fivestar.widget_manager')
        ->getWidgetLibrary($widget_name);
    }
    $element['#prefix'] = '<div ' . new Attribute([
      'class' => $class,
    ]) . '>';
    $element['#suffix'] = '</div>';
    $element['#attached']['library'][] = 'fivestar/fivestar.base';
    return $element;
  }

  /**
   * Return rating description.
   *
   * @param array $element
   *   Fivestar element data.
   *
   * @return array
   */
  public static function getElementDescription(array $element) {
    if (empty($element['#settings']['text_format']) || empty($element['#values'])) {
      return [];
    }
    $settings = $element['#settings'];
    $values = $element['#values'];
    $base_element_data = [
      '#theme' => 'fivestar_summary',
      '#stars' => $element['#stars'],
      '#microdata' => isset($settings['microdata']) ? $settings['microdata'] : NULL,
    ];
    switch ($settings['text_format']) {
      case 'user':
        return [
          '#user_rating' => $values['vote_user'],
          '#votes' => $settings['display_format'] == 'dual' ? NULL : $values['vote_count'],
        ] + $base_element_data;
      case 'average':
        return [
          '#average_rating' => $values['vote_average'],
          '#votes' => $values['vote_count'],
        ] + $base_element_data;
      case 'smart':
        return $settings['display_format'] == 'dual' && !$values['vote_user'] ? [] : [
          '#user_rating' => $values['vote_user'],
          '#average_rating' => $values['vote_user'] ? NULL : $values['vote_average'],
          '#votes' => $settings['display_format'] == 'dual' ? NULL : $values['vote_count'],
        ] + $base_element_data;
      case 'dual':
        return [
          '#user_rating' => $values['vote_user'],
          '#average_rating' => $settings['display_format'] == 'dual' ? NULL : $values['vote_average'],
          '#votes' => $settings['display_format'] == 'dual' ? NULL : $values['vote_count'],
        ] + $base_element_data;
      case 'none':
        return [];
    }
  }

  /**
   * Determines if a user can vote on content.
   *
   * @param array $element
   *   Fivestar element data.
   *
   * @return bool
   */
  public static function userCanVote(array $element) {
    if ($element['#show_static_result']) {
      return FALSE;
    }
    if ($element['#allow_revote']) {
      return TRUE;
    }

    // Check if user have votes in current entity type.
    $vote_ids = [];
    $current_user = \Drupal::currentUser();
    $entity_type = isset($element['#settings']['content_type']) ? $element['#settings']['content_type'] : NULL;
    $entity_id = isset($element['#settings']['content_id']) ? $element['#settings']['content_id'] : NULL;
    if (!$entity_type || !$entity_id) {
      $vote_ids = \Drupal::entityQuery('vote')
        ->condition('entity_type', $entity_type)
        ->condition('entity_id', $entity_id)
        ->condition('user_id', $current_user
        ->id())
        ->execute();
    }

    // If user voted before, return FALSE.
    if (empty($vote_ids)) {
      return FALSE;
    }

    // Check allowed own vote.
    if ($element['#allow_ownvote']) {
      return TRUE;
    }

    // Check that we have entity details, allow if not.
    if (!$entity_type || !$entity_id) {
      return TRUE;
    }
    $entity = \Drupal::entityTypeManager()
      ->getStorage($entity_type)
      ->load($entity_id);
    $owner_uid = $entity
      ->getOwner()
      ->id();
    return $owner_uid != $current_user
      ->id();
  }

  /**
   * Provides the correct default value for a fivestar element.
   *
   * @param array $element
   *   The fivestar element.
   *
   * @return float
   *   The default value for the element.
   */
  public static function getElementDefaultValue(array $element) {
    switch ($element['#settings']['display_format']) {
      case 'average':
        $widget_is_average = $element['#settings']['display_format'] == 'average';
        $default_value = $widget_is_average && !empty($element['#values']['vote_average']) ? $element['#values']['vote_average'] : $element['#default_value'];
        break;
      case 'user':
        $default_value = $element['#values']['vote_user'];
        break;
      case 'smart':
        $default_value = !empty($element['#values']['vote_user']) ? $element['#values']['vote_user'] : $element['#values']['vote_average'];
        break;
      case 'dual':
        $default_value = $element['#values']['vote_user'];
        break;
      default:
        $default_value = $element['#default_value'];
    }
    for ($i = 0; $i <= $element['#stars']; $i++) {
      $this_value = ceil($i * 100 / $element['#stars']);
      $next_value = ceil(($i + 1) * 100 / $element['#stars']);

      // Round up the default value to the next exact star value if needed.
      if ($this_value < $default_value && $next_value > $default_value) {
        $default_value = $next_value;
      }
    }
    return $default_value;
  }

  /**
   * {@inheritdoc}
   */
  public static function valueCallback(&$element, $input, FormStateInterface $form_state) {
    return $input;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property An array of entity type IDs keyed by the property name of their storages.
DependencySerializationTrait::$_serviceIds protected property An array of service IDs keyed by property name used for serialization.
DependencySerializationTrait::__sleep public function 1
DependencySerializationTrait::__wakeup public function 2
Fivestar::getElementDefaultValue public static function Provides the correct default value for a fivestar element.
Fivestar::getElementDescription public static function Return rating description.
Fivestar::getInfo public function Returns the element properties for this element. Overrides ElementInterface::getInfo
Fivestar::process public static function Process callback: process fivestar element.
Fivestar::userCanVote public static function Determines if a user can vote on content.
Fivestar::valueCallback public static function Determines how user input is mapped to an element's #value property. Overrides FormElement::valueCallback
FormElement::processAutocomplete public static function Adds autocomplete functionality to elements.
FormElement::processPattern public static function #process callback for #pattern form element property.
FormElement::validatePattern public static function #element_validate callback for #pattern form element property.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
PluginBase::__construct public function Constructs a \Drupal\Component\Plugin\PluginBase object. 92
RenderElement::preRenderAjaxForm public static function Adds Ajax information about an element to communicate with JavaScript.
RenderElement::preRenderGroup public static function Adds members of this group as actual elements for rendering.
RenderElement::processAjaxForm public static function Form element processing handler for the #ajax form property. 1
RenderElement::processGroup public static function Arranges elements into groups.
RenderElement::setAttributes public static function Sets a form element's class attribute. Overrides ElementInterface::setAttributes
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.