views_handler_field_date.inc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. <?php
  2. /**
  3. * @file
  4. * Definition of views_handler_field_date.
  5. */
  6. /**
  7. * A handler to provide proper displays for dates.
  8. *
  9. * This may be used on table fields that hold either UNIX timestamps or SQL
  10. * datetime strings.
  11. *
  12. * @ingroup views_field_handlers
  13. */
  14. class views_handler_field_date extends views_handler_field {
  15. /**
  16. * {@inheritdoc}
  17. */
  18. public function option_definition() {
  19. $options = parent::option_definition();
  20. $options['date_format'] = array('default' => 'small');
  21. $options['custom_date_format'] = array('default' => '');
  22. $options['second_date_format_custom'] = array('default' => '');
  23. $options['second_date_format'] = array('default' => 'small');
  24. $options['timezone'] = array('default' => '');
  25. return $options;
  26. }
  27. /**
  28. * {@inheritdoc}
  29. */
  30. public function options_form(&$form, &$form_state) {
  31. $date_formats = array();
  32. $date_types = system_get_date_types();
  33. foreach ($date_types as $key => $value) {
  34. $date_formats[$value['type']] = t('@date_format format', array('@date_format' => $value['title'])) . ': ' . format_date(REQUEST_TIME, $value['type']);
  35. }
  36. $form['date_format'] = array(
  37. '#type' => 'select',
  38. '#title' => t('Date format'),
  39. '#options' => $date_formats + array(
  40. 'custom' => t('Custom'),
  41. 'raw time ago' => t('Time ago'),
  42. 'time ago' => t('Time ago (with "ago" appended)'),
  43. 'today time ago' => t('Time ago (with "ago" appended) for today\'s date, but not for other dates'),
  44. 'raw time hence' => t('Time hence'),
  45. 'time hence' => t('Time hence (with "hence" appended)'),
  46. 'raw time span' => t('Time span (future dates have "-" prepended)'),
  47. 'inverse time span' => t('Time span (past dates have "-" prepended)'),
  48. 'time span' => t('Time span (with "ago/hence" appended)'),
  49. ),
  50. '#default_value' => isset($this->options['date_format']) ? $this->options['date_format'] : 'small',
  51. );
  52. $form['custom_date_format'] = array(
  53. '#type' => 'textfield',
  54. '#title' => t('Custom date format'),
  55. '#description' => t('If "Custom", see the <a href="@url" target="_blank">PHP manual</a> for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.', array('@url' => 'http://php.net/manual/function.date.php')),
  56. '#default_value' => isset($this->options['custom_date_format']) ? $this->options['custom_date_format'] : '',
  57. '#dependency' => array(
  58. 'edit-options-date-format' => $this->supported_date_types(),
  59. ),
  60. );
  61. $form['second_date_format'] = array(
  62. '#type' => 'select',
  63. '#title' => t('Second date format'),
  64. '#options' => $date_formats + array(
  65. 'custom' => t('Custom'),
  66. ),
  67. '#description' => t('The date format which will be used for rendering dates other than today.'),
  68. '#default_value' => isset($this->options['second_date_format']) ? $this->options['second_date_format'] : 'small',
  69. '#dependency' => array(
  70. 'edit-options-date-format' => array('today time ago'),
  71. ),
  72. );
  73. $form['second_date_format_custom'] = array(
  74. '#type' => 'textfield',
  75. '#title' => t('Custom date format of second date'),
  76. '#description' => t('If "Custom" is selected in "Second date format", see the <a href="@url" target="_blank">PHP manual</a> for date formats. Otherwise, enter the number of different time units to display, which defaults to 2.', array('@url' => 'http://php.net/manual/function.date.php')),
  77. '#default_value' => isset($this->options['second_date_format_custom']) ? $this->options['second_date_format_custom'] : '',
  78. // We have to use states instead of ctools dependency because dependency
  79. // doesn't handle multiple conditions.
  80. '#states' => array(
  81. 'visible' => array(
  82. '#edit-options-date-format' => array('value' => 'today time ago'),
  83. '#edit-options-second-date-format' => array('value' => 'custom'),
  84. ),
  85. ),
  86. // We have to use ctools dependency too because states doesn't add the
  87. // correct left margin to the element's wrapper.
  88. '#dependency' => array(
  89. // This condition is handled by form API's states.
  90. // 'edit-options-date-format' => array('today time ago'),
  91. 'edit-options-second-date-format' => array('custom'),
  92. ),
  93. );
  94. $form['timezone'] = array(
  95. '#type' => 'select',
  96. '#title' => t('Timezone'),
  97. '#description' => t('Timezone to be used for date output.'),
  98. '#options' => array(
  99. '' => t('- Default site/user timezone -'),
  100. ) + system_time_zones(FALSE),
  101. '#default_value' => $this->options['timezone'],
  102. '#dependency' => array(
  103. 'edit-options-date-format' => array_merge(array('custom'), array_keys($date_formats)),
  104. ),
  105. );
  106. parent::options_form($form, $form_state);
  107. }
  108. /**
  109. * Provide a list of all of the supported standard date types.
  110. *
  111. * @return array
  112. * The list of supported formats.
  113. */
  114. private function supported_date_types() {
  115. return array(
  116. 'custom',
  117. 'raw time ago',
  118. 'time ago',
  119. 'today time ago',
  120. 'raw time hence',
  121. 'time hence',
  122. 'raw time span',
  123. 'time span',
  124. 'raw time span',
  125. 'inverse time span',
  126. 'time span',
  127. );
  128. }
  129. /**
  130. * {@inheritdoc}
  131. */
  132. public function render($values) {
  133. $value = $this->get_value($values);
  134. if (!is_numeric($value)) {
  135. // If the value isn't numeric, assume it's an SQL DATETIME.
  136. $value = strtotime($value);
  137. }
  138. $format = $this->options['date_format'];
  139. if (in_array($format, $this->supported_date_types())) {
  140. $custom_format = $this->options['custom_date_format'];
  141. }
  142. if ($value) {
  143. $timezone = !empty($this->options['timezone']) ? $this->options['timezone'] : NULL;
  144. // Will be positive for a datetime in the past (ago), and negative for a
  145. // datetime in the future (hence).
  146. $time_diff = REQUEST_TIME - $value;
  147. switch ($format) {
  148. case 'raw time ago':
  149. return format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2);
  150. case 'time ago':
  151. $t_args = array(
  152. '%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2),
  153. );
  154. return t('%time ago', $t_args);
  155. case 'today time ago':
  156. $second_format = $this->options['second_date_format'];
  157. $second_custom_format = $this->options['second_date_format_custom'];
  158. if (format_date(REQUEST_TIME, 'custom', 'Y-m-d', $timezone) == format_date($value, 'custom', 'Y-m-d', $timezone)) {
  159. return t('%time ago', array('%time' => format_interval($time_diff, is_numeric($custom_format) ? $custom_format : 2)));
  160. }
  161. elseif ($second_format == 'custom') {
  162. if ($second_custom_format == 'r') {
  163. return format_date($value, $second_format, $second_custom_format, $timezone, 'en');
  164. }
  165. return format_date($value, $second_format, $second_custom_format, $timezone);
  166. }
  167. else {
  168. return format_date($value, $this->options['second_date_format'], '', $timezone);
  169. }
  170. case 'raw time hence':
  171. return format_interval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2);
  172. case 'time hence':
  173. return t('%time hence', array('%time' => format_interval(-$time_diff, is_numeric($custom_format) ? $custom_format : 2)));
  174. case 'raw time span':
  175. return ($time_diff < 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
  176. case 'inverse time span':
  177. return ($time_diff > 0 ? '-' : '') . format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2);
  178. case 'time span':
  179. return t(($time_diff < 0 ? '%time hence' : '%time ago'), array('%time' => format_interval(abs($time_diff), is_numeric($custom_format) ? $custom_format : 2)));
  180. case 'custom':
  181. if ($custom_format == 'r') {
  182. return format_date($value, $format, $custom_format, $timezone, 'en');
  183. }
  184. return format_date($value, $format, $custom_format, $timezone);
  185. default:
  186. return format_date($value, $format, '', $timezone);
  187. }
  188. }
  189. }
  190. }