Change the sorting of a view in Drupal 8

Site has moved

This site has moved to a new location. Visit the new site at http://programsdream.nl.

By Ronald van Belzen | February 10, 2017

The situation that required this solution was a view on nodes in which duplicate titles occurred frequently.

Instead of just sorting the list of nodes in the view by the title or the creation date, the sorting on title needed a secundary sorting field. For this I needed to implement the hook "hook_views_query_alter" in the file "mymodule.views_execution.inc" as shown below.

<?php

use Drupal\views\Plugin\views\query\QueryPluginBase;
use Drupal\views\ViewExecutable;

/**
 * Implements hook_views_query_alter().
 *
 * Order by title and created when order by title is requested.
 */
function mymodule_views_query_alter(ViewExecutable $view, QueryPluginBase $query) {
  if ($view->id() == 'my_view_id') {
    if ($query->orderby[0]['field'] == 'node_field_data.title') {
      $query->orderby[1]['field'] = 'node_field_data.created';
      $query->orderby[1]['direction'] = 'DESC';
    }
  }
}

I had some problems getting it to work. Fortunately, a test script made me realize that the hook function needed to placed in the above mentioned ".inc" file. And the test reminded me of the fact that the function parameters are not arrays, as would be the case in Drupal 7, but objects. For that reason you should not use '&$view' nor '&$query' as you would do in Drupal 7, which I did at first. After a cache rebuild the hook does its work by adding the second sorting criteria on the created field when the title field was clicked for the view with id "my_view_id".