diff --git a/core/modules/datetime/datetime.views.inc b/core/modules/datetime/datetime.views.inc index 84ade9b..eb25cb2 100644 --- a/core/modules/datetime/datetime.views.inc +++ b/core/modules/datetime/datetime.views.inc @@ -21,10 +21,16 @@ function datetime_field_views_data(FieldStorageConfigInterface $field_storage) { // Create year, month, and day arguments. $group = $data[$table_name][$field_storage->getName() . '_value']['group']; - foreach (array('year', 'month', 'day') as $argument_type) { + $arguments = array( + // Argument type => help text. + 'year' => t('Date in the form of YYYY.'), + 'month' => t('Date in the form of MM.'), + 'day' => t('Date in the form of DD.'), + ); + foreach ($arguments as $argument_type => $help_text) { $data[$table_name][$field_storage->getName() . '_value_' . $argument_type] = array( 'title' => $field_storage->getLabel() . ' (' . $argument_type . ')', - 'help' => t('Date in the form of YYYY.'), + 'help' => $help_text, 'argument' => array( 'field' => $field_storage->getName() . '_value', 'id' => 'datetime_' . $argument_type, @@ -32,6 +38,9 @@ function datetime_field_views_data(FieldStorageConfigInterface $field_storage) { 'group' => $group, ); } + + // Set the 'datetime' sort handler. + $data[$table_name][$field_storage->getName() . '_value']['sort']['id'] = 'datetime'; } return $data; diff --git a/core/modules/datetime/src/Plugin/views/sort/Date.php b/core/modules/datetime/src/Plugin/views/sort/Date.php new file mode 100644 index 0000000..3e0c804 --- /dev/null +++ b/core/modules/datetime/src/Plugin/views/sort/Date.php @@ -0,0 +1,46 @@ +tableAlias.$this->realField"; + } + + /** + * Override query to provide 'second' granularity. + */ + public function query() { + $this->ensureMyTable(); + switch ($this->options['granularity']) { + case 'second': + $formula = $this->getDateFormat('YmdHis'); + $this->query->addOrderBy(NULL, $formula, $this->options['order'], $this->tableAlias . '_' . $this->field . '_' . $this->options['granularity']); + return; + } + + // All other granularities are handled by the numeric sort handler. + parent::query(); + } + +} diff --git a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php index 4f4791d..b12db6d 100644 --- a/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php +++ b/core/modules/datetime/src/Tests/Views/DateTimeHandlerTestBase.php @@ -44,9 +44,6 @@ public function setUp() { parent::setUp(); - // Load test views. - ViewTestData::createTestViews(get_class($this), array('datetime_test')); - // Add a date field to page nodes. $node_type = entity_create('node_type', array( 'type' => 'page', @@ -57,7 +54,7 @@ public function setUp() { 'field_name' => static::$field_name, 'entity_type' => 'node', 'type' => 'datetime', - 'settings' => array('datetime_type' => 'date'), + 'settings' => array('datetime_type' => 'datetime'), )); $fieldStorage->save(); $field = entity_create('field_config', array( @@ -74,6 +71,9 @@ public function setUp() { $this->map = array( 'nid' => 'nid', ); + + // Load test views. + ViewTestData::createTestViews(get_class($this), array('datetime_test')); } } diff --git a/core/modules/datetime/src/Tests/Views/SortDateTimeTest.php b/core/modules/datetime/src/Tests/Views/SortDateTimeTest.php new file mode 100644 index 0000000..348aa27 --- /dev/null +++ b/core/modules/datetime/src/Tests/Views/SortDateTimeTest.php @@ -0,0 +1,99 @@ +nodes[] = $this->drupalCreateNode(array( + 'field_date' => array( + 'value' => $date, + ) + )); + } + } + + /** + * Tests the datetime sort handler. + */ + public function testDateTimeSort() { + $field = static::$field_name . '_value'; + $view = Views::getView('test_sort_datetime'); + + // Sort order is DESC. + $view->initHandlers(); + $view->sort[$field]->options['granularity'] = 'minute'; + $view->setDisplay('default'); + $this->executeView($view); + $expected_result = array( + array('nid' => $this->nodes[0]->id()), + array('nid' => $this->nodes[3]->id()), + array('nid' => $this->nodes[2]->id()), + array('nid' => $this->nodes[1]->id()), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Check ASC. + $view->initHandlers(); + $field = static::$field_name . '_value'; + $view->sort[$field]->options['order'] = 'ASC'; + $view->setDisplay('default'); + $this->executeView($view); + $expected_result = array( + array('nid' => $this->nodes[1]->id()), + array('nid' => $this->nodes[2]->id()), + array('nid' => $this->nodes[3]->id()), + array('nid' => $this->nodes[0]->id()), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + + // Change granularity to 'year', and the secondary node ID order should + // define the order of nodes with the same year. + $view->initHandlers(); + $view->sort[$field]->options['granularity'] = 'year'; + $view->sort[$field]->options['order'] = 'DESC'; + $view->setDisplay('default'); + $this->executeView($view); + $expected_result = array( + array('nid' => $this->nodes[0]->id()), + array('nid' => $this->nodes[1]->id()), + array('nid' => $this->nodes[2]->id()), + array('nid' => $this->nodes[3]->id()), + ); + $this->assertIdenticalResultset($view, $expected_result, $this->map); + $view->destroy(); + } + +} diff --git a/core/modules/datetime/tests/modules/datetime_test/test_views/views.view.test_sort_datetime.yml b/core/modules/datetime/tests/modules/datetime_test/test_views/views.view.test_sort_datetime.yml new file mode 100644 index 0000000..eca398a --- /dev/null +++ b/core/modules/datetime/tests/modules/datetime_test/test_views/views.view.test_sort_datetime.yml @@ -0,0 +1,59 @@ +langcode: und +status: true +dependencies: + module: + - node +id: test_sort_datetime +label: '' +module: views +description: '' +tag: '' +base_table: node +base_field: nid +core: '8' +display: + default: + display_options: + access: + type: none + cache: + type: none + exposed_form: + type: basic + fields: + nid: + field: nid + id: nid + table: node + plugin_id: node + sorts: + field_date_value: + field: field_date_value + id: field_date_value + relationship: none + table: node__field_date + order: DESC + plugin_id: datetime + id: + field: nid + id: nid + order: ASC + relationship: none + table: node + plugin_id: numeric + pager: + type: full + query: + options: + query_comment: false + type: views_query + style: + type: default + row: + type: fields + field_langcode: '***LANGUAGE_language_content***' + field_langcode_add_to_query: null + display_plugin: default + display_title: Master + id: default + position: 0