diff --git a/.idea/oliverdavies-uk.iml b/.idea/oliverdavies-uk.iml index 488833a..1664e07 100644 --- a/.idea/oliverdavies-uk.iml +++ b/.idea/oliverdavies-uk.iml @@ -4,6 +4,8 @@ + + diff --git a/.idea/php-test-framework.xml b/.idea/php-test-framework.xml new file mode 100644 index 0000000..ac3134f --- /dev/null +++ b/.idea/php-test-framework.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/php.xml b/.idea/php.xml index b312881..6d17c06 100644 --- a/.idea/php.xml +++ b/.idea/php.xml @@ -142,4 +142,9 @@ + + + + + \ No newline at end of file diff --git a/config/default/core.extension.yml b/config/default/core.extension.yml index c295b27..152347a 100644 --- a/config/default/core.extension.yml +++ b/config/default/core.extension.yml @@ -38,6 +38,7 @@ module: migrate_plus: 0 migrate_tools: 0 node: 0 + opd_talks: 0 page_cache: 0 path: 0 path_alias: 0 diff --git a/config/default/views.view.talks.yml b/config/default/views.view.talks.yml index 7714f22..44397ff 100644 --- a/config/default/views.view.talks.yml +++ b/config/default/views.view.talks.yml @@ -8,6 +8,7 @@ dependencies: - system.menu.main module: - node + - opd_talks - user id: talks label: Talks @@ -141,21 +142,20 @@ display: operator_limit_selection: false operator_list: { } sorts: - created: - id: created + event_sort: + id: event_sort table: node_field_data - field: created - order: DESC - entity_type: node - entity_field: created - plugin_id: date + field: event_sort relationship: none group_type: group admin_label: '' + order: ASC exposed: false expose: label: '' granularity: second + entity_type: node + plugin_id: event_sort title: Talks header: { } footer: { } diff --git a/web/modules/custom/custom/tests/modules/custom_test/config/install/views.view.talks.yml b/web/modules/custom/custom/tests/modules/custom_test/config/install/views.view.talks.yml new file mode 100644 index 0000000..e05fb2b --- /dev/null +++ b/web/modules/custom/custom/tests/modules/custom_test/config/install/views.view.talks.yml @@ -0,0 +1,197 @@ +langcode: en +status: true +dependencies: + config: + - core.entity_view_mode.node.teaser + - node.type.talk + - system.menu.main + module: + - node + - opd_talks + - user +id: talks +label: Talks +module: views +description: '' +tag: '' +base_table: node_field_data +base_field: nid +display: + default: + display_plugin: default + id: default + display_title: Master + position: 0 + display_options: + access: + type: perm + options: + perm: 'access content' + cache: + type: tag + options: { } + query: + type: views_query + options: + disable_sql_rewrite: false + distinct: false + replica: false + query_comment: '' + query_tags: { } + exposed_form: + type: basic + options: + submit_button: Apply + reset_button: false + reset_button_label: Reset + exposed_sorts_label: 'Sort by' + expose_sort_order: true + sort_asc_label: Asc + sort_desc_label: Desc + pager: + type: none + options: + items_per_page: 0 + offset: 0 + style: + type: html_list + options: + row_class: '' + default_row_class: true + uses_fields: false + type: ul + wrapper_class: '' + class: space-y-8 + row: + type: 'entity:node' + options: + view_mode: teaser + fields: + title: + id: title + table: node_field_data + field: title + entity_type: node + entity_field: title + label: '' + alter: + alter_text: false + make_link: false + absolute: false + trim: false + word_boundary: false + ellipsis: false + strip_tags: false + html: false + hide_empty: false + empty_zero: false + settings: + link_to_entity: true + plugin_id: field + relationship: none + group_type: group + admin_label: '' + exclude: false + element_type: '' + element_class: '' + element_label_type: '' + element_label_class: '' + element_label_colon: true + element_wrapper_type: '' + element_wrapper_class: '' + element_default_classes: true + empty: '' + hide_alter_empty: true + click_sort_column: value + type: string + group_column: value + group_columns: { } + group_rows: true + delta_limit: 0 + delta_offset: 0 + delta_reversed: false + delta_first_last: false + multi_type: separator + separator: ', ' + field_api_classes: false + filters: + status: + value: '1' + table: node_field_data + field: status + plugin_id: boolean + entity_type: node + entity_field: status + id: status + expose: + operator: '' + operator_limit_selection: false + operator_list: { } + group: 1 + type: + id: type + table: node_field_data + field: type + value: + talk: talk + entity_type: node + entity_field: type + plugin_id: bundle + expose: + operator_limit_selection: false + operator_list: { } + sorts: + event_sort: + id: event_sort + table: node_field_data + field: event_sort + relationship: none + group_type: group + admin_label: '' + order: ASC + exposed: false + expose: + label: '' + granularity: second + entity_type: node + plugin_id: event_sort + title: Talks + header: { } + footer: { } + empty: { } + relationships: { } + arguments: { } + display_extenders: { } + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } + page_1: + display_plugin: page + id: page_1 + display_title: Page + position: 1 + display_options: + display_extenders: { } + path: talks + menu: + type: normal + title: Talks + description: '' + expanded: false + parent: '' + weight: -48 + context: '0' + menu_name: main + cache_metadata: + max-age: -1 + contexts: + - 'languages:language_content' + - 'languages:language_interface' + - 'user.node_grants:view' + - user.permissions + tags: { } diff --git a/web/modules/custom/custom/tests/src/Kernel/TalksTestBase.php b/web/modules/custom/custom/tests/src/Kernel/TalksTestBase.php index 90b0d94..b272b29 100644 --- a/web/modules/custom/custom/tests/src/Kernel/TalksTestBase.php +++ b/web/modules/custom/custom/tests/src/Kernel/TalksTestBase.php @@ -12,6 +12,8 @@ use Drupal\paragraphs\ParagraphInterface; abstract class TalksTestBase extends EntityKernelTestBase { + protected $strictConfigSchema = FALSE; + /** * {@inheritDoc} */ diff --git a/web/modules/custom/opd_talks/opd_talks.info.yml b/web/modules/custom/opd_talks/opd_talks.info.yml new file mode 100644 index 0000000..a1b07e3 --- /dev/null +++ b/web/modules/custom/opd_talks/opd_talks.info.yml @@ -0,0 +1,5 @@ +name: Oliver Davies Talks +description: Custom code for talks pages. +type: module +core_version_requirement: ^8 || ^9 +package: Custom diff --git a/web/modules/custom/opd_talks/opd_talks.module b/web/modules/custom/opd_talks/opd_talks.module new file mode 100644 index 0000000..9b237e7 --- /dev/null +++ b/web/modules/custom/opd_talks/opd_talks.module @@ -0,0 +1,23 @@ + t('Custom event sort'), + 'group' => t('Content'), + 'help' => t('Sort events by past/future, then distance from now.'), + 'sort' => [ + 'field' => 'created', + 'id' => 'event_sort', + ] + ]; +} diff --git a/web/modules/custom/opd_talks/src/Plugin/views/sort/Event.php b/web/modules/custom/opd_talks/src/Plugin/views/sort/Event.php new file mode 100644 index 0000000..e65dc51 --- /dev/null +++ b/web/modules/custom/opd_talks/src/Plugin/views/sort/Event.php @@ -0,0 +1,40 @@ +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" + ); + } + +} diff --git a/web/modules/custom/opd_talks/tests/src/Kernel/TalksPageSortTest.php b/web/modules/custom/opd_talks/tests/src/Kernel/TalksPageSortTest.php new file mode 100644 index 0000000..169b512 --- /dev/null +++ b/web/modules/custom/opd_talks/tests/src/Kernel/TalksPageSortTest.php @@ -0,0 +1,35 @@ +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); + } + +}