From 4269e847878a9b540007038b70bf2346e7ca86ce Mon Sep 17 00:00:00 2001 From: Ralf Becker Date: Sun, 12 Dec 2004 12:31:41 +0000 Subject: [PATCH] some fixes for the freetime search: - if an endtime leads to a duration biger the the difference between day-start and -end, the day-end from the user prefs are ignored, else it would never find a free time - using one selectbox for the duration with an extra item 'use enddate', to be more intuitive about duration or enddate is used - selecting a fitting search-frame for new searches, not just one week --- calendar/inc/class.uiforms.inc.php | 82 +++++++++++++++++++----------- calendar/setup/etemplates.inc.php | 5 +- 2 files changed, 57 insertions(+), 30 deletions(-) diff --git a/calendar/inc/class.uiforms.inc.php b/calendar/inc/class.uiforms.inc.php index 2c8d36920b..0bdf71e998 100644 --- a/calendar/inc/class.uiforms.inc.php +++ b/calendar/inc/class.uiforms.inc.php @@ -26,7 +26,7 @@ class uiforms extends uical var $public_functions = array( 'freetimesearch' => True, ); - + /** * Constructor */ @@ -50,6 +50,13 @@ class uiforms extends uical */ function freetimesearch($content = false) { + $sel_options['search_window'] = array( + 7*DAY_s => lang('one week'), + 14*DAY_s => lang('two weeks'), + 31*DAY_s => lang('one month'), + 92*DAY_s => lang('three month'), + 365*DAY_s => lang('one year'), + ); if (!is_array($content)) { if ($this->debug) echo "
".print_r($_GET,true)."
"; @@ -60,18 +67,8 @@ class uiforms extends uical $arr += $_GET[$name]; $content[$name] = $this->bo->date2ts($arr); } - $duration = $content['end'] - $content['start']; + $content['duration'] = $content['end'] - $content['start']; - if ($duration <= 12*HOUR_s) - { - $content['duration_h'] = (int) ($duration / HOUR_s); - $content['duration_min'] = ($duration/60) % 60; - $content['end'] = 0; - } - else - { - $content['duration_h'] = $content['duration_min'] = 0; - } foreach(explode(':',$_GET['participants']) as $uid) { if ((int) $uid) $content['participants'][] = (int) $uid; @@ -82,23 +79,33 @@ class uiforms extends uical // default search parameters $content['start_time'] = $this->cal_prefs['workdaystarts']; $content['end_time'] = $this->cal_prefs['workdayends']; - if ($this->cal_prefs['workdayends']*HOUR_s < $this->cal_prefs['workdaystarts']*HOUR_s+$duration) + if ($this->cal_prefs['workdayends']*HOUR_s < $this->cal_prefs['workdaystarts']*HOUR_s+$content['duration']) { $content['end_time'] = 0; // no end-time limit, as duration would never fit } $content['weekdays'] = MCAL_M_WEEKDAYS; + $content['search_window'] = 7 * DAY_s; + // pick a searchwindow fitting the duration (search for a 10 day slot in a one week window never succeeds) + foreach($sel_options['search_window'] as $window => $label) + { + if ($window > $content['duration']) + { + $content['search_window'] = $window; + break; + } + } } else { - $duration = $content['end'] ? $content['end']-$content['start'] : 60*(60*$content['duration_h']+$content['duration_min']); + if (!$content['duration']) $content['duration'] = $content['end'] - $content['start']; if (is_array($content['freetime']['select'])) { list($selected) = each($content['freetime']['select']); //echo "$selected = ".date('D d.m.Y H:i',$content['freetime'][$selected]['start']); $start = (int) $content['freetime'][$selected]['start']; - $end = $start + $duration; + $end = $start + $content['duration']; $fields_to_set = array( 'start[str]' => date($this->common_prefs['dateformat'],$start), 'start[min]' => date('i',$start), @@ -146,16 +153,13 @@ class uiforms extends uical { $content['msg'] .= lang('Only the initial date of that recuring event is checked!'); } - $content['freetime'] = $this->freetime($content['participants'],$content['start'],$content['start']+$content['search_window'],$duration,$content['cal_id']); - $content['freetime'] = $this->split_freetime_daywise($content['freetime'],$duration,$content['weekdays'],$content['start_time'],$content['end_time'],$sel_options); - $sel_options['search_window'] = array( - 7*DAY_s => lang('one week'), - 14*DAY_s => lang('two weeks'), - 31*DAY_s => lang('one month'), - 92*DAY_s => lang('three month'), - 365*DAY_s => lang('one year'), - ); - + $content['freetime'] = $this->freetime($content['participants'],$content['start'],$content['start']+$content['search_window'],$content['duration'],$content['cal_id']); + $content['freetime'] = $this->split_freetime_daywise($content['freetime'],$content['duration'],$content['weekdays'],$content['start_time'],$content['end_time'],$sel_options); + $sel_options['duration'][] = lang('use end date'); + for ($n=15; $n <= 8*60; $n+=($n < 60 ? 15 : ($n < 240 ? 30 : 60))) + { + $sel_options['duration'][$n*60] = sprintf('%d:%02d',$n/60,$n%60); + } $etpl = CreateObject('etemplate.etemplate','calendar.freetimesearch'); //echo "
".print_r($content,true)."
\n"; @@ -173,15 +177,17 @@ class uiforms extends uical /** * calculate the freetime of given $participants in a certain time-span * + * @param $participants array of user-id's * @param $start int start-time timestamp in user-time * @param $end int end-time timestamp in user-time - * @param $participants array of user-id's * @param $duration int min. duration in sec, default 1 * @param $cal_id int own id for existing events, to exclude them from being busy-time, default 0 * @return array of free time-slots: array with start and end values */ function freetime($participants,$start,$end,$duration=1,$cal_id=0) { + if ($this->debug > 2) $this->bo->debug_message('uiforms::freetime(participants=%1, start=%2, end=%3, duration=%4, cal_id=%5)',true,$participants,$start,$end,$duration,$cal_id); + $busy = $this->bo->search(array( 'start' => $start, 'end' => $end, @@ -227,16 +233,20 @@ class uiforms extends uical 'start' => $ft_start, 'end' => $ft_end, ); - if ($this->debug) echo "

freetime: ".date('D d.m.Y H:i',$ft_start)." - ".date('D d.m.Y H:i',$ft_end)."

\n"; + if ($this->debug > 1) echo "

freetime: ".date('D d.m.Y H:i',$ft_start)." - ".date('D d.m.Y H:i',$ft_end)."

\n"; } $ft_start = $event['end']['raw']; } + if ($this->debug > 0) $this->bo->debug_message('uiforms::freetime(participants=%1, start=%2, end=%3, duration=%4, cal_id=%5) freetime=%6',true,$participants,$start,$end,$duration,$cal_id,$freetime); + return $freetime; } /** * split the freetime in daywise slot, taking into account weekdays, start- and stop-times * + * If the duration is bigger then the difference of start- and end_time, the end_time is ignored + * * @param $freetime array of free time-slots: array with start and end values * @param $duration int min. duration in sec * @param $weekdays int allowed weekdays, bitfield of MCAL_M_... @@ -247,9 +257,21 @@ class uiforms extends uical */ function split_freetime_daywise($freetime,$duration,$weekdays,$start_time,$end_time,&$sel_options) { - $freetime_daywise = $sel_options = array(); + if ($this->debug > 1) $this->bo->debug_message('uiforms::split_freetime_daywise(freetime=%1, duration=%2, start_time=%3, end_time=%4)',true,$freetime,$duration,$start_time,$end_time); + + $freetime_daywise = array(); + if (!is_array($sel_options)) $sel_options = array(); $time_format = $this->common_prefs['timeformat'] == 12 ? 'h:i a' : 'H:i'; + + $start_time = (int) $start_time; // ignore leading zeros + $end_time = (int) $end_time; + // ignore the end_time, if duration would never fit + if (($end_time - $start_time)*HOUR_s < $duration) + { + $end_time = 0; + if ($this->debug > 1) $this->bo->debug_message('uiforms::split_freetime_daywise(, duration=%2, start_time=%3,..) end_time set to 0, it never fits durationn otherwise',true,$duration,$start_time); + } $n = 0; foreach($freetime as $ft) { @@ -264,6 +286,7 @@ class uiforms extends uical $mcal_dow = pow(2,$dow); if (!($weekdays & $mcal_dow)) { + //echo "wrong day of week $dow
\n"; continue; // wrong day of week } $start = $t < $ft['start'] ? $ft['start'] : $t; @@ -279,6 +302,7 @@ class uiforms extends uical // slot to small for duration if ($end - $start < $duration) { + //echo "slot to small for duration=$duration
\n"; continue; } $freetime_daywise[++$n] = array( @@ -286,7 +310,7 @@ class uiforms extends uical 'end' => $end, ); $times = array(); - for ($s = $start; $s+$duration <= $end; $s += 60*$this->cal_prefs['interval']) + for ($s = $start; $s+$duration <= $end && $s < $daybegin+DAY_s; $s += 60*$this->cal_prefs['interval']) { $e = $s + $duration; $end_date = $e-$daybegin > DAY_s ? lang(date('l',$e)).' '.date($this->common_prefs['dateformat'],$e).' ' : ''; diff --git a/calendar/setup/etemplates.inc.php b/calendar/setup/etemplates.inc.php index 3861746d78..9a07b76b48 100644 --- a/calendar/setup/etemplates.inc.php +++ b/calendar/setup/etemplates.inc.php @@ -1,10 +1,13 @@ 'calendar.freetimesearch','template' => '','lang' => '','group' => '0','version' => '1.0.1.001','data' => 'a:7:{i:0;a:0:{}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:9:",size120b";s:5:"label";s:15:"Freetime Search";}s:1:"B";a:4:{s:4:"type";s:5:"label";s:4:"span";s:5:",ired";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Startdate / -time";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"start";s:4:"help";s:33:"Startdate and -time of the search";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Duration";}s:1:"B";a:6:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"4";i:1;a:4:{s:4:"type";s:13:"select-number";s:4:"size";s:5:",0,12";s:4:"name";s:10:"duration_h";s:4:"help";s:23:"Duration of the meeting";}i:2;a:5:{s:4:"type";s:13:"select-number";s:4:"size";s:8:",0,59,05";s:5:"label";s:1:":";s:4:"name";s:12:"duration_min";s:4:"help";s:19:"Timeframe to search";}i:3;a:2:{s:4:"type";s:5:"label";s:5:"label";s:18:"or Enddate / -time";}i:4;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:3:"end";s:4:"help";s:57:"Enddate / -time of the meeting, eg. for more then one day";}}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Timeframe";}s:1:"B";a:7:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"5";i:1;a:3:{s:4:"type";s:13:"date-houronly";s:4:"name";s:10:"start_time";s:4:"help";s:19:"Timeframe to search";}i:2;a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"til";}i:3;a:3:{s:4:"type";s:13:"date-houronly";s:4:"name";s:8:"end_time";s:4:"help";s:19:"Timeframe to search";}i:4;a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Weekdays";}i:5;a:4:{s:4:"type";s:10:"select-dow";s:4:"size";s:1:"3";s:4:"name";s:8:"weekdays";s:4:"help";s:25:"Weekdays to use in search";}}}i:5;a:2:{s:1:"A";a:4:{s:4:"type";s:6:"button";s:5:"label";s:10:"New search";s:4:"name";s:6:"search";s:4:"help";s:36:"new search with the above parameters";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"search_window";s:4:"help";s:34:"how far to search (from startdate)";}}i:6;a:2:{s:1:"A";a:4:{s:4:"type";s:8:"template";s:4:"size";s:8:"freetime";s:4:"span";s:3:"all";s:4:"name";s:4:"rows";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}','size' => '','style' => '.size120b { text-size: 120%; font-weight: bold; } .ired { color: red; font-style: italic; }','modified' => '1097251203',); +$templ_data[] = array('name' => 'calendar.freetimesearch','template' => '','lang' => '','group' => '0','version' => '1.0.1.002','data' => 'a:7:{i:0;a:0:{}i:1;a:2:{s:1:"A";a:3:{s:4:"type";s:5:"label";s:4:"span";s:9:",size120b";s:5:"label";s:15:"Freetime Search";}s:1:"B";a:4:{s:4:"type";s:5:"label";s:4:"span";s:5:",ired";s:7:"no_lang";s:1:"1";s:4:"name";s:3:"msg";}}i:2;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:17:"Startdate / -time";}s:1:"B";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:5:"start";s:4:"help";s:33:"Startdate and -time of the search";}}i:3;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Duration";}s:1:"B";a:5:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"3";i:1;a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:8:"duration";s:4:"help";s:23:"Duration of the meeting";}i:2;a:2:{s:4:"type";s:5:"label";s:5:"label";s:18:"or Enddate / -time";}i:3;a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:3:"end";s:4:"help";s:57:"Enddate / -time of the meeting, eg. for more then one day";}}}i:4;a:2:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:9:"Timeframe";}s:1:"B";a:7:{s:4:"type";s:4:"hbox";s:4:"size";s:1:"5";i:1;a:3:{s:4:"type";s:13:"date-houronly";s:4:"name";s:10:"start_time";s:4:"help";s:19:"Timeframe to search";}i:2;a:2:{s:4:"type";s:5:"label";s:5:"label";s:3:"til";}i:3;a:3:{s:4:"type";s:13:"date-houronly";s:4:"name";s:8:"end_time";s:4:"help";s:19:"Timeframe to search";}i:4;a:2:{s:4:"type";s:5:"label";s:5:"label";s:8:"Weekdays";}i:5;a:4:{s:4:"type";s:10:"select-dow";s:4:"size";s:1:"3";s:4:"name";s:8:"weekdays";s:4:"help";s:25:"Weekdays to use in search";}}}i:5;a:2:{s:1:"A";a:4:{s:4:"type";s:6:"button";s:5:"label";s:10:"New search";s:4:"name";s:6:"search";s:4:"help";s:36:"new search with the above parameters";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"search_window";s:4:"help";s:34:"how far to search (from startdate)";}}i:6;a:2:{s:1:"A";a:4:{s:4:"type";s:8:"template";s:4:"size";s:8:"freetime";s:4:"span";s:3:"all";s:4:"name";s:4:"rows";}s:1:"B";a:1:{s:4:"type";s:5:"label";}}}','size' => '','style' => '.size120b { text-size: 120%; font-weight: bold; } +.ired { color: red; font-style: italic; }','modified' => '1102850646',); + $templ_data[] = array('name' => 'calendar.freetimesearch.rows','template' => '','lang' => '','group' => '0','version' => '1.0.1.001','data' => 'a:3:{i:0;a:2:{s:2:"c1";s:2:"th";s:2:"c2";s:3:"row";}i:1;a:4:{s:1:"A";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Date";}s:1:"B";a:2:{s:4:"type";s:5:"label";s:5:"label";s:4:"Time";}s:1:"C";a:2:{s:4:"type";s:5:"label";s:5:"label";s:6:"Select";}s:1:"D";a:2:{s:4:"type";s:5:"label";s:5:"label";s:7:"Enddate";}}i:2;a:4:{s:1:"A";a:4:{s:4:"type";s:4:"date";s:4:"size";s:3:",16";s:4:"name";s:13:"${row}[start]";s:8:"readonly";s:1:"1";}s:1:"B";a:4:{s:4:"type";s:6:"select";s:7:"no_lang";s:1:"1";s:4:"name";s:13:"${row}[start]";s:4:"help";s:13:"select a time";}s:1:"C";a:4:{s:4:"type";s:6:"button";s:5:"label";s:6:"Select";s:4:"name";s:12:"select[$row]";s:4:"help";s:41:"use the selected time and close the popup";}s:1:"D";a:3:{s:4:"type";s:9:"date-time";s:4:"name";s:11:"${row}[end]";s:8:"readonly";s:1:"1";}}}','size' => '','style' => '','modified' => '1097183756',);