Location: PHPKode > projects > O - OpenSource GroupWare > osgw/calendar/classes/class.recurrence.php
<?php
/**************************************************************************
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   @Authors:	Ryan Thompson(hide@address.com)
***************************************************************************/
include($O->dir ."/calendar/classes/class.events.php");
class recurrence extends events
{
	function set_recurrence($data, $recur_type, $event_id, $start_time, $end_time, $db_call)
	{
		GLOBAL $O, $db;
	
		switch($recur_type)
		{

			case 0:
				//No Recurrence. Nothing to be done
			break;
			case 1:
		
				//Daily
				$type = 1;
				
				$frequency = $data['recur_freq'] * 86400;
				if($data['recur_end'] == 2)
				{
				
					//Take one recurrence off. O doesn't count day 1 as an occurrence and
					//will display one extra.
					$times = $data['recur_after'] - 1;
					$end = $start_time + ($times * ($frequency));
				
				} elseif($data['recur_end'] == 1)
				{
					$end = date('U', mktime(0,0,0, $data['recur_end_month'], $data['recur_end_day'], $data['recur_end_year']));
				} else {
					$end = 0;
				}
				if($db_call == "UPDATE")
				{
					$sql = "UPDATE o_recurrence SET type='$recur_type',frequency='$frequency',times='$times',
						rstart='$start_time',rend='$end',data='0' WHERE event_id='$event_id'";
				} else {
				
					$sql = "INSERT INTO o_recurrence (event_id, type, frequency, times, rstart, rend, data)
						VALUES ('$event_id','$recur_type','$frequency','$times','$start_time','$end','0')";
				}
				$db->query($sql);
				
				
			break;
			case 2:
				//weekly
				$frequency = $data['recur_freq'];
				$start = $start_time;
				switch($data['recur_end'])
				{
					case 0:
						$end = 0;
					break;
					case 1:
						$end = date('U', mktime(0,0,0, $data['recur_end_month'], $data['recur_end_day'], $data['recur_end_year']));
					break;
					case 2:
						//Remove one for the first day
						$times = $data['recur_after'];
						$end = $start_time + (($times * $frequency) * (DAY_SEC * 7));
						
					break;
				}
				$db_data = serialize($data['recur_weekday']);
				if($db_call == "UPDATE")
				{
					$sql = "UPDATE o_recurrence SET type='$recur_type',frequency='$frequency',times='$times',
							rstart='$start_time',rend='$end',data='$db_data' WHERE event_id='$event_id'";
				} else {
					$sql = "INSERT INTO o_recurrence (event_id, type, frequency, times, rstart, rend, data)
						VALUES ('$event_id','$recur_type','$frequency','$times','$start_time','$end','$db_data')";
				}
				$db->query($sql);
				
				
				
				//Hold weekdays that it occurs on
				
			break;
			case 3:
				//Monthly
				
					$start = $start_time;
					$frequency = $data['recur_freq'];
					switch($data['recur_end'])
					{
						case 0:
							$end = 0;
						break;
						case 1:
							$end = date('U', mktime(0,0,0, $data['recur_end_month'], $data['recur_end_day'], $data['recur_end_year']));
						break;
						case 2:
							$times = $data['recur_after'] - 1;
							$end = $start_time + ($times * ($frequency));
						break;
					}

					switch($data['recur_monthly_type'])
					{
						//by date					
						case 0:
							$db_data = $data['recur_monthly_type']. ":". $data['start_day'];
							
							
						break;
						
						//by day
						case 1:
							$day_of_week = date('w', $start_time);
							
							$first_weekday = date('U', mktime(0,0,0,$data['start_month'], 1, $data['start_year']));
							$total_days = date('t', $start_time);
							$last_day = date('U', mktime(23,59,59, $data['start_month'], $total_days, $data['start_year']));
							
							$first_week_num = date('W', $first_weekday);
							$working_week_num = date('W', $start_time);
							/*
							//Don't know if I need it yet.
							$total_weeks = ceil($total_days / 7);
							
							if($first_weekday > $day_of_week)
							{
								$total_weeks_for_day = $total_weeks - 1;
							} else {
								$total_weeks_for_day = $total_weeks;
							}
							$data['start_day'] / $total_weeks_for_day;
							*/
							
							
							$week_num = $working_week_num - $first_week_num;
					
							
						$db_data = $data['recur_monthly_type'] .":". $day_of_week .":". $week_num;
							
							
						break;
					}
					
				if($db_call == "UPDATE")
				{
					$sql = "UPDATE o_recurrence SET type='$recur_type',frequency='$frequency',times='$times',
							rstart='$start_time',rend='$end',data='$db_data' WHERE event_id='$event_id'";
				} else {
									
					$sql = "INSERT INTO o_recurrence (event_id, type, frequency, times, rstart, rend, data)
						VALUES ('$event_id','$recur_type','$frequency','$times','$start_time','$end','$db_data')";
				}
		
				$db->query($sql);
			
			
			
			break;
			case 4:
				//Annually

				$start = date('U', mktime(0,0,0,$data['start_month'], $data['start_day'],$data['start_year']));

				if($data['recur_end'] == 0)
				{
					$end = 0;
					$times = '0';
				} elseif($data['recur_end'] == 1)
				{
					$end =  date('U', mktime(0,0,0, $data['recur_end_day'],$data['recur_end_month'],$data['recur_end_year']));
					//$time = '99999';

				} else {
					$end = '0';
					$times = $data['recur_after'];
				}


				$recur_day = $data['start_day'];

				$recur_month = $data['recur_annually'];
				$sql = "INSERT INTO o_recurrence (event_id, type, frequency, times, rstart, rend, data)
					VALUES ('$event_id','$recur_type','$data[frequency]','$times','$start','$end',
					'$data[start_month]')";
				$db->query($sql);
				


			break;
		}
	}

	function get_month_recur($day, $month, $year)
	{
		GLOBAL $O, $db;
		$sql = "SELECT event_id, evt_start FROM o_calendar WHERE recurring='1' AND user_id='". $O->user->user_id ."'";
		
		$db->query($sql);
		
		$i = 0;
		while($db->fetch_results())
		{
			$recurrences[$i] = $O->db->record;
			$i++;
		}
		$ret = NULL;
		for($i = 0; $i < count($recurrences); $i++)
		{
		
			if($recur = $this->get_recurrence($day, $month, $year, $recurrences[$i]['event_id'], $recurrences[$i]['start']))
			{
				$ret = array_merge($ret, $recur);
			}
			

		}
		
		if(!is_null($ret))
		{

			return $ret;
		} else {

			return FALSE;
		}
	}


	function get_day_recurrence($day, $month, $year, $hour, $min)
	{
		GLOBAL $O, $db;
	
		//return date('d-M-Y G:i:s', mktime($hour, $min, 0, $month, $day, $year));
		$sql = "SELECT event_id, evt_start FROM o_calendar WHERE recurring='1'";
		$db->query($sql);
	
		$i = 0;
		while($db->fetch_results())
		{
			$recurrences[$i] = $db->record;
			$i++;
		}
		$ret = NULL;
		
		for($i = 0; $i < count($recurrences); $i++)
		{

	
			if($recur = $this->get_recurrence($day, $month, $year, $recurrences[$i]['event_id'], $recurrences[$i]['start']))
			{
				$start_hour = date('G', $recur[$i]['start']);
				if($start_hour == $hour)
				{
					$ret = array_merge($ret, $recur);
				}
				
			}
			

		}

		if(!is_null($ret))
		{

			return $ret;
		} else {

			return FALSE;
		}
	
	}
	function get_recurrence($day, $month, $year, $id, $start)
	{
		GLOBAL $O, $db;
		$current_date = date('U', mktime(0,0,0,$month, $day, $year));

		$sql = "SELECT * FROM o_recurrence LEFT JOIN o_calendar ON o_recurrence.event_id=o_calendar.event_id WHERE 
			o_calendar.event_id='$id'";
			

		$db->query($sql);
		$db->fetch_results();
		$start = $db->record['rstart'];
		$end = $db->record['rend'];
		$t = 0;
		
		switch($db->record['type'])
		{
			case 1:
			
				//Daily
				$start = date('n:j:Y', $O->db->record['rstart']);
				$start = explode(':', $start);
				$start_of_first_day = date('U', mktime(0,0,0, $start[0], $start[1], $start[2]));
				
				$end = $db->record['rend'];
				//If were within the start and end
				if($current_date >= $db->record['rstart'] && $current_date <= $end || $end == 0)
				{
					//Days since start
					if(strlen($end))
					{
					
					}
					$diff = $current_date - $start_of_first_day;
					$diff_days = $diff / 86400;
					$freq_in_days = $db->record['frequency'] / 86400;
					if($diff_days%$freq_in_days == 0)
					{
						$recur[$t] = $O->db->record;
						$t++;
					}
				}
					
	
			break;
			case 2:
				//Weekly
				
				if(date('U', mktime(23,59,59,$month, $day, $year)) >= $start)
				{
				
					if(date('U', mktime(23,59,59,$month, $day, $year)) <= $end || $end == 0)
					{
					
				
					$db_data = unserialize($db->record['data']);	
					$current_date = date('U', mktime(0,0,0, $month, $day, $year));
					$weekday = date('w', $current_date);
					$week_num_start = date('W', $start);
					$week_num_current = date('W', $current_date);

					$diff_sec = $current_date - $start;
					$diff_days = ($diff_sec / 3600) / 24;
					//Don't know if this patch will work
					//Need a way to find the week difference and return the same value for same weeks
					
					if($weekday > 4)
					{
						$diff_weeks = floor($diff_days / 7);
					} else {
						$diff_weeks = round($diff_days / 7);
					}
				

					if($diff_weeks % $db->record['frequency'] == 0)
					{
						if(in_array($weekday, $db_data))
						{
							//echo $day;
							$recur[$t] = $db->record;
							$t++;
						}
					}
					}
				}
			break;
			case 3:
				//Monthly
				$temp = explode(':', $db->record['data']);
				$recur_monthly_type = $temp[0];
				
				//We need it to be available for that entire day
				if(date('U', mktime(23,59,59,$month, $day, $year)) >= $start)
				{
					switch($recur_monthly_type)
					{
						//by date					
						case 0:
							$start = date('U', $db->record['rstart']);
					
							$recur_day = $temp[1];
							$month_start = date('n', $start);
							$year_start = date('Y', $start);
							
							date('d-M-Y', $current_date);
							
							//This function (modified) was found on PHP.net to find months between two dates.
   							$dateLow = $start;
   							$dateHigh = strftime('%m/%Y', $current_date);
							$month_diff = 0;
							while (strftime('%m/%Y', $start) != $dateHigh) 
							{
       							$month_diff++;
							     $start = strtotime('+1 month', $start);
							}
							//End 
							if($recur_day == $day)
							{
								
								if(($month_diff) % $db->record['frequency'] == 0)
								{
									
									$recur[$t] = $db->record;
									$t++;
							
								}
								
							}
						break;
						
						//by day
						case 1:
						
							$weekday = $temp[1];
							$num = $temp[2];
							$first_weekday = date('U', mktime(0,0,0,$month, 1, $year));
							
							
							$first_week_num = date('W', $first_weekday);
							$working_week_num = date('W', mktime(0,0,0, $month, $day, $year));
							$week_num = $working_week_num - $first_week_num;
	
							if($week_num == $num && $weekday == date('w',mktime(0,0,0,$month,$day,$year)))
							{
								$recur[$t] = $db->record;
								$t++;
							}
						break;
					}
						
				}	
					
					
			break;
			case 4:
				//Annual
				$start = $O->db->record['rstart'];
				$start_year = date('Y', $start);
				$start_day = date('j', $start);

				$start_month = date('n', $start);
				$next_date = date('U', mktime(0,0,0,date('n', $start), date('j', $start), $year));
				if($db->record['rend'] == 0)
				{
					if($O->db->record['times'] == 0)
					{
						$times = 100;
					} else {
						$times = $O->db->record['times'];
					}

					if($year >= $start_year + $times || $year < $start_year)
					{
						return FALSE;
					} else {

						if($start_day == $day && $O->db->record['data'] == $month)
						{
							
							$recur[$t] = $O->db->record;
								
							$t++;								
						}
					}
				} else {

				}


			break;
		}


		if($t == 0)
		{
			return FALSE;
		} else {
		
			return $recur;
		}
		
	}
}
Return current item: O - OpenSource GroupWare