| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 //$Id: calendar.inc,v 1.1.2.4 2011/01/02 00:00:56 karens Exp $ 3 /** 4 * Build calendar 5 * 6 * @param unknown_type $view 7 * @param unknown_type $items 8 * @return themed table 9 */ 10 function calendar_build_calendar($view, $items) { 11 // Remove nodes outside the selected date range. 12 $values = array(); 13 foreach ($items as $delta => $item) { 14 if (empty($item->calendar_start_date) || empty($item->calendar_end_date)) { 15 continue; 16 } 17 $item_start = date_format($item->calendar_start_date, DATE_FORMAT_DATE); 18 $item_end = date_format($item->calendar_end_date, DATE_FORMAT_DATE); 19 if (($item_start >= $view->date_info->min_date_date && $item_start <= $view->date_info->max_date_date) 20 || ($item_end >= $view->date_info->min_date_date && $item_end <= $view->date_info->max_date_date)) { 21 $values[$item_start][date_format($item->date_start, 'H:i:s')][] = $item; 22 } 23 } 24 $items = $values; 25 ksort($items); 26 27 $rows = array(); 28 $curday = drupal_clone($view->date_info->min_date); 29 30 switch ($view->date_info->granularity) { 31 case 'year': 32 $rows = array(); 33 $view->date_info->mini = TRUE; 34 for ($i = 1; $i <= 12; $i++) { 35 $rows[$i] = calendar_build_mini_month($curday, $view, $items); 36 } 37 $view->date_info->mini = FALSE; 38 break; 39 case 'month': 40 $rows = ($view->date_info->mini) ? calendar_build_mini_month($curday, $view, $items) : calendar_build_month($curday, $view, $items); 41 break; 42 case 'day': 43 $rows = calendar_build_day($curday, $view, $items); 44 break; 45 case 'week': 46 $rows = calendar_build_week($curday, $view, $items); 47 // Merge the day names in as the first row. 48 $rows = array_merge(array(calendar_week_header($view)), $rows); 49 break; 50 } 51 return $rows; 52 53 } 54 /** 55 * Build one month. 56 */ 57 function calendar_build_mini_month(&$curday, $view, $items) { 58 $month = date_format($curday, 'n'); 59 date_modify($curday, '-' . strval(date_format($curday, 'j')-1) . ' days'); 60 $rows = array(); 61 do { 62 $rows = array_merge($rows, calendar_build_mini_week($curday, $view, $items, TRUE)); 63 $curday_date = date_format($curday, DATE_FORMAT_DATE); 64 $curday_month = date_format($curday, 'n'); 65 } while ($curday_month == $month && $curday_date <= $view->date_info->max_date_date); 66 // Merge the day names in as the first row. 67 $rows = array_merge(array(calendar_week_header($view)), $rows); 68 return $rows; 69 } 70 /** 71 * Build one month. 72 */ 73 function calendar_build_month(&$curday, $view, $items) { 74 $month = date_format($curday, 'n'); 75 $curday_date = date_format($curday, DATE_FORMAT_DATE); 76 $weekdays = calendar_untranslated_days($items, $view); 77 date_modify($curday, '-' . strval(date_format($curday, 'j')-1) . ' days'); 78 $rows = array(); 79 do { 80 $init_day = clone($curday); 81 $today = date_format(date_now(date_default_timezone_name()), DATE_FORMAT_DATE); 82 $month = date_format($curday, 'n'); 83 $week = date_week($curday_date); 84 $first_day = variable_get('date_first_day', 0); 85 $week_rows = calendar_build_week($curday, $view, $items, TRUE); 86 $multiday_buckets = $week_rows['multiday_buckets']; 87 $singleday_buckets = $week_rows['singleday_buckets']; 88 89 $total_rows = $week_rows['total_rows']; 90 91 // Theme each row 92 $output = ""; 93 $final_day = clone($curday); 94 95 $iehint = 0; 96 $max_multirow_cnt = 0; 97 $max_singlerow_cnt = 0; 98 99 for ($i = 0; $i < $total_rows + 1; $i++) { 100 $inner = ""; 101 102 // If we're displaying the week number, add it as the 103 // first cell in the week. 104 if ($i == 0 && !empty($view->date_info->style_with_weekno) && !in_array($view->date_info->granularity, array('day', 'week'))) { 105 $url = $view->get_path() .'/'. $view->date_info->year .'-W'. $week; 106 if (!empty($view->date_info->display_types['week'])) { 107 $weekno = l($week, $url, array('query' => !empty($view->date_info->append) ? $view->date_info->append : '')); 108 } 109 else { 110 // Do not link week numbers, if Week views are disabled. 111 $weekno = $week; 112 } 113 $item = array( 114 'entry' => $weekno, 115 'colspan' => 1, 116 'rowspan' => $total_rows + 1, 117 'id' => $view->name . '-weekno-' . $curday_date, 118 'class' => 'week' 119 ); 120 $inner .= theme('calendar_month_col', $item); 121 } 122 123 $curday = clone($init_day); 124 125 // move backwards to the first day of the week 126 $day_wday = date_format($curday, 'w'); 127 date_modify($curday, '-' . strval((7 + $day_wday - $first_day) % 7) . ' days'); 128 129 for ( $wday = 0; $wday < 7; $wday++) { 130 131 $curday_date = date_format($curday, DATE_FORMAT_DATE); 132 $class = strtolower($weekdays[$wday]); 133 $item = NULL; 134 $in_month = !($curday_date < $view->date_info->min_date_date || $curday_date > $view->date_info->max_date_date || date_format($curday, 'n') != $month); 135 136 // Add the datebox 137 if ($i == 0) { 138 $count = $in_month ? intval(count($multiday_buckets[$wday]) + count($singleday_buckets[$wday])) : FALSE; 139 $item = array( 140 'entry' => theme('calendar_datebox', $curday_date, $view, $items, $count), 141 'colspan' => 1, 142 'rowspan' => 1, 143 'class' => 'date-box', 144 'date' => $curday_date, 145 'id' => $view->name . '-' . $curday_date . '-date-box' 146 ); 147 $item['class'] .= ($curday_date == $today && $in_month ? ' today' : '') . 148 ($curday_date < $today ? ' past' : '') . 149 ($curday_date > $today ? ' future' : ''); 150 } 151 else { 152 $index = $i - 1; 153 $multi_count = count($multiday_buckets[$wday]); 154 155 // Process multiday buckets first. If there is a multiday-bucket item in this row... 156 if ($index < $multi_count) { 157 158 // If this item is filled with either a blank or an entry... 159 if ($multiday_buckets[$wday][$index]['filled']) { 160 161 // Add item and add class 162 $item = $multiday_buckets[$wday][$index]; 163 $item['class'] = 'multi-day'; 164 $item['date'] = $curday_date; 165 166 // Is this an entry? 167 if (!$multiday_buckets[$wday][$index]['avail']) { 168 169 // If the item either starts or ends on today, 170 // then add tags so we can style the borders 171 if ($curday_date == $today && $in_month) { 172 $item['class'] .= ' starts-today'; 173 } 174 175 // Calculate on which day of this week this item ends on.. 176 $end_day = clone($curday); 177 $span = $item['colspan'] - 1; 178 date_modify($end_day, '+' . $span .' day'); 179 $endday_date = date_format($end_day, DATE_FORMAT_DATE); 180 181 // If it ends today, add class 182 if ($endday_date == $today && $in_month) { 183 $item['class'] .= ' ends-today'; 184 } 185 } 186 } 187 188 // If this is an acutal entry, add classes regarding the state of the 189 // item 190 if ($multiday_buckets[$wday][$index]['avail']) { 191 $item['class'] .= ' ' . $wday . ' ' . $index . ' no-entry ' . ($curday_date == $today && $in_month ? ' today' : '') . 192 ($curday_date < $today ? ' past' : '') . 193 ($curday_date > $today ? ' future' : ''); 194 } 195 196 // Else, process the single day bucket - we only do this once per day 197 } 198 elseif ($index == $multi_count) { 199 200 $single_day_cnt = 0; 201 // If it's empty, add class 202 if (count($singleday_buckets[$wday]) == 0) { 203 $single_days = " "; 204 if ($max_multirow_cnt == 0 ) { 205 $class = ($multi_count > 0 ) ? 'single-day no-entry noentry-multi-day' : 'single-day no-entry'; 206 } 207 else { 208 $class = 'single-day'; 209 } 210 } 211 else { 212 $single_days = ""; 213 foreach ($singleday_buckets[$wday] as $day) { 214 foreach ($day as $event) { 215 $single_day_cnt++; 216 $single_days .= (isset($event['more_link'])) ? '<div class="calendar-more">' . $event['entry'] . '</div>' : $event['entry']; 217 } 218 } 219 $class = 'single-day'; 220 } 221 222 $rowspan = $total_rows - $index; 223 224 // Add item... 225 $item = array( 226 'entry' => $single_days, 227 'colspan' => 1, 228 'rowspan' => $rowspan, 229 'class' => $class, 230 'date' => $curday_date, 231 'id' => $view->name . '-' . $curday_date . '-' . $index 232 ); 233 234 // Hack for ie to help it properly space single day rows 235 if ($rowspan > 1 && $in_month && $single_day_cnt > 0) { 236 $max_multirow_cnt = max($max_multirow_cnt, $single_day_cnt); 237 } 238 else { 239 $max_singlerow_cnt = max($max_singlerow_cnt, $single_day_cnt); 240 } 241 242 // If the singlerow is bigger than the multi-row, then null out 243 // ieheight - I'm estimating that a single row is twice the size of 244 // multi-row. This is really the best that can be done with ie 245 if ($max_singlerow_cnt >= $max_multirow_cnt || $max_multirow_cnt <= $multi_count / 2 ) { 246 $iehint = 0; 247 } 248 elseif ($rowspan > 1 && $in_month && $single_day_cnt > 0) { 249 $iehint = max($iehint, $rowspan - 1); // How many rows to adjust for? 250 } 251 252 // Set the class 253 $item['class'] .= ($curday_date == $today && $in_month ? ' today' : '') . 254 ($curday_date < $today ? ' past' : '') . 255 ($curday_date > $today ? ' future' : ''); 256 } 257 } 258 259 // If there isn't an item, then add empty class 260 if ($item != NULL) { 261 if (!$in_month) { 262 $item['class'] .= ' empty'; 263 } 264 // Style this entry - it will be a <td>. 265 $inner .= theme('calendar_month_col', $item); 266 } 267 268 date_modify($curday, '+1 day'); 269 } 270 271 if ($i == 0) { 272 $output .= theme('calendar_month_row', $inner, 'date-box', $iehint); 273 } 274 elseif ($i == $total_rows) { 275 $output .= theme('calendar_month_row', $inner, 'single-day', $iehint); 276 $iehint = 0; 277 $max_singlerow_cnt = 0; 278 $max_multirow_cnt = 0; 279 } 280 else { 281 // Style all the columns into a row 282 $output .= theme('calendar_month_row', $inner, 'multi-day'); 283 } 284 } 285 $curday = $final_day; 286 287 // Add the row into the row array.... 288 $rows[] = array('data' => $output); 289 290 $curday_date = date_format($curday, DATE_FORMAT_DATE); 291 $curday_month = date_format($curday, 'n'); 292 } while ($curday_month == $month && $curday_date <= $view->date_info->max_date_date); 293 294 // Merge the day names in as the first row. 295 $rows = array_merge(array(calendar_week_header($view)), $rows); 296 return $rows; 297 } 298 /** 299 * Build one week row. 300 */ 301 function calendar_build_mini_week(&$curday, $view, $items, $check_month = FALSE) { 302 $curday_date = date_format($curday, DATE_FORMAT_DATE); 303 $weekdays = calendar_untranslated_days($items, $view); 304 $today = date_format(date_now(date_default_timezone_name()), DATE_FORMAT_DATE); 305 $month = date_format($curday, 'n'); 306 $week = date_week($curday_date); 307 $first_day = variable_get('date_first_day', 0); 308 // move backwards to the first day of the week 309 $day_wday = date_format($curday, 'w'); 310 date_modify($curday, '-' . strval((7 + $day_wday - $first_day) % 7) . ' days'); 311 $curday_date = date_format($curday, DATE_FORMAT_DATE); 312 313 // If we're displaying the week number, add it as the 314 // first cell in the week. 315 if (!empty($view->date_info->style_with_weekno) && !in_array($view->date_info->granularity, array('day', 'week'))) { 316 $url = date_real_url($view, NULL, $view->date_info->year .'-W'. $week); 317 if (!empty($view->date_info->display_types['week'])) { 318 $weekno = l($week, $url, array('query' => !empty($view->date_info->append) ? $view->date_info->append : '')); 319 } 320 else { 321 // Do not link week numbers, if Week views are disabled. 322 $weekno = $week; 323 } 324 $rows[$week][] = array( 325 'data' => $weekno, 326 'id' => $view->name . '-weekno-' . $curday_date, 327 'class' => 'week'); 328 } 329 for ($i = 0; $i < 7; $i++) { 330 $curday_date = date_format($curday, DATE_FORMAT_DATE); 331 $class = strtolower($weekdays[$i] . ' mini'); 332 if ($check_month && ($curday_date < $view->date_info->min_date_date || $curday_date > $view->date_info->max_date_date || date_format($curday, 'n') != $month)) { 333 $class .= ' empty'; 334 $content = array( 335 'date' => '', 336 'datebox' => '', 337 'empty' => theme('calendar_empty_day', $curday_date, $view), 338 'link' => '', 339 'all_day' => array(), 340 'items' => array(), 341 ); 342 } 343 else { 344 $content = calendar_build_day($curday, $view, $items); 345 $class .= ($curday_date == $today ? ' today' : '') . 346 ($curday_date < $today ? ' past' : '') . 347 ($curday_date > $today ? ' future' : '') . 348 (empty($items[$curday_date]) ? ' has-no-events' : ' has-events'); 349 } 350 351 $rows[$week][] = array( 352 'data' => $content, 353 'class' => $class, 'id' => $view->name . '-' . $curday_date); 354 date_modify($curday, '+1 day'); 355 } 356 return $rows; 357 } 358 /** 359 * Build one week row. 360 */ 361 function calendar_build_week(&$curday, $view, $items, $check_month = FALSE) { 362 $curday_date = date_format($curday, DATE_FORMAT_DATE); 363 $weekdays = calendar_untranslated_days($items, $view); 364 $month = date_format($curday, 'n'); 365 $first_day = variable_get('date_first_day', 0); 366 367 // Set up buckets 368 $total_rows = 0; 369 $multiday_buckets = array( array(), array(), array(), array(), array(), array(), array()); 370 $singleday_buckets = array( array(), array(), array(), array(), array(), array(), array()); 371 372 // move backwards to the first day of the week 373 $day_wday = date_format($curday, 'w'); 374 date_modify($curday, '-' . strval((7 + $day_wday - $first_day) % 7) . ' days'); 375 $curday_date = date_format($curday, DATE_FORMAT_DATE); 376 377 for ($i = 0; $i < 7; $i++) { 378 if ($check_month && ($curday_date < $view->date_info->min_date_date || $curday_date > $view->date_info->max_date_date || date_format($curday, 'n') != $month)) { 379 $class = strtolower($weekdays[$i]) .' empty'; 380 $singleday_buckets[$i][][] = array( 381 'entry' => theme('calendar_empty_day', $curday_date, $view), 382 'item' => NULL 383 ); 384 } 385 else { 386 calendar_build_week_day($curday, $view, $items, $i, $multiday_buckets, $singleday_buckets); 387 } 388 $total_rows = max(count($multiday_buckets[$i]) + 1, $total_rows); 389 date_modify($curday, '+1 day'); 390 $curday_date = date_format($curday, DATE_FORMAT_DATE); 391 } 392 393 $rows = array( 394 'multiday_buckets' => $multiday_buckets, 395 'singleday_buckets' => $singleday_buckets, 396 'total_rows' => $total_rows); 397 return $rows; 398 } 399 /** 400 * Build the contents of a single day for the $rows results. 401 */ 402 function calendar_build_week_day($curday, $view, $items, $wday, &$multiday_buckets, &$singleday_buckets) { 403 $curday_date = date_format($curday, DATE_FORMAT_DATE); 404 $max_events = !empty($view->date_info->style_max_items) ? $view->date_info->style_max_items : 0; 405 $hide = !empty($view->date_info->style_max_items_behavior) ? ($view->date_info->style_max_items_behavior == 'hide') : FALSE; 406 $multiday_theme = ($view->date_info->style_multiday_theme == '1'); 407 $cur_cnt = 0; 408 $total_cnt = 0; 409 $types = array(); 410 411 // If we are hiding, count before processing further 412 if ($max_events != CALENDAR_SHOW_ALL) { 413 foreach ($items as $date => $day) { 414 if ($date == $curday_date) { 415 foreach ($day as $time => $hour) { 416 foreach ($hour as $key => $item) { 417 $total_cnt++; 418 $types[$item->type] = $item; 419 } 420 } 421 } 422 } 423 } 424 425 // If we haven't already exceeded the max or we'll showing all, then process the items 426 if ($max_events == CALENDAR_SHOW_ALL || !$hide || $total_cnt <= $max_events) { 427 // Count currently filled items 428 foreach ($multiday_buckets[$wday] as $bucket) { 429 if (!$bucket['avail']) { 430 $cur_cnt++; 431 } 432 } 433 434 foreach ($items as $date => $day) { 435 if ($date == $curday_date) { 436 $count = 0; 437 ksort($day); 438 foreach ($day as $time => $hour) { 439 foreach ($hour as $key => $item) { 440 $count++; 441 442 // Can we add an item? 443 if ($max_events == CALENDAR_SHOW_ALL || $cur_cnt <= $max_events) { 444 $all_day = $item->calendar_start_date == $item->calendar_end_date; 445 $theme = isset($item->calendar_node_theme) ? $item->calendar_node_theme : 'calendar_'. $view->date_info->granularity .'_node'; 446 447 // Parse out date part 448 $start_ydate = date_format($item->date_start, DATE_FORMAT_DATE); 449 $end_ydate = date_format($item->date_end, DATE_FORMAT_DATE); 450 $cur_ydate = date_format($curday, DATE_FORMAT_DATE); 451 452 $is_multi_day = ($start_ydate < $cur_ydate || $end_ydate > $cur_ydate); 453 454 // Does this event span multi-days? 455 if ($multiday_theme && ($is_multi_day || $all_day)) { 456 457 // If this the first day of the week, or is the start date of the multi-day event, 458 // then record this item, otherwise skip over 459 $day_no = date_format($curday, 'd'); 460 if ($wday == 0 || $start_ydate == $cur_ydate || ($view->date_info->granularity == 'month' && $day_no == 1) || ($all_day && !$is_multi_day)) { 461 $cur_cnt++; 462 463 // Calculate the colspan for this event 464 465 // If the last day of this event exceeds the end of the current month or week, 466 // truncate the remaining days 467 $diff = date_difference($view->date_info->max_date, $curday, 'days'); 468 $remaining_days = ($view->date_info->granularity == 'month') ? min(6 - $wday, $diff) : $diff - 1; 469 // The bucket_cnt defines the colspan. colspan = bucket_cnt + 1 470 $days = date_difference($curday, $item->date_end, 'days'); 471 $bucket_cnt = max(0, min($days, $remaining_days)); 472 473 // See if there is an avaiable slot to add an event. This will allow 474 // an event to precede a row filled up by a previous day event 475 $avail = FALSE; 476 $bucket_index = count($multiday_buckets[$wday]); 477 for ($i = 0; $i < $bucket_index; $i++) { 478 if ($multiday_buckets[$wday][$i]['avail']) { 479 $bucket_index = $i; 480 break; 481 } 482 } 483 484 // Add continuation attributes 485 $item->continuation = ($item->date_start < $curday); 486 $item->continues = ( $days > $bucket_cnt ); 487 488 // Assign the item to the available bucket 489 $multiday_buckets[$wday][$bucket_index] = array( 490 'colspan' => $bucket_cnt + 1, 491 'rowspan' => 1, 492 'filled' => TRUE, 493 'avail' => FALSE, 494 'all_day' => $all_day, 495 'item' => $item, 496 'wday' => $wday, 497 'entry' => theme($theme, $item, $view) 498 ); 499 500 // Block out empty buckets for the next days in this event for this week 501 for ($i = 0; $i < $bucket_cnt; $i++) { 502 $bucket = &$multiday_buckets[$i + $wday + 1]; 503 $bucket_row_count = count($bucket); 504 $row_diff = $bucket_index - $bucket_row_count; 505 506 // Fill up the preceding buckets - these are available for future 507 // events 508 for ( $j = 0; $j < $row_diff; $j++) { 509 $bucket[($bucket_row_count + $j) ] = array( 510 'entry' => ' ', 511 'colspan' => 1, 512 'rowspan' => 1, 513 'filled' => TRUE, 514 'avail' => TRUE, 515 'wday' => $wday, 516 'item' => NULL 517 ); 518 } 519 $bucket[$bucket_index] = array( 520 'filled' => FALSE, 521 'avail' => FALSE 522 ); 523 } 524 } 525 } 526 else { 527 $cur_cnt++; 528 // Assign to single day bucket 529 $singleday_buckets[$wday][$time][] = array( 530 'entry' => theme($theme, $item, $view), 531 'item' => $item, 532 'colspan' => 1, 533 'rowspan' => 1, 534 'filled' => TRUE, 535 'avail' => FALSE, 536 'wday' => $wday, 537 ); 538 } 539 } 540 else { 541 break; // exceeded count 542 } 543 } 544 } 545 } 546 } 547 } 548 549 // Add a more link if necessary 550 if ($max_events != CALENDAR_SHOW_ALL && $total_cnt > 0 && $cur_cnt < $total_cnt) { 551 $singleday_buckets[$wday][][] = array( 552 'entry' => theme('calendar_'. $view->date_info->calendar_type .'_multiple_node', $curday_date, $total_cnt, $view, $types), 553 'more_link' => TRUE, 554 'item' => NULL 555 ); 556 } 557 } 558 /** 559 * Build the contents of a single day for the $rows results. 560 */ 561 function calendar_build_day($curday, $view, $items) { 562 $curday_date = date_format($curday, DATE_FORMAT_DATE); 563 $selected = FALSE; 564 $max_events = !empty($view->date_info->style_max_items) ? $view->date_info->style_max_items : 0; 565 $types = array(); 566 $inner = array(); 567 $all_day = array(); 568 $empty = ''; 569 $link = ''; 570 $count = 0; 571 foreach ($items as $date => $day) { 572 if ($date == $curday_date) { 573 $count = 0; 574 $selected = TRUE; 575 ksort($day); 576 foreach ($day as $time => $hour) { 577 foreach ($hour as $key => $item) { 578 $count++; 579 $types[$item->type] = $item; 580 if (!$view->date_info->mini && ($max_events == CALENDAR_SHOW_ALL || $count <= $max_events || ($count > 0 && $max_events == CALENDAR_HIDE_ALL))) { 581 // Theme the item here unless this is a 'Day' or 'Week' view. 582 // Day and week views need to do more processing before rendering 583 // the item, so just past them the unrendered item. 584 $theme = isset($item->calendar_node_theme) ? $item->calendar_node_theme : 'calendar_'. $view->date_info->granularity .'_node'; 585 if ($item->calendar_all_day) { 586 $all_day[] = in_array($view->date_info->calendar_type, array('day', 'week')) ? $item : theme($theme, $item, $view); 587 } 588 else { 589 $key = date_format($item->date_start, 'H:i:s'); 590 $inner[$key][] = in_array($view->date_info->calendar_type, array('day', 'week')) ? $item : theme($theme, $item, $view); 591 } 592 } 593 } 594 } 595 } 596 } 597 ksort($inner); 598 if (empty($inner) && empty($all_day)) { 599 $empty = theme('calendar_empty_day', $curday_date, $view); 600 } 601 // We have hidden events on this day, use the theme('calendar_multiple_') to show a link. 602 if ($max_events != CALENDAR_SHOW_ALL && $count > 0 && $count > $max_events && $view->date_info->calendar_type != 'day' && !$view->date_info->mini) { 603 if ($view->date_info->style_max_items_behavior == 'hide' || $max_events == CALENDAR_HIDE_ALL) { 604 $all_day = array(); 605 $inner = array(); 606 } 607 $link = theme('calendar_'. $view->date_info->calendar_type .'_multiple_node', $curday_date, $count, $view, $types); 608 } 609 610 $content = array( 611 'date' => $curday_date, 612 'datebox' => theme('calendar_datebox', $curday_date, $view, $items, $selected), 613 'empty' => $empty, 614 'link' => $link, 615 'all_day' => $all_day, 616 'items' => $inner, 617 ); 618 return $content; 619 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |