function week_table_innerhtml($day, $month, $year, $user, $timetohighlight = NULL) { global $tbl_entry, $tbl_room, $tbl_area; global $enable_periods, $periods; global $times_along_top, $row_labels_both_sides, $column_labels_both_ends; global $resolution, $morningstarts, $morningstarts_minutes, $eveningends, $eveningends_minutes; global $weekstarts, $strftime_format; global $first_last_width, $column_hidden_width, $hidden_days; global $sql_mysqli_conn; // Check that we've got a valid, enabled room $sql = "SELECT COUNT(*)\n FROM users\n WHERE code='{$user}'\n AND disabled=0"; $n_users = sql_mysqli_query1($sql, $sql_mysqli_conn); if ($n_users < 0 || $n_users > 1) { if ($n_users < 0) { // SQL error, probably because the tables haven't been created trigger_error(sql_error(), E_USER_WARNING); } else { // Should never happen trigger_error("Internal error: multiple rooms with same id", E_USER_WARNING); } fatal_error(FALSE, get_vocab("fatal_db_error")); } if ($n_users == 0) { // No rooms have been created yet, or else they are all disabled // Add an 'empty' data flag so that the JavaScript knows whether this is a real table or not return "<tbody data-empty=1><tr><td><h1>" . get_vocab("no_rooms_for_area") . "</h1></td></tr></tbody>"; } // We have a valid room $num_of_days = 7; // days in a week // ensure that $morningstarts_minutes defaults to zero if not set if (!isset($morningstarts_minutes)) { $morningstarts_minutes = 0; } if ($enable_periods) { $resolution = 60; $morningstarts = 12; $morningstarts_minutes = 0; $eveningends = 12; $eveningends_minutes = count($periods) - 1; } // Calculate how many days to skip back to get to the start of the week $time = mktime(12, 0, 0, $month, $day, $year); $skipback = day_of_MRBS_week($time); $day_start_week = $day - $skipback; // We will use $day for links and $day_start_week for anything to do with showing the bookings, // because we want the booking display to start on the first day of the week (eg Sunday if $weekstarts is 0) // but we want to preserve the notion of the current day (or 'sticky day') when switching between pages // Define the start and end of each day of the week in a way which is not // affected by daylight saving... for ($j = 0; $j <= $num_of_days - 1; $j++) { $am7[$j] = get_start_first_slot($month, $day_start_week + $j, $year); $pm7[$j] = get_start_last_slot($month, $day_start_week + $j, $year); // Work out whether there's a possibility that a time slot is invalid, // in other words whether the booking day includes a transition into DST. // If we know that there's a transition into DST then some of the slots are // going to be invalid. Knowing whether or not there are possibly invalid slots // saves us bothering to do the detailed calculations of which slots are invalid. $is_possibly_invalid[$j] = !$enable_periods && is_possibly_invalid($am7[$j], $pm7[$j]); } unset($j); // Just so that we pick up any accidental attempt to use it later // Get all appointments for this week in the room that we care about. // // row['room_id'] = Room ID // row['start_time'] = Start time // row['end_time'] = End time // row['type'] = Entry type // row['name'] = Entry name (brief description) // row['entry_id'] = Entry ID // row['entry_description'] = Complete description // row['status'] = status code // row['entry_create_by'] = User who created entry // This data will be retrieved day-by-day $week_map = array(); for ($j = 0; $j <= $num_of_days - 1; $j++) { $sql = "SELECT user, start_time, end_time, type, number, repeat_id,\n id AS entry_id\n FROM times\n WHERE user = '******'\n AND start_time <= {$pm7[$j]} AND end_time > {$am7[$j]}\n ORDER BY start_time"; // necessary so that multiple bookings appear in the right order // Each row returned from the query is a meeting. Build an array of the // form: $week_map[room][weekday][slot][x], where x = id, color, data, long_desc. // [slot] is based at 000 (HHMM) for midnight, but only slots within // the hours of interest (morningstarts : eveningends) are filled in. // [id], [data] and [long_desc] are only filled in when the meeting // should be labeled, which is once for each meeting on each weekday. // Note: weekday here is relative to the $weekstarts configuration variable. // If 0, then weekday=0 means Sunday. If 1, weekday=0 means Monday. $res = sql_query($sql); if (!$res) { trigger_error(sql_error(), E_USER_WARNING); fatal_error(TRUE, get_vocab("fatal_db_error")); } else { for ($i = 0; $row = sql_row_keyed($res, $i); $i++) { map_add_booking($row, $week_map[0][$j], $am7[$j], $pm7[$j]); } } } // for ($j = 0; ... unset($j); // Just so that we pick up any accidental attempt to use it later // START DISPLAYING THE MAIN TABLE $n_time_slots = get_n_time_slots(); $morning_slot_seconds = ($morningstarts * 60 + $morningstarts_minutes) * 60; $evening_slot_seconds = $morning_slot_seconds + ($n_time_slots - 1) * $resolution; // TABLE HEADER $thead = "<thead>\n"; $header_inner = "<tr>\n"; $dformat = "%a<br>" . $strftime_format['daymonth']; // If we've got a table with times along the top then put everything on the same line // (ie replace the <br> with a space). It looks slightly better if ($times_along_top) { $dformat = preg_replace("/<br>/", " ", $dformat); } // We can display the table in two ways if ($times_along_top) { // with times along the top and days of the week down the side $first_last_html = '<th class="first_last" style="width: ' . $first_last_width . '%">' . get_vocab('date') . ":</th>\n"; $header_inner .= $first_last_html; $column_width = get_main_column_width($n_time_slots); for ($s = $morning_slot_seconds; $s <= $evening_slot_seconds; $s += $resolution) { // Put the seconds since the start of the day (nominal, not adjusted for DST) // into a data attribute so that it can be picked up by JavaScript $header_inner .= "<th data-seconds=\"{$s}\" style=\"width: {$column_width}%\">"; // We need the span so that we can apply some padding. We can't apply it // to the <th> because that is used by jQuery.offset() in resizable bookings $header_inner .= "<span>"; if ($enable_periods) { $header_inner .= period_name($s); } else { $header_inner .= hour_min($s); } $header_inner .= "</span>"; $header_inner .= "</th>\n"; } // next: line to display times on right side if (!empty($row_labels_both_sides)) { $header_inner .= $first_last_html; } } else { // the standard view, with days along the top and times down the side $first_last_html = '<th class="first_last" style="width: ' . $first_last_width . '%">' . ($enable_periods ? get_vocab('period') : get_vocab('time')) . ':</th>'; $header_inner .= $first_last_html; $column_width = get_main_column_width($num_of_days, count($hidden_days)); for ($j = 0; $j <= $num_of_days - 1; $j++) { $t = mktime(12, 0, 0, $month, $day_start_week + $j, $year); $date = date('Y-n-d', $t); if (is_hidden_day(($j + $weekstarts) % 7)) { // These days are to be hidden in the display (as they are hidden, just give the // day of the week in the header row $style = $column_hidden_width == 0 ? 'display: none' : 'width: ' . $column_hidden_width . '%'; $header_inner .= '<th class="hidden_day" style="' . $style . '">' . utf8_strftime($strftime_format['dayname_cal'], $t) . "</th>\n"; } else { // Put the date into a data attribute so that it can be picked up by JavaScript $header_inner .= '<th data-date="' . $date . '" style="width: ' . $column_width . '%>' . '<a href="day.php?year=' . strftime("%Y", $t) . '&month=' . strftime("%m", $t) . '&day=' . strftime('%d', $t) . '&area=' . $area . ' title="' . get_vocab('viewday') . '">' . utf8_strftime($dformat, $t) . "</a></th>\n"; } } // for ($j = 0 ... unset($j); // Just so that we pick up any accidental attempt to use it later // next line to display times on right side if (!empty($row_labels_both_sides)) { $header_inner .= $first_last_html; } } // end standard view (for the header) $header_inner .= "</tr>\n"; $thead .= $header_inner; $thead .= "</thead>\n"; // Now repeat the header in a footer if required $tfoot = $column_labels_both_ends ? "<tfoot>\n{$header_inner}</tfoot>\n" : ''; // TABLE BODY LISTING BOOKINGS $tbody = "<tbody>\n"; // URL for highlighting a time. Don't use REQUEST_URI or you will get // the timetohighlight parameter duplicated each time you click. $base_url = "temp.php?year={$year}&month={$month}&day={$day}&area={$area}&room={$room}"; $row_class = "even_row"; // We can display the table in two ways if ($times_along_top) { // with times along the top and days of the week down the side // See note above: weekday==0 is day $weekstarts, not necessarily Sunday. for ($thisday = 0; $thisday <= $num_of_days - 1; $thisday++, $row_class = $row_class == "even_row" ? "odd_row" : "even_row") { if (is_hidden_day(($thisday + $weekstarts) % 7)) { // These days are to be hidden in the display: don't display a row // Toggle the row class back to keep it in sequence $row_class = $row_class == "even_row" ? "odd_row" : "even_row"; continue; } else { $tbody .= "<tr class=\"{$row_class}\">\n"; $wt = mktime(12, 0, 0, $month, $day_start_week + $thisday, $year); $wday = date("d", $wt); $wmonth = date("m", $wt); $wyear = date("Y", $wt); $wdate = date('Y-n-d', $wt); $day_cell_text = utf8_strftime($dformat, $wt); $day_cell_link = "day.php?year=" . strftime("%Y", $wt) . "&month=" . strftime("%m", $wt) . "&day=" . strftime("%d", $wt) . "&area={$area}"; $tbody .= day_cell_html($day_cell_text, $day_cell_link, $wdate); for ($s = $morning_slot_seconds; $s <= $evening_slot_seconds; $s += $resolution) { $is_invalid = $is_possibly_invalid[$thisday] && is_invalid_datetime(0, 0, $s, $wmonth, $wday, $wyear); // set up the query strings to be used for the link in the cell $query_strings = get_query_strings($user, $wmonth, $wday, $wyear, $s); // and then draw the cell if (!isset($week_map[0][$thisday][$s])) { $week_map[0][$thisday][$s] = array(); // to avoid an undefined index NOTICE error } $tbody .= cell_html($week_map[0][$thisday][$s], $query_strings, $is_invalid); } // end looping through the time slots if (FALSE != $row_labels_both_sides) { $tbody .= day_cell_html($day_cell_text, $day_cell_link, $wdate); } $tbody .= "</tr>\n"; } } // end looping through the days of the week } else { // the standard view, with days of the week along the top and times down the side for ($s = $morning_slot_seconds; $s <= $evening_slot_seconds; $s += $resolution, $row_class = $row_class == "even_row" ? "odd_row" : "even_row") { // Show the time linked to the URL for highlighting that time: $class = $row_class; if (isset($timetohighlight) && $s == $timetohighlight) { $class .= " row_highlight"; $url = $base_url; } else { $url = $base_url . "&timetohighlight={$s}"; } $tbody .= "<tr class=\"{$class}\">"; $tbody .= time_cell_html($s, $url); // See note above: weekday==0 is day $weekstarts, not necessarily Sunday. for ($thisday = 0; $thisday <= $num_of_days - 1; $thisday++) { if (is_hidden_day(($thisday + $weekstarts) % 7)) { // These days are to be hidden in the display $tbody .= "<td class=\"hidden_day\"> </td>\n"; } else { // set up the query strings to be used for the link in the cell $wt = mktime(12, 0, 0, $month, $day_start_week + $thisday, $year); $wday = date("d", $wt); $wmonth = date("m", $wt); $wyear = date("Y", $wt); $is_invalid = $is_possibly_invalid[$thisday] && is_invalid_datetime(0, 0, $s, $wmonth, $wday, $wyear); $query_strings = get_query_strings($user, $wmonth, $wday, $wyear, $s); // and then draw the cell if (!isset($week_map[0][$thisday][$s])) { $week_map[0][$thisday][$s] = array(); // to avoid an undefined index NOTICE error } $tbody .= cell_html($week_map[0][$thisday][$s], $query_strings, $is_invalid); } } // for loop // next lines to display times on right side if (FALSE != $row_labels_both_sides) { $tbody .= time_cell_html($s, $url); } $tbody .= "</tr>\n"; } } // end standard view (for the body) $tbody .= "</tbody>\n"; return $thead . $tfoot . $tbody; }
// Do some consistency checking of user settings from config.inc.php if ($enable_periods) { if (count($periods) > 60) { die('Configuration error: too many periods defined'); } } else { if (!isset($resolution)) { die('Configuration error: $resolution has not been set.'); } if ($resolution <= 0) { die('Configuration error: $resolution is less than or equal to zero.'); } if ($resolution % 60 != 0) { die('Configuration error: $resolution is not an integral number of minutes.'); } $start_first_slot = get_start_first_slot(1, 1, 2000); // 1 Jan 2000 free of DST changes $start_last_slot = get_start_last_slot(1, 1, 2000); $start_difference = $start_last_slot - $start_first_slot; // seconds if ($start_difference % $resolution != 0) { die('Configuration error: make sure that the length of the booking day is an integral multiple of $resolution.'); } } /*************************************** * DOCTYPE - internal use, do not change ***************************************/ define('DOCTYPE', '<!DOCTYPE html>'); // Records which DOCTYPE is being used. Do not change - it will not change the DOCTYPE // that is used; it is merely used when the code needs to know the DOCTYPE, for example // in calls to nl2br. TRUE means XHTML, FALSE means HTML.
if ($enable_periods) { $resolution = 60; } // Now work out the start and times $starttime = mktime(0, 0, $start_seconds, $start_month, $start_day, $start_year); $endtime = mktime(0, 0, $end_seconds, $end_month, $end_day, $end_year); // If we're using periods then the endtime we've been returned by the form is actually // the beginning of the last period in the booking (it's more intuitive for users this way) // so we need to add on 60 seconds (1 period) if ($enable_periods) { $endtime = $endtime + 60; } // Round down the starttime and round up the endtime to the nearest slot boundaries // (This step is probably unnecesary now that MRBS always returns times aligned // on slot boundaries, but is left in for good measure). $am7 = get_start_first_slot($start_month, $start_day, $start_year); $starttime = round_t_down($starttime, $resolution, $am7); $endtime = round_t_up($endtime, $resolution, $am7); // If they asked for 0 minutes, and even after the rounding the slot length is still // 0 minutes, push that up to 1 resolution unit. if ($endtime == $starttime) { $endtime += $resolution; } if (isset($rep_type) && $rep_type != REP_NONE && isset($rep_end_month) && isset($rep_end_day) && isset($rep_end_year)) { // Get the repeat entry settings $end_date = mktime(intval($start_seconds / SECONDS_PER_HOUR), intval($start_seconds % SECONDS_PER_HOUR / 60), 0, $rep_end_month, $rep_end_day, $rep_end_year); } else { $rep_type = REP_NONE; $end_date = 0; // to avoid an undefined variable notice }
$resolution = 60; $morningstarts = 12; $morningstarts_minutes = 0; $eveningends = 12; $eveningends_minutes = count($periods) - 1; } // Define the start and end of each day of the month in a way which is not // affected by daylight saving... for ($j = 1; $j <= $days_in_month; $j++) { // are we entering or leaving daylight saving // dst_change: // -1 => no change // 0 => entering DST // 1 => leaving DST $dst_change[$j] = is_dst($month, $j, $year); $am7[$j] = get_start_first_slot($month, $j, $year); $pm7[$j] = get_start_last_slot($month, $j, $year); } // Section with areas, rooms, minicals. echo "<div id=\"dwm_header\" class=\"screenonly\">\n"; // Get the area and room names (we will need them later for the heading) $this_area_name = sql_query1("SELECT area_name FROM {$tbl_area} WHERE id={$area} AND disabled=0 LIMIT 1"); $this_room_name = sql_query1("SELECT room_name FROM {$tbl_room} WHERE id={$room} AND disabled=0 LIMIT 1"); // The room is invalid if it doesn't exist, or else it has been disabled, either explicitly // or implicitly because the area has been disabled $room_invalid = $this_area_name === -1 || $this_room_name === -1; // Show all available areas echo make_area_select_html('month.php', $area, $year, $month, $day); // Show all available rooms in the current area: echo make_room_select_html('month.php', $area, $room, $year, $month, $day); // Draw the three month calendars