Drupal views create exposed filter programmatically

Lets assume there is requirement where we need to create a views exposed filter that will filter node content for the selected year.

Here I am going to create a module with name custom_views_filter for demonstration

Create custom_views_filter.module file and add below code


    /**
     * Implements hook_views_data_alter().
     */
    function custom_views_filter_views_data_alter(array &$data) {
      $data['node']['year_filter'] = [
        'title' => t('Year'),
        'filter' => [
          'title' => t('Year'),
          'help' => t('Provides a custom filter for nodes to search yearly.'),
          'id' => 'year_views_filter',
        ],
      ];
    }
  

This will register filter with views plugin, now create views plugin filter.

Create folder Plugin/view/filter under src folder and add file with name ContentYearViewsFilter.php, then add below code:


    namespace Drupal\custom_views_filter\Plugin\views\filter;

    use Drupal\Core\Datetime\DrupalDateTime;
    use Drupal\views\Plugin\views\display\DisplayPluginBase;
    use Drupal\views\Plugin\views\filter\InOperator;
    use Drupal\views\ViewExecutable;

    /**
     * Filter content yearly.
     *
     * @ingroup views_filter_handlers
     *
     * @ViewsFilter("year_views_filter")
     */
    class ContentYearViewsFilter extends InOperator {

      /**
       * The current display.
       *
       * @var string
       *   The current display of the view.
       */
      protected $currentDisplay;

      /**
       * {@inheritdoc}
       */
      public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) {
        parent::init($view, $display, $options);
        $this->valueTitle = t('Year');
        $this->definition['options callback'] = [$this, 'generateOptions'];
        $this->currentDisplay = $view->current_display;
      }

      /**
       * Helper function to generates options.
       *
       * @return array
       *   An array of options.
       */
      public function generateOptions(): array {
        $keys = range(date("Y"), date("Y") - 5);
        $values = range(date("Y"), date("Y") - 5);
        return array_combine($keys, $values);
      }

      /**
       * Helper function to builds the query.
       */
      public function query() {
        if (!empty($this->value)) {
          // Start date like 2021-01-01.
          $start_date_timestamp = DrupalDateTime::createFromArray([
            'year' => $this->value[0],
            'month' => 1,
            'day' => 1,
          ])->getTimestamp();
          // End date like 2021-12-31.
          $start_end_timestamp = DrupalDateTime::createFromArray([
            'year' => $this->value[0],
            'month' => 12,
            'day' => 31,
          ])->getTimestamp();
          $this->query->addWhere('AND', 'node_field_data.created', $this->value, '>=');
          $this->query->addWhere('AND', 'node_field_data.created', $start_end_timestamp, '<=');
        }
      }
    }
  

Comments

Popular posts from this blog

How to setup Drupal 8 Multisite on nginx webserver with different domain.

Install drush globally using composer on WSL