![]() |
|---|
| [ Index ] |
Source Code Reference for V1.00 |
[Summary view] [Print] [Text view]
1 <?php /* $Id: clash.php 137 2008-04-04 16:12:02Z pedroix $ $URL: https://web2project.svn.sourceforge.net/svnroot/web2project/trunk/modules/calendar/clash.php $ */ 2 if (!defined('W2P_BASE_DIR')) { 3 die('You should not access this file directly.'); 4 } 5 global $AppUI, $cal_sdf; 6 $AppUI->loadCalendarJS(); 7 8 if (isset($_REQUEST['clash_action'])) { 9 $do_include = false; 10 switch ($_REQUEST['clash_action']) { 11 case 'suggest': 12 clash_suggest(); 13 break; 14 case 'process': 15 clash_process(); 16 break; 17 case 'cancel': 18 clash_cancel(); 19 break; 20 case 'mail': 21 clash_mail(); 22 break; 23 case 'accept': 24 clash_accept(); 25 break; 26 default: 27 $AppUI->setMsg('Invalid action, event cancelled', UI_MSG_ALERT); 28 break; 29 } 30 // Why do it here? Because it is in the global scope and requires 31 // less hacking of the included file. 32 if ($do_include) { 33 include $do_include; 34 } 35 } else { 36 37 ?> 38 <script language="javascript"> 39 function set_clash_action(action) { 40 var f = document.clash_form; 41 f.clash_action.value = action; 42 f.submit(); 43 } 44 45 </script> 46 <?php 47 48 $titleBlock = &new CTitleBlock(($obj->event_id ? 'Edit Event' : 'Add Event'), 'myevo-appointments.png', $m, $m.'.'.$a); 49 $titleBlock->show(); 50 51 $_SESSION['add_event_post'] = get_object_vars($obj); 52 $_SESSION['add_event_clash'] = implode(',', array_keys($clash)); 53 $_SESSION['add_event_caller'] = $last_a; 54 $_SESSION['add_event_attendees'] = $_POST['event_assigned']; 55 $_SESSION['add_event_mail'] = isset($_POST['mail_invited']) ? $_POST['mail_invited'] : 'off'; 56 57 $s = '<table width="100%" class="std"><tr><td><b>' . $AppUI->_('clashEvent') . '</b></tr></tr>'; 58 foreach ($clash as $user) { 59 $s .= '<tr><td>' . $user . '</td></tr>'; 60 } 61 $s .= '</table>'; 62 $calurl = W2P_BASE_URL . '/index.php?m=calendar&a=clash&event_id=' . $obj->event_id; 63 $s .= '<a href="javascript: void(0);" onclick="set_clash_action(\'suggest\');">' . $AppUI->_('Suggest Alternative') . '</a> : '; 64 $s .= '<a href="javascript: void(0);" onclick="set_clash_action(\'cancel\');">' . $AppUI->_('Cancel') . '</a> : '; 65 $s .= '<a href="javascript: void(0);" onclick="set_clash_action(\'mail\');">' . $AppUI->_('Mail Request') . '</a> : '; 66 $s .= '<a href="javascript: void(0);" onclick="set_clash_action(\'accept\');">' . $AppUI->_('Book Event Despite Conflict') . '</a>'; 67 $s .= '<form name="clash_form" method="POST" action="' . $calurl . '">'; 68 $s .= '<input type="hidden" name="clash_action" value="cancel">'; 69 $s .= '</form>'; 70 echo $s; 71 } 72 73 // Clash functions. 74 /* 75 * Cancel the event, simply clear the event details and return to the previous 76 * page. 77 */ 78 function clash_cancel() { 79 global $AppUI, $a; 80 $a = $_SESSION['add_event_caller']; 81 clear_clash(); 82 $AppUI->setMsg('Event Cancelled', UI_MSG_ALERT); 83 $AppUI->redirect(); 84 } 85 86 /* 87 * display a form 88 */ 89 function clash_suggest() { 90 global $AppUI, $m, $a; 91 $obj = &new CEvent; 92 $obj->bind($_SESSION['add_event_post']); 93 94 $start_date = &new CDate($obj->event_start_date); 95 $end_date = &new CDate($obj->event_end_date); 96 $df = $AppUI->getPref('SHDATEFORMAT'); 97 $start_secs = $start_date->getTime(); 98 $end_secs = $end_date->getTime(); 99 $duration = (int)(($end_secs - $start_secs) / 60); 100 101 $titleBlock = &new CTitleBlock('Suggest Alternative Event Time', 'myevo-appointments.png', $m, $m . '.' . $a); 102 $titleBlock->show(); 103 $calurl = W2P_BASE_URL . '/index.php?m=calendar&a=clash&event_id=' . $obj->event_id; 104 $times = array(); 105 $t = new CDate(); 106 $t->setTime(0, 0, 0); 107 if (!defined('LOCALE_TIME_FORMAT')) 108 define('LOCALE_TIME_FORMAT', '%I:%M %p'); 109 for ($m = 0; $m < 60; $m++) { 110 $times[$t->format('%H%M%S')] = $t->format(LOCALE_TIME_FORMAT); 111 $t->addSeconds(1800); 112 } 113 114 ?> 115 <script language="javascript"> 116 function setDate( frm_name, f_date ) { 117 fld_date = eval( 'document.' + frm_name + '.' + f_date ); 118 fld_real_date = eval( 'document.' + frm_name + '.' + 'event_' + f_date ); 119 if (fld_date.value.length>0) { 120 if ((parseDate(fld_date.value))==null) { 121 alert('The Date/Time you typed does not match your prefered format, please retype.'); 122 fld_real_date.value = ''; 123 fld_date.style.backgroundColor = 'red'; 124 } else { 125 fld_real_date.value = formatDate(parseDate(fld_date.value), 'yyyyMMdd'); 126 fld_date.value = formatDate(parseDate(fld_date.value), '<?php echo $cal_sdf ?>'); 127 fld_date.style.backgroundColor = ''; 128 } 129 } else { 130 fld_real_date.value = ''; 131 } 132 } 133 134 function set_clash_action(action) { 135 document.editFrm.clash_action.value = action; 136 document.editFrm.submit(); 137 } 138 139 </script> 140 <form name='editFrm' method='POST' action='<?php echo $calurl.'&clash_action=process'; ?>'> 141 <table width='100%' class='std'> 142 <tr> 143 <td width='50%' align='right'><?php echo $AppUI->_('Earliest Date'); ?>:</td> 144 <td width='50%' align='left' nowrap="nowrap"> 145 <input type="hidden" name="event_start_date" id="event_start_date" value="<?php echo $start_date ? $start_date->format(FMT_TIMESTAMP_DATE) : ''; ?>" /> 146 <input type="text" name="start_date" id="start_date" onchange="setDate('editFrm', 'start_date');" value="<?php echo $start_date ? $start_date->format($df) : ''; ?>" class="text" /> 147 <a href="javascript: void(0);" onclick="return showCalendar('start_date', '<?php echo $df ?>', 'editFrm', null, true)"> 148 <img src="<?php echo w2PfindImage('calendar.gif'); ?>" width="24" height="12" alt="<?php echo $AppUI->_('Calendar'); ?>" border="0" /> 149 </a> 150 </td> 151 </tr> 152 <tr> 153 <td width='50%' align='right'><?php echo $AppUI->_('Latest Date'); ?>:</td> 154 <td width='50%' align='left' nowrap="nowrap"> 155 <input type="hidden" name="event_end_date" id="event_end_date" value="<?php echo $end_date ? $end_date->format(FMT_TIMESTAMP_DATE) : ''; ?>" /> 156 <input type="text" name="end_date" id="end_date" onchange="setDate('editFrm', 'end_date');" value="<?php echo $end_date ? $end_date->format($df) : ''; ?>" class="text" /> 157 <a href="javascript: void(0);" onclick="return showCalendar('end_date', '<?php echo $df ?>', 'editFrm', null, true)"> 158 <img src="<?php echo w2PfindImage('calendar.gif'); ?>" width="24" height="12" alt="<?php echo $AppUI->_('Calendar'); ?>" border="0" /> 159 </a> 160 </td> 161 </tr> 162 <tr> 163 <td width='50%' align='right'><?php echo $AppUI->_('Earliest Start Time'); ?>:</td> 164 <td width='50%' align='left'> 165 <?php echo arraySelect($times, 'start_time', 'size="1" class="text"', $start_date->format('%H%M%S')); ?> 166 </td> 167 </tr> 168 <tr> 169 <td width='50%' align='right'><?php echo $AppUI->_('Latest Finish Time'); ?>:</td> 170 <td width='50%' align='left'> 171 <?php echo arraySelect($times, 'end_time', 'size="1" class="text"', $end_date->format('%H%M%S')); ?> 172 </td> 173 </tr> 174 <tr> 175 <td width='50%' align='right'><?php echo $AppUI->_('Duration'); ?>:</td> 176 <td width='50%' align='left'> 177 <input type="text" class="text" size="5" name="duration" value="<?php echo $duration; ?>" /> 178 <?php echo $AppUI->_('minutes'); ?> 179 </td> 180 </tr> 181 <tr> 182 <td><input type="button" value="<?php echo $AppUI->_('cancel'); ?>" class="button" onclick="set_clash_action('cancel');" /></td> 183 <td align="right"><input type="button" value="<?php echo $AppUI->_('submit'); ?>" class="button" onclick="set_clash_action('process')" /></td> 184 </tr> 185 </table> 186 <input type='hidden' name='clash_action' value='cancel' /> 187 </form> 188 <?php 189 } 190 191 /* 192 * Build an SQL to determine an appropriate time slot that will meet 193 * The requirements for all participants, including the requestor. 194 */ 195 function clash_process() { 196 global $AppUI, $do_include; 197 198 $obj = &new CEvent; 199 $obj->bind($_SESSION['add_event_post']); 200 $attendees = $_SESSION['add_event_attendees']; 201 $users = array(); 202 if (isset($attendees) && $attendees) { 203 $users = explode(',', $attendees); 204 } 205 array_push($users, $obj->event_owner); 206 // First remove any duplicates 207 $users = array_unique($users); 208 // Now remove any null entries, so implode doesn't create a dud SQL 209 // Foreach is safer as it works on a copy of the array. 210 foreach ($users as $key => $user) { 211 if (!$user) 212 unset($users[$key]); 213 } 214 215 $start_date = &new CDate($_POST['event_start_date'] . "000000"); 216 $end_date = &new CDate($_POST['event_end_date'] . "235959"); 217 218 // First find any events in the range requested. 219 $event_list = $obj->getEventsInWindow($start_date->format(FMT_DATETIME_MYSQL), $end_date->format(FMT_DATETIME_MYSQL), (int)($_POST['start_time'] / 100), (int)($_POST['end_time'] / 100), $users); 220 $event_start_date = &new CDate($_POST['event_start_date'] . $_POST['start_time']); 221 $event_end_date = &new CDate($_POST['event_end_date'] . $_POST['end_time']); 222 223 if (!$event_list || !count($event_list)) { 224 // First available date/time is OK, seed addEdit with the details. 225 $obj->event_start_date = $event_start_date->format(FMT_DATETIME_MYSQL); 226 $obj->event_end_date = $event_end_date->format(FMT_DATETIME_MYSQL); 227 $_SESSION['add_event_post'] = get_object_vars($obj); 228 $AppUI->setMsg('No clashes in suggested timespan', UI_MSG_OK); 229 $_SESSION['event_is_clash'] = true; 230 $_GET['event_id'] = $obj->event_id; 231 $do_include = W2P_BASE_DIR . "/modules/calendar/addedit.php"; 232 return; 233 } 234 235 // Now we grab the events, in date order, and compare against the 236 // required start and end times. 237 // Working in 30 minute increments from the start time, and remembering 238 // the end time stipulation, find the first hole in the times. 239 // Determine the duration in hours/minutes. 240 $start_hour = (int)($_POST['start_time'] / 10000); 241 $start_minutes = (int)(($_POST['start_time'] % 10000) / 100); 242 $start_time = $start_hour * 60 + $start_minutes; 243 $end_hour = (int)($_POST['end_time'] / 10000); 244 $end_minutes = (int)(($_POST['end_time'] % 10000) / 100); 245 $end_time = ($end_hour * 60 + $end_minutes) - $_POST['duration']; 246 247 // First, build a set of "slots" that give us the duration 248 // and start/end times we need 249 $first_day = $start_date->format('%E'); 250 $end_day = $end_date->format('%E'); 251 $days_between = ($end_day + 1) - $first_day; 252 $oneday = &new Date_Span(array(1, 0, 0, 0)); 253 254 $slots = array(); 255 $slot_count = 0; 256 $first_date = new CDate($start_date); 257 for ($i = 0; $i < $days_between; $i++) { 258 if ($first_date->isWorkingDay()) { 259 $slots[$i] = array(); 260 for ($j = $start_time; $j <= $end_time; $j += 30) { 261 $slot_count++; 262 $slots[$i][] = array('date' => $first_date->format('%Y-%m-%d'), 'start_time' => $j, 'end_time' => $j + $_POST['duration'], 'committed' => false); 263 } 264 } 265 $first_date->addSpan($oneday); 266 } 267 268 // Now process the events list 269 foreach ($event_list as $event) { 270 $sdate = new CDate($event['event_start_date']); 271 $edate = new CDate($event['event_end_date']); 272 $sday = $sdate->format('%E'); 273 $day_offset = $sday - $first_day; 274 275 // Now find the slots on that day that match 276 list($syear, $smonth, $sday, $shour, $sminute, $ssecond) = sscanf($event['event_start_date'], "%4d-%2d-%2d %2d:%2d:%2d"); 277 list($eyear, $emonth, $eday, $ehour, $eminute, $esecond) = sscanf($event['event_start_date'], "%4d-%2d-%2d %2d:%2d:%2d"); 278 $start_mins = $shour * 60 + $sminute; 279 $end_mins = $ehour * 60 + $eminute; 280 if (isset($slots[$day_offset])) { 281 foreach ($slots[$day_offset] as $key => $slot) { 282 if ($start_mins <= $slot['end_time'] && $end_mins >= $slot['start_time']) { 283 $slots[$day_offset][$key]['committed'] = true; 284 } 285 } 286 } 287 } 288 289 // Third pass through, find the first uncommitted slot; 290 foreach ($slots as $day_offset => $day_slot) { 291 foreach ($day_slot as $slot) { 292 if (!$slot['committed']) { 293 $hour = (int)($slot['start_time'] / 60); 294 $min = $slot['start_time'] % 60; 295 $ehour = (int)($slot['end_time'] / 60); 296 $emin = $slot['end_time'] % 60; 297 $obj->event_start_date = $slot['date'] . ' ' . sprintf("%02d:%02d:00", $hour, $min); 298 $obj->event_end_date = $slot['date'] . ' ' . sprintf("%02d:%02d:00", $ehour, $emin); 299 $_SESSION['add_event_post'] = get_object_vars($obj); 300 $AppUI->setMsg('First available time slot', UI_MSG_OK); 301 $_SESSION['event_is_clash'] = true; 302 $_GET['event_id'] = $obj->event_id; 303 $do_include = W2P_BASE_DIR . '/modules/calendar/addedit.php'; 304 return; 305 } 306 } 307 } 308 // If we get here we have found no available slots 309 clear_clash(); 310 $AppUI->setMsg('No times match your parameters', UI_MSG_ALERT); 311 $AppUI->redirect(); 312 } 313 314 /* 315 * Cancel the event, but notify attendees of a possible meeting and request 316 * they might like to contact author regarding the date. 317 * 318 */ 319 function clash_mail() { 320 global $AppUI; 321 $obj = &new CEvent; 322 if (!$obj->bind($_SESSION['add_event_post'])) { 323 $AppUI->setMsg($obj->getError(), UI_MSG_ERROR); 324 } else { 325 $obj->notify($_SESSION['add_event_post']['event_assigned'], w2PgetParam($_REQUEST, 'event_id', 0) ? false : true, true); 326 $AppUI->setMsg('Mail sent', UI_MSG_OK); 327 } 328 clear_clash(); 329 $AppUI->redirect(); 330 } 331 332 /* 333 * Even though we end up with a clash, accept the detail. 334 */ 335 function clash_accept() { 336 global $AppUI, $do_redirect; 337 338 $AppUI->setMsg('Event'); 339 $obj = &new CEvent; 340 $obj->bind($_SESSION['add_event_post']); 341 $GLOBALS['a'] = $_SESSION['add_event_caller']; 342 $is_new = ($obj->event_id == 0); 343 if (($msg = $obj->store())) { 344 $AppUI->setMsg($msg, UI_MSG_ERROR); 345 } else { 346 if (isset($_SESSION['add_event_attendees']) && $_SESSION['add_event_attendees']) 347 $obj->updateAssigned(explode(',', $_SESSION['add_event_attendees'])); 348 if (isset($_SESSION['add_event_mail']) && $_SESSION['add_event_mail'] == 'on') 349 $obj->notify($_SESSION['add_event_attendees'], !$is_new); 350 $AppUI->setMsg($is_new ? 'added' : 'updated', UI_MSG_OK, true); 351 } 352 clear_clash(); 353 $AppUI->redirect(); 354 } 355 356 function clear_clash() { 357 unset($_SESSION['add_event_caller']); 358 unset($_SESSION['add_event_post']); 359 unset($_SESSION['add_event_clash']); 360 unset($_SESSION['add_event_attendees']); 361 unset($_SESSION['add_event_mail']); 362 } 363 364 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Wed Jan 7 03:00:01 2009 | Cross-referenced by PHPXref 0.7 |