start_time->ts == $act1->start_time->ts)
{
return 0;
}
return ($act0->start_time->ts < $act1->start_time->ts) ? -1 : 1;
}
class Calendar
{
var $view = 'month';
var $date_time;
var $slices_arr = array();
// for monthly calendar view, if you want to see all the
// days in the grid, otherwise you only see that months
var $show_only_current_slice = false;
var $show_activities = true;
var $show_tasks = true;
var $activity_focus;
var $show_week_on_month_view = true;
var $use_24 = 1;
var $toggle_appt = true;
var $slice_hash = array();
var $shared_users_arr = array();
function Calendar($view,$time_arr=array())
{
global $current_user;
global $sugar_config;
if ( $current_user->getPreference('time'))
{
$time = $current_user->getPreference('time');
}
else
{
$time = $sugar_config['default_time_format'];
}
if( substr_count($time, 'h') > 0)
{
$this->use_24 = 0;
}
$this->view = $view;
if ( isset($time_arr['activity_focus']))
{
$this->activity_focus = new CalendarActivity($time_arr['activity_focus']);
$this->date_time = $this->activity_focus->start_time;
}
else
{
$this->date_time = new DateTimeUtil($time_arr,true);
}
if (!( $view == 'day' || $view == 'month' || $view == 'year' || $view == 'week' || $view == 'shared') )
{
sugar_die ("view needs to be one of: day, week, month, shared, or year");
}
if ( empty($this->date_time->year))
{
sugar_die ("all views: year was not set");
}
else if ( $this->view == 'month' && empty($this->date_time->month))
{
sugar_die ("month view: month was not set");
}
else if ( $this->view == 'week' && empty($this->date_time->week))
{
sugar_die ("week view: week was not set");
}
else if ( $this->view == 'shared' && empty($this->date_time->week))
{
sugar_die ("shared view: shared was not set");
}
else if ( $this->view == 'day' && empty($this->date_time->day) && empty($this->date_time->month))
{
sugar_die ("day view: day and month was not set");
}
$this->create_slices();
}
function add_shared_users(&$shared_users_arr)
{
$this->shared_users_arr = $shared_users_arr;
}
function get_view_name($view)
{
if ($view == 'month')
{
return "MONTH";
}
else if ($view == 'week')
{
return "WEEK";
}
else if ($view == 'day')
{
return "DAY";
}
else if ($view == 'year')
{
return "YEAR";
}
else if ($view == 'shared')
{
return "SHARED";
}
else
{
sugar_die ("get_view_name: view ".$this->view." not supported");
}
}
function isDayView() {
return $this->view == 'day';
}
function get_slices_arr()
{
return $this->slices_arr;
}
function create_slices()
{
global $current_user;
if ( $this->view == 'month')
{
$days_in_month = $this->date_time->days_in_month;
$first_day_of_month = $this->date_time->get_day_by_index_this_month(0);
$num_of_prev_days = $first_day_of_month->day_of_week;
// do 42 slices (6x7 grid)
for($i=0;$i < 42;$i++)
{
$slice = new Slice('day',$this->date_time->get_day_by_index_this_month($i-$num_of_prev_days));
$this->slice_hash[$slice->start_time->get_mysql_date()] = $slice;
array_push($this->slices_arr, $slice->start_time->get_mysql_date());
}
}
else if ( $this->view == 'week' || $this->view == 'shared')
{
$days_in_week = 7;
for($i=0;$i<$days_in_week;$i++)
{
$slice = new Slice('day',$this->date_time->get_day_by_index_this_week($i));
$this->slice_hash[$slice->start_time->get_mysql_date()] = $slice;
array_push($this->slices_arr, $slice->start_time->get_mysql_date());
}
}
else if ( $this->view == 'day')
{
$hours_in_day = 24;
for($i=0;$i<$hours_in_day;$i++)
{
$slice = new Slice('hour',$this->date_time->get_datetime_by_index_today($i));
$this->slice_hash[$slice->start_time->get_mysql_date().":".$slice->start_time->hour ] = $slice;
$this->slices_arr[] = $slice->start_time->get_mysql_date().":".$slice->start_time->hour;
}
}
else if ( $this->view == 'year')
{
for($i=0;$i<12;$i++)
{
$slice = new Slice('month',$this->date_time->get_day_by_index_this_year($i));
$this->slice_hash[$slice->start_time->get_mysql_date()] = $slice;
array_push($this->slices_arr, $slice->start_time->get_mysql_date());
}
}
else
{
sugar_die("not a valid view:".$this->view);
}
}
function add_activities($user,$type='sugar') {
if ( $this->view == 'week' || $this->view == 'shared') {
$end_date_time = $this->date_time->get_first_day_of_next_week();
} else {
$end_date_time = $this->date_time;
}
$acts_arr = array();
if($type == 'vfb') {
$acts_arr = CalendarActivity::get_freebusy_activities($user, $this->date_time, $end_date_time);
} else {
$acts_arr = CalendarActivity::get_activities($user->id, $this->show_tasks, $this->date_time, $end_date_time, $this->view);
}
// loop thru each activity for this user
for ($i = 0;$i < count($acts_arr);$i++) {
$act = $acts_arr[$i];
// get "hashed" time slots for the current activity we are looping through
$hash_list =DateTimeUtil::getHashList($this->view,$act->start_time,$act->end_time);
for($j=0;$j < count($hash_list); $j++) {
if(!isset($this->slice_hash[$hash_list[$j]]) || !isset($this->slice_hash[$hash_list[$j]]->acts_arr[$user->id])) {
$this->slice_hash[$hash_list[$j]]->acts_arr[$user->id] = array();
}
$this->slice_hash[$hash_list[$j]]->acts_arr[$user->id][] = $act;
}
}
}
function occurs_within_slice(&$slice,&$act)
{
// if activity starts within this slice
// OR activity ends within this slice
// OR activity starts before and ends after this slice
if ( ( $act->start_time->ts >= $slice->start_time->ts &&
$act->start_time->ts <= $slice->end_time->ts )
||
( $act->end_time->ts >= $slice->start_time->ts &&
$act->end_time->ts <= $slice->end_time->ts )
||
( $act->start_time->ts <= $slice->start_time->ts &&
$act->end_time->ts >= $slice->end_time->ts )
)
{
//print "act_start:{$act->start_time->ts}
";
//print "act_end:{$act->end_time->ts}
";
//print "slice_start:{$slice->start_time->ts}
";
//print "slice_end:{$slice->end_time->ts}
";
return true;
}
return false;
}
function get_previous_date_str()
{
if ($this->view == 'month')
{
$day = $this->date_time->get_first_day_of_last_month();
}
else if ($this->view == 'week' || $this->view == 'shared')
{
$day = $this->date_time->get_first_day_of_last_week();
}
else if ($this->view == 'day')
{
$day = $this->date_time->get_yesterday();
}
else if ($this->view == 'year')
{
$day = $this->date_time->get_first_day_of_last_year();
}
else
{
return "get_previous_date_str: notdefined for this view";
}
return $day->get_date_str();
}
function get_next_date_str()
{
if ($this->view == 'month')
{
$day = $this->date_time->get_first_day_of_next_month();
}
else
if ($this->view == 'week' || $this->view == 'shared' )
{
$day = $this->date_time->get_first_day_of_next_week();
}
else
if ($this->view == 'day')
{
$day = $this->date_time->get_tomorrow();
}
else
if ($this->view == 'year')
{
$day = $this->date_time->get_first_day_of_next_year();
}
else
{
sugar_die("get_next_date_str: not defined for view");
}
return $day->get_date_str();
}
function get_start_slice_idx()
{
if ($this->isDayView())
{
$start_at = 8;
for($i=0;$i < 8; $i++)
{
if (count($this->slice_hash[$this->slices_arr[$i]]->acts_arr) > 0)
{
$start_at = $i;
break;
}
}
return $start_at;
}
else
{
return 0;
}
}
function get_end_slice_idx()
{
if ( $this->view == 'month')
{
return $this->date_time->days_in_month - 1;
}
else if ( $this->view == 'week' || $this->view == 'shared')
{
return 6;
}
else if ($this->isDayView())
{
$end_at = 18;
for($i=$end_at;$i < 23; $i++)
{
if (count($this->slice_hash[$this->slices_arr[$i+1]]->acts_arr) > 0)
{
$end_at = $i + 1;
}
}
return $end_at;
}
else
{
return 1;
}
}
}
class Slice
{
var $view = 'day';
var $start_time;
var $end_time;
var $acts_arr = array();
function Slice($view,$time)
{
$this->view = $view;
$this->start_time = $time;
if ( $view == 'day')
{
$this->end_time = $this->start_time->get_day_end_time();
}
if ( $view == 'hour')
{
$this->end_time = $this->start_time->get_hour_end_time();
}
}
function get_view()
{
return $this->view;
}
}
// global to switch on the offet
$DO_USER_TIME_OFFSET = false;
class CalendarActivity
{
var $sugar_bean;
var $start_time;
var $end_time;
function CalendarActivity($args)
{
// if we've passed in an array, then this is a free/busy slot
// and does not have a sugarbean associated to it
global $DO_USER_TIME_OFFSET;
if ( is_array ( $args ))
{
$this->start_time = $args[0];
$this->end_time = $args[1];
$this->sugar_bean = null;
return;
}
// else do regular constructor..
$sugar_bean = $args;
global $timedate;
$this->sugar_bean = $sugar_bean;
if ($sugar_bean->object_name == 'Task')
{
$newdate = $timedate->merge_date_time($this->sugar_bean->date_due, $this->sugar_bean->time_due);
$tempdate = $timedate->to_db_date($newdate,$DO_USER_TIME_OFFSET);
if($newdate != $tempdate){
$this->sugar_bean->date_due = $tempdate;
}
$temptime = $timedate->to_db_time($newdate, $DO_USER_TIME_OFFSET);
if($newdate != $temptime){
$this->sugar_bean->time_due = $temptime;
}
$this->start_time =DateTimeUtil::get_time_start(
$this->sugar_bean->date_due,
$this->sugar_bean->time_due
);
if ( empty($this->start_time))
{
return null;
}
$this->end_time = $this->start_time;
}
else
{
// Convert it back to database time so we can properly manage it for getting the proper start and end dates
$dbDate = $timedate->to_db($this->sugar_bean->date_start);
$this->start_time =DateTimeUtil::get_time_start($dbDate);
$this->end_time =DateTimeUtil::get_time_end(
$this->start_time,
$this->sugar_bean->duration_hours,
$this->sugar_bean->duration_minutes
);
}
}
function get_occurs_within_where_clause($table_name, $rel_table, $start_ts_obj, $end_ts_obj, $field_name='date_start', $view) {
global $timedate;
$dtUtilArr = array();
switch ($view) {
case 'month':
$start_ts = $start_ts_obj->get_first_day_of_this_month();
$end_ts = $end_ts_obj->get_first_day_of_next_month();
break;
default:
// Date for the past 5 days as that is the maximum duration of a single activity
$dtUtilArr['ts'] = $start_ts_obj->ts - (86400*5);
$start_ts = new DateTimeUtil($dtUtilArr, false);
// Date for the next 5 days as that is the maximum duration of a single activity
$dtUtilArr['ts'] = $end_ts_obj->ts + (86400*5);
$end_ts = new DateTimeUtil($dtUtilArr, false);
break;
}
$start_day = $timedate->getDayStartEndGMT(date($timedate->get_date_format(), $start_ts->ts));
$end_day = $timedate->getDayStartEndGMT(date($timedate->get_date_format(), $end_ts->ts));
$field_date = $GLOBALS['db']->convert($table_name.'.'.$field_name,'datetime');
$where = "($field_date >= '{$start_day['start']}' AND $field_date < '{$end_day['start']}'";
if($rel_table != '') {
$where .= " AND $rel_table.accept_status != 'decline'";
}
$where .= ")";
return $where;
}
function get_freebusy_activities(&$user_focus,&$start_date_time,&$end_date_time)
{
$act_list = array();
$vcal_focus = new vCal();
$vcal_str = $vcal_focus->get_vcal_freebusy($user_focus);
$lines = explode("\n",$vcal_str);
foreach ($lines as $line)
{
$dates_arr = array();
if ( preg_match('/^FREEBUSY.*?:([^\/]+)\/([^\/]+)/i',$line,$matches))
{
$dates_arr[] =DateTimeUtil::parse_utc_date_time($matches[1]);
$dates_arr[] =DateTimeUtil::parse_utc_date_time($matches[2]);
$act_list[] = new CalendarActivity($dates_arr);
}
}
usort($act_list,'sort_func_by_act_date');
return $act_list;
}
function get_activities($user_id, $show_tasks, &$view_start_time, &$view_end_time, $view) {
global $current_user;
$act_list = array();
$seen_ids = array();
// get all upcoming meetings, tasks due, and calls for a user
if(ACLController::checkAccess('Meetings', 'list', $current_user->id == $user_id)) {
$meeting = new Meeting();
if($current_user->id == $user_id) {
$meeting->disable_row_level_security = true;
}
$where = CalendarActivity::get_occurs_within_where_clause($meeting->table_name, $meeting->rel_users_table, $view_start_time, $view_end_time, 'date_start', $view);
$focus_meetings_list = build_related_list_by_user_id($meeting,$user_id,$where);
foreach($focus_meetings_list as $meeting) {
if(isset($seen_ids[$meeting->id])) {
continue;
}
$seen_ids[$meeting->id] = 1;
$act = new CalendarActivity($meeting);
if(!empty($act)) {
$act_list[] = $act;
}
}
}
if(ACLController::checkAccess('Calls', 'list',$current_user->id == $user_id)) {
$call = new Call();
if($current_user->id == $user_id) {
$call->disable_row_level_security = true;
}
$where = CalendarActivity::get_occurs_within_where_clause($call->table_name, $call->rel_users_table, $view_start_time, $view_end_time, 'date_start', $view);
$focus_calls_list = build_related_list_by_user_id($call,$user_id,$where);
foreach($focus_calls_list as $call) {
if(isset($seen_ids[$call->id])) {
continue;
}
$seen_ids[$call->id] = 1;
$act = new CalendarActivity($call);
if(!empty($act)) {
$act_list[] = $act;
}
}
}
if($show_tasks) {
if(ACLController::checkAccess('Tasks', 'list',$current_user->id == $user_id)) {
$task = new Task();
$where = CalendarActivity::get_occurs_within_where_clause('tasks', '', $view_start_time, $view_end_time, 'date_due', $view);
$where .= " AND tasks.assigned_user_id='$user_id' ";
$focus_tasks_list = $task->get_full_list("", $where,true);
if(!isset($focus_tasks_list)) {
$focus_tasks_list = array();
}
foreach($focus_tasks_list as $task) {
$act = new CalendarActivity($task);
if(!empty($act)) {
$act_list[] = $act;
}
}
}
}
usort($act_list,'sort_func_by_act_date');
return $act_list;
}
}