Skip to content

Instantly share code, notes, and snippets.

@mattschaff
Last active March 1, 2023 15:58
Show Gist options
  • Save mattschaff/f8329913caad1b3507232434acc5fd00 to your computer and use it in GitHub Desktop.
Save mattschaff/f8329913caad1b3507232434acc5fd00 to your computer and use it in GitHub Desktop.
Drupal 8: Custom Views Filter by Open Now (also dependency injection in plugin)
<?php
namespace Drupal\my_module\Plugin\views\filter;
use Drupal\Core\Form\FormStateInterface;
use Drupal\views\Plugin\views\filter\FilterPluginBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Database\Driver\mysql\Connection;
/**
* @ViewsFilter("open_now_filter")
*/
class ExampleOpenNowFilter extends FilterPluginBase implements ContainerFactoryPluginInterface {
private $database;
/**
* Constructor
*
* @param array $configuration
* @param [type] $plugin_id
* @param [type] $plugin_definition
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, Connection $database) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->database = $database;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('database')
);
}
/**
* {@inheritdoc}
*/
public function query() {
// Get current day and time, paying respect to timezone.
// Set appropriate timezone.
$config = \Drupal::config('system.date');
$config_data_default_timezone = $config->get('timezone.default');
date_default_timezone_set($config_data_default_timezone);
// Time at midnight today
$time = time();
$time_at_midnight = $time - ($time - strtotime("today"));
// Current day.
$now_day_of_week = date('w');
// Seconds since midnight.
$seconds_since_midnight = $time - $time_at_midnight;
// Run Open Now query.
// Get paragraph IDs where field day is today.
// Join inner w/ paragraph IDs where field time from is before and time to is after time.
// Then get service NIDs w/ these paragraph IDs.
$query = $this->database->select('paragraph__field_day', 'd');
$query->join('paragraph__field_time', 't', 't.entity_id = d.entity_id');
$query->join('node__field_schedule', 's', 's.field_schedule_target_id = t.entity_id');
$result = $query
->fields('s', ['entity_id'])
->condition('d.field_day_value', $now_day_of_week)
->condition('t.field_time_from', $seconds_since_midnight, '<=')
->condition('t.field_time_to', $seconds_since_midnight, '>=')
->execute()
->fetchAllKeyed(0,0);
// Add where clause to view query.
$this->query->addWhere('AND', 'node_field_data.nid', $result, 'IN');
}
protected function valueForm(&$form, FormStateInterface $form_state) {
if ($exposed = $form_state->get('exposed')) {
$filter_form_type = 'checkbox';
}
else {
$filter_form_type = 'radios';
}
$form['value'] = [
'#type' => $filter_form_type,
'#title' => $this->t('Open Now'),
'#options' => [0 => $this->t('Open Now'), 1 => $this->t('Closed')],
'#default_value' => 0,
];
}
}
<?php
/**
* Implements hook_views_data_alter().
*/
function my_module_views_data_alter(&$data) {
// Add Open Now Filter.
$data['node']['open_now_filter'] = [
'title' => t('Open Now filter'),
'filter' => [
'title' => t('Open Now filter'),
'help' => 'filters services based on whether service is open now',
'field' => 'nid',
'id' => 'open_now_filter',
]
];
}
@mattschaff
Copy link
Author

@kbrinner works without it, but adding that is definitely better form. I'll update -- thank you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment