date.theme 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. <?php
  2. /**
  3. * @file
  4. * Theme functions.
  5. */
  6. /**
  7. * @addtogroup themeable
  8. * @{
  9. *
  10. * Formatter themes
  11. */
  12. /**
  13. * Returns HTML for a date element formatted as a Start/End combination.
  14. *
  15. * $entity->date_id
  16. * If set, this will show only an individual date on a field with
  17. * multiple dates. The value should be a string that contains
  18. * the following values, separated with periods:
  19. * - module name of the module adding the item
  20. * - node nid
  21. * - field name
  22. * - delta value of the field to be displayed
  23. * - other information the module's custom theme might need
  24. *
  25. * Used by the calendar module and available for other uses.
  26. * example: 'date.217.field_date.3.test'
  27. *
  28. * $entity->date_repeat_show
  29. * If true, tells the theme to show all the computed values of a repeating
  30. * date. If not true or not set, only the start date and the repeat rule
  31. * will be displayed.
  32. *
  33. * $dates['format']
  34. * The format string used on these dates
  35. * $dates['value']['local']['object']
  36. * The local date object for the Start date
  37. * $dates['value2']['local']['object']
  38. * The local date object for the End date
  39. * $dates['value']['local']['datetime']
  40. * The datetime value of the Start date database (GMT) value
  41. * $dates['value2']['local']['datetime']
  42. * The datetime value of the End date database (GMT) value
  43. * $dates['value']['formatted']
  44. * Formatted Start date, i.e. 'February 15, 2007 2:00 pm';
  45. * $dates['value']['formatted_date']
  46. * Only the date part of the formatted Start date
  47. * $dates['value']['formatted_time']
  48. * Only the time part of the formatted Start date
  49. * $dates['value2']['formatted']
  50. * Formatted End date, i.e. 'February 15, 2007 6:00 pm';
  51. * $dates['value2']['formatted_date']
  52. * Only the date part of the formatted End date
  53. * $dates['value2']['formatted_time']
  54. * Only the time part of the formatted End date
  55. */
  56. function theme_date_display_combination($variables) {
  57. static $repeating_ids = array();
  58. $entity_type = $variables['entity_type'];
  59. $entity = $variables['entity'];
  60. $field = $variables['field'];
  61. $instance = $variables['instance'];
  62. $langcode = $variables['langcode'];
  63. $item = $variables['item'];
  64. $delta = $variables['delta'];
  65. $display = $variables['display'];
  66. $field_name = $field['field_name'];
  67. $formatter = $display['type'];
  68. $options = $display['settings'];
  69. $dates = $variables['dates'];
  70. $attributes = $variables['attributes'];
  71. $rdf_mapping = $variables['rdf_mapping'];
  72. $add_rdf = $variables['add_rdf'];
  73. $precision = date_granularity_precision($field['settings']['granularity']);
  74. $output = '';
  75. // If date_id is set for this field and delta doesn't match, don't display it.
  76. if (!empty($entity->date_id)) {
  77. foreach ((array) $entity->date_id as $key => $id) {
  78. list($module, $nid, $field_name, $item_delta, $other) = explode('.', $id . '.');
  79. if ($field_name == $field['field_name'] && isset($delta) && $item_delta != $delta) {
  80. return $output;
  81. }
  82. }
  83. }
  84. // Check the formatter settings to see if the repeat rule should be displayed.
  85. // Show it only with the first multiple value date.
  86. list($id) = entity_extract_ids($entity_type, $entity);
  87. if (!in_array($id, $repeating_ids) && module_exists('date_repeat_field') && !empty($item['rrule']) && $options['show_repeat_rule'] == 'show') {
  88. $repeat_vars = array(
  89. 'field' => $field,
  90. 'item' => $item,
  91. 'entity_type' => $entity_type,
  92. 'entity' => $entity,
  93. );
  94. $output .= theme('date_repeat_display', $repeat_vars);
  95. $repeating_ids[] = $id;
  96. }
  97. // If this is a full node or a pseudo node created by grouping multiple
  98. // values, see exactly which values are supposed to be visible.
  99. if (isset($entity->$field_name)) {
  100. $entity = date_prepare_entity($formatter, $entity_type, $entity, $field, $instance, $langcode, $item, $display);
  101. // Did the current value get removed by formatter settings?
  102. if (empty($entity->{$field_name}[$langcode][$delta])) {
  103. return $output;
  104. }
  105. // Adjust the $element values to match the changes.
  106. $element['#entity'] = $entity;
  107. }
  108. switch ($options['fromto']) {
  109. case 'value':
  110. $date1 = $dates['value']['formatted'];
  111. $date2 = $date1;
  112. break;
  113. case 'value2':
  114. $date2 = $dates['value2']['formatted'];
  115. $date1 = $date2;
  116. break;
  117. default:
  118. $date1 = $dates['value']['formatted'];
  119. $date2 = $dates['value2']['formatted'];
  120. break;
  121. }
  122. // Pull the timezone, if any, out of the formatted result and tack it back on
  123. // at the end, if it is in the current formatted date.
  124. $timezone = $dates['value']['formatted_timezone'];
  125. if ($timezone) {
  126. $timezone = ' ' . $timezone;
  127. }
  128. $date1 = str_replace($timezone, '', $date1);
  129. $date2 = str_replace($timezone, '', $date2);
  130. $time1 = preg_replace('`^([\(\[])`', '', $dates['value']['formatted_time']);
  131. $time1 = preg_replace('([\)\]]$)', '', $time1);
  132. $time2 = preg_replace('`^([\(\[])`', '', $dates['value2']['formatted_time']);
  133. $time2 = preg_replace('([\)\]]$)', '', $time2);
  134. // A date with a granularity of 'hour' has a time string that is an integer
  135. // value. We can't use that to replace time strings in formatted dates.
  136. $has_time_string = date_has_time($field['settings']['granularity']);
  137. if ($precision == 'hour') {
  138. $has_time_string = FALSE;
  139. }
  140. // No date values, display nothing.
  141. if (empty($date1) && empty($date2)) {
  142. $output .= '';
  143. }
  144. // Start and End dates match or there is no End date, display a complete
  145. // single date.
  146. elseif ($date1 == $date2 || empty($date2)) {
  147. $output .= theme('date_display_single', array(
  148. 'date' => $date1,
  149. 'timezone' => $timezone,
  150. 'attributes' => $attributes,
  151. 'rdf_mapping' => $rdf_mapping,
  152. 'add_rdf' => $add_rdf,
  153. 'dates' => $dates,
  154. ));
  155. }
  156. // Same day, different times, don't repeat the date but show both Start and
  157. // End times. We can NOT do this if the replacement value is an integer
  158. // instead of a time string.
  159. elseif ($has_time_string && $dates['value']['formatted_date'] == $dates['value2']['formatted_date']) {
  160. // Replace the original time with the start/end time in the formatted start
  161. // date. Make sure that parentheses or brackets wrapping the time will be
  162. // retained in the final result.
  163. $time = theme('date_display_range', array(
  164. 'date1' => $time1,
  165. 'date2' => $time2,
  166. 'timezone' => $timezone,
  167. 'attributes' => $attributes,
  168. 'rdf_mapping' => $rdf_mapping,
  169. 'add_rdf' => $add_rdf,
  170. 'dates' => $dates,
  171. ));
  172. $replaced = str_replace($time1, $time, $date1);
  173. $output .= theme('date_display_single', array(
  174. 'date' => $replaced,
  175. 'timezone' => $timezone,
  176. 'attributes' => array(),
  177. 'rdf_mapping' => array(),
  178. 'add_rdf' => FALSE,
  179. 'dates' => $dates,
  180. ));
  181. }
  182. // Different days, display both in their entirety.
  183. else {
  184. $output .= theme('date_display_range', array(
  185. 'date1' => $date1,
  186. 'date2' => $date2,
  187. 'timezone' => $timezone,
  188. 'attributes' => $attributes,
  189. 'rdf_mapping' => $rdf_mapping,
  190. 'add_rdf' => $add_rdf,
  191. 'dates' => $dates,
  192. ));
  193. }
  194. return $output;
  195. }
  196. /**
  197. * Template preprocess function for displaying a single date.
  198. */
  199. function template_preprocess_date_display_single(&$variables) {
  200. if ($variables['add_rdf']) {
  201. // Pass along the rdf mapping for this field, if any. Add some default rdf
  202. // attributes that will be used if not overridden by attributes passed in.
  203. $rdf_mapping = $variables['rdf_mapping'];
  204. $base_attributes = array(
  205. 'property' => array('dc:date'),
  206. 'datatype' => 'xsd:dateTime',
  207. 'content' => $variables['dates']['value']['formatted_iso'],
  208. );
  209. $variables['attributes'] = $variables['attributes'] + $base_attributes;
  210. }
  211. }
  212. /**
  213. * Returns HTML for a date element formatted as a single date.
  214. */
  215. function theme_date_display_single($variables) {
  216. $date = $variables['date'];
  217. $timezone = $variables['timezone'];
  218. $attributes = $variables['attributes'];
  219. // Wrap the result with the attributes.
  220. return '<span class="date-display-single"' . drupal_attributes($attributes) . '>' . $date . $timezone . '</span>';
  221. }
  222. /**
  223. * Template preprocess function for displaying a range of dates.
  224. */
  225. function template_preprocess_date_display_range(&$variables) {
  226. // Merge in the shared attributes for themes to use.
  227. $variables['attributes_start'] += $variables['attributes'];
  228. $variables['attributes_end'] += $variables['attributes'];
  229. if ($variables['add_rdf']) {
  230. // Pass along the rdf mapping for this field, if any. Add some default rdf
  231. // attributes that will be used if not overridden by attributes passed in.
  232. $rdf_mapping = $variables['rdf_mapping'];
  233. $dates = $variables['dates'];
  234. $base_attributes = array(
  235. 'property' => array('dc:date'),
  236. 'datatype' => 'xsd:dateTime',
  237. 'content' => $dates['value']['formatted_iso'],
  238. );
  239. $variables['attributes_start'] += $base_attributes;
  240. $variables['attributes_end'] += $base_attributes;
  241. $variables['attributes_end']['content'] = $dates['value2']['formatted_iso'];
  242. foreach ($variables['attributes_end']['property'] as $delta => $property) {
  243. $variables['attributes_end']['property'][$delta] = str_replace('start', 'end', $property);
  244. }
  245. }
  246. }
  247. /**
  248. * Returns HTML for a date element formatted as a range.
  249. */
  250. function theme_date_display_range($variables) {
  251. $date1 = $variables['date1'];
  252. $date2 = $variables['date2'];
  253. $timezone = $variables['timezone'];
  254. $attributes_start = $variables['attributes_start'];
  255. $attributes_end = $variables['attributes_end'];
  256. // Wrap the result with the attributes.
  257. return t('!start-date to !end-date', array(
  258. '!start-date' => '<span class="date-display-start"' . drupal_attributes($attributes_start) . '>' . $date1 . '</span>',
  259. '!end-date' => '<span class="date-display-end"' . drupal_attributes($attributes_end) . '>' . $date2 . $timezone . '</span>',
  260. ));
  261. }
  262. /**
  263. * Returns HTML for a date element formatted as an interval.
  264. */
  265. function theme_date_display_interval($variables) {
  266. $entity = $variables['entity'];
  267. $options = $variables['display']['settings'];
  268. $dates = $variables['dates'];
  269. $attributes = $variables['attributes'];
  270. // Get the formatter settings, either the default settings for this node type
  271. // or the View settings stored in $entity->date_info.
  272. if (!empty($entity->date_info) && !empty($entity->date_info->formatter_settings)) {
  273. $options = $entity->date_info->formatter_settings;
  274. }
  275. $time_ago_vars = array(
  276. 'start_date' => $dates['value']['local']['object'],
  277. 'end_date' => $dates['value2']['local']['object'],
  278. 'interval' => $options['interval'],
  279. 'interval_display' => $options['interval_display'],
  280. );
  281. if ($return = theme('date_time_ago', $time_ago_vars)) {
  282. return '<span class="date-display-interval"' . drupal_attributes($attributes) . ">$return</span>";
  283. }
  284. else {
  285. return '';
  286. }
  287. }
  288. /**
  289. * Returns HTML for a start/end date combination on form.
  290. */
  291. function theme_date_combo($variables) {
  292. $element = $variables['element'];
  293. $field = field_info_field($element['#field_name']);
  294. $instance = field_info_instance($element['#entity_type'], $element['#field_name'], $element['#bundle']);
  295. // Group start/end items together in fieldset.
  296. $fieldset = array(
  297. '#title' => t($element['#title']) . ' ' . ($element['#delta'] > 0 ? intval($element['#delta'] + 1) : ''),
  298. '#value' => '',
  299. '#description' => !empty($element['#fieldset_description']) ? $element['#fieldset_description'] : '',
  300. '#attributes' => array(),
  301. '#children' => $element['#children'],
  302. );
  303. return theme('fieldset', array('element' => $fieldset));
  304. }
  305. /**
  306. * Returns HTML for the text/select options for date parts in a table.
  307. */
  308. function theme_date_text_parts($variables) {
  309. $element = $variables['element'];
  310. $rows = array();
  311. foreach (date_granularity_names() as $key => $part) {
  312. if ($element[$key]['#type'] == 'hidden') {
  313. $rows[] = drupal_render($element[$key]);
  314. }
  315. else {
  316. $rows[] = array($part, drupal_render($element[$key][0]), drupal_render($element[$key][1]));
  317. }
  318. }
  319. if ($element['year']['#type'] == 'hidden') {
  320. return implode($rows) . drupal_render_children($element);
  321. }
  322. else {
  323. $header = array(t('Date part'), t('Select list'), t('Text field'));
  324. return theme('table', array('header' => $header, 'rows' => $rows)) . drupal_render_children($element);
  325. }
  326. }
  327. /** @} End of addtogroup themeable */