Show upcoming talks in chronological order

Update the ordering of the future talks on the talks page so that
upcoming talks are shown in chronological order (soonest first),
followed by past talks in reverse chronological order (most recent
first).

This still uses the `created` date for ordering, which is updated
automatically on saving the node to match the furthest future talk, but
I may want to move that into a custom node property at some point.

Fixes #140
This commit is contained in:
Oliver Davies 2020-06-26 01:49:47 +01:00
parent b71f8cc7f8
commit 58d56220de
11 changed files with 331 additions and 7 deletions

View file

@ -0,0 +1,5 @@
name: Oliver Davies Talks
description: Custom code for talks pages.
type: module
core_version_requirement: ^8 || ^9
package: Custom

View file

@ -0,0 +1,23 @@
<?php
/**
* @file
* Custom code for talks pages.
*/
declare(strict_types=1);
/**
* Implements hook_views_data_alter().
*/
function opd_talks_views_data_alter(array &$data): void {
$data['node_field_data']['event_sort'] = [
'title' => t('Custom event sort'),
'group' => t('Content'),
'help' => t('Sort events by past/future, then distance from now.'),
'sort' => [
'field' => 'created',
'id' => 'event_sort',
]
];
}

View file

@ -0,0 +1,40 @@
<?php
declare(strict_types=1);
namespace Drupal\opd_talks\Plugin\views\sort;
use Drupal\Core\Datetime\DrupalDateTime;
use Drupal\datetime\DateTimeComputed;
use Drupal\views\Plugin\views\sort\Date;
use Drupal\views\Annotation\ViewsSort;
/**
* @ViewsSort("event_sort")
*/
final class Event extends Date {
public function query() {
$this->ensureMyTable();
$currentTime = time();
$dateAlias = "$this->tableAlias.$this->realField";
// Is this event in the past?
$this->query->addOrderBy(
NULL,
sprintf("%d > %s", $currentTime, $dateAlias),
$this->options['order'],
"in_past"
);
// How far in the past/future is this event?
$this->query->addOrderBy(
NULL,
sprintf('ABS(%s - %d)', $dateAlias, $currentTime),
$this->options['order'],
"distance_from_now"
);
}
}

View file

@ -0,0 +1,35 @@
<?php
declare(strict_types=1);
namespace Drupal\Tests\opd_talks\Kernel;
use Carbon\Carbon;
use Drupal\Tests\custom\Kernel\TalksTestBase;
use Drupal\views\ResultRow;
final class TalksPageSortTest extends TalksTestBase {
public static $modules = [
'views',
'opd_talks',
];
/**
* @test
*/
public function upcoming_talks_are_shown_first_followed_by_past_talks_and_ordered_by_distance() {
$this->createTalk(['created' => Carbon::parse('+4 days')->getTimestamp()]);
$this->createTalk(['created' => Carbon::parse('-2 days')->getTimestamp()]);
$this->createTalk(['created' => Carbon::parse('+1 days')->getTimestamp()]);
$this->createTalk(['created' => Carbon::parse('-10 days')->getTimestamp()]);
$talkIds = array_map(
fn(ResultRow $row) => (int) $row->_entity->id(),
views_get_view_result('talks')
);
$this->assertSame([3, 1, 2, 4], $talkIds);
}
}