Let's assume there is a requirement where we need to filter node content for a given year. We can achieve this by creating a views exposed filter that will filter node content for the selected year.
In this post, I am using the module named "custom_views_filter" for demonstration purposes.
We will create a custom_views_filter.module file and add the 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 the filter with the views plugin. Now create the views plugin filter.
Create a folder called Plugin/view/filter under the src folder and add a file named ContentYearViewsFilter.php, then add the 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, '<=');
}
}
}
- Log in to post comments