Change record status: 
Project: 
Introduced in branch: 
8.5.x
Description: 

In order to better handle dates in the various SQL backends, date handling has been separated out to a new service \Drupal\views\Plugin\views\query\DateSqlInterface, with separate implementations for MySQL, PostgreSQL, and SQLite.

The \Drupal\views\Plugin\views\query\Sql::__construct() method now takes an additional argument, $date_sql:

  /**
   * Constructs a Sql object.
   *
   * @param array $configuration
   *   A configuration array containing information about the plugin instance.
   * @param string $plugin_id
   *   The plugin_id for the plugin instance.
   * @param mixed $plugin_definition
   *   The plugin implementation definition.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\views\Plugin\views\query\DateSqlInterface $date_sql
   *   The database-specific date handler.
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, DateSqlInterface $date_sql) {

Three classes are provided that implement this interface

  • Drupal\views\Plugin\views\query\MysqlDateSql
  • Drupal\views\Plugin\views\query\PostgresqlDateSql
  • Drupal\views\Plugin\views\query\SqliteDateSql

These classes should not be used outside of the Views SQL query plugin.

The views.date_sql service is tagged as backend_overridable, and provides the default implementation for MySQL. To create a service for a new database type, create a class that implements DateSqlInterface, and create a service definition with the appropriate name, eg

  mongodb.views.date_sql:
    class: Drupal\mongodb\Plugin\views\query\MongoDBDateSql
    arguments: ['@database']
    public: false

The Drupal\views\Plugin\views\query\QueryPluginBase class has two new methods:

  • setTimezoneOffset()
  • getTimezoneOffset()

and the signature for getDateField() has been updated with two optional parameters:

  /**
   * {@inheritdoc}
   */
  public function getDateField($field, $string_date = FALSE, $calculate_offset = TRUE) {
    $field = $this->dateSql->getDateField($field, $string_date);
    if ($calculate_offset && $offset = $this->getTimezoneOffset()) {
      $this->setFieldTimezoneOffset($field, $offset);
    }
    return $field;
  }
Impacts: 
Module developers