datetime_range.module 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <?php
  2. /**
  3. * @file
  4. * Field hooks to implement a datetime field that stores a start and end date.
  5. */
  6. use Drupal\Core\Url;
  7. use Drupal\Core\Routing\RouteMatchInterface;
  8. use Drupal\views\Views;
  9. use Drupal\views\ViewEntityInterface;
  10. /**
  11. * Implements hook_help().
  12. */
  13. function datetime_range_help($route_name, RouteMatchInterface $route_match) {
  14. switch ($route_name) {
  15. case 'help.page.datetime_range':
  16. $output = '';
  17. $output .= '<h3>' . t('About') . '</h3>';
  18. $output .= '<p>' . t('The Datetime Range module provides a Date field that stores start dates and times, as well as end dates and times. See the <a href=":field">Field module help</a> and the <a href=":field_ui">Field UI module help</a> pages for general information on fields and how to create and manage them. For more information, see the <a href=":datetime_do">online documentation for the Datetime Range module</a>.', [':field' => Url::fromRoute('help.page', ['name' => 'field'])->toString(), ':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#', ':datetime_do' => 'https://www.drupal.org/documentation/modules/datetime_range']) . '</p>';
  19. $output .= '<h3>' . t('Uses') . '</h3>';
  20. $output .= '<dl>';
  21. $output .= '<dt>' . t('Managing and displaying date fields') . '</dt>';
  22. $output .= '<dd>' . t('The <em>settings</em> and the <em>display</em> of the Date field can be configured separately. See the <a href=":field_ui">Field UI help</a> for more information on how to manage fields and their display.', [':field_ui' => (\Drupal::moduleHandler()->moduleExists('field_ui')) ? Url::fromRoute('help.page', ['name' => 'field_ui'])->toString() : '#']) . '</dd>';
  23. $output .= '<dt>' . t('Displaying dates') . '</dt>';
  24. $output .= '<dd>' . t('Dates can be displayed using the <em>Plain</em> or the <em>Default</em> formatter. The <em>Plain</em> formatter displays the date in the <a href="http://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> format. If you choose the <em>Default</em> formatter, you can choose a format from a predefined list that can be managed on the <a href=":date_format_list">Date and time formats</a> page.', [':date_format_list' => Url::fromRoute('entity.date_format.collection')->toString()]) . '</dd>';
  25. $output .= '</dl>';
  26. return $output;
  27. }
  28. }
  29. /**
  30. * Implements hook_ENTITY_TYPE_presave().
  31. *
  32. * When a view is saved using the old string or standard plugin format for
  33. * Datetime Range filters or sorts, they will automatically be updated to
  34. * Datetime filters or sorts. Old plugins usage must to be considered
  35. * deprecated and must be converted before 9.0.0, when this updating layer will
  36. * be removed.
  37. *
  38. * @deprecated in drupal:8.5.0 and is removed from drupal:9.0.0.
  39. *
  40. * @see https://www.drupal.org/node/2857691
  41. */
  42. function datetime_range_view_presave(ViewEntityInterface $view) {
  43. $config_factory = \Drupal::configFactory();
  44. $displays = $view->get('display');
  45. $changed = FALSE;
  46. foreach ($displays as $display_name => &$display) {
  47. // Update datetime_range filters.
  48. if (isset($display['display_options']['filters'])) {
  49. foreach ($display['display_options']['filters'] as $field_name => &$filter) {
  50. if ($filter['plugin_id'] === 'string') {
  51. $table_data = Views::viewsData()->get($filter['table']);
  52. if (!$table_data) {
  53. continue;
  54. }
  55. // Get field config.
  56. $filter_views_data = $table_data[$filter['field']]['filter'];
  57. if (!isset($filter_views_data['entity_type']) || !isset($filter_views_data['field_name'])) {
  58. continue;
  59. }
  60. $field_storage_name = 'field.storage.' . $filter_views_data['entity_type'] . '.' . $filter_views_data['field_name'];
  61. $field_configuration = $config_factory->get($field_storage_name);
  62. if ($field_configuration->get('type') === 'daterange') {
  63. // Set entity_type if missing.
  64. if (!isset($filter['entity_type'])) {
  65. $filter['entity_type'] = $filter_views_data['entity_type'];
  66. }
  67. // Set datetime plugin_id.
  68. $filter['plugin_id'] = 'datetime';
  69. // Create datetime value array.
  70. $datetime_value = [
  71. 'min' => '',
  72. 'max' => '',
  73. 'value' => $filter['value'],
  74. 'type' => 'date',
  75. ];
  76. // Map string operator/value to numeric equivalent.
  77. switch ($filter['operator']) {
  78. case '=':
  79. case 'empty':
  80. case 'not empty':
  81. $operator = $filter['operator'];
  82. break;
  83. case '!=':
  84. case 'not':
  85. $operator = '!=';
  86. break;
  87. case 'starts':
  88. $operator = 'regular_expression';
  89. $datetime_value['value'] = '^' . preg_quote($datetime_value['value']);
  90. break;
  91. case 'ends':
  92. $operator = 'regular_expression';
  93. $datetime_value['value'] = preg_quote($datetime_value['value']) . '$';
  94. break;
  95. default:
  96. $operator = 'regular_expression';
  97. // Add .* to prevent blank regexes.
  98. if (empty($datetime_value['value'])) {
  99. $datetime_value['value'] = '.*';
  100. }
  101. else {
  102. $datetime_value['value'] = preg_quote($datetime_value['value']);
  103. }
  104. }
  105. // Set value and operator.
  106. $filter['value'] = $datetime_value;
  107. $filter['operator'] = $operator;
  108. $changed = TRUE;
  109. @trigger_error('Use of string filters for datetime_range fields is deprecated. Use the datetime filters instead. See https://www.drupal.org/node/2857691', E_USER_DEPRECATED);
  110. }
  111. }
  112. }
  113. }
  114. // Update datetime_range sort handlers.
  115. if (isset($display['display_options']['sorts'])) {
  116. foreach ($display['display_options']['sorts'] as $field_name => &$sort) {
  117. if ($sort['plugin_id'] === 'standard') {
  118. $table_data = Views::viewsData()->get($sort['table']);
  119. if (!$table_data) {
  120. continue;
  121. }
  122. // Get field config.
  123. $sort_views_data = $table_data[$sort['field']]['sort'];
  124. if (!isset($sort_views_data['entity_type']) || !isset($sort_views_data['field_name'])) {
  125. continue;
  126. }
  127. $field_storage_name = 'field.storage.' . $sort_views_data['entity_type'] . '.' . $sort_views_data['field_name'];
  128. $field_configuration = $config_factory->get($field_storage_name);
  129. if ($field_configuration->get('type') === 'daterange') {
  130. // Set entity_type if missing.
  131. if (!isset($sort['entity_type'])) {
  132. $sort['entity_type'] = $sort_views_data['entity_type'];
  133. }
  134. // Set datetime plugin_id.
  135. $sort['plugin_id'] = 'datetime';
  136. $changed = TRUE;
  137. @trigger_error('Use of standard sort handlers for datetime_range fields is deprecated. Use the datetime sort handlers instead. See https://www.drupal.org/node/2857691', E_USER_DEPRECATED);
  138. }
  139. }
  140. }
  141. }
  142. }
  143. if ($changed) {
  144. $view->set('display', $displays);
  145. }
  146. }