[ Index ]

PHP Cross Reference of MyBB

title

Body

[close]

/inc/ -> functions_calendar.php (source)

   1  <?php
   2  /**
   3   * MyBB 1.6
   4   * Copyright 2010 MyBB Group, All Rights Reserved
   5   *
   6   * Website: http://mybb.com
   7   * License: http://mybb.com/about/license
   8   *
   9   * $Id$
  10   */
  11  
  12  /**
  13   * Build a mini calendar for a specific month
  14   *
  15   * @param array The calendar array for the calendar
  16   * @param int The month of the year
  17   * @param int The year
  18   * @param array Optional events cache for this calendar
  19   * @return string The built mini calendar
  20   */
  21  function build_mini_calendar($calendar, $month, $year, &$events_cache)
  22  {
  23      global $events_cache, $mybb, $templates, $theme, $monthnames;
  24  
  25      // Incoming month/year?
  26      if(!$year || $year > my_date("Y")+5)
  27      {
  28          $year = my_date("Y");
  29      }
  30      
  31      // Then the month
  32      if($month < 1 || $month > 12)
  33      {
  34          $month = my_date("n");
  35      }
  36  
  37      $weekdays = fetch_weekday_structure($calendar['startofweek']);
  38      
  39      $calendar_permissions = get_calendar_permissions($calendar['cid']);
  40  
  41      $month_link = get_calendar_link($calendar['cid'], $year, $month);
  42  
  43      $next_month = get_next_month($month, $year);
  44      $prev_month = get_prev_month($month, $year);
  45  
  46      $month_start_weekday = gmdate("w", gmmktime(0, 0, 0, $month, $calendar['startofweek']+1, $year));
  47      if($month_start_weekday != $weekdays[0] || $calendar['startofweek'] != 0)
  48      {
  49          $day = gmdate("t", gmmktime(0, 0, 0, $prev_month['month'], 1, $prev_month['year']));
  50          $day -= array_search(($month_start_weekday), $weekdays);
  51          $day += $calendar['startofweek']+1;
  52          $calendar_month = $prev_month['month'];
  53          $calendar_year = $prev_month['year'];
  54  
  55          if($day > 31 && $calendar['startofweek'] == 1 && $prev_month_days == 30)
  56          {
  57              // We need to fix it for these days
  58              $day = 25;
  59          }
  60      }
  61      else
  62      {
  63          $day = $calendar['startofweek']+1;
  64          $calendar_month = $month;
  65          $calendar_year = $year;
  66      }
  67  
  68      $prev_month_days = gmdate("t", gmmktime(0, 0, 0, $prev_month['month'], 1, $prev_month['year']));
  69  
  70      // So now we fetch events for this month
  71      $start_timestamp = gmmktime(0, 0, 0, $calendar_month, $day, $year);
  72      $num_days = gmdate("t", gmmktime(0, 0, 0, $month, 1, $year));
  73      $end_timestamp = gmmktime(23, 59, 59, $month, $num_days, $year);
  74  
  75      if(!$events_cache)
  76      {
  77          $events_cache = get_events($calendar, $start_timestamp, $end_timestamp, $calendar_permissions['canmoderateevents']);
  78      }
  79  
  80      $today = my_date("dnY");
  81  
  82      // Build weekday headers
  83      foreach($weekdays as $weekday)
  84      {
  85          $weekday_name = fetch_weekday_name($weekday, true);
  86          eval("\$weekday_headers .= \"".$templates->get("calendar_mini_weekdayheader")."\";");
  87      }
  88  
  89      for($row = 0; $row < 6; ++$row) // Iterate weeks (each week gets a row)
  90      {
  91          foreach($weekdays as $weekday_id => $weekday)
  92          {
  93              // Current month always starts on 1st row
  94              if($row == 0 && $day == $calendar['startofweek']+1)
  95              {
  96                  $in_month = 1;
  97                  $calendar_month = $month;
  98                  $calendar_year = $year;
  99              }
 100              else if($calendar_month == $prev_month['month'] && $day > $prev_month_days)
 101              {
 102                  $day = 1;
 103                  $in_month = 1;
 104                  $calendar_month = $month;
 105                  $calendar_year = $year;
 106              }
 107              else if($day > $num_days && $calendar_month != $prev_month['month'])
 108              {
 109                  $in_month = 0;
 110                  $calendar_month = $next_month['month'];
 111                  $calendar_year = $next_month['year'];
 112                  $day = 1;
 113                  if($calendar_month == $month)
 114                  {
 115                      $in_month = 1;
 116                  }
 117              }
 118  
 119              if($weekday_id == 0)
 120              {
 121                  $week_stamp = gmmktime(0, 0, 0, $calendar_month, $day, $calendar_year);
 122                  $week_link = get_calendar_week_link($calendar['cid'], $week_stamp);
 123              }
 124  
 125              if($weekday_id == 0 && $calendar_month == $next_month['month'])
 126              {
 127                  break;
 128              }
 129  
 130              // Any events on this specific day?
 131              if(@count($events_cache["$day-$calendar_month-$calendar_year"]) > 0)
 132              {
 133                  $link_to_day = true;
 134              }
 135  
 136              // Is the current day
 137              if($day.$calendar_month.$year == $today && $month == $calendar_month)
 138              {
 139                  $day_class = "trow_sep";
 140              }
 141              // Not in this month
 142              else if($in_month == 0)
 143              {
 144                  $day_class = "trow1";
 145              }
 146              // Just a normal day in this month
 147              else
 148              {
 149                  $day_class = "trow2";
 150              }
 151              if($link_to_day)
 152              {
 153                  $day_link = "<a href=\"".get_calendar_link($calendar['cid'], $calendar_year, $calendar_month, $day)."\">{$day}</a>";
 154              }
 155              else
 156              {
 157                  $day_link = $day;
 158              }
 159              eval("\$day_bits .= \"".$templates->get("calendar_mini_weekrow_day")."\";");
 160              $link_to_day = false;
 161              ++$day;
 162          }
 163          if($day_bits)
 164          {
 165              eval("\$calendar_rows .= \"".$templates->get("calendar_mini_weekrow")."\";");
 166          }
 167          $day_bits = "";
 168      }
 169      eval("\$mini_calendar .= \"".$templates->get("calendar_mini")."\";");
 170      return $mini_calendar;
 171  }
 172  
 173  /**
 174   * Cache available calendars in to memory or return the cached calendars
 175   *
 176   * @return array Cached calendars
 177   */
 178  function cache_calendars()
 179  {
 180      global $db;
 181      static $calendar_cache;
 182  
 183      if(is_array($calendar_cache))
 184      {
 185          return $calendar_cache;
 186      }
 187  
 188      $query = $db->simple_select("calendars", "*", "", array("order_by" => "disporder", "order_dir" => "asc"));
 189      while($calendar = $db->fetch_array($query))
 190      {
 191          $calendar_cache[$calendar['cid']] = $calendar;
 192      }
 193      return $calendar_cache;
 194  }
 195  
 196  /**
 197   * Fetch the calendar permissions for the current user for one or more calendars
 198   *
 199   * @param int Optional calendar ID. If none specified, permissions for all calendars are returned
 200   * @return array Array of permissions
 201   */
 202  function get_calendar_permissions($cid=0)
 203  {
 204      global $db, $mybb;
 205      static $calendar_permissions;
 206  
 207      $calendars = cache_calendars();
 208  
 209      $group_permissions = array(
 210          "canviewcalendar" => $mybb->usergroup['canviewcalendar'],
 211          "canaddevents" => $mybb->usergroup['canaddevents'],
 212          "canbypasseventmod" => $mybb->usergroup['canbypasseventmod'],
 213          "canmoderateevents" => $mybb->usergroup['canmoderateevents']
 214      );
 215  
 216      if(!is_array($calendars))
 217      {
 218          return $group_permissions;
 219      }
 220  
 221      $gid = $mybb->user['usergroup'];
 222  
 223      if(isset($mybb->user['additionalgroups']))
 224      {
 225          $gid .= ",".$mybb->user['additionalgroups'];
 226      }
 227  
 228      if(!is_array($calendar_permissions))
 229      {
 230          $calendar_permissions = array();
 231          $query = $db->simple_select("calendarpermissions", "*");
 232          while($permission = $db->fetch_array($query))
 233          {
 234              $calendar_permissions[$permission['cid']][$permission['gid']] = $permission;
 235          }
 236  
 237          // Add in our usergroup permissions (if custom ones are set, these aren't added)
 238          if(is_array($calendar_permissions))
 239          {
 240              foreach($calendar_permissions as $calendar => $permission)
 241              {
 242                  if(is_array($calendar_permissions[$calendar][$mybb->user['usergroup']]))
 243                  {
 244                      // Already has permissions set
 245                      continue;
 246                  }
 247  
 248                  // Use the group permissions!
 249                  $calendar_permissions[$calendar][$mybb->user['usergroup']] = $group_permissions;
 250                  $calendar_permissions[$calendar][$mybb->user['usergroup']]['cid'] = $calendar;
 251                  $calendar_permissions[$calendar][$mybb->user['usergroup']]['gid'] = $mybb->user['usergroup'];
 252              }
 253          }
 254      }
 255  
 256      if($cid > 0)
 257      {
 258          $permissions = fetch_calendar_permissions($cid, $gid, $calendar_permissions[$cid]);
 259          if(!$permissions)
 260          {
 261              $permissions = $group_permissions;
 262          }
 263      }
 264      else
 265      {
 266          foreach($calendars as $calendar)
 267          {
 268              $permissions[$calendar['cid']] = fetch_calendar_permissions($calendar['cid'], $gid, $calendar_permissions[$calendar['cid']]);
 269              if(!$permissions[$calendar['cid']])
 270              {
 271                  $permissions[$calendar['cid']] = $group_permissions;
 272              }
 273          }
 274      }
 275      return $permissions;
 276  }
 277  
 278  /**
 279   *
 280   */
 281  function fetch_calendar_permissions($cid, $gid, $calendar_permissions)
 282  {
 283      $groups = explode(",", $gid);
 284      
 285      if(!is_array($calendar_permissions))
 286      {
 287          return;
 288      }
 289  
 290      $current_permissions = array();
 291      
 292      foreach($groups as $gid)
 293      {
 294          // If this calendar has permissions set for this group
 295          if($calendar_permissions[$gid])
 296          {
 297              $level_permissions = $calendar_permissions[$gid];
 298              foreach($level_permissions as $permission => $access)
 299              {
 300                  if($access >= $current_permissions[$permission] || ($access == "yes" && $current_permissions[$permission] == "no") || !$current_permissions[$permission])
 301                  {
 302                      $current_permissions[$permission] = $access;
 303                  }
 304              }
 305          }
 306      }
 307      
 308      if(count($current_permissions) == 0)
 309      {
 310          return;
 311      }
 312      return $current_permissions;
 313  }
 314  
 315  /**
 316   * Build a calendar select list to jump between calendars
 317   *
 318   * @param int The selected calendar ID
 319   * @return string The calendar select
 320   */
 321  function build_calendar_jump($selected=0)
 322  {
 323      global $db, $mybb;
 324  
 325      $calendar_permissions = get_calendar_permissions();
 326  
 327      $calendars = cache_calendars();
 328  
 329      if(!is_array($calendars))
 330      {
 331          return;
 332      }
 333  
 334      foreach($calendars as $calendar)
 335      {
 336          if($calendar_permissions[$calendar['cid']]['canviewcalendar'] == 0)
 337          {
 338              continue;
 339          }
 340          $calendar['name'] = htmlspecialchars_uni($calendar['name']);
 341          $sel = "";
 342          if($selected == $calendar['cid'] || ($selected == 0 && $calendar['disporder'] == 1))
 343          {
 344              $sel = "selected=\"selected\"";
 345          }
 346          $jump_options .= "<option value=\"{$calendar['cid']}\" $sel>{$calendar['name']}</option>\n";
 347      }
 348      return "<select name=\"calendar\">\n{$jump_options}</select>";
 349  }
 350  
 351  /**
 352   * Fetch the next calendar month from a specified month/year
 353   *
 354   * @param int The month
 355   * @param int The year
 356   * @return array Array of the next month and next year
 357   */
 358  function get_next_month($month, $year)
 359  {
 360      global $monthnames;
 361  
 362      if($month == 12)
 363      {
 364          $nextmonth = 1;
 365          $nextyear = $year+1;
 366      }
 367      else
 368      {
 369          $nextmonth = $month+1;
 370          $nextyear = $year;
 371      }
 372  
 373      return array("month" => $nextmonth, "year" => $nextyear, "name" => $monthnames[$nextmonth]);
 374  }
 375  
 376  /**
 377   * Fetch the previous calendar month from a specified month/year
 378   *
 379   * @param int The month
 380   * @param int The year
 381   * @return array Array of the previous month and previous year
 382   */
 383  function get_prev_month($month, $year)
 384  {
 385      global $monthnames;
 386  
 387      if($month == 1)
 388      {
 389          $prevmonth = 12;
 390          $prevyear = $year-1;
 391      }
 392      else
 393      {
 394          $prevmonth = $month-1;
 395          $prevyear = $year;
 396      }
 397  
 398      return array("month" => $prevmonth, "year" => $prevyear, "name" => $monthnames[$prevmonth]);
 399  }
 400  
 401  /**
 402   * Fetch the events for a specific calendar and date range
 403   *
 404   * @param int The calendar ID
 405   * @param int Start time stamp
 406   * @param int End time stmap
 407   * @param int 1 to fetch unapproved events too
 408   * @param int The user ID to fetch private events for (0 fetches none)
 409   * @return array Array of events
 410   */
 411  function get_events($calendar, $start, $end, $unapproved=0, $private=1)
 412  {
 413      global $db, $mybb;
 414      
 415      // We take in to account timezones here - we add/subtract 12 hours from our GMT time ranges
 416      $start -= 12*3600;
 417      $end += 12*3600;
 418  
 419      if($unapproved != 1)
 420      {
 421          $visible_where = " AND e.visible='1'";
 422      }
 423      $query = $db->query("
 424          SELECT u.*, e.*
 425          FROM ".TABLE_PREFIX."events e
 426          LEFT JOIN ".TABLE_PREFIX."users u ON (u.uid=e.uid)
 427          WHERE e.cid='{$calendar['cid']}' {$visible_where} AND ((e.endtime>={$start} AND e.starttime<={$end}) OR (e.endtime=0 AND e.starttime>={$start} AND e.starttime<={$end})) AND ((e.uid='{$mybb->user['uid']}' AND private='1') OR private!='1')
 428          ORDER BY endtime DESC
 429      ");
 430      while($event = $db->fetch_array($query))
 431      {
 432          if($event['ignoretimezone'] == 0)
 433          {
 434              $offset = $event['timezone'];
 435          }
 436          else
 437          {
 438              $offset = $mybb->user['timezone'];
 439          }
 440          $event['starttime_user'] = $event['starttime']+($offset*3600);
 441  
 442          // Single day event
 443          if($event['endtime'] == 0)
 444          {
 445              $event_date = gmdate("j-n-Y", $event['starttime_user']);
 446              $events_cache[$event_date][] = $event;
 447          }
 448          // Ranged event
 449          else
 450          {
 451              $event_date = explode("-", gmdate("j-n-Y", $event['starttime_user']));
 452              $event['endtime_user'] = $event['endtime']+($offset*3600);
 453              $event['weekday_start'] = $calendar['startofweek'];
 454  
 455              $start_day = gmmktime(0, 0, 0, $event_date[1], $event_date[0], $event_date[2]);
 456  
 457              $event['repeats'] = @unserialize($event['repeats']);
 458  
 459              // Event does not repeat - just goes over a few days
 460              if($event['repeats']['repeats'] == 0)
 461              {
 462                  if($start_day < $start)
 463                  {
 464                      $range_start = gmmktime(0, 0, 0, gmdate("n", $start), gmdate("j", $start), gmdate("Y", $start));
 465                  }
 466                  else
 467                  {
 468                      $range_start = $start_day;
 469                  }
 470              }
 471              else
 472              {
 473                  $range_start = fetch_next_occurance($event, array("start" => $start, "end" => $end), $start_day, true);
 474              }
 475              $first = "";
 476              $event_date = explode("-", gmdate("j-n-Y", $range_start));
 477              
 478              // Get rid of hour/minutes because sometimes they cause the events to stretch into the next day
 479              $range_end = gmmktime(23, 59, 59, gmdate("n", $event['endtime_user']), gmdate("j", $event['endtime_user']), gmdate("Y", $event['endtime_user']));
 480              while($range_start < $range_end)
 481              {
 482                  // Outside the dates we care about, break! (No unnecessary looping here!)
 483                  if($range_start > $end || !$range_start)
 484                  {
 485                      break;
 486                  }
 487                  if($range_start >= $start)
 488                  {
 489                      $day_date = gmdate("j-n-Y", $range_start);
 490                      if($first && $day_date != "{$first}")
 491                      {
 492                          $events_cache[$day_date][] = &$events_cache["{$first}"][$count];
 493                      }
 494                      else if(!$first)
 495                      {
 496                          $count = count($events_cache["{$day_date}"]);
 497                          $first = $day_date;
 498                          $events_cache["{$day_date}"][] = $event;
 499                      }
 500                  }
 501                  if($event['repeats']['repeats'] == 0)
 502                  {
 503                      $range_start += 86400;
 504                  }
 505                  else
 506                  {
 507                      $range_start = fetch_next_occurance($event, array("start" => $start, "end" => $end), $range_start);
 508                  }
 509              }
 510          }
 511      }
 512      return $events_cache;
 513  }
 514  
 515  /**
 516   * Fetch the birthdays for one or more months or a specific day
 517   *
 518   * @param mixed Integer of the month or array of months
 519   * @param int Day of the specific month (if only one month specified above)
 520   * @return array Array of birthdays
 521   */
 522  function get_birthdays($months, $day="")
 523  {
 524      global $db;
 525  
 526      $year = my_date("Y");
 527  
 528      if(!is_array($months))
 529      {
 530          $months = array($months);
 531      }
 532  
 533      foreach($months as $month)
 534      {
 535          if($day)
 536          {
 537              $day_where = "{$day}-{$month}";
 538          }
 539          else
 540          {
 541              $day_where = "%-{$month}";
 542          }
 543          if($month == 3 && ($day == 1 || !$day) && my_date("L", gmmktime(0, 0, 0, $month, 1, $year)) != 1)
 544          {
 545              $where[] = "birthday LIKE '29-2%' OR birthday='29-2'";
 546              $feb_fix = 1;
 547          }
 548          $where[] = "birthday LIKE '{$day_where}-%' OR birthday LIKE '{$day_where}'";
 549      }
 550  
 551      $where = implode(" OR ", $where);
 552  
 553      $query = $db->simple_select("users", "uid, username, birthday, birthdayprivacy, usergroup, displaygroup", $where);
 554      while($user = $db->fetch_array($query))
 555      {
 556          $bday = explode("-", $user['birthday']);
 557          if($bday[2] && $bday[2] < $year)
 558          {
 559              $user['age'] = $year - $bday[2];
 560          }
 561          if($feb_fix == 1 && $bday[0] == 29 && $bday[1] == 2)
 562          {
 563              $bdays["1-3"][] = $user;
 564          }
 565          else
 566          {
 567              $bdays["$bday[0]-$bday[1]"][] = $user;
 568          }
 569      }
 570      if($day)
 571      {
 572          return $bdays["$day-$month"];
 573      }
 574      return $bdays;
 575  }
 576  
 577  /**
 578   * Fetch an ordered list of weekdays depended on a specified starting day
 579   *
 580   * @param int The weekday we want to start the week with
 581   * @return array Ordered list of weekdays dependant on start of week
 582   */
 583  function fetch_weekday_structure($week_start)
 584  {
 585      switch($week_start)
 586      {
 587          case "1":
 588              $weekdays = array(1,2,3,4,5,6,0);
 589              break;
 590          case "2":
 591              $weekdays = array(2,3,4,5,6,0,1);
 592              break;
 593          case "3":
 594              $weekdays = array(3,4,5,6,0,1,2);
 595              break;
 596          case "4":
 597              $weekdays = array(4,5,6,0,1,2,3);
 598              break;
 599          case "5":
 600              $weekdays = array(5,6,0,1,2,3,4);
 601              break;
 602          case "6":
 603              $weekdays = array(6,0,1,2,3,4,5);
 604              break;
 605          default:
 606              $weekdays = array(0,1,2,3,4,5,6);
 607              break;
 608      }
 609      return $weekdays;
 610  }
 611  
 612  /**
 613   * Fetch a weekday name based on a number
 614   *
 615   * @param int The weekday number
 616   * @param boolean True to fetch the short name ('S'), false to fetch full name
 617   * @param string The weekday name
 618   */
 619  function fetch_weekday_name($weekday, $short=false)
 620  {
 621      global $lang;
 622      switch($weekday)
 623      {
 624          case 1:
 625              $weekday_name = $lang->monday;
 626              $short_weekday_name = $lang->short_monday;
 627              break;
 628          case 2:
 629              $weekday_name = $lang->tuesday;
 630              $short_weekday_name = $lang->short_tuesday;
 631              break;
 632          case 3:
 633              $weekday_name = $lang->wednesday;
 634              $short_weekday_name = $lang->short_wednesday;
 635              break;
 636          case 4:
 637              $weekday_name = $lang->thursday;
 638              $short_weekday_name = $lang->short_thursday;
 639              break;
 640          case 5:
 641              $weekday_name = $lang->friday;
 642              $short_weekday_name = $lang->short_friday;
 643              break;
 644          case 6:
 645              $weekday_name = $lang->saturday;
 646              $short_weekday_name = $lang->short_saturday;
 647              break;
 648          case 0:
 649              $weekday_name = $lang->sunday;
 650              $short_weekday_name = $lang->short_sunday;
 651              break;
 652      }
 653      
 654      if($short == true)
 655      {
 656          return $short_weekday_name;
 657      }
 658      else
 659      {
 660          return $weekday_name;
 661      }
 662  }
 663  
 664  /**
 665   * Fetches the next occurance for a repeating event.
 666   *
 667   * @param array The event array
 668   * @param array The range of start/end timestamps
 669   * @param int The last occurance of this event
 670   * @param boolean True if this is our first iteration of this function (Does some special optimised calculations on false)
 671   * @return int The next occurance timestamp
 672   */
 673  function fetch_next_occurance($event, $range, $last_occurance, $first=false)
 674  {
 675      $new_time = $last_occurance;
 676      
 677      $repeats = $event['repeats'];
 678  
 679      $start_day = explode("-", gmdate("j-n-Y", $event['starttime_user']));
 680      $start_date = gmmktime(0, 0, 0, $start_day[1], $start_day[0], $start_day[2]);
 681  
 682      if($repeats['repeats'] == 0)
 683      {
 684          $new_time += 86400;
 685      }
 686      // Repeats daily
 687      else if($repeats['repeats'] == 1)
 688      {
 689          // If this isn't the first time we've called this function then we can just tack on the time since $last_occurance
 690          if($first == false)
 691          {
 692              $new_time += 86400*$repeats['days'];
 693          }
 694          else
 695          {
 696              // Need to count it out
 697              if($range['start'] > $event['starttime'])
 698              {
 699                  $days_since = ceil(($range['start']-$start_date)/86400);
 700                  $occurances = floor($days_since/$repeats['days']);
 701                  $next_date = $occurances*$repeats['days'];
 702                  $new_time = $event['starttime']+(86400*$next_date);
 703              }
 704              else
 705              {
 706                  $new_time = $start_date;
 707              }
 708          }
 709      }
 710      // Repeats on weekdays only
 711      else if($repeats['repeats'] == 2)
 712      {
 713          if($first == false)
 714          {
 715              $last_dow = gmdate("w", $last_occurance);
 716              // Last day of week = friday, +3 gives monday
 717              if($last_dow == 5)
 718              {
 719                  $new_time += 86400*3;
 720              }
 721              // Still in week, add a day
 722              else
 723              {
 724                  $new_time += 86400;
 725              }
 726          }
 727          // First loop with start date
 728          else
 729          {
 730              if($range['start'] < $event['starttime'])
 731              {
 732                  $start = $event['starttime'];
 733              }
 734              else
 735              {
 736                  $start = $range['start'];
 737              }
 738              $first_dow = gmdate("w", $start);
 739              if($first_dow == 6)
 740              {
 741                  $new_time = $start + (86400*2);
 742              }
 743              else if($first_dow == 0)
 744              {
 745                  $new_time = $start + 86400;
 746              }
 747              else
 748              {
 749                  $new_time = $start;
 750              }
 751          }
 752      }
 753      // Repeats weekly
 754      else if($repeats['repeats'] == 3)
 755      {
 756          $weekdays = fetch_weekday_structure($event['weekday_start']);
 757          $last_dow = gmdate("w", $last_occurance);
 758          if($first == true)
 759          {
 760              $last_dow = -1;
 761              $start_day = gmdate('w', $last_occurance);
 762              if(in_array($start_day, $weekdays))
 763              {
 764                  $next_dow = 0;
 765              }
 766          }
 767          else
 768          {
 769              foreach($repeats['days'] as $weekday)
 770              {
 771                  if($weekday > $last_dow)
 772                  {
 773                      $next_dow = $weekday;
 774                      break;
 775                  }
 776              }
 777          }
 778          if(!isset($next_dow))
 779          {
 780              // Fetch first weekday
 781              $first = $repeats['days'][0]*86400;
 782              $new_time += $first;
 783              // Increase x weeks
 784              $new_time += (7-$last_dow)*86400;
 785              $new_time += (($repeats['weeks']-1)*604800);
 786          }
 787          else
 788          {
 789              // Next day of week exists
 790              if($last_dow > 0)
 791              {
 792                  $day_diff = $next_dow-$last_dow;
 793              }
 794              else
 795              {
 796                  $day_diff = $next_dow;
 797              }
 798              $new_time += $day_diff*86400;
 799          }
 800      }
 801      // Repeats monthly
 802      else if($repeats['repeats'] == 4)
 803      {
 804          $last_month = gmdate("n", $last_occurance);
 805          $last_year = gmdate("Y", $last_occurance);
 806          $last_day = gmdate("j", $last_occurance);
 807          $last_num_days = gmdate("t", $last_occurance);
 808  
 809          // X of every Y months
 810          if($repeats['day'])
 811          {
 812              if($first == true)
 813              {
 814                  if($last_day <= $repeats['day'])
 815                  {
 816                      $new_time = gmmktime(0, 0, 0, $last_month, $repeats['day'], $last_year);
 817                  }
 818                  else
 819                  {
 820                      $new_time = gmmktime(0, 0, 0, $last_month+1, $repeats['day'], $last_year);
 821                      if($new_time > $event['endtime'])
 822                      {
 823                          return false;
 824                      }
 825                  }
 826              }
 827              else
 828              {
 829                  $new_time = gmmktime(0, 0, 0, $last_month+$repeats['months'], $repeats['day'], $last_year);
 830              }
 831          }
 832          // The 1st/etc (weekday) of every X months
 833          else
 834          {
 835              if($first == true)
 836              {
 837                  $new_time = fetch_weekday_monthly_repetition($repeats, $last_month, $last_year);
 838                  if($new_time < $last_occurance)
 839                  {
 840                      $new_time = fetch_weekday_monthly_repetition($repeats, $last_month+1, $last_year);
 841                  }
 842              }
 843              else
 844              {
 845                  $new_time = fetch_weekday_monthly_repetition($repeats, $last_month+$repeats['months'], $last_year);
 846              }
 847          }
 848      }
 849      // Repeats yearly
 850      else if($repeats['repeats'] == 5)
 851      {
 852          $last_year = gmdate("Y", $last_occurance);
 853  
 854          // Repeats on (day) of (month) every (years)
 855          if($repeats['day'])
 856          {
 857              if($first == true)
 858              {
 859                  $new_time = gmmktime(0, 0, 0, $repeats['month'], $repeats['day'], $last_year);
 860                  if($new_time < $last_occurance)
 861                  {
 862                      $new_time = gmmktime(0, 0, 0, $repeats['month'], $repeats['day'], $last_year+1);
 863                  }
 864              }
 865              else
 866              {
 867                  $new_time = gmmktime(0, 0, 0, $repeats['month'], $repeats['day'], $last_year+$repeats['years']);
 868              }
 869          }
 870          // The 1st/etc (weekday) of (month) every (years)
 871          else
 872          {
 873              if($first == true)
 874              {
 875                  $new_time = fetch_weekday_monthly_repetition($repeats, $repeats['month'], $last_year);
 876                  if($new_time < $last_occurance)
 877                  {
 878                      $new_time = fetch_weekday_monthly_repetition($repeats, $repeats['month'], $last_year+1);
 879                  }
 880              }
 881              else
 882              {
 883                  $new_time = fetch_weekday_monthly_repetition($repeats, $repeats['month'], $last_year+$repeats['years']);
 884              }
 885          }
 886      }
 887      return $new_time;
 888  }
 889  
 890  /**
 891   * Fetch a friendly repetition value for a specific event (Repeats every x months etc)
 892   *
 893   * @param array The array of the event
 894   * @return string The friendly repetition string
 895   */
 896  function fetch_friendly_repetition($event)
 897  {
 898      global $lang;
 899  
 900      $monthnames = array(
 901          "offset",
 902          $lang->month_1,
 903          $lang->month_2,
 904          $lang->month_3,
 905          $lang->month_4,
 906          $lang->month_5,
 907          $lang->month_6,
 908          $lang->month_7,
 909          $lang->month_8,
 910          $lang->month_9,
 911          $lang->month_10,
 912          $lang->month_11,
 913          $lang->month_12
 914      );
 915  
 916      if(!is_array($event['repeats']))
 917      {
 918          $event['repeats'] = @unserialize($event['repeats']);
 919          if(!is_array($event['repeats']))
 920          {
 921              return false;
 922          }
 923      }
 924  
 925      $repeats = $event['repeats'];
 926  
 927      switch($repeats['repeats'])
 928      {
 929          case 1:
 930              if($repeats['days'] <= 1)
 931              {
 932                  return $lang->repeats_every_day;
 933              }
 934              return $lang->sprintf($lang->repeats_every_x_days, $event['repeats']['days']);
 935              break;
 936          case 2:
 937              return $lang->repeats_on_weekdays;
 938              break;
 939          case 3:
 940              if($event['repeats']['days'] || count($event['repeats']['days']) == 7)
 941              {
 942                  foreach($event['repeats']['days'] as $id => $weekday)
 943                  {
 944                      $weekday_name = fetch_weekday_name($weekday);
 945                      if($event['repeats']['days'][$id+1] && $weekdays)
 946                      {
 947                          $weekdays .= $lang->comma;
 948                      }
 949                      else if(!$event['repeats']['days'][$id+1] && $weekdays)
 950                      {
 951                          $weekdays .= " {$lang->and} ";
 952                      }
 953                      $weekdays .= $weekday_name;
 954                  }
 955              }
 956              if($event['repeats']['weeks'] == 1)
 957              {
 958                  if($weekdays)
 959                  {
 960                      return $lang->sprintf($lang->every_week_on_days, $weekdays);
 961                  }
 962                  else
 963                  {
 964                      return $lang->sprintf($lang->every_week);
 965                  }
 966              }
 967              else
 968              {
 969                  if($weekdays)
 970                  {
 971                      return $lang->sprintf($lang->every_x_weeks_on_days, $event['repeats']['weeks'], $weekdays);
 972                  }
 973                  else
 974                  {
 975                      return $lang->sprintf($lang->every_x_weeks, $event['repeats']['weeks']);
 976                  }
 977              }
 978              break;
 979          case 4:
 980              if($event['repeats']['day'])
 981              {
 982                  if($event['repeats']['months'] == 1)
 983                  {
 984                      return $lang->sprintf($lang->every_month_on_day, $event['repeats']['day']);
 985                  }
 986                  else
 987                  {
 988                      return $lang->sprintf($lang->every_x_months_on_day, $event['repeats']['day'], $event['repeats']['months']);
 989                  }
 990              }
 991              else
 992              {
 993                  $weekday_name = fetch_weekday_name($event['repeats']['weekday']);
 994                  $occurance = "weekday_occurance_".$event['repeats']['occurance'];
 995                  $occurance = $lang->$occurance;
 996                  if($event['repeats']['months'] == 1)
 997                  {
 998                      return $lang->sprintf($lang->every_month_on_weekday, $occurance, $weekday_name);
 999                  }
1000                  else
1001                  {
1002                      return $lang->sprintf($lang->every_x_months_on_weekday, $occurance, $weekday_name, $event['repeats']['months']);
1003                  } 
1004              }
1005              break;
1006          case 5:
1007              $month = $monthnames[$event['repeats']['month']];
1008              if($event['repeats']['day'])
1009              {
1010                  if($event['repeats']['years'] == 1)
1011                  {
1012                      return $lang->sprintf($lang->every_year_on_day, $event['repeats']['day'], $month);
1013                  }
1014                  else
1015                  {
1016                      return $lang->sprintf($lang->every_x_years_on_day, $event['repeats']['day'], $month, $event['repeats']['years']);
1017                  }
1018              }
1019              else
1020              {
1021                  $weekday_name = fetch_weekday_name($event['repeats']['weekday']);
1022                  $occurance = "weekday_occurance_".$event['repeats']['occurance'];
1023                  $occurance = $lang->$occurance;
1024                  if($event['repeats']['years'] == 1)
1025                  {
1026                      return $lang->sprintf($lang->every_year_on_weekday, $occurance, $weekday_name, $month);
1027                  }
1028                  else
1029                  {
1030                      return $lang->sprintf($lang->every_x_year_on_weekday, $occurance, $weekday_name, $month, $event['repeats']['years']);
1031                  }
1032              }
1033              break;
1034      }
1035  }
1036  
1037  /**
1038   * Fetch a timestamp for "the first/second etc weekday" for a month.
1039   *
1040   * @param array The repetition array from the event
1041   * @param int The month of the year
1042   * @param int The year
1043   * @return int The UNIX timestamp
1044   */
1045  function fetch_weekday_monthly_repetition($repeats, $month, $year)
1046  {
1047      $first_last = gmmktime(0, 0, 0, $month, 1, $year);
1048      $first_dow = gmdate("w", $first_last);
1049      $day = 1+($repeats['weekday']-$first_dow);
1050      if($day < 1)
1051      {
1052          $day += 7;
1053      }
1054      if($repeats['occurance'] != "last")
1055      {
1056          $day += ($repeats['occurance']-1)*7;
1057      }
1058      else
1059      {
1060          $last_dow = gmdate("w", gmmktime(0, 0, 0, $month, gmdate("t", $first_last), $year));
1061          $day = (gmdate("t", $first_last)-$last_dow)+$repeats['weekday'];
1062          if($day > gmdate("t", $first_dow))
1063          {
1064              $day -= 7;
1065          }
1066      }
1067      return gmmktime(0, 0, 0, $month, $day, $year);
1068  }
1069  ?>


Generated: Tue Oct 8 19:19:50 2013 Cross-referenced by PHPXref 0.7.1