calendar_plugin_row.inc 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631
  1. <?php
  2. /**
  3. * @file
  4. * Contains the Calendar row style plugin.
  5. *
  6. * This plugin takes the view results, finds the date value for each,
  7. * then compares that date to the date range for the current view.
  8. * Items that started before or ended after the current date range
  9. * are shortened to the current range. Items that extend over more
  10. * than one day are cloned to create a calendar item for each day.
  11. * The resulting array of results (which may have a different number
  12. * of items than the original view result) are then passed back
  13. * to the style plugin so they can be displayed in a calendar.
  14. *
  15. */
  16. /**
  17. * Plugin which creates a view on the resulting object
  18. * and formats it as a Calendar node.
  19. */
  20. class calendar_plugin_row extends views_plugin_row {
  21. // Stores the entities loaded with pre_render.
  22. var $entities = array();
  23. function init(&$view, &$display, $options = NULL) {
  24. parent::init($view, $display, $options);
  25. $this->base_table = $view->base_table;
  26. $this->base_field = $view->base_field;
  27. }
  28. /**
  29. * Helper function to find the date argument handler for this view.
  30. */
  31. function date_argument_handler() {
  32. foreach ($this->view->argument as $name => $handler) {
  33. if (date_views_handler_is_date($handler, 'argument')) {
  34. return $handler;
  35. }
  36. }
  37. }
  38. function option_definition() {
  39. $options = parent::option_definition();
  40. $options['date_fields'] = array('default' => array());
  41. $options['calendar_date_link'] = array('default' => '');
  42. $options['colors'] = array(
  43. 'contains' => array(
  44. 'legend' => array('default' => ''),
  45. 'calendar_colors_type' => array('default' => array()),
  46. 'taxonomy_field' => array('default' => ''),
  47. 'calendar_colors_vocabulary' => array('default' => array()),
  48. 'calendar_colors_taxonomy' => array('default' => array()),
  49. 'calendar_colors_group' => array('default' => array()),
  50. ));
  51. return $options;
  52. }
  53. /**
  54. * Provide a form for setting options.
  55. */
  56. function options_form(&$form, &$form_state) {
  57. parent::options_form($form, $form_state);
  58. $form['markup']['#markup'] = t("The calendar row plugin will format view results as calendar items. Make sure this display has a 'Calendar' format and uses a 'Date' contextual filter, or this plugin will not work correctly.");
  59. $form['calendar_date_link'] = array(
  60. '#title' => t('Add new date link'),
  61. '#type' => 'select',
  62. '#default_value' => $this->options['calendar_date_link'],
  63. '#options' => array('' => t('No link')) + node_type_get_names(),
  64. '#description' => t('Display a link to add a new date of the specified content type. Displayed only to users with appropriate permissions.'),
  65. );
  66. $form['colors'] = array(
  67. '#type' => 'fieldset',
  68. '#title' => t('Legend Colors'),
  69. '#description' => t('Set a hex color value (like #ffffff) to use in the calendar legend for each content type. Items with empty values will have no stripe in the calendar and will not be added to the legend.'),
  70. );
  71. $options = array(
  72. '' => t('None')
  73. );
  74. if ($this->view->base_table == 'node') {
  75. $options['type'] = t('Based on Content Type');
  76. }
  77. if (module_exists('taxonomy')) {
  78. $options['taxonomy'] = t('Based on Taxonomy');
  79. }
  80. if (module_exists('og')) {
  81. $options['group'] = t('Based on Organic Group');
  82. }
  83. // If none of the options but the None option is available, stop here.
  84. if (count($options) == 1) {
  85. return;
  86. }
  87. $form['colors']['legend'] = array(
  88. '#title' => t('Stripes'),
  89. '#description' => t('Add stripes to calendar items.'),
  90. '#type' => 'select',
  91. '#options' => $options,
  92. '#default_value' => $this->options['colors']['legend'],
  93. );
  94. if ($this->view->base_table == 'node') {
  95. $colors = $this->options['colors']['calendar_colors_type'];
  96. $type_names = node_type_get_names();
  97. foreach ($type_names as $key => $name) {
  98. $form['colors']['calendar_colors_type'][$key] = array(
  99. '#title' => check_plain($name),
  100. '#type' => 'textfield',
  101. '#default_value' => isset($colors[$key]) ? $colors[$key] : '#ffffff',
  102. '#size' => 7,
  103. '#maxlength' => 7,
  104. '#element_validate' => array('calendar_validate_hex_color'),
  105. '#dependency' => array('edit-row-options-colors-legend' => array('type')),
  106. '#prefix' => '<div class="calendar-colorpicker-wrapper">',
  107. '#suffix' => '<div class="calendar-colorpicker"></div></div>',
  108. '#attributes' => array('class' => array('edit-calendar-colorpicker')),
  109. '#attached' => array(
  110. // Add Farbtastic color picker.
  111. 'library' => array(
  112. array('system', 'farbtastic'),
  113. ),
  114. // Add javascript to trigger the colorpicker.
  115. 'js' => array(drupal_get_path('module', 'calendar') . '/js/calendar_colorpicker.js'),
  116. ),
  117. );
  118. }
  119. }
  120. if (module_exists('taxonomy')) {
  121. $vocab_field_options = array();
  122. $fields = $this->display->handler->get_option('fields');
  123. foreach ($fields as $name => $field) {
  124. if (!empty($field['type']) && $field['type'] == 'taxonomy_term_reference_link') {
  125. $vocab_field_options[$field['field']] = $field['field'];
  126. }
  127. }
  128. $form['colors']['taxonomy_field'] = array(
  129. '#title' => t('Term field'),
  130. '#type' => !empty($vocab_field_options) ? 'select' : 'hidden',
  131. '#default_value' => $this->options['colors']['taxonomy_field'],
  132. '#description' => t("Select the taxonomy term field to use when setting stripe colors. This works best for vocabularies with only a limited number of possible terms."),
  133. '#options' => $vocab_field_options,
  134. '#dependency' => array('edit-row-options-colors-legend' => array('taxonomy')),
  135. );
  136. if (empty($vocab_field_options)) {
  137. $form['colors']['taxonomy_field']['#options'] = array('' => '');
  138. $form['colors']['taxonomy_field']['#suffix'] = t('You must add a term field to this view to use taxonomy stripe values. This works best for vocabularies with only a limited number of possible terms.');
  139. }
  140. $taxonomy_field = field_info_field($this->options['colors']['taxonomy_field']);
  141. $vocab_names[] = array();
  142. foreach ((array) $taxonomy_field['settings']['allowed_values'] as $delta => $options) {
  143. $vocab_names[] = $options['vocabulary'];
  144. }
  145. $taxonomies = taxonomy_get_vocabularies();
  146. foreach ($taxonomies as $vid => $vocab) {
  147. if (in_array($vocab->machine_name, $vocab_names)) {
  148. $this->options['colors']['calendar_colors_vocabulary'][] = $vid;
  149. }
  150. }
  151. $form['colors']['calendar_colors_vocabulary'] = array(
  152. '#title' => t('Vocabulary Legend Types'),
  153. '#type' => 'value',
  154. '#value' => $this->options['colors']['calendar_colors_vocabulary'],
  155. );
  156. $vocabularies = (array) $this->options['colors']['calendar_colors_vocabulary'];
  157. $term_colors = $this->options['colors']['calendar_colors_taxonomy'];
  158. foreach ($vocabularies as $vid) {
  159. $vocab = taxonomy_get_tree($vid);
  160. foreach ($vocab as $tid => $term) {
  161. $form['colors']['calendar_colors_taxonomy'][$term->tid] = array(
  162. '#title' => check_plain(t($term->name)),
  163. '#type' => 'textfield',
  164. '#default_value' => isset($term_colors[$term->tid]) ? $term_colors[$term->tid] : '#ffffff',
  165. '#size' => 7,
  166. '#maxlength' => 7,
  167. '#access' => !empty($vocab_field_options),
  168. '#dependency' => array('edit-row-options-colors-legend' => array('taxonomy')),
  169. '#element_validate' => array('calendar_validate_hex_color'),
  170. '#prefix' => '<div class="calendar-colorpicker-wrapper">',
  171. '#suffix' => '<div class="calendar-colorpicker"></div></div>',
  172. '#attributes' => array('class' => array('edit-calendar-colorpicker')),
  173. '#attached' => array(
  174. // Add Farbtastic color picker.
  175. 'library' => array(
  176. array('system', 'farbtastic'),
  177. ),
  178. // Add javascript to trigger the colorpicker.
  179. 'js' => array(drupal_get_path('module', 'calendar') . '/js/calendar_colorpicker.js'),
  180. ),
  181. );
  182. }
  183. }
  184. }
  185. if (module_exists('og')) {
  186. $colors_group = $this->options['colors']['calendar_colors_group'];
  187. $groups = og_get_all_group();
  188. foreach ($groups as $gid) {
  189. $form['colors']['calendar_colors_group'][$gid] = array(
  190. '#title' => check_plain(t(og_label($gid))),
  191. '#type' => 'textfield',
  192. '#default_value' => isset($colors_group[$gid]) ? $colors_group[$gid] : '#ffffff',
  193. '#dependency' => array('edit-row-options-colors-legend' => array('group')),
  194. '#element_validate' => array('calendar_validate_hex_color'),
  195. '#prefix' => '<div class="calendar-colorpicker-wrapper">',
  196. '#suffix' => '<div class="calendar-colorpicker"></div></div>',
  197. '#attributes' => array('class' => array('edit-calendar-colorpicker')),
  198. '#attached' => array(
  199. // Add Farbtastic color picker.
  200. 'library' => array(
  201. array('system', 'farbtastic'),
  202. ),
  203. // Add javascript to trigger the colorpicker.
  204. 'js' => array(drupal_get_path('module', 'calendar') . '/js/calendar_colorpicker.js'),
  205. ),
  206. );
  207. }
  208. }
  209. }
  210. function options_submit(&$form, &$form_state) {
  211. parent::options_submit($form, $form_state);
  212. if ($this->view->base_table == 'node') {
  213. $path = $this->view->display_handler->get_option('path');
  214. calendar_clear_link_path($path);
  215. if (!empty($form_state['values']['row_options']['calendar_date_link'])) {
  216. $node_type = $form_state['values']['row_options']['calendar_date_link'];
  217. calendar_set_link('node', $node_type, $path);
  218. }
  219. }
  220. }
  221. function pre_render($values) {
  222. // @TODO When the date is coming in through a relationship, the nid
  223. // of the view is not the right node to use, then we need the related node.
  224. // Need to sort out how that should be handled.
  225. // Preload each entity used in this view from the cache.
  226. // Provides all the entity values relatively cheaply, and we don't
  227. // need to do it repeatedly for the same entity if there are
  228. // multiple results for one entity.
  229. $ids = array();
  230. foreach ($values as $row) {
  231. // Use the $id as the key so we don't create more than one value per entity.
  232. $id = $row->{$this->field_alias};
  233. // Node revisions need special loading.
  234. if ($this->view->base_table == 'node_revision') {
  235. $this->entities[$id] = node_load(NULL, $id);
  236. }
  237. // For other entities we just create an array of ids to pass
  238. // to entity_load().
  239. else {
  240. $ids[$id] = $id;
  241. }
  242. }
  243. $base_tables = date_views_base_tables();
  244. $this->entity_type = $base_tables[$this->view->base_table];
  245. if (!empty($ids)) {
  246. $this->entities = entity_load($this->entity_type, $ids);
  247. }
  248. // Let the style know if a link to create a new date is required.
  249. $this->view->date_info->calendar_date_link = $this->options['calendar_date_link'];
  250. // Identify the date argument and fields that apply to this view.
  251. // Preload the Date Views field info for each field, keyed by the
  252. // field name, so we know how to retrieve field values from the cached node.
  253. $data = date_views_fields($this->view->base_table);
  254. $data = $data['name'];
  255. $date_fields = array();
  256. foreach ($this->view->argument as $handler) {
  257. if (date_views_handler_is_date($handler, 'argument')) {
  258. // If this is the complex Date argument, the date fields are stored in the handler options,
  259. // otherwise we are using the simple date field argument handler.
  260. if ($handler->definition['handler'] != 'date_views_argument_handler') {
  261. $alias = $handler->table_alias . '.' . $handler->field;
  262. $info = $data[$alias];
  263. $field_name = str_replace(array('_value2', '_value'), '', $info['real_field_name']);
  264. $date_fields[$field_name] = $info;
  265. }
  266. else {
  267. foreach ($handler->options['date_fields'] as $alias) {
  268. $info = $data[$alias];
  269. $field_name = str_replace(array('_value2', '_value'), '', $info['real_field_name']);
  270. // This is ugly and hacky but I can't figure out any generic way to
  271. // recognize that the node module is going to give some the revision timestamp
  272. // a different field name on the entity than the actual column name in the database.
  273. if ($this->view->base_table == 'node_revision' && $field_name == 'timestamp') {
  274. $field_name = 'revision_timestamp';
  275. }
  276. $date_fields[$field_name] = $info;
  277. }
  278. }
  279. $this->date_argument = $handler;
  280. $this->date_fields = $date_fields;
  281. }
  282. }
  283. // Get the language for this view.
  284. $this->language = $this->display->handler->get_option('field_language');
  285. $substitutions = views_views_query_substitutions($this->view);
  286. if (array_key_exists($this->language, $substitutions)) {
  287. $this->language = $substitutions[$this->language];
  288. }
  289. }
  290. function render($row) {
  291. global $base_url;
  292. $rows = array();
  293. $date_info = $this->date_argument->view->date_info;
  294. $id = $row->{$this->field_alias};
  295. if (!is_numeric($id)) {
  296. return $rows;
  297. }
  298. // There could be more than one date field in a view
  299. // so iterate through all of them to find the right values
  300. // for this view result.
  301. foreach ($this->date_fields as $field_name => $info) {
  302. // Load the specified node:
  303. // We have to clone this or nodes on other views on this page,
  304. // like an Upcoming block on the same page as a calendar view,
  305. // will end up acquiring the values we set here.
  306. $entity = clone($this->entities[$id]);
  307. if (empty($entity)) {
  308. return $rows;
  309. }
  310. $table_name = $info['table_name'];
  311. $delta_field = $info['delta_field'];
  312. $tz_handling = $info['tz_handling'];
  313. $tz_field = $info['timezone_field'];
  314. $rrule_field = $info['rrule_field'];
  315. $is_field = $info['is_field'];
  316. $info = entity_get_info($this->entity_type);
  317. $this->id_field = $info['entity keys']['id'];
  318. $this->id = $entity->{$this->id_field};
  319. $this->type = !empty($info['entity keys']['bundle']) ? $info['entity keys']['bundle'] : $this->entity_type;
  320. $this->title = entity_label($this->entity_type, $entity);
  321. $uri = entity_uri($this->entity_type, $entity);
  322. $uri['options']['absolute'] = TRUE;
  323. $this->url = url($uri['path'], $uri['options']);
  324. // Retrieve the field value(s) that matched our query from the cached node.
  325. // Find the date and set it to the right timezone.
  326. $entity->date_id = array();
  327. $item_start_date = NULL;
  328. $item_end_date = NULL;
  329. $granularity = 'second';
  330. $increment = 1;
  331. if ($is_field) {
  332. $delta = isset($row->$delta_field) ? $row->$delta_field : 0;
  333. $items = field_get_items($this->view->base_table, $entity, $field_name, $this->language);
  334. $item = $items[$delta];
  335. $db_tz = date_get_timezone_db($tz_handling, isset($item->$tz_field) ? $item->$tz_field : $date_info->display_timezone_name);
  336. $to_zone = date_get_timezone($tz_handling, isset($item->$tz_field) ? $item->$tz_field : $date_info->display_timezone_name);
  337. // Set the date_id for the node, used to identify which field value to display for
  338. // fields that have multiple values. The theme expects it to be an array.
  339. $entity->date_id = array('calendar.' . $id . '.' . $field_name . '.' . $delta);
  340. if (!empty($item['value'])) {
  341. $item_start_date = new dateObject($item['value'], $db_tz);
  342. $item_end_date = array_key_exists('value2', $item) ? new dateObject($item['value2'], $db_tz) : $item_start_date;
  343. }
  344. $cck_field = field_info_field($field_name);
  345. $instance = field_info_instance($this->view->base_table, $field_name, $entity->type);
  346. $granularity = date_granularity_precision($cck_field['settings']['granularity']);
  347. $increment = $instance['widget']['settings']['increment'];
  348. }
  349. elseif (!empty($entity->$field_name)) {
  350. $item = $entity->$field_name;
  351. $db_tz = date_get_timezone_db($tz_handling, isset($item->$tz_field) ? $item->$tz_field : $date_info->display_timezone_name);
  352. $to_zone = date_get_timezone($tz_handling, isset($item->$tz_field) ? $item->$tz_field : $date_info->display_timezone_name);
  353. $item_start_date = new dateObject($item, $db_tz);
  354. $item_end_date = $item_start_date;
  355. $entity->date_id = array('calendar.' . $id . '.' . $field_name . '.0');
  356. }
  357. // If we don't have a date value, go no further.
  358. if (empty($item_start_date)) {
  359. continue;
  360. }
  361. // Set the item date to the proper display timezone;
  362. $item_start_date->setTimezone(new dateTimezone($to_zone));
  363. $item_end_date->setTimezone(new dateTimezone($to_zone));
  364. $event = new stdClass();
  365. $event->id = $this->id;
  366. $event->title = $this->title;
  367. $event->type = $this->type;
  368. $event->date_start = $item_start_date;
  369. $event->date_end = $item_end_date;
  370. $event->db_tz = $db_tz;
  371. $event->to_zone = $to_zone;
  372. $event->granularity = $granularity;
  373. $event->increment = $increment;
  374. $event->field = $is_field ? $item : NULL;
  375. $event->url = $this->url;
  376. $event->row = $row;
  377. $event->entity = $entity;
  378. // All calendar row plugins should provide a date_id that the theme can use.
  379. $event->date_id = $entity->date_id[0];
  380. $entities = $this->explode_values($event);
  381. foreach ($entities as $entity) {
  382. switch ($this->options['colors']['legend']) {
  383. case 'type':
  384. $this->calendar_node_type_stripe($entity);
  385. break;
  386. case 'taxonomy':
  387. $this->calendar_taxonomy_stripe($entity);
  388. break;
  389. case 'group':
  390. $this->calendar_group_stripe($entity);
  391. break;
  392. }
  393. $rows[] = $entity;
  394. }
  395. }
  396. return $rows;
  397. }
  398. function explode_values($event) {
  399. $rows = array();
  400. $date_info = $this->date_argument->view->date_info;
  401. $item_start_date = $event->date_start;
  402. $item_end_date = $event->date_end;
  403. $to_zone = $event->to_zone;
  404. $db_tz = $event->db_tz;
  405. $granularity = $event->granularity;
  406. $increment = $event->increment;
  407. // Now that we have an 'entity' for each view result, we need
  408. // to remove anything outside the view date range,
  409. // and possibly create additional nodes so that we have a 'node'
  410. // for each day that this item occupies in this view.
  411. $now = max($date_info->min_zone_string, $item_start_date->format(DATE_FORMAT_DATE));
  412. $to = min($date_info->max_zone_string, $item_end_date->format(DATE_FORMAT_DATE));
  413. $next = new DateObject($now . ' 00:00:00', $date_info->display_timezone);
  414. if ($date_info->display_timezone_name != $to_zone) {
  415. // Make $start and $end (derived from $node) use the timezone $to_zone, just as the original dates do.
  416. date_timezone_set($next, timezone_open($to_zone));
  417. }
  418. if (empty($to) || $now > $to) {
  419. $to = $now;
  420. }
  421. // $now and $next are midnight (in display timezone) on the first day where node will occur.
  422. // $to is midnight on the last day where node will occur.
  423. // All three were limited by the min-max date range of the view.
  424. $pos = 0;
  425. while (!empty($now) && $now <= $to) {
  426. $entity = clone($event);
  427. // Get start and end of current day.
  428. $start = $next->format(DATE_FORMAT_DATETIME);
  429. date_modify($next, '+1 day');
  430. date_modify($next, '-1 second');
  431. $end = $next->format(DATE_FORMAT_DATETIME);
  432. // Get start and end of item, formatted the same way.
  433. $item_start = $item_start_date->format(DATE_FORMAT_DATETIME);
  434. $item_end = $item_end_date->format(DATE_FORMAT_DATETIME);
  435. // Get intersection of current day and the node value's duration (as strings in $to_zone timezone).
  436. $entity->calendar_start = $item_start < $start ? $start : $item_start;
  437. $entity->calendar_end = !empty($item_end) ? ($item_end > $end ? $end : $item_end) : $node->calendar_start;
  438. // Make date objects
  439. $entity->calendar_start_date = date_create($entity->calendar_start, timezone_open($to_zone));
  440. $entity->calendar_end_date = date_create($entity->calendar_end, timezone_open($to_zone));
  441. // Change string timezones into
  442. // calendar_start and calendar_end are UTC dates as formatted strings
  443. $entity->calendar_start = date_format($entity->calendar_start_date, DATE_FORMAT_DATETIME);
  444. $entity->calendar_end = date_format($entity->calendar_end_date, DATE_FORMAT_DATETIME);
  445. $entity->calendar_all_day = date_is_all_day($entity->calendar_start, $entity->calendar_end, $granularity, $increment);
  446. unset($entity->calendar_fields);
  447. if (isset($entity) && (empty($entity->calendar_start))) {
  448. // if no date for the node and no date in the item
  449. // there is no way to display it on the calendar
  450. unset($entity);
  451. }
  452. else {
  453. $entity->date_id .= '.' . $pos;
  454. $rows[] = $entity;
  455. unset($entity);
  456. }
  457. date_modify($next, '+1 second');
  458. $now = date_format($next, DATE_FORMAT_DATE);
  459. $pos++;
  460. }
  461. return $rows;
  462. }
  463. /**
  464. * Create a stripe base on node type.
  465. */
  466. function calendar_node_type_stripe(&$entity) {
  467. $colors = isset($this->options['colors']['calendar_colors_type']) ? $this->options['colors']['calendar_colors_type'] : array();
  468. if (empty($colors)) {
  469. return;
  470. }
  471. if (empty($entity->type)) {
  472. return;
  473. }
  474. $type_names = node_type_get_names();
  475. $type = $entity->type;
  476. $label = '';
  477. $stripe = '';
  478. if (!(isset($entity->stripe))) {
  479. $entity->stripe = array();
  480. $entity->stripe_label = array();
  481. }
  482. if (array_key_exists($type, $type_names)) {
  483. $label = $type_names[$type];
  484. }
  485. if (array_key_exists($type, $colors)) {
  486. $stripe = $colors[$type];
  487. }
  488. $entity->stripe[] = $stripe;
  489. $entity->stripe_label[] = $label;
  490. return $stripe;
  491. }
  492. /**
  493. * Create a stripe based on a taxonomy term.
  494. */
  495. function calendar_taxonomy_stripe(&$entity) {
  496. $term_colors = isset($this->options['colors']['calendar_colors_taxonomy']) ? $this->options['colors']['calendar_colors_taxonomy'] : array();
  497. if (empty($term_colors)) {
  498. return;
  499. }
  500. $terms = array();
  501. if ($this->options['colors']['legend'] == 'taxonomy') {
  502. $term_field_name = $this->options['colors']['taxonomy_field'];
  503. if ($term_field = field_get_items($this->view->base_table, $entity->entity, $term_field_name)) {
  504. foreach ($term_field as $delta => $items) {
  505. foreach ($items as $item) {
  506. $terms[] = $item['tid'];
  507. }
  508. }
  509. }
  510. }
  511. if (empty($terms)) {
  512. return;
  513. }
  514. if (!(isset($entity->stripe))) {
  515. $entity->stripe = array();
  516. $entity->stripe_label = array();
  517. }
  518. if (count($terms)) {
  519. foreach ($terms as $tid) {
  520. $term_for_entity = taxonomy_term_load($tid);
  521. if (!array_key_exists($term_for_entity->tid, $term_colors)) {
  522. continue;
  523. }
  524. $stripe = $term_colors[$term_for_entity->tid];
  525. $stripe_label = $term_for_entity->name;
  526. $entity->stripe[] = $stripe;
  527. $entity->stripe_label[] = $stripe_label;
  528. }
  529. }
  530. else {
  531. $entity->stripe[] = '';
  532. $entity->stripe_label[] = '';
  533. }
  534. return;
  535. }
  536. /**
  537. * Create a stripe based on group.
  538. */
  539. function calendar_group_stripe(&$entity) {
  540. $colors_group = isset($this->options['colors']['calendar_colors_group']) ? $this->options['colors']['calendar_colors_group'] : array();
  541. if (empty($colors_group)) {
  542. return;
  543. }
  544. if (!function_exists('og_get_entity_groups')) {
  545. return;
  546. }
  547. $groups_for_entity = og_get_entity_groups($this->view->base_table, $entity);
  548. if (!(isset($entity->stripe))) {
  549. $entity->stripe = array();
  550. $entity->stripe_label = array();
  551. }
  552. if (count($groups_for_entity)) {
  553. foreach ($groups_for_entity as $gid => $group_name) {
  554. if (!array_key_exists($gid, $colors_group)) {
  555. continue;
  556. }
  557. $stripe = $colors_group[$gid];
  558. $stripe_label = $group_name;
  559. $entity->stripe[] = $stripe;
  560. $entity->stripe_label[] = $stripe_label;
  561. }
  562. }
  563. else {
  564. $entity->stripe[] = '';
  565. $entity->stripe_label[] = '';
  566. }
  567. return;
  568. }
  569. }