recurring_events-2.0.x-dev/modules/recurring_events_registration/src/Plugin/views/filter/EventInstanceRegistrationAvailability.php

modules/recurring_events_registration/src/Plugin/views/filter/EventInstanceRegistrationAvailability.php
<?php

declare(strict_types=1);

namespace Drupal\recurring_events_registration\Plugin\views\filter;

use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Attribute\ViewsFilter;
use Drupal\views\Plugin\views\filter\FilterPluginBase;

/**
 * Filter handler to show the availability of registrations for event instances.
 *
 * @ingroup views_filter_handlers
 */
#[ViewsFilter(
  id: "eventinstance_registration_availability",
)]
class EventInstanceRegistrationAvailability extends FilterPluginBase {

  /**
   * Stores all operations which are available on the form.
   *
   * @var array
   */
  protected $valueOptions = NULL;

  /**
   * {@inheritdoc}
   */
  public function canExpose() {
    return TRUE;
  }

  /**
   * {@inheritdoc}
   */
  protected function canBuildGroup() {
    return FALSE;
  }

  /**
   * {@inheritdoc}
   */
  public function adminSummary() {
    if ($this->isAGroup()) {
      return $this->t('grouped');
    }
    if (!empty($this->options['exposed'])) {
      return $this->t('exposed');
    }
    return $this->options['value'];
  }

  /**
   * {@inheritdoc}
   */
  protected function defineOptions() {
    $options = parent::defineOptions();
    $options['available'] = [
      'default' => 'available',
    ];
    return $options;
  }

  /**
   * {@inheritdoc}
   */
  public function getValueOptions() {
    if (isset($this->valueOptions)) {
      return $this->valueOptions;
    }
    $this->valueOptions = [
      'available' => $this->t('Spaces Available'),
      'full' => $this->t('Event Full'),
    ];
    return $this->valueOptions;
  }

  /**
   * {@inheritdoc}
   */
  public function buildOptionsForm(&$form, FormStateInterface $form_state) {
    parent::buildOptionsForm($form, $form_state);

    $default_value = (array) $this->value;

    $exposed = $form_state->get('exposed');
    if ($exposed) {
      if (empty($default_value)) {
        $keys = array_keys($this->getValueOptions());
        $default_value = array_shift($keys);
      }
      else {
        $copy = $default_value;
        $default_value = array_shift($copy);
      }
    }

    if (!$this->isExposed()) {
      $form['value'] = [
        '#title' => $this->t('Availability.'),
        '#type' => 'select',
        '#options' => $this->getValueOptions(),
        '#default_value' => $default_value,
      ];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function valueForm(&$form, FormStateInterface $form_state) {
    parent::valueForm($form, $form_state);

    $default_value = (array) $this->value;

    $exposed = $form_state->get('exposed');
    if ($exposed) {
      if (empty($default_value)) {
        $keys = array_keys($this->getValueOptions());
        $default_value = array_shift($keys);
      }
      else {
        $copy = $default_value;
        $default_value = array_shift($copy);
      }
    }

    if ($this->isExposed()) {
      $form['value'] = [
        '#title' => $this->t('Availability.'),
        '#type' => 'select',
        '#options' => $this->getValueOptions(),
        '#default_value' => $default_value,
      ];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function query() {
    // Set -1 as the default value so that if no events match the checks, then
    // we should get no results, rather than all results.
    $items = ['-1'];
    $table = $this->ensureMyTable();

    // Grab the current view being executed.
    $view = clone $this->query->view;
    $filters = $view->filter;
    // Remove any instances of this filter from the filters.
    if (!empty($filters)) {
      foreach ($filters as $key => $filter) {
        if ($filter instanceof EventInstanceRegistrationAvailability) {
          unset($view->filter[$key]);
        }
      }
    }
    // Execute the current view with the filters removed, so we can reduce the
    // number of event instances we need to examine to find their availability.
    // This makes the query more efficient and avoids having to do messy union
    // selects across multiple tables to determine the availability of an event.
    $view->preExecute();
    $view->execute();

    $available = $this->value;
    if (is_array($available)) {
      $available = reset($this->value);
    }

    if (!empty($view->result)) {
      foreach ($view->result as $key => $result) {
        $availability = $result->_entity->get('availability_count')->getValue()[0]['value'] ?? -1;

        switch ($available) {
          // Filtering for available events means unlimited availability of an
          // availability greater than zero.
          case 'available':
            if ($availability === -1 || $availability > 0) {
              $items[] = $result->_entity->id();
            }
            break;

          // Filtering for full events means an event with exactly zero
          // availability.
          case 'full':
            if ($availability == 0) {
              $items[] = $result->_entity->id();
            }
            break;
        }
      }
    }

    // Filter this view by the events which match the availability above.
    $items = implode(',', $items);
    $this->query->addWhereExpression($this->options['group'], "$table.id IN (" . $items . ")");
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc