[ Index ]

Source Code Reference for V1.00

title

Body

[close]

/modules/calendar/ -> clash.php (source)

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


Generated: Wed Jan 7 03:00:01 2009 Cross-referenced by PHPXref 0.7