<?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;
}
}