<?php if (!defined('BASEPATH')) exit('No direct script access allowed');
/**
* MODULE NAME : grid_helper.php
*
* DESCRIPTION : concentric grid helper
*
* MODIFICATION HISTORY
* V1.0 2008-11-23 12:00 PM - Leane Verhulst - Created
*
* @package ConCentric
* @subpackage concentric grid helper Class
* @author Leane Verhulst
* @copyright Copyright (c) 2008
* @license http://www.gnu.org/licenses/gpl.html
*/
// --------------------------------------------------------------------------------------------
/**
* Return an array of panels between 2 dates using a specific interval and list (of locations or panelists)
*
* @access public
* @params str $sdttm date/time in mySQL format
* @params str $edttm date/time in mySQL format
* @params int $int interval to use in seconds
* @params array $list list of locations or panelists
* @return array
*/
// grid could be a grid of locations or a grid of panelists
function build_empty_grid($sdttm, $edttm, $int, $list)
{
list($sdt, $stm) = explode(' ', $sdttm);
list($edt, $etm) = explode(' ', $edttm);
$stm = timeval($stm);
$etm = timeval($etm);
$grid = Array();
$grid = addIt($grid,$list,$sdt,$stm,$edt,$etm,$int,array('id'=>'','type'=>'','slots'=>'','cols'=>''));
return $grid;
}
// --------------------------------------------------------------------------------------------
/**
* Adds existing event to location grid.
* Assumes that conflicts don't exist, events meet "scheduled" criteria.
*
* @access public
* @params array $grid array of events by locations
* @params array $locations list of locations
* @params array $eventInfo array of event info
* @params integer $int interval to use in seconds
* @return array array of events by location
*/
function assign_event_to_locationgrid($grid, $locations, $eventInfo, $int)
{
$sdttm = $eventInfo['sdttm'];
$edttm = $eventInfo['edttm'];
$setupdttm = $eventInfo['setupdttm'];
$teardowndttm = $eventInfo['teardowndttm'];
$setup = $eventInfo['setup'];
$teardown = $eventInfo['teardown'];
$eventlength = $eventInfo['eventlength'];
$locationcnt = $eventInfo['locationcnt'];
// get time and change to seconds and then round up to match interval
list($sdt, $stm) = explode(' ', $sdttm);
$stm = timeval($stm);
$stm = match_interval($stm, $int);
// get time and change to seconds and then round up to match interval
list($edt, $etm) = explode(' ', $edttm);
$etm = timeval($etm);
$etm = match_interval($etm, $int);
// get time and change to seconds and then round up to match interval
list($sudt, $sutm) = explode(' ', $setupdttm);
$sutm = timeval($sutm);
$sutm = match_interval($sutm, $int);
// get time and change to seconds and then round up to match interval
list($tddt, $tdtm) = explode(' ', $teardowndttm);
$tdtm = timeval($tdtm);
$tdtm = match_interval($tdtm, $int);
if ($setup > 0)
{
$slots = countSlots($sudt,$sutm,$sdt,$stm,$int);
$grid = addIt($grid,$locations,$sudt,$sutm,$sdt,$stm,$int,array('id'=>$eventInfo['id'],'type'=>'setup','slots'=>$slots,'cols'=>$locationcnt));
}
if ($eventlength > 0)
{
$slots = countSlots($sdt,$stm,$edt,$etm,$int);
$grid = addIt($grid,$locations,$sdt,$stm,$edt,$etm,$int,array('id'=>$eventInfo['id'],'type'=>'event','slots'=>$slots,'cols'=>$locationcnt));
}
if ($teardown > 0)
{
$slots = countSlots($edt,$etm,$tddt,$tdtm,$int);
$grid = addIt($grid,$locations,$edt,$etm,$tddt,$tdtm,$int,array('id'=>$eventInfo['id'],'type'=>'teardown','slots'=>$slots,'cols'=>$locationcnt));
}
return $grid;
}
// --------------------------------------------------------------------------------------------
/**
* Adds existing event to participant grid.
* Assumes that conflicts don't exist, events meet "scheduled" criteria.
*
* @access public
* @params array $grid array of events by locations
* @params array $locations list of locations
* @params array $eventInfo array of event info
* @params integer $int interval to use in seconds
* @return array array of events by location
*/
function assign_event_to_partgrid($grid, $participants, $eventInfo, $int)
{
$sdttm = $eventInfo['sdttm'];
$edttm = $eventInfo['edttm'];
$setupdttm = $eventInfo['setupdttm'];
$teardowndttm = $eventInfo['teardowndttm'];
$setup = $eventInfo['setup'];
$teardown = $eventInfo['teardown'];
$eventlength = $eventInfo['eventlength'];
list($sdt, $stm) = explode(' ', $sdttm);
$stm = timeval($stm);
list($edt, $etm) = explode(' ', $edttm);
$etm = timeval($etm);
list($sudt, $sutm) = explode(' ', $setupdttm);
$sutm = timeval($sutm);
list($tddt, $tdtm) = explode(' ', $teardowndttm);
$tdtm = timeval($tdtm);
if ($eventlength > 0)
{
$slots = countSlots($sdt,$stm,$edt,$etm,$int);
$grid = addIt($grid,$participants,$sdt,$stm,$edt,$etm,$int,array('id'=>$eventInfo['id'],'type'=>'event','slots'=>$slots,'cols'=>1));
}
return $grid;
}
// --------------------------------------------------------------------------------------------
// Add the event (item) to the (list) grid from start dttm to end dttm using int slots
function addIt($grid,$list,$sdt,$stm,$edt,$etm,$int,$item)
{
//loop thru dates
$i=0;
while ( strtotime($edt) >= strtotime("+".$i." day",strtotime($sdt)) )
{
$dt=date("Y-m-d",strtotime("+".$i++." day",strtotime($sdt)));
$slptm = 0; //start loop time
$elptm = 86400; //end loop time
if ($dt == $sdt)
$slptm = $stm; // override start loop time
if ($dt == $edt)
$elptm = $etm; // override end loop time
//loop thru times
$j = $slptm;
for ($j = $slptm; $j <= ($elptm - $int); $j = $j + $int)
{
$h = floor($j / 3600);
$m = ($j - ($h*3600)) / 60;
$tm = date("H:i", mktime($h, $m));
// array is sortval as key and id as val
foreach ($list as $key => $val)
{
//if ($grid[$dt][$tm][$key] != '')
//{
// flashMsg('info','a non blank slot is overwritten');
//}
$item['listID'] = $val;
$grid[$dt][$tm][$key] = $item;
}
}
}
return $grid;
}
// --------------------------------------------------------------------------------------------
// Count the number of slots from start dttm to end dttm using int length slots
function countSlots($sdt,$stm,$edt,$etm,$int)
{
//loop thru dates
$i=0;
$slots = 0;
while ( strtotime($edt) >= strtotime("+".$i." day",strtotime($sdt)) )
{
$dt=date("Y-m-d",strtotime("+".$i++." day",strtotime($sdt)));
$slptm = 0; //start loop time
$elptm = 86400; //end loop time
if ($dt == $sdt)
$slptm = $stm; // override start loop time
if ($dt == $edt)
$elptm = $etm; // override end loop time
//loop thru times
$j = $slptm;
for ($j = $slptm; $j <= ($elptm - $int); $j = $j + $int)
{
$slots++;
}
}
return $slots;
}
// --------------------------------------------------------------------------------------------
// Removes event from grid. ???Not needed???
function remove_event_from_grid($grid, $locations, $eventInfo, $int)
{
$sdttm = $eventInfo['sdttm'];
$edttm = $eventInfo['edttm'];
$setupdttm = $eventInfo['setupdttm'];
$teardowndttm = $eventInfo['teardowndttm'];
$setup = $eventInfo['setup'];
$teardown = $eventInfo['teardown'];
$eventlength = $eventInfo['eventlength'];
list($sdt, $stm) = explode(' ', $sdttm);
$tm = explode(':', $stm);
$stm = ($tm[0] * 60 * 60) + ($tm[1] * 60) + $tm[2];
list($edt, $etm) = explode(' ', $edttm);
$tm = explode(':', $etm);
$etm = ($tm[0] * 60 * 60) + ($tm[1] * 60) + $tm[2];
list($sudt, $sutm) = explode(' ', $setupdttm);
$tm = explode(':', $sutm);
$sutm = ($tm[0] * 60 * 60) + ($tm[1] * 60) + $tm[2];
list($tddt, $tdtm) = explode(' ', $teardowndttm);
$tm = explode(':', $tdtm);
$tdtm = ($tm[0] * 60 * 60) + ($tm[1] * 60) + $tm[2];
if ($setup > 0)
{
$grid = addIt($grid,$locations,$sudt,$sutm,$sdt,$stm,$int,'');
}
if ($eventlength > 0)
{
$grid = addIt($grid,$locations,$sdt,$stm,$edt,$etm,$int,'');
}
if ($teardown > 0)
{
$grid = addIt($grid,$locations,$edt,$etm,$tddt,$tdtm,$int,'');
}
return $grid;
}
// --------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------
// Notes:
// - An event cannot be scheduled without a start time.
// - An event cannot be scheduled without a location and/or participant.
// - Therefore, a conflict cannot happen until an event has both a start time and a location/participant.
// --------------------------------------------------------------------------------------------
/**
* Check to see if the event being scheduled can fit into the existing grid
*
* @params array $grid array of panels
* @params array $locations array of locations that event is using
* @params array $eventInfo array of current event details
* @params integer $int interval length
* @return string non-empty if a conflict, empty if no conflict
*/
function check_event_on_locationgrid($grid, $locations, $eventInfo, $int)
{
// get start date, length, setup time, teardown time and calculate time slots
// loop thru the calculated timeslots on the grid and check if slots are empty
// if all are empty, then no conflict
// if all are filled, and if all match the current event, then no conflict
// if some are filled, and those that are filled match the current event, then no conflict
// else conflict
$id = $eventInfo['id'];
$sdttm = $eventInfo['sdttm'];
$edttm = $eventInfo['edttm'];
$setupdttm = $eventInfo['setupdttm'];
$teardowndttm = $eventInfo['teardowndttm'];
$setup = $eventInfo['setup'];
$teardown = $eventInfo['teardown'];
$eventlength = $eventInfo['eventlength'];
list($sdt, $stm) = explode(' ', $sdttm);
$stm = timeval($stm);
list($edt, $etm) = explode(' ', $edttm);
$etm = timeval($etm);
list($sudt, $sutm) = explode(' ', $setupdttm);
$sutm = timeval($sutm);
list($tddt, $tdtm) = explode(' ', $teardowndttm);
$tdtm = timeval($tdtm);
$status = '';
if ($setup > 0)
{
$status .= checkItRm($grid,$locations,$sudt,$sutm,$sdt,$stm,$int,$id);
}
if ($eventlength > 0)
{
$status .= checkItRm($grid,$locations,$sdt,$stm,$edt,$etm,$int,$id);
}
if ($teardown > 0)
{
$status .= checkItRm($grid,$locations,$edt,$etm,$tddt,$tdtm,$int,$id);
}
//if status is blank, no conflicts, else it contains details on conflict
return $status;
}
// --------------------------------------------------------------------------------------------
function checkItRm($grid,$list,$sdt,$stm,$edt,$etm,$int,$id)
{
$CI = & get_instance();
$CI->load->model('locations_model');
$CI->load->model('events_model');
$output = '';
$i=0;
// loop thru dates between start and end times
while ( strtotime($edt) >= strtotime("+".$i." day",strtotime($sdt)) )
{
$dt=date("Y-m-d",strtotime("+".$i++." day",strtotime($sdt)));
$slptm = 0; //start loop time is midnight
$elptm = 86400; //end loop time is also midnight
// if loop date is start date
if ($dt == $sdt)
$slptm = $stm; // override start loop time
// if loop date is end date
if ($dt == $edt)
$elptm = $etm; // override end loop time
$j = $slptm;
// loop thru times between start and end times using interval
for ($j = $slptm; $j <= ($elptm - $int); $j = $j + $int)
{
$h = floor($j / 3600); // get hour
$m = ($j - ($h*3600)) / 60; // get minute
$tm = date("H:i", mktime($h, $m)); // make new time
// array is sortval as key and id as val
foreach ($list as $key => $val)
{
if ($grid[$dt][$tm][$key]['id'] != '')
{
// if grid is populated and it is not current id, get error msg
if ($grid[$dt][$tm][$key]['id'] != $id)
{
$query = $CI->events_model->fetch('events','name','','id = '.$grid[$dt][$tm][$key]['id']);
$eventname = '';
if ($query->num_rows() > 0)
{
$row = $query->row_array();
$eventname = $row['name'];
}
$query = $CI->locations_model->fetch('locations','name','','sortOrder='.$key);
$locationname = '';
if ($query->num_rows() > 0)
{
$row = $query->row_array();
$locationname = $row['name'];
}
$output .= 'There is a conflict with event id ' . $grid[$dt][$tm][$key]['id'] . ' (' . $eventname . ') on ' . $dt . ' ' . $tm . ' in location ' . $locationname . '<br />';
}
}
}
}
}
return $output;
}
// --------------------------------------------------------------------------------------------
/**
* Check to see if the event being scheduled can fit into the existing grid
*
* @params array $grid array of panels
* @params array $participants array
* @params array $eventInfo array of current event details
* @params integer $int interval length
* @return string non-empty if a conflict, empty if no conflict
*/
function check_event_on_partgrid($grid, $participants, $eventInfo, $int)
{
// get start date, length, setup time, teardown time and calculate time slots
// loop thru the calculated timeslots on the grid and check if slots are empty
// if all are empty, then no conflict
// if all are filled, and if all match the current event, then no conflict
// if some are filled, and those that are filled match the current event, then no conflict
// else conflict
$id = $eventInfo['id'];
$sdttm = $eventInfo['sdttm'];
$edttm = $eventInfo['edttm'];
$eventlength = $eventInfo['eventlength'];
list($sdt, $stm) = explode(' ', $sdttm);
$stm = timeval($stm);
list($edt, $etm) = explode(' ', $edttm);
$etm = timeval($etm);
$status = '';
if ($eventlength > 0)
{
$status .= checkItPt($grid,$participants,$sdt,$stm,$edt,$etm,$int,$id);
}
//if status is blank, no conflicts, else it contains details on conflict
return $status;
}
// --------------------------------------------------------------------------------------------
function checkItPt($grid,$list,$sdt,$stm,$edt,$etm,$int,$id)
{
$CI = & get_instance();
$CI->load->model('participants_model');
$CI->load->model('events_model');
$output = '';
$i=0;
while ( strtotime($edt) >= strtotime("+".$i." day",strtotime($sdt)) )
{
$dt=date("Y-m-d",strtotime("+".$i++." day",strtotime($sdt)));
$slptm = 0;
$elptm = 86400;
if ($dt == $sdt)
$slptm = $stm; // override start loop time
if ($dt == $edt)
$elptm = $etm; // override end loop time
$j = $slptm;
for ($j = $slptm; $j <= ($elptm - $int); $j = $j + $int)
{
$h = floor($j / 3600);
$m = ($j - ($h*3600)) / 60;
$tm = date("H:i", mktime($h, $m));
// array is sortval as key and id as val
foreach ($list as $key => $val)
{
//if (!isset($grid[$dt][$tm][$key]))
// continue;
if ($grid[$dt][$tm][$key]['id'] != '')
{
if ($grid[$dt][$tm][$key]['id'] != $id)
{
$query = $CI->events_model->fetch('events','name','','id = '.$grid[$dt][$tm][$key]['id']);
$eventname = '';
if ($query->num_rows() > 0)
{
$row = $query->row_array();
$eventname = $row['name'];
}
$query = $CI->participants_model->fetch('participants','name','','sortedName="'.$key.'"');
$partname = '';
if ($query->num_rows() > 0)
{
$row = $query->row_array();
$partname = $row['name'];
}
$output .= 'There is a conflict with event id ' . $grid[$dt][$tm][$key]['id'] . ' (' . $eventname . ') on ' . $dt . ' ' . $tm . ' for participant ' . $partname . '<br />';
}
}
}
}
}
return $output;
}
// --------------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------------
/**
* Return an html string of the locationgrid
*
* @access public
* @params array $grid array of events by locations
* @params array $locations list of locations
* @params string $mode 'internal', 'public', 'publication'
* @return string
*/
function output_locationgrid($grid, $locations, $mode = 'internal')
{
$CI = & get_instance();
$CI->load->model('locations_model');
$CI->load->model('events_model');
$output = '';
$output .= '<table class=grid border=1>' . "\n";
$locationHeader = '';
$locationHeader .= '<tr><th> </th>';
foreach ($locations as $locationkey => $locationval)
{
$qry = $CI->locations_model->fetch('locations','name,alternateName,capacity','',array('sortOrder'=>$locationkey));
$row = $qry->row_array();
$locationHeader .= '<th class=' . classname($row['name']);
$locationHeader .= '>' . $row['name'];
if ($row['capacity'] !='' && $mode == 'internal')
$locationHeader .= ' (' . $row['capacity'] . ')';
if ($row['alternateName'] != '')
$locationHeader .= '<hr />' . $row['alternateName'];
$locationHeader .= '</th>';
}
$locationHeader .= '</tr>' . "\n";
$output .= $locationHeader;
// number of columns plus one for times column
$locationcnt = count($locations) + 1;
$flag = 0;
// loop thru grid dates
foreach ($grid as $dt=>$dtarr)
{
$dtname = date('l',strtotime($dt));
// use flag to indicate first row of grid and output date
if ($flag == 0)
{
$output .= '<tr><td colspan=' . $locationcnt . '>' . $dt . ' - ' . $dtname . '</td></tr>' . "\n";
$flag += 1;
}
// loop thru grid times
foreach ($dtarr as $tm=>$tmarr)
{
// output date on grid at 6am
if ($tm == '06:00')
{
$output .= $locationHeader;
$output .= '<tr><td colspan=' . $locationcnt . '>' . $dt . ' - ' . $dtname . '</td></tr>' . "\n";
}
// output time
$output .= '<tr><td>' . cnv_tm_from_military($tm) . '</td>';
// loop thru grid locations
foreach ($tmarr as $location => $item)
{
// get event id
$id = $item['id'];
// get event details
$type = $item['type']; // event, setup, teardown
$slots = $item['slots']; // number of rows
$cols = $item['cols']; // number of columns
$locationID = $item['listID']; // location id
$locationName = $CI->locations_model->fetchLocationName($locationID); //get location name
$className = classname($locationName);
$classNameOrig = $className; // save original name before changing it
if ($type != 'event' and $type != '')
$className = $type; // change classname to setup or teardown
$row['name'] = '';
if ($id != '')
{
$where = array('id' => $id);
// if mode is public or publication, exclude hidden events
if ($mode == 'public' or $mode == 'publication')
$where = array('id' => $id, 'hideQ' => 0);
// get data related to event and create row array
$qry = $CI->events_model->fetch('events','name,startDateTime','',$where);
if ($qry->num_rows() > 0)
$row = $qry->row_array();
}
// if mode is public or publication and the item type is not event
// (meaning it is setup or teardown), then don't display it
if ( ($mode == 'public' or $mode == 'publication') and $type != 'event')
{
$output .= '<td';
if ($type != 'setup' and $type != 'teardown')
$output .= ' class=' . $className;
if ($type == 'setup' or $type == 'teardown')
$output .= ' class=' . $classNameOrig;
$output .= '> </td>';
continue;
}
// if mode is public or publication, there is an event, and it is hidden,
// then output blank cell
if ( ($mode == 'public' or $mode == 'publication') and $id != '' and $row['name'] == '')
{
$output .= '<td';
$output .= ' class=' . $classNameOrig;
$output .= '> </td>';
continue;
}
// check if this event is done already
if ($id != '')
{
if (isset($doneflag[$id][$type]))
continue;
$doneflag[$id][$type] = 1;
}
// row name could be null because of hidden event, so make sure to output nothing here
if ($row['name'] == '')
{
$output .= '<td class=' . $className . '> </td>';
}
else
{
// check if event starttime match grid time
$actual_start_time = '';
list($tempsdt, $tempstm) = explode(' ', $row['startDateTime']);
$temptm = explode(':',$tempstm);
$temptm1 = $temptm[0] . ':' . $temptm[1];
if ($temptm1 != $tm)
$actual_start_time = ' (' . cnv_tm_from_military($temptm1) . ')';
$output .= '<td';
$output .= ' rowspan=' . $slots;
$output .= ' colspan=' . $cols;
if ($type != 'event')
$output .= ' class=' . $className;
$output .= '>';
$output .= $row['name'];
if ($actual_start_time != '')
$output .= $actual_start_time;
if ($mode == 'internal' and $type != 'event')
$output .= '<br />' . $type;
//$output .= '<br />' . $cols;
//$output .= '<br />' . $slots;
$output .= '</td>';
}
}
$output .= '</tr>' . "\n";
}
}
$output .= '</table>' . "\n";
return $output;
}
// --------------------------------------------------------------------------------------------
/*
* Strip spaces from string and change to lowercase
*/
function classname($name)
{
return str_replace(array(' ','-'), '', strtolower($name));
}
// --------------------------------------------------------------------------------------------
/*
* Convert time from military time to am/pm time
*/
function cnv_tm_from_military($tm)
{
list($t1, $t2) = explode(':', $tm);
$t1 = ($t1 + 0); // strip leading zero
$ampm = ' am';
if ($t1 > 12)
{
$t1 = ($t1 - 12);
$ampm = ' pm';
}
if ($t1 == 12)
$ampm = ' pm'; //noon
if ($t1 == 0)
$t1 = 12; //midnight
return ($t1 . ':' . $t2 . $ampm);
}
/* End of file grid_helper.php */
/* Location: ./system/application/helpers/grid_helper.php */