Location: PHPKode > projects > O - OpenSource GroupWare > osgw/calendar/classes/class.events.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)
***************************************************************************/
/*$Id: class.events.php,v 1.37 2004/05/30 05:59:17 rthomp Exp $*/
class events {

	var $event_buffer;
	var $event_list;

	/*!
	
		@function search_events()
		@author Ryan Thompson
		@abstract Searchs for events on a given day
		@version 0.1
		@params $start_time
		@params $finish_time
		@return TRUE/FALSE
		@since 08-04-2004
	*/
	function search_events($start_time, $finish_time) {
		GLOBAL $db, $user, $share;
		$sql = "SELECT * FROM o_calendar WHERE evt_start >= '$start_time' AND evt_start <= '$finish_time'
			AND user_id='{$user->user_id}' OR recurring='1' AND user_id='{$user->user_id}'";
		$ref_id = $db -> query($sql);
		
		while($db -> fetch_results($ref_id))
		{	
				
			if($db->record['recurring'] == 1)
			{
				$event = $db->record;
				if($this -> recurring_search($db -> record, $start_time, $finish_time))
				{
					$event_list[] = $event;
				}				
			} else {
				$event_list[] = $db -> record;
			}
		}

		$results = $share->run_share_query('cl', $user->user_id,'o_calendar', 'event_id', '');

			
		foreach($results AS $key => $value)
		{
			if($value['evt_start'] >= $start_time AND $value['evt_start'] <= $finish_time || $value['recurring'] == 1)
			{
				if($value['recurring'] == 1)
				{
					$event = $value;
					if($this -> recurring_search($value, $start_time, $finish_time))
					{
						$share_list[] = $event;
					}				
				} else {
					$share_list[] = $value;
				}
			}
		}
		
		
		if (is_array($event_list) || is_array($share_list)) {
			if(is_array($event_list) && is_array($share_list))
			{
				$event_list = array_merge($event_list, $share_list);
			}
			if(is_array($event_list))
			{
				return $event_list;
			} elseif(is_array($share_list))
			{
				return $share_list;
			}
			//return $event_list;
		} else {
			return FALSE;
		}

	}

	/*!
		@function day_events()
		@author Ryan Thompson
		@abstract Determines whether an event occurs during a giving timespan in a day.
		@version 0.2
		@param $start_time
		@param $finish_time
		@return TRUE/FALSE
		@since 06-05-2004
	*/
	function day_events($start_time, $finish_time) {
		GLOBAL $db, $user, $share;
		//Find events that start and end within day. Start before and end after or start 
		//before end it or start during and end after
		$sql = "SELECT * FROM o_calendar WHERE evt_start > '$start_time' AND evt_end < '$finish_time' 
			AND user_id='{$user->user_id}' OR evt_start < '$start_time' AND evt_end > '$finish_time' AND user_id='{$user->user_id}' OR 
			evt_start < '$start_time' AND evt_end > '$start_time' AND evt_end < '$finish_time' AND user_id='{$user->user_id}'OR
					evt_start > '$start_time' AND evt_start < '$finish_time' AND evt_end > '$finish_time' OR recurring = 1 AND user_id='{$user->user_id}'";
		$ref_id = $db -> query($sql);
		
		while ($db -> fetch_results($ref_id)) {
			if(date('j', $db->record['evt_start']) != date('j', $db->record['evt_end']))
			{
				if(date('j', $start_time) == date('j', $db->record['evt_end']))
				{
					$db->record['evt_start'] = mktime(0,0,0, date('n', $db->record['evt_end']), 
						date('j', $db->record['evt_end']), date('Y', $db->record['evt_end']));	
						
			
				}
				
			}
			if ($db -> record['recurring'] == 1) {
				//Need a way to store the record data while we execute a new query
				//Don't know if this can be done at the database level
				$tmp = $db->record;
				
				//Search recurring event to see if it happens at this time.
				
				if($this -> recurring_search($db -> record, $start_time, $finish_time))
				{
					
					$this->event_list[] = $tmp;
				}
				
				
			} else {
				
				$this->event_list[] = $db -> record;
			}
		}
		
		$results = $share->run_share_query('cl', $user->user_id,'o_calendar', 'event_id', '');
		
		foreach($results AS $key => $value)
		{
			
			if($value['evt_start'] > $start_time && $value['evt_end'] < $finish_time ||
				$value['evt_start'] < $start_time && $value['evt_end'] > $finish_time ||
				$value['evt_start'] < $start_time && $value['evt_end'] > $start_time && $value['evt_end'] < $finish_time ||
				$value['evt_start'] > $start_time && $value['evt_start'] < $finish_time && $value['evt_end'] > $finish_time ||
				$value['recurring'] == 1)
			
			{
				if(date('j', $value['evt_start']) != date('j', $value['evt_end']))
				{
					if(date('j', $start_time) == date('j', $value['evt_end']))
					{
						$value['evt_start'] = mktime(0,0,0, date('n', $value['evt_end']), 
							date('j', $value['evt_end']), date('Y', $value['evt_end']));	
					}
				
				}
			
				if ($value['recurring'] == 1) {
					//Need a way to store the record data while we execute a new query
					//Don't know if this can be done at the database level
					$tmp = $value;
				
					//Search recurring event to see if it happens at this time.
				
					if($this -> recurring_search($value, $start_time, $finish_time))
					{
					
						$this->event_list[] = $tmp;
					}

				
				} else {
					
					$this->event_list[] = $value;
				}
			}	
		}
		
		$this -> event_buffer = count($events);

		return $this->event_list;
	}

	/*!
		@function create_event()
		@author Ryan Thompson
		@abstract Creates a new event in the database
		@version 0.1
		@params $data
		@return TRUE/FALSE
		@since 03-04-2004
	*/
	function create_event($data) {
		GLOBAL $date, $user, $db, $category, $share;
		$start_time = $date -> utimestamp($data['start_hour'], $data['start_min'], $data['start_day'], $data['start_month'], $data['start_year']);
		$end_time = $date -> utimestamp($data['end_hour'], $data['end_min'], $data['end_day'], $data['end_month'], $data['end_year']);

		$now = time();

		if ($data['recure_type'] != 0) {
			$recurring = 1;
		} else {
			$recurring = 0;
		}
		$sql = "INSERT INTO o_calendar (user_id, date, subject, description, location, evt_start, evt_end, recurring, notify,
				who, public) VALUES 
				('{$user->user_id}', '$now', '{$data['event_subject']}', '{$data['description']}','{$data['location']}','$start_time',
				'$end_time', '$recurring', '0','0','0')";

		$db -> query($sql);

		$insert_id = $db -> insert_id;
		$category -> categorize($insert_id, 'cl', $data['category']);

		$share -> add_share($insert_id, 'cl', $data['share_users']);
		if ($recurring == 1) {

			$this -> set_recurrence($insert_id, $start_time, $data, 'INSERT');
		}
	}

	/*!
		@function update_event()
		@author Ryan Thompson
		@abstract Updates an event in the database
		@version 0.1
		@param $event_id
		@param $data
		@return TRUE/FALSE
		@since 26-05-2004
	*/
	function update_event($event_id, $data)
	{
		GLOBAL $date, $user, $db, $category, $share;
		//echo $data['start_hour'];
		//echo $data['end_hour'];
		$start_time = $date -> utimestamp($data['start_hour'], $data['start_min'], $data['start_day'], $data['start_month'], $data['start_year']);
		$end_time = $date -> utimestamp($data['end_hour'], $data['end_min'], $data['end_day'], $data['end_month'], $data['end_year']);

		$now = time();

		if ($data['recure_type'] != 0) {
			$recurring = 1;
		} else {
			$recurring = 0;
		}

		$sql = "UPDATE o_calendar SET subject='{$data['event_subject']}', description='{$data['description']}', location='{$data['location']}',
		evt_start='$start_time', evt_end='$end_time', recurring='$recurring' WHERE event_id='$event_id' AND user_id='{$user->user_id}'";

		$db -> query($sql);
		
		$insert_id = $event_id;
		$category -> edit_category($insert_id, 'cl', $data['category']);

		$share ->update_share($data['shared'], $event_id, 'cl', $data['share_users']);
		if ($recurring == 1) {
			$db->query("DELETE FROM o_recurrence WHERE event_id='$event_id'");
			$this -> set_recurrence($insert_id, $start_time, $data, 'INSERT');
		} elseif($recurring == 0)
		{
			$db->query("DELETE FROM o_recurrence WHERE event_id='$event_id'");
		}
	}
	
	
	/*!
		@function check_date()
		@author Ryan Thompson
		@abstract Verifies where item is a valid date
		@version 0.1
		@params $day
		@params $month
		@params $year
		@params $hour
		@params $min
		@return TRUE/FALSE
		@since 14-04-2004
		@note Move this to global date class
	*/
	function check_date($day, $month, $year, $hour, $min) {
		if (checkdate($month, $day, $year)) {
			return date('U', mktime($hour, $min, 0, $month, $day, $year));
		} else {
			return FALSE;
		}
	}

	/*!
		@function verify_fields()
		@author Ryan Thompson
		@abstract Checkes to see if required fields have been set.
		@version 0.1
		@params	$data
		@return TRUE/FALSE
		@since 14-04-2004
	*/
	function verify_fields($data) {

		if (!empty($data['event_subject'])) {
			return TRUE;
		} else {
			return FALSE;
		}

	}

	/*!
		@function set_recurrence()
		@author Ryan Thompson
		@abstract Checkes to see if required fields have been set.
		@version 0.1
		@params	$event_id
		@params $start_time
		@params	$data
		@params $call INSERT|UPDATE
		@return TRUE/FALSE
		@since 04-05-2004
	*/
	function set_recurrence($event_id, $start_time, $data, $call = "INSERT") {
		GLOBAL $db;
		
		if($data['recure_end'] == 0)
		{
			$times = 0;
		} elseif ($data['recure_end'] == 1)
		{
			$times = -1;
		} else {
			$times = $data['recure_after'];
		}
		switch ($data['recure_type']) {
			case 0 :
				//I don't know how it would get to here but just a safety net in case.
				break;
			case 1 : //Daily
				$type = 1;

				//a day is equal to 86400 seconds
				//We multiply this by frequency and it will give us the number of months in seconds
				$frequency = $data['recure_freq'] * 86400;
				if ($data['recure_end'] == 2) 
				{

					$times = $data['recure_after'] - 0;
					$end = $start_time + ($times * ($frequency));

				}
				elseif ($data['recure_end'] == 1) {
					$end = date('U', mktime(0, 0, 0, $data['recure_end_month'], $data['recure_end_day'], $data['recure_end_year']));
				} else {
					$end = 0;
				}
				if ($call == "UPDATE") {
					$sql = "UPDATE o_recurrence SET type='$type',frequency='$frequency',times='$times',
											rstart='$start_time',rend='$end',data='0' WHERE event_id='$event_id'";
				}
				elseif ($call == "INSERT") {

					$sql = "INSERT INTO o_recurrence (event_id, type, frequency, times, rstart, rend, data)
											VALUES ('$event_id','$type','$frequency','$times','$start_time','$end','0')";
				}
				$db -> query($sql);

				break;
			case 2 : //Weekly
				$type = 2;
				$frequency = $data['recure_freq'];
				$start = $start_time;
				switch ($data['recure_end']) {
					case 0 :
						$end = 0;
						break;
					case 1 :
						$end = date('U', mktime(0, 0, 0, $data['recure_end_month'], $data['recure_end_day'], $data['recure_end_year']));
						break;
					case 2 :
						//Remove one for the first day
						$times = $data['recure_after'];
						$end = $start + (($times * $frequency) * (DAY_SEC * 7));

						break;
				}
				$db_data = serialize($data['recure_weekday']);
				if ($call == "UPDATE") {
					$sql = "UPDATE o_recurrence SET type='$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','$type','$frequency','$times','$start_time','$end','$db_data')";
				}
				$db -> query($sql);
				break;
			case 3 : //Monthly

				$type = 3;
				$start = $start_time;
				$frequency = $data['recure_freq'];
				switch ($data['recure_end']) {
					case 0 :
						$end = 0;
						break;
					case 1 :
						$end = date('U', mktime(0, 0, 0, $data['recure_end_month'], $data['recure_end_day'], $data['recure_end_year']));
						break;
					case 2 :
						$times = $data['recure_after'];
						$end = $start_time + ($times * ($frequency));
						break;
				}

				switch ($data['recure_monthly_type']) {
					//by date					
					case 0 :
						$db_data = $data['recure_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']));

						$first_week_num = date('W', $first_weekday);
						$working_week_num = date('W', $start_time);

						$week_num = $working_week_num - $first_week_num;

						$db_data = $data['recure_monthly_type'].":".$day_of_week.":".$week_num;

						break;
				}

				if ($call == "UPDATE") {
					$sql = "UPDATE o_recurrence SET type='$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','$type','$frequency','$times','$start_time','$end','$db_data')";
				}

				$db -> query($sql);
				break;
			case 4 : //Annually
				$type = 4;
				$start = date('U', mktime(0, 0, 0, $data['start_month'], $data['start_day'], $data['start_year']));

				if ($data['recure_end'] == 0) {
					$end = 0;
					$times = '0';
				}
				elseif ($data['recur_end'] == 1) {
					$end = date('U', mktime(0, 0, 0, $data['recure_end_day'], $data['recure_end_month'], $data['recure_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','$type','{$data['recure_freq']}','$times','$start','$end',
									'{$data['start_month']}')";
				$db -> query($sql);

				break;
		}

	}

	/*!
		@function recurring_search()
		@author Ryan Thompson
		@abstract Search a recurring event to see if an event happens within start and finish time
		@version 0.1
		@param $data
		@param $start_time
		@param $finish_time
		@return TRUE/FALSE
		@since 25-05-2004
	*/

	function recurring_search($data, $start_time, $finish_time) {
		GLOBAL $db;

		$sql = "SELECT * FROM o_recurrence WHERE event_id='{$data['event_id']}'";
		$ref_id = $db -> query($sql);
		$db -> fetch_results($ref_id);
		$recurrence_data = $db->record;
		// 1 = daily
		// 2 = weekly
		// 3 = monthly
		// 4 = annually

		switch ($db -> record['type']) {
			case 1 :
			
				if($this->check_daily_recurrence($recurrence_data, $start_time, $finish_time))
				{
					
					return TRUE;
				}

			break;
			case 2 :
				if($this->check_weekly_recurrence($recurrence_data, $start_time, $finish_time))
				{
					return TRUE;
				}
			break;
			case 3 :
				if($this->check_monthly_recurrence($recurrence_data, $start_time, $finish_time))
				{
					return TRUE;
				}
			break;
			case 4 :
				if($this->check_annual_recurrence($recurrence_data, $start_time, $finish_time))
				{
					return TRUE;
				}
			break;
		}

	}
	
	/*!
		@function delete()
		@author Ryan Thompson
		@abstract Deletes events from database (Handled here due to two tables) 
		@version 0.1
		@param $data
		@return TRUE/FALSE
		@since 27-05-2004
	*/

	function  delete($data)
	{
		GLOBAL $O, $db, $user;
	
		if($items = $O->delete_items('cl', 'o_calendar', 'event_id', $data, $user->user_id))
		{
			foreach($items AS $key => $value)
			{
				$sql = "DELETE FROM o_recurrence WHERE event_id='$value'";
				$db->query($sql);	
			}
		}
		
	}
	
	/*!
		@function check_daily_recurrence()
		@author Ryan Thompson
		@abstract Deletes events from database (Handled here due to two tables) 
		@version 0.1
		@param $data
		@return TRUE/FALSE
		@since 26-05-2004
	*/
	
	function check_daily_recurrence($recurrence_data, $start_time, $finish_time)
	{
		//To make it easier we're working with 00:00:00 of the working days to find the event occur on our working day
		//If this can be done in less code that would be great
		$start = date('n:j:Y', $recurrence_data['rstart']);
		$event_start = explode(':', $start);

		//Return recurring events that begin on the current working day
		if($recurrence_data['rstart'] >= $start_time && $recurrence_data['rstart'] <= $finish_time)
		{
			
			return TRUE;
		}
		//This is the beginning of the first day the event occurs
		$start_of_event_day = date('U', mktime(0,0,0, $event_start[0], $event_start[1], $event_start[2]));
					
		//The day the event last occurs
		$event_end = $recurrence_data['rend'];
			
		//Find the difference in seconds between our working day and the event start
		$diff = $start_time - $start_of_event_day;
		//In days
		$diff_days = $diff / DAY_SEC;

		$frequency_days = $recurrence_data['frequency'] / DAY_SEC;
		
		$diff_days % $frequency_days;
		if($diff_days % $frequency_days == 0 && $finish_time <= $event_end 
			 && $start_time >= $recurrence_data['rstart'])
		{
			return TRUE;
			//We have an event today						
		}
		
		//Events that don't end can't pass the previous check.
		if($diff_days % $frequency_days == 0 && $event_end == 0 && $start_time >= $recurrence_data['rstart'])
		{
			return TRUE;
		}

	}
	
	/*!
		@function check_weekly_recurrence()
		@author Ryan Thompson
		@abstract Algorithm for checking weekly recurrences
		@version 0.1
		@param $data
		@return TRUE/FALSE
		@since 27-05-2004
	*/
	function check_weekly_recurrence($recurrence_data, $start_time, $finish_time)
	{
			$weekdays = unserialize(stripslashes($recurrence_data['data']));
			
			
			if(in_array(date('w', $start_time), $weekdays))
			{
				if($recurrence_data['rstart'] < $start_time)
				{
					$diff = $start_time - $recurrence_data['rstart'];
					$days = $diff / DAY_SEC;
					$weeks = round($days / 7);
					
					if($weeks % $recurrence_data['frequency'] == 0)
					{
						if($recurrence_data['rend'] == 0 || $recurrence_data['rend'] > $finish_time)
						{
							return TRUE;
						}
					} 	
				}
			}
		
	}
	
	/*!
		@function check_monthly_recurrence()
		@author Ryan Thompson
		@abstract Algorithm for checking monthly recurrences
		@version 0.1
		@param $data
		@return TRUE/FALSE
		@since 27-05-2004
	*/	
	function check_monthly_recurrence($recurrence_data, $start_time, $finish_time)
	{
		
		$data = explode(':', $recurrence_data['data']);
		
		$working_month = date('n', $start_time);
		$working_year = date('Y', $start_time);
		$event_month = date('n', $recurrence_data['rstart']);
		$event_year = date('Y', $recurrence_data['rstart']);
		
		
		$year_diff = $working_year - $event_year;
		 $months = $year_diff * 12;
		
		$t = $months + $working_month - $event_month;
		if($t % $recurrence_data['frequency'] == 0)
		{	
			switch($data[0])
			{
				case 0:
					if(date('d', $start_time) == $data[1] && $recurrence_data['rstart'] <= $finish_time)
					{
					
						if($recurrence_data['rend'] == 0 || $finish_time <= $recurrence_data['rend'])
						{
							return TRUE;
						}
					}	
				break;
				case 1:
			
				//This works out the date by using week numbers in PHP which determines the current week
				//using ISO-8601 standards. Meaning Monday is the first day of the week
				//I may at a later date make a preference to change this but it won't be in the near future.
					$week_num = $data[2];
					$weekday = $data[1];
					$month = date('n', $start_time);
					$year = date('Y', $start_time);
				
					$first_weekday = date('W', mktime(0, 0, 0, $month, 1, $year));

					if(date('W', $start_time) - $first_weekday == $week_num)
					{
						if($weekday == date('w', $start_time))
						{
							if($recurrence_data['rend'] == 0 || $recurrence_data['rend'] < $finish_time)
							{
								return TRUE;
							}	
						}
					}
			
				break;
		
			}
		}
	}
	
	/*!
		@function check_annual_recurrence()
		@author Ryan Thompson
		@abstract Algorithm for checking annual recurrences
		@version 0.1
		@param $recurrence_data
		@param $start_time
		@param $finish_time
		@return TRUE/FALSE
		@since 27-05-2004
	*/	
	function check_annual_recurrence($recurrence_data, $start_time, $finish_time)
	{
		if($start_time >= $recurrence_data['rstart'])
		{
			if((date('Y', $start_time) - date('Y', $recurrence_data['rstart'])) % $recurrence_data['frequency'] == 0)
			{
		
				if(date('j', $start_time) == date('j', $recurrence_data['rstart']) &&
					date('n', $start_time) == date('n', $recurrence_data['rstart']))
				{
					if($recurrence_data['rend'] <= $finish_time || $recurrence_data['rend'] == 0)
					{
						return TRUE;
					}
				}
			}
		}
	}
	
	/*!
		@function search_holidays()
		@author Ryan Thompson
		@abstract Algorithm for checking when holidays occur
		@version 0.1
		@param $start_time
		@param $finish_time
		@return $holidays
		@since 28-05-2004
	*/
	function search_holidays($start_time, $finish_time)
	{
		GLOBAL $db, $user, $date;
		$holiday_country = $user->get_preference('cl', 'show_holidays_for', $user->user_id);
		$day = date('j', $start_time);
		//echo " - ";
		$month = date('n', $start_time);
		// echo "<br />";
		 
		$sql = "SELECT * FROM o_holidays WHERE country='$holiday_country' AND month='$month' AND day='$day'
		 OR
		country='$holiday_country' AND day='0' AND month='0'";
		
		$ref_id = $db->query($sql);
		while($db->fetch_results($ref_id))
		{
			$holiday_name = $db->record['holiday'];
			if($db->record['special'] == 1)
			{
				if($this->special_holidays($db->record['holiday'], $start_time))
				{
					$holidays[] = $db->record;
				}
			} elseif($db->record['occurrence'] != NULL)
			{
				$criteria = explode(':', $db->record['occurrence']);
				if($criteria[0] == date('n', $start_time) && $criteria[2] == date('w', $start_time))
				{

					if(floor(date('j', $start_time) / 7) == $criteria[1] - 1)
					{
						$holidays[] = $db->record;
					}
				}
			} else {
				$holidays[] = $db->record;
			}

			
		}
		return $holidays;
	}
	
	/*!
		@function special_holidays()
		@author Ryan Thompson
		@abstract Used to store data on complicated holiday dates (ie Easter)
		@version 0.1
		@param $holiday
		@param $start_time
		@return TRUE/FALSE
		@since 28-05-2004
	*/
	function special_holidays($holiday, $start_time)
	{
		switch($holiday)
		{
			case 'Easter':
				if(function_exists(easter_date))
				{
					$tmp = easter_date(date('Y', $start_time));
					if($tmp == $start_time)
					{
						return TRUE;
					} 
			
				}
			break;
		}	
	}
	
	/*!
		@function search_birthdays()
		@author Ryan Thompson
		@abstract Search for birthdays
		@version 0.1
		@param $start_time
		@return TRUE/FALSE
		@since 28-05-2004
	*/	
	function search_birthdays($start_time)
	{
		
		GLOBAL $db, $user;
		$birthday = date('m-d', $start_time);

		$sql = "SELECT lastname, firstname, address_id FROM o_contacts WHERE birthday LIKE '%$birthday' AND user_id='{$user->user_id}'";
		$db->query($sql);
		$db->fetch_results();
		
		return $db->record;
		
	}
}
Return current item: O - OpenSource GroupWare