Changes   Courses   Enrollment   Faculty   Filter   Frequencies   Limits   Rooms   Spreadsheet   Log on
INDEX TO FUNCTIONS   A B C D E F G H I K L M N P Q R S T U W     Search Code
FUNCTION GROUPS
Arrays   _general_utilities.php [181]
Case-insensitive find & compare   _general_utilities.php [726]
Files   _general_utilities.php [51]
General properties   _database_utilities.php [339]
Hmtl generation   _general_utilities.php [663]
Input widgets   _general_utilities.php [387]
Links and redirection   _general_utilities.php [2]
Logic-driven parsing   _general_utilities.php [578]
Mail   _general_utilities.php [310]
Numeric   _general_utilities.php [1227]
Request, session, and global   _general_utilities.php [534]
Schedule   _schedule_routines_new.php [8]
Sql datetime handling   _database_utilities.php [277]
Sql insert/delete   _database_utilities.php [186]
Sql multi-record   _database_utilities.php [140]
Sql scalar   _database_utilities.php [90]
Sql single record   _database_utilities.php [117]
Sql vector   _database_utilities.php [161]
Sql-related   _database_utilities.php [16]
String filters   _general_utilities.php [950]
String parsing   _general_utilities.php [593]
Substring extraction   _general_utilities.php [749]
Table construction   _general_utilities.php [1001]
Time & date conversions   _general_utilities.php [1135]

398 FUNCTIONS - Ordered by Name

A   [
Top]
 [112]
 [785]
 [807]
 [793]
 [203]
 [203]
   [9]
 [955]
 [954]
 [818]
 [843]
 [827]
 [258]
 [188]
 [265]
 [183]
 [194]
 [194]
[1248]
 [155]

B   [
Top]
  [87]
 [755]
 [775]
 [763]
 [745]
  [40]
  [40]
 [902]
 [927]
 [912]
 [677]
 [675]
  [50]
 [673]
 [680]

C   [
Top]
[1115]
 [196]
 [414]
 [419]
  [50]
  [50]
 [590]
 [275]
 [284]
 [214]
 [585]
 [142]
 [495]
 [594]
 [741]
  [16]
  [24]
  [24]
 [213]

D   [
Top]
   [6]
 [167]
 [174]
 [158]
[1136]
 [149]
 [145]
  [91]
 [180]
 [141]
 [130]
 [171]
 [148]
 [153]
 [112]
 [126]
 [118]
 [107]
 [162]
  [98]
 [187]
  [20]
  [20]
 [986]
 [987]
 [602]
 [951]
 [213]
 [213]
 [156]
 [156]
 [160]
 [160]
 [152]
 [152]
 [281]
 [281]
[1124]
 [881]
 [874]
 [973]
 [208]
 [208]
 [981]
[1218]

E   [
Top]
 [182]
 [967]
 [523]
 [517]
  [88]
 [180]
 [180]
  [28]
  [28]
  [10]
  [10]
 [329]
 [341]
 [336]
 [336]
 [342]
 [342]
 [225]
 [225]
 [329]
 [329]

F   [
Top]
 [151]
 [151]
 [166]
 [360]
  [75]
  [75]
 [115]
 [115]
 [662]
 [110]
 [398]
  [56]
 [143]
  [53]
  [52]
  [62]
  [63]
  [73]
  [76]
 [307]
  [67]
 [513]
  [42]

G   [
Top]
[1166]
 [340]
 [165]
 [165]
 [137]
  [93]
  [93]
 [112]
 [112]
  [78]
  [78]
  [89]
  [89]
  [84]
  [84]
 [201]
 [204]
 [574]
 [575]

H   [
Top]
 [665]
 [108]
 [498]
 [509]
 [505]
[1244]
[1236]
  [18]

I   [
Top]
 [351]
 [676]

K   [
Top]
 [895]
 [888]
 [237]
 [225]

L   [
Top]
 [731]
 [312]
 [312]
 [953]
 [952]
 [635]
 [174]
 [631]
  [75]
  [80]
 [138]
  [63]
 [102]
 [107]
[1163]

M   [
Top]
 [318]
 [255]
  [40]
  [48]
  [44]
  [52]
[1165]
  [18]
 [323]
[1142]
[1214]
 [311]
 [584]
[1150]

N   [
Top]
 [959]
 [958]
 [956]
 [957]
 [104]
  [13]
 [670]
 [664]
 [212]
 [672]
  [89]
 [211]
 [595]
[1164]
[1162]
[1121]

P   [
Top]
 [685]
 [241]
  [70]
  [40]
  [52]
 [709]
 [718]
 [116]
 [404]
 [686]
[1233]
 [136]
 [750]
 [669]
  [12]
 [610]
 [614]
 [727]
 [548]
 [148]
  [93]
 [526]
  [82]
[1065]
 [109]

Q   [
Top]
[1228]

R   [
Top]
 [431]
 [439]
  [96]
   [9]
   [9]
  [87]
 [105]
   [3]
   [8]
 [105]
 [105]
 [535]
  [27]
[1175]
  [34]
  [34]
 [328]
 [328]
 [129]
 [974]
 [149]
 [149]
 [972]
 [167]
 [552]
 [551]
 [550]
 [549]
 [561]
 [569]

S   [
Top]
  [85]
  [85]
 [735]
 [104]
 [106]
 [106]
 [107]
 [107]
 [549]
 [549]
  [60]
  [60]
 [557]
 [557]
  [65]
  [65]
  [70]
  [70]
 [321]
 [321]
 [161]
 [168]
 [465]
 [452]
 [480]
  [40]
  [40]
 [220]
 [220]
  [35]
  [35]
  [18]
  [18]
 [357]
 [343]
 [113]
[1161]
 [296]
 [314]
 [640]
 [625]
 [377]
  [30]
   [7]
  [23]
 [220]
 [678]
 [150]
 [150]
 [671]
 [679]
  [17]
 [325]
 [258]
  [20]
  [19]
  [39]
  [46]
 [278]
 [253]
 [235]
  [58]
  [28]
 [249]
 [266]
 [336]
 [221]
 [195]
  [18]
  [34]
 [215]
 [274]
 [576]
 [577]
 [383]

T   [
Top]
[1002]
[1117]
[1102]
[1013]
[1096]
 [674]
  [22]
[1032]
[1047]
[1049]
[1048]
  [49]
  [49]
  [28]
  [28]
 [410]
 [407]
 [411]
 [388]
 [393]
[1116]
 [579]
[1030]
[1200]
[1187]
  [10]
  [10]
[1157]
 [687]
 [596]
[1058]
 [181]
 [181]
 [111]

U   [
Top]
  [99]
  [99]
 [248]
 [348]
 [111]
 [322]

W   [
Top]
 [751]
 [690]
 [581]
 [580]
 [160]
 [132]
46 FILES
  _all_includes.php
  _code_search.php
  _code_show.php
  _database_utilities.php
  _equate_check.php
  _general_utilities.php
  _gpl.php
  _page_routines.php
  _schedule_routines.php
  _schedule_routines_new.php
  _site_unzip.php
[Run]   accounts.php
[Run]   code_compare.php
[Run]   copy_instructions.php
[Run]   document_feedback.php
[Run]   evaluation_address_labels.php
[Run]   evaluation_labels.php
[Run]   index.php
[Run]   logoff.php
[Run]   make_oiea_script.php
[Run]   make_oiea_sql_script.php
[Run]   make_table.php
[Run]   math_scheduling_feedback.php
[Run]   register.php
[Run]   sample_cardset.php
[Run]   schedule_changes.php
[Run]   schedule_copy_to_spreadsheet.php
[Run]   schedule_courses.php
[Run]   schedule_discipline_groups.php
[Run]   schedule_emails.php
[Run]   schedule_enrollment.php
[Run]   schedule_enrollment_old.php
[Run]   schedule_faculty.php
[Run]   schedule_filter.php
[Run]   schedule_frequencies.php
[Run]   schedule_growth.php
[Run]   schedule_import.php
[Run]   schedule_limits.php
[Run]   schedule_management.php
[Run]   schedule_rooms.php
[Run]   schedule_snapshot.php
[Run]   schedule_to_spreadsheet.php
[Run]   search.php
[Run]   tables.php
[Run]   tabulation_filter.php
[Run]   txt_to_htm.php

398 FUNCTIONS - Ordered by Location

FILE:
_code_show.php [Top]
 [137]
 [138]
 [142]

FILE:
_database_utilities.php [Top]
  [6]
  _database_utilities.php   [Top]
  [17]
  [18]
  [19]
  [20]
  [28]
  [34]
  [39]
  [46]
  [58]
  [63]
  _database_utilities.php   [Top]
  [91]
  [98]
 [107]
 [112]
  _database_utilities.php   [Top]
 [118]
 [126]
 [130]
  _database_utilities.php   [Top]
 [141]
 [145]
 [148]
 [153]
  _database_utilities.php   [Top]
 [162]
 [171]
 [180]
  _database_utilities.php   [Top]
 [187]
 [195]
 [221]
 [235]
 [249]
 [253]
 [258]
 [266]
  _database_utilities.php   [Top]
 [278]
 [296]
 [314]
 [325]
 [336]
  _database_utilities.php   [Top]
 [340]
 [343]
 [348]
 [351]
 [360]

FILE:
_general_utilities.php [Top]
  _general_utilities.php   [Top]
  [3]
  [8]
  [9]
  [12]
  [13]
  [18]
  [22]
  [27]
  [42]
  [50]
  _general_utilities.php   [Top]
  [52]
  [53]
  [56]
  [62]
  [63]
  [73]
  [76]
  [87]
  [96]
 [105]
 [111]
 [143]
 [149]
 [158]
 [167]
 [174]
  _general_utilities.php   [Top]
 [182]
 [183]
 [188]
 [196]
 [201]
 [204]
 [211]
 [212]
 [213]
 [214]
 [215]
 [220]
 [225]
 [237]
 [241]
 [248]
 [255]
 [258]
 [265]
 [274]
 [275]
 [284]
 [307]
  _general_utilities.php   [Top]
 [311]
 [318]
 [322]
 [323]
 [329]
 [341]
 [357]
 [377]
 [383]
  _general_utilities.php   [Top]
 [388]
 [393]
 [398]
 [404]
 [407]
 [410]
 [411]
 [414]
 [419]
 [431]
 [439]
 [452]
 [465]
 [480]
 [495]
 [498]
 [505]
 [509]
 [513]
 [517]
 [523]
 [526]
  _general_utilities.php   [Top]
 [535]
 [548]
 [549]
 [550]
 [551]
 [552]
 [561]
 [569]
 [574]
 [575]
 [576]
 [577]
  _general_utilities.php   [Top]
 [579]
 [580]
 [581]
 [584]
 [585]
 [590]
  _general_utilities.php   [Top]
 [594]
 [595]
 [596]
 [602]
 [610]
 [614]
 [625]
 [631]
 [635]
 [640]
 [662]
  _general_utilities.php   [Top]
 [664]
 [665]
 [669]
 [670]
 [671]
 [672]
 [673]
 [674]
 [675]
 [676]
 [677]
 [678]
 [679]
 [680]
 [685]
 [686]
 [687]
 [690]
 [709]
 [718]
  _general_utilities.php   [Top]
 [727]
 [731]
 [735]
 [741]
 [745]
  _general_utilities.php   [Top]
 [750]
 [751]
 [755]
 [763]
 [775]
 [785]
 [793]
 [807]
 [818]
 [827]
 [843]
 [874]
 [881]
 [888]
 [895]
 [902]
 [912]
 [927]
  _general_utilities.php   [Top]
 [951]
 [952]
 [953]
 [954]
 [955]
 [956]
 [957]
 [958]
 [959]
 [967]
 [972]
 [973]
 [974]
 [981]
 [986]
 [987]
  _general_utilities.php   [Top]
[1002]
[1013]
[1030]
[1032]
[1047]
[1048]
[1049]
[1058]
[1065]
[1096]
[1102]
[1115]
[1116]
[1117]
[1121]
[1124]
  _general_utilities.php   [Top]
[1136]
[1142]
[1150]
[1157]
[1161]
[1162]
[1163]
[1164]
[1165]
[1166]
[1175]
[1187]
[1200]
[1214]
[1218]
  _general_utilities.php   [Top]
[1228]
[1233]
[1236]
[1244]
[1248]

FILE:
_page_routines.php [Top]
  [7]
  [23]
  [30]
  [40]
  [52]
  [70]
  [82]
  [87]
  [88]
  [89]

FILE:
search.php [Top]
 [181]

FILE:
_page_routines.php [Top]
 [102]
 [107]
 [108]
 [109]
 [112]
 [113]
 [132]

FILE:
_schedule_routines_new.php [Top]
  _schedule_routines_new.php   [Top]
  [9]
  [10]
  [18]
  [28]
  [35]
  [40]
  [49]
  [50]
  [60]
  [65]
  [70]
  [78]
  [84]
  [89]
  [93]
 [105]
 [106]
 [107]
 [112]
 [115]
 [149]
 [152]
 [156]
 [160]
 [165]
 [180]
 [194]
 [203]
 [208]
 [213]
 [220]
 [225]
 [281]
 [312]
 [321]
 [328]
 [329]
 [336]
 [342]
 [549]
 [557]

FILE:
code_compare.php [Top]
  [85]
  [75]
  [80]

FILE:
math_scheduling_feedback.php [Top]
 [150]
 [151]

FILE:
evaluation_labels.php [Top]
  [10]
  [20]
  [24]
  [28]
  [34]
  [40]

FILE:
make_oiea_sql_script.php [Top]
  [75]
  [99]

FILE:
make_table.php [Top]
 [104]
 [110]
 [111]

FILE:
math_scheduling_feedback.php [Top]
 [155]
 [160]
 [166]

FILE:
schedule_changes.php [Top]
  [93]
 [104]

FILE:
schedule_growth.php [Top]
 [129]

FILE:
schedule_limits.php [Top]
 [136]
 [148]
 [161]
 [167]
 [168]
 [174]

FILE:
schedule_management.php [Top]
  [18]

FILE:
schedule_to_spreadsheet.php [Top]
  [16]

FILE:
search.php [Top]
  [67]
 [116]

FILE:
tabulation_filter.php [Top]
  [40]
  [44]
  [48]
  [52]

CODE LISTINGS


FILE: _all_includes.php - 51 lines, 0 functions [
Top]
  [1] <?php
  [2] session_start();
  [3] ini_set('session.bug_compat_warn',0);
  [4] date_default_timezone_set('America/Chicago');
  [5] require_once '_general_utilities.php';
  [6] if (file_exists('_database_utilities.php')) include_once '_database_utilities.php';
  [7] include_once '_page_routines.php';
  [8] include_once '_schedule_routines.php';
  [9] // system parameters
  [10] $system_email = 'hunter@ellinger.org';
  [11] $sql_now = '(DATE_ADD(NOW(), INTERVAL 2 HOUR))';
  [12] // site-specific settings for parameters used by standard routines
  [13] $site_name = 'ACC Schedule Tools';
  [14] $site_abbr = 'ACC Tools';
  [15] $site_domain = 'www.tlok.org/acc_tools';
  [16] $site_email_domain = 'acc_tools.org';
  [17] $site_email_address = 'info@acc_tools.org';
  [18] $site_heading_title = 'ACC Tools';
  [19] // current-page tracking
  [20] $_SESSION['previous_page'] = $_SESSION['current_page'];
  [21] $_SESSION['current_page'] = $current_page = $_SERVER['PHP_SELF'];
  [22] $current_page_name = substr($current_page,strrpos($current_page_name,'/') + 1);
  [23] $current_page_name = substr($current_page_name,0,strpos($current_page,'.php'));
  [24] $development_site = strpos($current_page,'_development/') !== FALSE;
  [25] if (rq1('developer')) $_SESSION['developer'] = TRUE;
  [26] $trace_page = !$development_site && $database_connection;
  [27] // standard page settings, can be overridden in _all_includes or in page prior to page_start() call
  [28] $site_css = '_site.css';
  [29] $hide_site_banner = FALSE; // to suppress heading, set to TRUE before page_start() call
  [30] $no_mail_copy = FALSE;
  [31] $page_title = $site_name;
  [32] // page format
  [33] $page_background_color = 'aqua';
  [34] $page_font_style = 'Verdana';
  [35] $page_width = '';
  [36] $site_navigation = function_exists('site_navigation');
  [37] // standard querystring parameters which are parsed into globals on every page access
  [38] if (rq1('reset')) reset_schedule_settings();
  [39] $all = rq1('all');
  [40] $command = rq('command');
  [41] $id = rq('id');
  [42] $sort = str_replace('^',' desc',rq('sort'));
  [43] if (rq('user_email')) { // process log-on when email given for any page
  [44]     $_SESSION['user_email'] = extract_email(rq('user_email'));
  [45]     $_SESSION['user_id'] = set_session_variables_from_user_account($_SESSION['user_email']);
  [46]     $_SESSION['disciplines_permitted'] = (!$_SESSION['discipline_options'] || isset($_SESSION['discipline_options']['All'])) ? 0 : count($_SESSION['discipline_options']);
  [47] }
  [48] $user_id = $_SESSION['user_id'];
  [49] if ($development_site || $_SESSION['developer']) {$_SESSION['privileges'] = 'All'; $privileged = TRUE;}
  [50] else $privileged = same(sv('user_email'),'mparker@austincc.edu','hunter@ellinger.org','ellinger@io.com');
  [51] ?>
FILE: _code_search.php - 89 lines, 0 functions [
Top]
  [1] <?php // display specified source code, with function-name indexes into a bookmarked listing
  [2] include '_all_includes.php';
  [3] $suppress_banner = TRUE;
  [4] $page_width = "'96%'";
  [5] page_start('Search Site Script Code',' &nbsp; ' . alink('Index to code listings','_code_show.php'));
  [6] $boxes = 3;
  [7] $needles = $antineedles = $hneedles = $hantineedles = array();
  [8] for ($i=0; $i<$boxes; $i++) { // get search input, ignoring blanks or duplicates
  [9]     $needle = rq("needle$i");
  [10]     if ($needle!=='' && !in_array($needle,$needles)) $needles[] = $needle;
  [11] }
  [12] for ($i=0; $i<$boxes; $i++) {
  [13]     $antineedle = rq("antineedle$i"); // antineedles must contain, but not equal, some needle
  [14]     if ($antineedle!=='' && !in_array($antineedle,$antineedles) && !in_array($antineedle,$needles)) {
  [15]         foreach ($needles as $needle) {if (strpos($antineedle,$needle)) {$antineedles[] = $antineedle; break;}}
  [16]     }
  [17] }
  [18] foreach ($needles as $needle) $hneedles[] = '<b>' . h($needle) . '</b>';
  [19] foreach ($antineedles as $antineedle) $hantineedles[] = '<b>' . h($antineedle) . '</b>';
  [20] print "<table border=1 cellpadding=5><tr><td><table border=0>\n";
  [21] print tr(th(' &nbsp; Contains one of these: &nbsp; ') . th(' &nbsp; But not as part of these: &nbsp; '));
  [22] for ($i=0; $i<$boxes; $i++) {
  [23]     print tr(tdc(textbox("needle$i",$needles[$i])) . tdc(textbox("antineedle$i",$antineedles[$i])));
  [24] }
  [25] print tr(td(commandbutton('Search'),'center 2'));
  [26] print "</table></td></tr></table><br>\n";
  [27] if ($_POST) {
  [28]     $files = fileset('*.php');
  [29]     $match_count = 0;
  [30]     foreach ($files as $filename) {
  [31]         $file_text = file_get_contents($filename);
  [32]         $index = 0;
  [33]         foreach (explode("\n",$file_text) as $line) {
  [34]             $index++; // maintain line number
  [35]             $matches = array();
  [36]             $match = FALSE;
  [37]             foreach ($needles as $needle) {
  [38]                 $position = strpos($line,$needle);
  [39]                 if ($position !== FALSE) { // this needle is a potential match
  [40]                     $match = TRUE;
  [41]                     foreach ($antineedles as $antineedle) {
  [42]                         $offset = strpos($antineedle,$needle);
  [43]                         if ($offset === FALSE) continue; // needle not part of this antineedle
  [44]                         if (substr($line,$position-$offset,strlen($antineedle)) === $antineedle) {
  [45]                             $match = FALSE; // potential needle match voided by this antineedle
  [46]                             break;
  [47]                         }
  [48]                     }
  [49]                 }
  [50]                 if ($match) $matches[$needle] = $position;
  [51]             }
  [52]             if ($matches) {$match_count++; $found[$filename][$index] = array($line,$matches);}
  [53]         }
  [54]     }
  [55]     if ($found) {
  [56]         print "<b>A total of " . plural($match_count,'matching line was','matching lines were') . " found</b><br>\n";
  [57]         if (count($needles)==1 && !$antineedles) print "Search string: $needles[0]";
  [58]         else {
  [59]             $text = count($hneedles) > 1 ? ' at least one of' : '';
  [60]             print "containing$text { " . implode(' | ',$hneedles) . " }<br>\n";
  [61]             if ($antineedles) print 'but not as part of { ' . implode(' | ',$hantineedles) . " }<br>\n";
  [62]         }
  [63]         print "<table cellpadding=10><tr><td><i>Files containing matches:</i>";
  [64]         foreach ($found as $filename => $line_info) {
  [65]             $name = filename_only($filename);
  [66]             print "<br> &nbsp; <a href='#$name'>$name</a>";
  [67]         }
  [68]         print "</td></tr></table>\n";
  [69]         print "\n<br>\n<table border=1 cellpadding=3>\n";
  [70]         foreach ($found as $filename => $line_info) {
  [71]             $name = filename_only($filename);
  [72]             $lines = array();
  [73]             foreach ($line_info as $index => $linematches) {
  [74]                 list($line,$matches) = $linematches;
  [75]                 // TO DO -- use $matches array to make the matches in $line bold for emphasis
  [76]                 $lines[] = " <small>[$index]</small> " . h($line);
  [77]             }
  [78]             print tr(td("<a name='$name'><i>$filename</i> &nbsp; $top_link<br>\n" . implode("<br>\n",$lines)));
  [79]         }
  [80]         print "</table>\n";
  [81]     } else print big("No instances of '$hneedle' were found");
  [82] }
  [83] page_end('');
  [89] ?>
FILE: _code_show.php - 152 lines, 3 functions [
Top]
  [1] <?php // display specified source code, with function-name indexes into a bookmarked listing
  [2] include '_all_includes.php';
  [3] $page_width="'96%'";
  [4] $suppress_banner = TRUE;
  [5] page_start();
  [6] $search_files = fileset('*.php','__*.php');
  [7] // first pass to extract function references
  [8] $function_index = $group_index = $file_index = 0; // used to make bookmark tags into code listing
  [9] $functions = $groups = $function_names = $function_initials = array();
  [10] foreach ($search_files as $filename) {
  [11]     $file_index++;
  [12]     $local = (substr(filename_base($filename),0,1) !== '_'); // general-include filenames start with underscore
  [13]     $code_lines = explode("\n",file_get_contents($filename));
  [14]     $group = '';
  [15]     $line = $group_count = $function_count = $file_function_count = 0;
  [16]     foreach ($code_lines as $code) {
  [17]         $line++;
  [18]         $code = trim($code);
  [19]         if (substr($code,0,5) === '//// ') { // function-group comment
  [20]             $group = get_group_name($code);
  [21]             if ($group) {
  [22]                 $group_index++;
  [23]                 $group_count++;
  [24]                 $title = ($group === $code) ? '' : $code; // suppress hover title if same as group name
  [25]                 $groups[$group] = array('name'=>$group,'file'=>$filename,'line'=>$line,'index'=>$group_index,'title'=>h($title));
  [26]             }
  [27]         } else if (substr($code,0,9) === 'function ') { // function definition
  [28]             $name = trim(between($code,'function','('));
  [29]             if ($name[0] === '_') continue; // ignore helper functions
  [30]             $function_index++;
  [31]             $function_count++;
  [32]             $file_function_count++;
  [33]             $args = trim(between($code,$name,'{'));
  [34]             $title = trim(after($code,'function'));
  [35]             $functions[$name] = array('name'=>$name,'file'=>$filename,'line'=>$line,'args'=>$args,'title'=>h($title),
  [36]                 'index'=>$function_index,'group'=>$group,'functions'=>$file_function_count,'local'=>$local);
  [37]             $function_names[] = $name;
  [38]             $function_initials[strtoupper($name[0])]++;
  [39]         }
  [40]     }
  [41]     $files[$filename] = array('name'=>filename_base($filename),'index'=>$file_index,'lines'=>count($code_lines),
  [42]         'functions'=>$function_count,'groups'=>$group_count,'local'=>$local);
  [43] }
  [44] // sort, then write index tables with group/subgroup and alphabetized list on left, then file-order list on right
  [45] print "<table border=1 cellpadding=5>\n";
  [46] ksort($function_initials);
  [47] foreach ($function_initials as $initial => $count) $initial_links .= " <a href='#I_$initial'>$initial</a>";
  [48] $directory = after(substr($_SERVER['PHP_SELF'],0,strrpos($_SERVER['PHP_SELF'],'/')),'/');
  [49] print tr(tdc("<b><i>INDEX TO $directory FUNCTIONS</i> &nbsp;$initial_links</b> &nbsp; &nbsp; " . alink('Search Code','_code_search.php'),2));
  [50] print "<tr>\n";
  [51] // left index column (groups, then alphabetized function list)
  [52] print "<td width='48%' valign=top>\n<b>FUNCTION GROUPS</b>\n";
  [53] ksort($groups);
  [54] foreach ($groups as $group) {
  [55]     print "<br><a href='#R$group[index]'><b>$group[name]</b></a> &nbsp; <small>$group[file] [$group[line]]</small>\n";
  [56] }
  [57] print "<br><br><b>$function_index FUNCTIONS - Ordered by Name</b>\n";
  [58] natcasesort($function_names);
  [59] $initial = '';
  [60] foreach ($function_names as $name) {
  [61]     if (strtoupper($name[0]) !== $initial) {
  [62]         $initial = strtoupper($name[0]);
  [63]         print "<br><a name='I_$initial'><br><b>$initial</b> &nbsp; $top_link\n";
  [64]     }
  [65]     $function = $functions[$name];
  [66]     $index = $files[$function['file']]['index'];
  [67]     $local = $function['local'] ? " &nbsp; <small>[Local]</small>" : '';
  [68]     $number = titled(spaces(4-strlen($function['line'])) . small("[<a href='#Q$index'>$function[line]</a>]"),"Line $function[line] in $function[file]");
  [69]     print "<br>$number <label title='$function[title]'><a href='#F$function[index]'><b>$function[name]</b>" .
  [70]         h($function['args']) . "</a>$local</label>\n";
  [71] }
  [72] print "</td>\n";
  [73] // right index column (files, then sequential function list)
  [74] print "<td width='52%' valign=top>\n<b>" . count($files) . " FILES</b>\n";
  [75] $alphabetized_files = $files;
  [76] ksort($alphabetized_files);
  [77] foreach ($alphabetized_files as $file) {
  [78]     $letter = $file['functions'] ? 'Q' : 'P';
  [79]     $filename = $file['name'];
  [80]     $run_link = $filename[0]==='_' ? '' : small('[' . alink('Run',$filename) . ']');
  [81]     print "<br>$run_link &nbsp; <a href='#$letter$file[index]'>$file[name]</a>\n";
  [82] }
  [83] $groupname = $file = '';
  [84] print "<br><br><b>$function_index FUNCTIONS - Ordered by Location</b>\n";
  [85] foreach ($functions as $function) {
  [86]     if ($function['file'] !== $file) {
  [87]         $file = $function['file'];
  [88]         $index = $files[$file]['index'];
  [89]         print "<a name='Q$index'><br><br><i><b>FILE:</b> <a href='#P$index'>$file</a></i> $top_link\n";
  [90]     }
  [91]     if ($function['group'] !== $groupname) {
  [92]         $groupname = $function['group'];
  [93]         $group = $groups[$groupname];
  [94]         $index = $group['index'];
  [95]         if ($groupname) print "<br><label title='$group[title]'><a name='R$index'>" .
  [96]             "<a href='#G$index'><b><i>$groupname</i></b></a></label> &nbsp; $file &nbsp; $top_link\n";
  [97]     }
  [98]     print line_number($function['line']) . "<label title='$function[title]'><a href='#F$function[index]'>" .
  [99]         "<b>$function[name]</b>" . h($function['args']) . "</a></label>\n";
 [100] }
 [101] print "</td>\n";
 [102] print "</tr>\n";
 [103] print "</table>\n";
 [104] // finally, list code for each file, with bookmark anchors at the start of each function
 [105] print "<br><h3>CODE LISTINGS</h3>\n";
 [106] print "<table style='font-family:Helvetica'><tr><td>\n";
 [107] $function_count = $group_count = 0;
 [108] foreach ($files as $filename => $file) {
 [109]     print "<a name='P$file[index]'><hr><b>FILE: $filename - $file[lines] lines, " . plural($file['functions'],'function') . "</b> $top_link\n";
 [110]     $code_lines = explode("\n",file_get_contents($filename));
 [111]     $line = 0;
 [112]     $copyright = FALSE;
 [113]     foreach ($code_lines as $code) {
 [114]         $line++;
 [115]         $trimmed_code = trim($code);
 [116]         if ($copyright && strpos($trimmed_code,'*/')===0) {$copyright = FALSE; continue;}
 [117]         if (strpos($trimmed_code,'/* Copyright (C)') === 0) $copyright = TRUE;
 [118]         if ($copyright) continue; // don't include copyright notice in these code listings
 [119]         if (substr($trimmed_code,0,9) === 'function ') { // function definition
 [120]             $declaration = trim(between($trimmed_code,'function ','{'));
 [121]             $remainder = after_with($trimmed_code,'{');
 [122]             $name = trim(before($declaration,'('));
 [123]             $function = $functions[$name];
 [124]             print " $top_link &nbsp; <small><a href='#Q$file[index]'>$file[name]</a></small>\n<a name='F$function[index]'>\n" .
 [125]                 code_line("function $declaration",$line,'b') . ' ' . h($remainder) . "\n";
 [126]         } else {
 [127]             if (substr($code,0,5) === '//// ') {
 [128]                 $group = $groups[get_group_name($code)];
 [129]                 if ($group['name']) print "<a name='G$group[index]'>\n";
 [130]             }
 [131]             print code_line($code,$line);
 [132]         }
 [133]     }
 [134] }
 [135] print "<hr>\n</td></tr></table>\n";
 [136] page_end(''); [Top]   _code_show.php
 [137] function get_group_name($text) {return ucfirst(trim(str_replace('//',' ',strtolower($text))));} [
Top]   _code_show.php
 [138] function line_number($linenumber) {
 [139]     $linenumber = $linenumber ? '<small>' . nbsp(substr(" [$linenumber]",-6)) . '</small> ' : '';
 [140]     return ("<br>$linenumber\n");
 [141] } [
Top]   _code_show.php
 [142] function code_line($code,$line='',$tag='') {
 [143]     $code = str_replace("\t",' &nbsp; &nbsp; ',h($code));
 [144]     if ($tag) $code = "<$tag>$code</$tag>";
 [145]     return (line_number($line) . $code);
 [146] }
 [152] ?>

FILE: _database_utilities.php - 370 lines, 43 functions [
Top]
  [1] <? // SQL-related routines
  [2] include_once '__settings.php';
  [3] require_once '_general_utilities.php';
  [4] $connection = database_connect();
  [5] [Top]   _database_utilities.php
  [6] function database_connect($database='',$context='',$username='',$password='') {
  [7]     if (!$database) $database = $GLOBALS['database_name'];
  [8]     if (!$database) return FALSE;
  [9]     if (!$username) $username = $GLOBALS['database_user'];
  [10]     if (!$password) $password = $GLOBALS['database_password'];
  [11]     $host = $GLOBALS['database_host'] ? $GLOBALS['database_host'] : 'localhost';
  [12]     $GLOBALS['connection'] = mysql_connect($host,"tlok02_$username",$password) or die('database connection failure ' . mysql_error());
  [13]     mysql_select_db("tlok02_$database$context",$GLOBALS['connection']) or die('database selection failure');
  [14]     return $GLOBALS['connection'];
  [15] }

  [16] //// SQL-RELATED [
Top]   _database_utilities.php
  [17] function sq($value) {return ("'" . str_replace("'","''",stripslashes($value)) . "'");} // guard SQL values [
Top]   _database_utilities.php
  [18] function sqrq($tag,$default='') {return sq(rq($tag,$default));} [
Top]   _database_utilities.php
  [19] function sql_close() {mysql_close();} // close SQL connection at end of page [
Top]   _database_utilities.php
  [20] function sql_clean($value) {
  [21]     $s = "";
  [22]     foreach (split(",",$value) as $c) { // collect non-forbidden characters
  [23]         if (ord($c)>31 && $c!==';' && $c!==':' && $c!=='`') $s .= $c; // drop control, system-call, and statement-separator characters
  [24]     }
  [25]     foreach (array('DROP ','DELETE ','UPDATE ') as $keyword) $s = str_ireplace("$keyword ",' ',$s);
  [26]     return $s;
  [27] } [
Top]   _database_utilities.php
  [28] function sql_query($text) {
  [29]     $GLOBALS[sql_query_text] = $text;
  [30]     $result = mysql_query($text);
  [31]     if ($result === FALSE) error($GLOBALS[sql_query_text] . ': ' . mysql_error($GLOBALS[connection]));
  [32]     return $result;
  [33] } [
Top]   _database_utilities.php
  [34] function sq_contents($value_array='') { // make parenthesized, comma-separated list, with '' as needed
  [35]     if (!is_array($value_array)) $value_array = func_get_args();
  [36]     foreach ($value_array as $value) $v[] = (is_numeric($value) ? "$value" : sq($value));
  [37]     return ('(' . join(',',$v) . ')'); // can be used either with "id in (1,2,3)" list or for insert-command value list
  [38] } [
Top]   _database_utilities.php
  [39] function sql_conditions($conditions) {
  [40]     if (!is_array($conditions)) $conditions = func_get_args();
  [41]     $where = '';
  [42]     foreach ($conditions as $condition) if ($condition) $where .= " AND ($condition)";
  [43]     if ($where) $where = substr($where,5); // drop leading " AND "
  [44]     return $where;
  [45] } [
Top]   _database_utilities.php
  [46] function sql_condition_phrase($condition) {
  [47]     if (is_array($condition) && count($condition)>0) $condition = 'id in ' . sq_contents($condition);
  [48]     elseif (is_numeric($condition)) {
  [49]         if ($condition > 0) $condition = "id=$condition"; // support lookup by id
  [50]         elseif ($condition < 0) $condition = 0; // negative ids are treated like zero (and thus ignored)
  [51]     } else {
  [52]         if (begins($condition,'()')) $condition = substr($condition,2);
  [53]         if (begins($condition,' and ')) $condition = substr($condition,5);
  [54]         if (begins($condition,' or ')) $condition = substr($condition,4);
  [55]     }
  [56]     return ($condition ? " WHERE $condition" : '');
  [57] } [
Top]   _database_utilities.php
  [58] function sql_order_phrase($order) {
  [59]     if (!$order) return '';
  [60]     if (is_array($order)) $order = join(',',$order);
  [61]     return (" ORDER BY " . str_replace('^',' desc',$order));
  [62] } [
Top]   _database_utilities.php
  [63] function list_table($table,$more='',$variables='*',$characters=200,$view_url='') { // lists contents of any SQL table
  [64]     // $table -- table name (in database that is already connected to)
  [65]     // $more -- SQL qualifying phrases, such as WHERE ..., ORDER BY ... or LIMIT ...
  [66]     // $variables -- optional list of fields (defaults to all fields)
  [67]     if ($characters < 5) $characters = 5;
  [68]     if ($view_url && $variables!=='*' && !contains(",$variables,",',id,')) $variables = "id,$variables";
  [69]     $result = sql_query("SELECT $variables FROM $table $more");
  [70]     $table = "\n<table cellpadding=3 border=1>\n";
  [71]     $headingdone = false;
  [72]     while ($row = mysql_fetch_assoc($result)) {
  [73]         if (!$headingdone) {
  [74]             $table .= "<tr>\n";
  [75]             foreach ($row as $var => $val) $table .= "<td><i>$var</i></td>";
  [76]             $table .= "</tr>\n";
  [77]             $headingdone = true;
  [78]         }
  [79]         $table .= "<tr>\n";
  [80]         foreach ($row as $var => $val) {
  [81]             if (same($var,'id') && $view_url) $val = small(alink('View',"$view_url?id=$val"));
  [82]             else {$val = h($val); if (strlen($val) > $characters) $val = titled(substr($val,0,$characters-3) . ' ...',$val);}
  [83]             $table .= "<td>$val</td>";
  [84]         }
  [85]         $table .= "</tr>\n";
  [86]     }
  [87]     $table .= "</table>\n";
  [88]     return $table;
  [89] }

  [90] //// SQL SCALAR [
Top]   _database_utilities.php
  [91] function DBC($table,$condition='') { // count of rows matching condition
  [92]     $condition = sql_condition_phrase($condition);
  [93]     $data = sql_query("SELECT count(*) FROM $table$condition");
  [94]     if ($data === FALSE) bailout("DBC error -- table=$table condition=$condition");
  [95]     if ($row = mysql_fetch_row($data)) return $row[0];
  [96]     return 0;
  [97] } [
Top]   _database_utilities.php
  [98] function DBZ($table,$field,$condition,$order='') { // return scalar value (NULL default)
  [99]     //if (!$condition) return NULL;
 [100]     $condition = sql_condition_phrase($condition);
 [101]     if ($order) sql_order_phrase($order);
 [102]     $result = sql_query("SELECT $field FROM $table$condition$order LIMIT 1");
 [103]     if (!$result) return FALSE;
 [104]     $row = mysql_fetch_array($result,MYSQL_NUM);
 [105]     return ($result===FALSE ? NULL : $row[0]);
 [106] } [
Top]   _database_utilities.php
 [107] function DBS($table,$field,$condition,$order='') { // return scalar value ('' default)
 [108]     //if (!$condition) return NULL;
 [109]     $result = DBZ($table,$field,$condition,$order);
 [110]     return ($result===NULL ? '' : $result);
 [111] } [
Top]   _database_utilities.php
 [112] function DBN($table,$field,$condition,$order='') { // return scalar numeric value (zero default)
 [113]     //if (!$condition) return NULL;
 [114]     $n = DBS($table,$field,$condition,$order);
 [115]     return (is_numeric($n) ? $n : 0);
 [116] }

 [117] //// SQL SINGLE RECORD [
Top]   _database_utilities.php
 [118] function DBR($table,$condition,$order='') { // returns first row meeting condition (or FALSE if none)
 [119]     if (!$condition) return NULL;
 [120]     $condition = sql_condition_phrase($condition);
 [121]     $order = sql_order_phrase($order);
 [122]     $result = sql_query("SELECT * FROM $table$condition$order LIMIT 1");
 [123]     if (!$result) return FALSE;
 [124]     return mysql_fetch_array($result,MYSQL_ASSOC);
 [125] } [
Top]   _database_utilities.php
 [126] function DBO($table,$condition='',$order='') { // returns either first row meeting condition, or "empty" row
 [127]     $result = DBR($table,$condition,$order);
 [128]     return ($result ? $result : DBF($table));
 [129] } [
Top]   _database_utilities.php
 [130] function DBF($table) { // returns an "empty object" row
 [131]     $result = sql_query("SELECT COLUMN_NAME,COLUMN_DEFAULT,DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name='$table'");
 [132]     if (!$result) return FALSE;
 [133]     $fields = array();
 [134]     while ($row = mysql_fetch_array($result,MYSQL_NUM)) { // set each field to its default
 [135]         if (contains($row[2],'INT')) $fields[$row[0]] = num($fields[$row[1]]);
 [136]         else $fields[$row[0]] = $fields[$row[1]];
 [137]     }
 [138]     return $fields;
 [139] }

 [140] //// SQL MULTI-RECORD [
Top]   _database_utilities.php
 [141] function DBE($table,$condition='',$order='') { // returns the array of enabled=1 rows meeting condition
 [142]     $condition = $condition!=='' ? "($condition) AND enabled=1" : "enabled=1";
 [143]     return DBA($table,$condition,$order);
 [144] } [
Top]   _database_utilities.php
 [145] function DBA($table,$condition='',$order='') { // returns rows meeting condition (all fields)
 [146]     return DBL($table,'*',$condition,$order);
 [147] } [
Top]   _database_utilities.php
 [148] function DBK($table,$key='id',$condition='',$order='') { // returns rows keyed by specified field
 [149]     $array_of_rows = array();
 [150]     foreach (DBA($table,$condition,$order) as $row) $array_of_rows[$row[$key]] = $row;
 [151]     return $array_of_rows;
 [152] } [
Top]   _database_utilities.php
 [153] function DBL($table,$selection='*',$condition='',$order='') { // returns rows meeting condition (specified fields)
 [154]     $condition = sql_condition_phrase($condition);
 [155]     $order = sql_order_phrase($order);
 [156]     $result = sql_query("SELECT $selection FROM $table$condition$order");
 [157]     $array_of_rows = array(); // empty array is return for no-results case
 [158]     if ($result) while($row = mysql_fetch_array($result)) {$array_of_rows[] = $row;}
 [159]     return $array_of_rows; // this is an array of keyed arrays, since rows are arrays keyed by field name
 [160] }

 [161] //// SQL VECTOR [
Top]   _database_utilities.php
 [162] function DBV($table,$field=id,$condition='',$order='') { // returns array of values of specified field in rows meeting condition
 [163]     $condition = sql_condition_phrase($condition);
 [164]     $order = sql_order_phrase($order);
 [165]     $result = sql_query("SELECT $field FROM $table$condition$order");
 [166]     if ($result === FALSE) return FALSE;
 [167]     $field_value_vector = array();
 [168]     while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {$field_value_vector[] = $row[$field];}
 [169]     return $field_value_vector; // this is a one-dimensional array, with one value from each qualifying row
 [170] } [
Top]   _database_utilities.php
 [171] function DBI($table,$field,$condition='',$order='') { // returns vector keyed by id number
 [172]     $condition = sql_condition_phrase($condition);
 [173]     $order = sql_order_phrase($order);
 [174]     $result = sql_query("SELECT id,$field FROM $table$condition$order");
 [175]     if ($result === FALSE) return FALSE;
 [176]     $field_value_vector = array();
 [177]     while($row = mysql_fetch_array($result,MYSQL_ASSOC)) {$field_value_vector[$row[id]] = $row[$field];}
 [178]     return $field_value_vector; // each key is the id for the corresponding row, each value the field value
 [179] } [
Top]   _database_utilities.php
 [180] function DBD($table,$id) { // returns comma-separated list of ids of a record and its descendents
 [181]     $descendents = array($id);
 [182]     do {$children = DBV($table,id,"parent_id in ($delete_list)"); $descendents = array_merge($descendents,$children);}
 [183]     while (count($children));
 [184]     return join(',',$descendents);
 [185] }

 [186] //// SQL INSERT/DELETE [
Top]   _database_utilities.php
 [187] function DB_delete_with_dependents($table,$id,$subtables='') {
 [188]     $id_list = DBD($table,$id); // get list of ids of this record and its dependents
 [189]     if (!$subtables) {
 [190]         if (!is_array($subtables)) $subtables = array($subtables); // to support scalar subtable name
 [191]         foreach ($subtables as $subtable) sql_query("delete from $subtable where {$table}_id in ($id_list)");
 [192]     }
 [193]     sql_query("delete from $table where id in ($id_list)"); // delete from primary table
 [194] } [
Top]   _database_utilities.php
 [195] function sql_update_or_insert($table,$contents,$condition='') {
 [196]     $names = $values = '';
 [197]     if ($condition && !is_array($contents)) { // plain update
 [198]         $s = "update $table set $contents" . sql_condition_phrase($condition);
 [199]         sql_query($s);
 [200]         return $condition;
 [201]     }
 [202]     foreach ($contents as $name => $value) {
 [203]         if ($name !== 'id') {
 [204]             $names .= ",$name";
 [205]             // if ($name === 'updated_at') $value = sql_timestamp_phrase();
 [206]             $value = sq(str_replace('&amp;', '&', $value));
 [207]             if ($condition) $names .= "=$value"; else $values .= ",$value";
 [208]         }
 [209]     }
 [210]     if ($condition) {
 [211]         $s = "update $table set " . substr($names,1) . sql_condition_phrase($condition);
 [212]         sql_query($s);
 [213]         return $condition;
 [214]     } else {
 [215]         $s = "insert into $table (". substr($names,1) . ") values (" . substr($values,1) . ")";
 [216]         sql_query($s);
 [217]         $id = mysql_insert_id();
 [218]         return $id;
 [219]     }
 [220] } [
Top]   _database_utilities.php
 [221] function sql_update($table,$contents,$condition='') {
 [222]     if (is_array($contents)) { // build set list from array keys and values
 [223]         foreach ($contents as $name => $value) {
 [224]             if ($name !== 'id') {
 [225]                 if ($name === 'modified_at') $value = 'NOW()';
 [226]                 else $value = sq(str_replace('&amp;', '&', $value));
 [227]                 $set .= ",$name=$value";
 [228]             }
 [229]         }
 [230]     } else $set = $contents; // plain update, already in name='value' form
 [231]     if (!$condition) bailout("No update condition specified for 'UPDATE $table SET $set'");
 [232]     sql_query("UPDATE $table SET $set" . sql_condition_phrase($condition));
 [233]     return mysql_affected_rows();
 [234] } [
Top]   _database_utilities.php
 [235] function sql_insert($table,$fields,$sequence_of_values) {
 [236]     if (!is_array($sequence_of_values)) {
 [237]         $v = func_get_args();
 [238]         $sequence_of_values = array_slice($v,2);
 [239]     }
 [240]     $values = array();
 [241]     for ($i=0; $i<count($sequence_of_values); $i++) {
 [242]         $value = $sequence_of_values[$i];
 [243]         if (substr($value,1,1)!=='(' || substr($value,1,-1)!==')') $value = sq($value);
 [244]         $values[] = $value;
 [245]     }
 [246]     $values = join(',',$values);
 [247]     return sql_raw_insert($table,$fields,$values);
 [248] } [
Top]   _database_utilities.php
 [249] function sql_raw_insert($table,$fields,$values) {
 [250]     sql_query("INSERT INTO $table ($fields) VALUES ($values)");
 [251]     return mysql_insert_id();
 [252] } [
Top]   _database_utilities.php
 [253] function sql_delete($table,$condition) {
 [254]     if (!$condition) bailout('Delete condition not specified');
 [255]     sql_query("DELETE FROM $table" . sql_condition_phrase($condition));
 [256]     return mysql_affected_rows();
 [257] } [
Top]   _database_utilities.php
 [258] function sql_backup_copy($table, $id) { // create disabled copy for possible later reversion
 [259]     $record = DBA($table,$id);
 [260]     if (!$record) return 0;
 [261]     $record[parent_id] = $id;
 [262]     unset($record[created_at]);
 [263]     $record[enabled] = FALSE;
 [264]     return sql_update_or_insert($table,$record,0); // return id of copy
 [265] } [
Top]   _database_utilities.php
 [266] function sql_revert_from_copy($table, $bid) {
 [267]     $backup_record = DBA($table,$bid);
 [268]     if (!$record || array_key_exists(parent_id,$record)) return FALSE;
 [269]     $parent_id = num($record[parent_id]);
 [270]     $current_record = DBA($table,$parent_id);
 [271]     if (!$current_record || !$parent_id) return FALSE;
 [272]     $backup_record[parent_id] = 0;
 [273]     sql_update_or_insert($table,$backup_record,$parent_id);
 [274]     sql_query("delete from $table where parent_id=$parent_id and id>$parent_id");
 [275]     return TRUE;
 [276] }

 [277] //// SQL DATETIME HANDLING [
Top]   _database_utilities.php
 [278] function sql_date($date_text) {
 [279]     $d = split("/",$date_text); // slash is standard separator
 [280]     if (count($d) < 2) { // try alternate separator if no slash
 [281]         $d = split("-",$date_text);
 [282]         if (count($d) < 2) return "";
 [283]     }
 [284]     if (count($d) == 2) { // if year not provided, assume nearest year of specified month
 [285]         $d[2] = idate("Y");
 [286]         if ((idate("m") - intval($d[0])) < 0) $d[2]--;
 [287]         if ((idate("m") - intval($d[0])) > 6) $d[2]++;
 [288]     }
 [289]     $d[0] = intval($d[0]); $d[1] = intval($d[1]); $d[2] = intval($d[2]); // force to integer
 [290]     if ($d[0] > 1900) { // convert into [month,day,year] sequence if in [year,month,day] sequence
 [291]         $d[3] = $d[0]; $d[0] = $d[1]; $d[1] = $d[2]; $d[2] = $d[3];
 [292]     }
 [293]     if ($d[2] < 100) $d[2] += ($d[2] < 50) ? 2000 : 1900; // extend two-digit year to four digits
 [294]     return "'{$d[2]}-{$d[0]}-{$d[1]}'"; // return single-quoted year-month-day form
 [295] } [
Top]   _database_utilities.php
 [296] function short_datetime($sqldate,$format='n/j/y') { // uses m/d/yy format if more than six months ago
 [297]     $h = $m = 0;
 [298]     $i = strpos($sqldate,":");
 [299]     if ($i>1 && $i<strlen($sqldate)) {
 [300]         $h = intval(substr($sqldate,$i-2,1))*10 + intval(substr($sqldate,$i-1,1));
 [301]         $m = intval(substr($sqldate,$i+1,2));
 [302]     }
 [303]     $d = split("-",$sqldate);
 [304]     if (count($d) < 3) return $sqldate; // return unchanged input if SQL-format date not found
 [305]     $time = mktime($h,$m,0,intval($d[1]),intval($d[2]),intval($d[0]));
 [306]     $ago = time() - $time;
 [307]     if (!$format) $format = 'g:i:s a T, l F j Y';
 [308]     elseif ($ago < 64800) $format = "g:i a"; // show only time if in last 18 hours
 [309]     elseif ($ago < 432000) $format = "D H:i"; // show day of week plus time if in last five days
 [310]     elseif ($ago < 16000000) $format = "n/j"; // drop year if in the last six months
 [311]     elseif ($time < 100000) $format = ""; // return blank if time is uninitialized value
 [312]     return date($format,$time);
 [313] } [
Top]   _database_utilities.php
 [314] function short_fulldatetime($sqldate) {
 [315]     $h = $m = 0;
 [316]     $i = strpos($sqldate,":");
 [317]     if ($i>1 && $i<strlen($sqldate)) {
 [318]         $h = intval(substr($sqldate,$i-2,1))*10 + intval(substr($sqldate,$i-1,1));
 [319]         $m = intval(substr($sqldate,$i+1,2));
 [320]     }
 [321]     $d = split("-",$sqldate);
 [322]     if (count($d) < 3) return $sqldate; // return unchanged input if SQL-format date not found
 [323]     return date("H:i n/j/y",mktime($h,$m,0,intval($d[1]),intval($d[2]),intval($d[0])));
 [324] } [
Top]   _database_utilities.php
 [325] function sqldatetime_to_timestamp($sqldate) {
 [326]     $h = $m = 0;
 [327]     $i = strpos($sqldate,":");
 [328]     if ($i>1 && $i<strlen($sqldate)) {
 [329]         $h = intval(substr($sqldate,$i-2,1))*10 + intval(substr($sqldate,$i-1,1));
 [330]         $m = intval(substr($sqldate,$i+1,2));
 [331]     }
 [332]     $d = split("-",$sqldate);
 [333]     if (count($d) < 3) return $sqldate; // return unchanged input if SQL-format date not found
 [334]     return mktime($h,$m,0,intval($d[1]),intval($d[2]),intval($d[0]));
 [335] } [
Top]   _database_utilities.php
 [336] function sql_timestamp_phrase($time) {
 [337]     return "'0'";
 [338] }

 [339] //// GENERAL PROPERTIES [
Top]   _database_utilities.php
 [340] function general_property($name) {
 [341]     return DBS('GeneralProperties','property_text','property_name=' . sq($name));
 [342] } [
Top]   _database_utilities.php
 [343] function set_general_property($name,$value) {
 [344]     if (DBC('GeneralProperties',$where)) update_general_property($name,$value);
 [345]     else sql_query('INSERT GeneralProperties (property_name,property_text) VALUES (' .
 [346]             sq($name) . ',' . sq($value) . ')');
 [347] } [
Top]   _database_utilities.php
 [348] function update_general_property($name,$value) {
 [349]     sql_query('UPDATE GeneralProperties SET property_text=' . sq($value),' WHERE property_name=' . sq($name));
 [350] } [
Top]   _database_utilities.php
 [351] function increment_general_property($name,$amount=1) {
 [352]     $where = 'property_name=' . sq($name);
 [353]     $value = DBG('GeneralProperties','property_text',$where);
 [354]     if (is_numeric($amount)) {
 [355]         $value += $amount;
 [356]         sql_query("UPDATE GeneralProperties SET property_text=$value",$where);
 [357]     }
 [358]     return $value;
 [359] } [
Top]   _database_utilities.php
 [360] function fetch_general_properties($list='') {
 [361]     if ($list) $list = "property_name in (" . implode(',',array_map(sq,csplit($list))) . ")";
 [362]     foreach (DBA('GeneralProperties',$list) as $property)
 [363]         $GLOBALS[$property[property_name]] = $property[property_text];
 [364] }
 [370] ?>

FILE: _equate_check.php - 30 lines, 0 functions [
Top]
  [1] <?php // display specified source code, with function-name indexes into a bookmarked listing
  [2] include '_all_includes.php';
  [3] $suppress_banner = TRUE;
  [4] $page_width = "'96%'";
  [5] page_start('Check directory for equal-sign anomolies');
  [6] $directory = rq('directory','./');
  [7] if (substr($directory,-1) !== '/') $directory .= '/';
  [8] print br('Directory: ' . textbox('directory',$directory,30) . ' ' . commandbutton('Search'));
  [9] if ($_POST) {
  [10]     $files = files("$directory*.php");
  [11]     $match_count = 0;
  [12]     foreach ($files as $filename) {
  [13]         $file_text = file_get_contents($filename);
  [14]         $index = 0;
  [15]         foreach (explode("\n",$file_text) as $line) {
  [16]             $index++; // maintain line number
  [17]             $matches = array();
  [18]             $match = FALSE;
  [19]             $text = str_replace('!==','',str_replace('===','',$line)); // eliminate safe equals
  [20]             if (contains($text,'==') || contains($text,'!=')) print br(textarea('text',"$index: $filename\n" . trim($line),2,100));
  [21]         }
  [22]     }
  [23] }
  [24] page_end('');
  [30] ?>
FILE: _general_utilities.php - 1257 lines, 204 functions [
Top]
  [1] <? // use _code_show.php to quickly find routines in this file
  [2] //// LINKS AND REDIRECTION [
Top]   _general_utilities.php
  [3] function redirect($target='?',$notice='') { // defaults to same page w/o querystring
  [4]     if ($notice) notice($notice);
  [5]     header("Location: ". regularize_url($target));
  [6]     exit;
  [7] } [
Top]   _general_utilities.php
  [8] function redirect_return($target,$page='') {$_SESSION['return_page'] = coalesce($page,$_SERVER['PHP_SELF']); redirect($target);} [
Top]   _general_utilities.php
  [9] function alink($text,$url='',$prefix='') { // internal hyperlink, in same window
  [10]     return hlink($text,$url,$prefix);
  [11] } [
Top]   _general_utilities.php
  [12] function plink($text,$url='?') {print alink($text,$url);} [
Top]   _general_utilities.php
  [13] function nav_link($label,$file='') {
  [14]     if (!$file) $file = strtolower($label) . '.php';
  [15]     if (position($_SERVER[SCRIPT_NAME],"$file")) $label = "<b>$label</b>";
  [16]     return (' ' . alink($label,$file));
  [17] } [
Top]   _general_utilities.php
  [18] function hlink($text,$url='',$prefix='') { // returns HTML for a hyperlink
  [19]     $url = regularize_url(str_replace('~',$text,$url));
  [20]     return "$prefix<a href=\"$url\">$text</a>";
  [21] } [
Top]   _general_utilities.php
  [22] function target_link($text,$url,$target='') { // hyperlink in separate window
  [23]     if (!$target) $target = $text;
  [24]     $url = regularize_url($url);
  [25]     return ("<a href='$url' target='$target'>$text</a>");
  [26] } [
Top]   _general_utilities.php
  [27] function regularize_url($url='') { // $url -- current page if filename omitted, php if extension omitted
  [28]     $url = trim($url);
  [29]     $a = substr($url,0,1); // first character will be used to detect initial # or ? or ''
  [30]     if ($a!=='/' && $a!=='.' && $a!=='_' && strtolower($a)===strtoupper($a)) $url = $_SERVER[SCRIPT_NAME].$url; // use current file if none specified
  [31]     $q = strpos($url,'?');
  [32]     $q_amp = strpos($url,'&'); // treat '&' before '?' as equivalent to '?'
  [33]     if ($q===FALSE || ($q_amp!==FALSE && $q_amp<$q)) $q = $q_amp;
  [34]     if ($q === FALSE) $q = strlen($url);
  [35]     $file = substr($url,0,$q);
  [36]     $last_slash = strrpos($file,'/');
  [37]     $dot = $last_slash===FALSE ? strpos($file,'.') : strpos($file,'.',$last_slash);
  [38]     if (($dot === FALSE) && substr($file,-1)!=='/') $file .= '.php';
  [39]     $query = (strlen($url)-$q > 1) ? ('?' . substr($url,$q+1)) : '';
  [40]     return "$file$query";
  [41] } [
Top]   _general_utilities.php
  [42] function full_url($text='') {
  [43]     $text = regularize_url($text);
  [44]     if ($text) {
  [45]         if (substr($text,0,1)==="/") $text = "$site_domain$text";
  [46]         if (position($text,"http://")===FALSE) $text = "http://$text";
  [47]     }
  [48]     return $text;
  [49] } [
Top]   _general_utilities.php
  [50] function bookmark($text) {return nameletters_underscore($text);}

  [51] //// FILES [
Top]   _general_utilities.php
  [52] function filename_only($filename='') {return before(filename_base($filename),'.');} // drops directories and extension [
Top]   _general_utilities.php
  [53] function filename_from_text($text,$directory='',$extension='txt') {
  [54]     return ($directory . nameletters_underscore(replace_chars($text,'./#?&=@ ','________')) . ".$extension");
  [55] } [
Top]   _general_utilities.php
  [56] function filename_base($filename='') { // drops directories and querystring
  [57]     if (!$filename) $filename = $_SERVER[SCRIPT_NAME];
  [58]     $i = strrpos($filename,'/');
  [59]     if ($i !== FALSE) $filename = substr($filename,$i+1);
  [60]     return before($filename,'?');
  [61] } [
Top]   _general_utilities.php
  [62] function files($pattern) {$filenames = glob($pattern); return (is_array($filenames) ? $filenames : array());} [
Top]   _general_utilities.php
  [63] function fileset($include_patterns,$omit_patterns=array()) { // returns non-duplicated list of files from patterns
  [64]     $omit = $files = array();
  [65]     foreach (make_array($omit_patterns) as $pattern) {if ($filenames) $omit = array_merge($omit,files($pattern));}
  [66]     foreach (make_array($include_patterns) as $pattern) {
  [67]         foreach (files($pattern) as $file) {
  [68]             if (!in_array($file,$omit) && !in_array($file,$files) && substr($file,0,2)!=='__') $files[] = $file;
  [69]         }
  [70]     }
  [71]     return $files; // ordered by pattern, alphabetically within pattern
  [72] } [
Top]   _general_utilities.php
  [73] function file_read_contents($filename) { // no-error read
  [74]     return (($filename && file_exists($filename)) ? file_get_contents($filename) : '');
  [75] } [
Top]   _general_utilities.php
  [76] function file_write_contents($filename,$content_args) {
  [77]     $lastslash = strrpos(before($filename,'?'),'/');
  [78]     $directory = $lastslash===FALSE ? '' : substr($filename,0,$lastslash);
  [79]     if ($directory && !is_dir($directory)) {if (@mkdir("$directory/",0777,TRUE) === FALSE) {error("Directory creation failure: $directory"); return FALSE;}}
  [80]     $fh = @fopen($filename,'w');
  [81]     if ($fh === FALSE) {error("File open failure: $filename"); return FALSE;}
  [82]     if (!is_array($content_args)) $content_args = array_slice(func_get_args(),1);
  [83]     $length = fwrite($fh,array_content($content_args));
  [84]     fclose($fh);
  [85]     return $length;
  [86] } [
Top]   _general_utilities.php
  [87] function read_url($url,$errormode=false) { // returns server response to supplied URL
  [88]     // $url -- must start with protocol (e.g., "http://") unless local file
  [89]     // $errormode -- if set, errors emit message and end page
  [90]     $page = '';
  [91]     $fh = fopen($url,'r');
  [92]     if (!$fh) {if ($errormode) die($php_errormsg);}
  [93]     else {while (!feof($fh)) $page .= fread($fh,1000000); fclose($fh);}
  [94]     return $page;
  [95] } [
Top]   _general_utilities.php
  [96] function read_cached_url($url,$timeout=3600) { // get url contents (or cache if $timeout seconds have not passed)
  [97]     if (!begins($url,'http://')) return file_get_contents($url);
  [98]     $filename = filename_from_text($url,'./cached/'); // make cache filename from url
  [99]     $updated = @filemtime($filename);
 [100]     if (!rq1('refresh') && $updated!==FALSE && $updated+$timeout>time()) return file_get_contents($filename); // use cached copy if still fresh
 [101]     $contents = read_url($url); // otherwise read url, write contents to cache, and return contents
 [102]     if ($contents) {file_write_contents($filename,$contents); return $contents;}
 [103]     else return file_get_contents($filename); // unless url cannot be read
 [104] } [
Top]   _general_utilities.php
 [105] function read_url_table($url,$field_delimiter="\t",$row_delimiter="\n",$errormode=false) {
 [106] $lines = explode($row_delimiter,read_url($url,$errormode));
 [107]     $table = array();
 [108]     foreach ($lines as $line) $table[] = explode($field_delimiter,$line);
 [109]     return $table;
 [110] } [
Top]   _general_utilities.php
 [111] function url_get_contents($url) {
 [112]     $url = str_replace('http://','',$url);
 [113] if (strpos($url,'/') === FALSE) $url = "$url/";
 [114] $slash = strpos($url,'/');
 [115] $host = substr($url,0,$slash);
 [116] $path = substr($url,$slash);
 [117] $headers = "GET $path HTTP/1.0\r\nUser-Agent: myHttpTool/1.0\r\n\r\n";
 [118] $fp = fsockopen($host, 80, $errno, $errmsg, 30);
 [119] if (!$fp) return "SOCKET OPEN ERROR: $errmsg";
 [120] fwrite($fp, $headers);
 [121] while(!feof($fp)) $resp .= fgets($fp, 4096);
 [122] fclose($fp);
 [123] $heading = before($resp,"\r\n\r\n") . "\r\n";
 [124] $cookie = trim(between($heading,'Set-Cookie:',';'));
 [125] $location = trim(between($heading,"\nLocation:","\n"));
 [126] if ($location) {
 [127]     if (strpos($location,'/') === FALSE) {
 [128]         $slash = strrpos($path,'/');
 [129]         $location = substr($path,0,$slash+1) . $location;
 [130]     }
 [131]         $headers = "GET $location HTTP/1.0\r\nUser-Agent: myHttpTool/1.0";
 [132]         if ($cookie) $headers .= "\r\nCookie: $cookie";
 [133]         $headers .= "\r\n\r\n";
 [134]     $fp = fsockopen($host, 80, $errno, $errmsg, 30);
 [135]     if (!$fp) return "SOCKET REOPEN ERROR: $errmsg";
 [136]     $resp .= "\r\n----------------------$location-------------------\r\n";
 [137]     fwrite($fp, $headers);
 [138]     while(!feof($fp)) $resp .= fgets($fp, 4096);
 [139]     fclose($fp);
 [140] }
 [141] return $resp;
 [142] } [
Top]   _general_utilities.php
 [143] function filename_from_datetime($datetime,$extension='',$prefix='') { // produces output such as "aaa_2010_12_03_0630.xxx"
 [144]     $filename = date('Y_m_d_Hi',$datetime);
 [145]     if ($prefix) $filename = $prefix . "_$filename";
 [146]     if ($extension) $filename .= ".$extension";
 [147]     return $filename;
 [148] } [
Top]   _general_utilities.php
 [149] function datetime_from_filename($filename) { // uses underscore-delimited text before the first dot, e.g. "aaa_2010_12_25_0630.xxx"
 [150]     $filenameparts = pathinfo($filename);
 [151]     $name = before($filenameparts['basename'],'.');
 [152]     list($time,$day,$month,$year) = array_reverse(explode('_',$name)); // get last four sections of name
 [153]     if (!is_numeric($year) || $year<1970) list($year,$month,$day,$time) = array($month,$day,$time,'0000'); // time-omitted mode
 [154]     $time = substr($time,0,-2) . ':' . substr($time,-2);
 [155]     if (!is_numeric($year) || $year<1970) return -1; // -1 is also the result from strtotime if datetime-parsing fails    
 [156]     return strtotime("$year-$month-$day-$time") + 21600;
 [157] } [
Top]   _general_utilities.php
 [158] function datenamed_files($pattern) { // fetch array using pattern-matching filenames that imply a datetime
 [159]     $files = array();
 [160]     foreach (files($pattern) as $filename) { // make array to sort by implied datetime
 [161]         $datetime = datetime_from_filename($filename);
 [162]         if ($datetime > 0) $files[$filename] = $datetime; // ignore files whose names do not yield a datetime
 [163]     }
 [164]     asort($files); // sort by date, retaining filenames as keys
 [165]     return array_reverse(array_keys($files)); // return filesnames with most recent first
 [166] } [
Top]   _general_utilities.php
 [167] function datenamedfile_label($filename) {
 [168]     $datetime = datetime_from_filename($filename);
 [169]     if ($datetime <= 0) return $filename; // return full filename if date-parse failure
 [170]     $label = trim(datenamedfile_prefix($filename));
 [171]     if ($label) $label .= ' - ';
 [172]     return ($label . date('H:i D M j Y',$datetime));
 [173] } [
Top]   _general_utilities.php
 [174] function datenamedfile_prefix($filename) {
 [175]     $lastslash = strrpos($filename,'/');
 [176]     if ($lastslash !== FALSE) $filename = substr($filename,$lastslash+1); // drop directory from label
 [177]     $filename = before($filename,'.'); // drop extension
 [178]     $parts = array_slice(explode('_',$filename),0,-4);
 [179]     return ($parts ? implode(' ',$parts) : '');
 [180] }

 [181] //// ARRAYS [
Top]   _general_utilities.php
 [182] function element($key,$array) {return (is_array($array) ? $array[$key] : NULL);} // can used with literal arrays [
Top]   _general_utilities.php
 [183] function array_vector($matrix,$column_key) {
 [184]     $array = array();
 [185]     foreach ($matrix as $row_key => $row) $array[$row_key] = $row[$column_key];
 [186]     return $array;
 [187] } [
Top]   _general_utilities.php
 [188] function array_content($array,$delimiter='') {
 [189]     $result = '';
 [190]     foreach($array as $element) {
 [191]         if (!is_array($element)) $result .= "$element$delimiter";
 [192]         else $result .= array_content($element,$delimiter);
 [193]     }
 [194]     return $result;
 [195] } [
Top]   _general_utilities.php
 [196] function char_array($text) { // split text into array of single-character strings
 [197]     $array = array();
 [198]     for ($i=0; $i<strlen($text); $i++) $array[] = substr($text,$i,1);
 [199]     return $array;
 [200] } [
Top]   _general_utilities.php
 [201] function gjoin($delimiter,$array,$prefix='',$suffix='') { // general-case safe join
 [202]     return ($prefix . (is_array($array) ? implode($delimiter,$array) : $array) . $suffix);
 [203] } [
Top]   _general_utilities.php
 [204] function gsplit($delimiter,$text) { // general-case safe split
 [205]     if (is_array($text)) return $text; // respect existing arrays
 [206]     if ($delimiter === '') return char_array($text);
 [207]     $pieces = array();
 [208]     if ($text!=='' && $text!==NULL) {foreach (explode($delimiter,$text) as $piece) $pieces[] = trim($piece);}
 [209]     return $pieces;
 [210] } [
Top]   _general_utilities.php
 [211] function nsplit($text) {return gsplit("\n",$text);} // split text into one-dimentional item-trimmed array at newlines [
Top]   _general_utilities.php
 [212] function njoin($array,$prefix='',$suffix='') {return gjoin("\n",$array,$prefix,$suffix);} [
Top]   _general_utilities.php
 [213] function csplit($text) {return gsplit(',',$text);} // split text into one-dimentional item-trimmed array at commas [
Top]   _general_utilities.php
 [214] function cjoin($array,$prefix='',$suffix='') {return gjoin(',',$array,$prefix,$suffix);} // undoes csplit (except for trim effects) [
Top]   _general_utilities.php
 [215] function ssplit($text) { // split text into two-dimensional array with semicolon & comma delimiters
 [216]     $array = array();
 [217]     if ($text) {foreach (gsplit(';',$text) as $subarray) $array[] = csplit($subarray);}
 [218]     return $array;
 [219] } [
Top]   _general_utilities.php
 [220] function sjoin($array) { // undoes ssplit
 [221]     $rows = array();
 [222]     foreach ($make_array($array) as $subarray) $rows[] = cjoin($subarray);
 [223]     return gjoin(';',$rows);
 [224] } [
Top]   _general_utilities.php
 [225] function ksplit($text) { // split text into key => value array (comma delimiters, colon key:value separators)
 [226]     if (is_array($text)) return $text; // tolerate pre-split arrays
 [227]     $result = array();
 [228]     if ($text) {
 [229]         foreach (csplit($text) as $element) {
 [230]             $colon = strpos($element,':');
 [231]             if ($colon === FALSE) $result[] = trim($element);
 [232]             else $result[trim(substr($element,0,$colon))] = trim(substr($element,$colon+1));
 [233]         }
 [234]     }
 [235]     return $result;
 [236] } [
Top]   _general_utilities.php
 [237] function kjoin($array) { // undoes ksplit
 [238]     foreach (make_array($array) as $key => $value) $items[] = is_numeric($key) ? $value : "$key:$value";
 [239]     return $items ? cjoin($items) : '';
 [240] } [
Top]   _general_utilities.php
 [241] function pack_wrap($array,$glue='|') { // make joined string, with glue also before and after
 [242]     $text = $glue; // empty array will cause return of single delimiter
 [243]     foreach ($array as $element) { // build string, replacing imbedded delimiters with \
 [244]         $text .= str_replace($glue,"\\",$element) . $glue;
 [245]     }
 [246]     return $text;
 [247] } [
Top]   _general_utilities.php
 [248] function unpack_unwrap($text) { // use first char as delimiter to split input w/o first and last char
 [249]     $n = strlen($text);
 [250]     if ($n < 2) return array(); // leading delimiter alone implies empty array
 [251]     $array = explode($text[0],substr($text,1,$n - ($text[0]===$text[$n-1] ? 2 : 1))); // split inside with delimiter
 [252]     foreach ($array as $key => $element) $array[$key] = str_replace("\\",$text[0],$element); // restore imbedded delimiters
 [253]     return $array; // return unpacked array
 [254] } [
Top]   _general_utilities.php
 [255] function make_array($var) { // force argument to array
 [256]     return (is_array($var) ? $var : (isset($var) ? array($var) : array()));
 [257] } [
Top]   _general_utilities.php
 [258] function array_concat() { // concatenates first level of array values, treating scalars as single-element arrays
 [259]     $array = array();
 [260]     foreach (func_get_args() as $arg) {
 [261]         if (is_array($arg)) {foreach ($arg as $key=>$element) $array[$key] = $element;}
 [262]         else $array[] = $arg;}
 [263]     return $array;
 [264] } [
Top]   _general_utilities.php
 [265] function array_listing($array,$label='ARRAY') {
 [266]     if (!is_array($array)) return '';
 [267]     $t = "\n*** $label (" . count($array) . ") ***\n";
 [268]     foreach ($array as $key => $value) {
 [269]         if (!is_array($value)) $t .= "[$key]: $value {" . strlen($value) . "}\n";
 [270]         else foreach ($value as $k => $v) $t .= "\t[$k]: $v {" . strlen($v) . "}\n";
 [271]     }
 [272]     return $t;
 [273] } [
Top]   _general_utilities.php
 [274] function string_r($variable) {ob_start(); print_r($variable); return ob_get_clean();} [
Top]   _general_utilities.php
 [275] function chunked_array($array,$preferred=6,$leeway=TRUE) { // splits array into nearly-equal chunks
 [276]     $count = count($array);
 [277]     if ($preferred < 0) $preferred = (int)($count-1)/(abs($preferred)) + 1; // negative size means to split into that many pieces
 [278]     if ($preferred < 1) $preferred = 1;
 [279]     $chunks = (int) (($count-1) / $preferred) + 1;
 [280]     $chunk = (int) (($count+$chunks-1) / $chunks);
 [281]     if ($leeway && $count%$chunk>0 && $count%$chunk<$chunks) $chunk++;
 [282]     return array_chunk($array,$chunk,TRUE);
 [283] } [
Top]   _general_utilities.php
 [284] function chunked_string($string,$preferred=80,$delimiters=" \n\r\t") { // breaks string into nearly-equal pieces at delimiters
 [285]     $length = strlen($string);
 [286]     if ($preferred==0 || $preferred>=$length || !$delimiters) return array($string);
 [287]     if ($preferred < 0) $pieces = abs($preferred); // negative preferred size means to split into that many pieces
 [288]     else $pieces = (int) (($length-1) / $preferred) + 1;
 [289]     $search = replace_chars($string,$delimiters,str_repeat(' ',strlen($delimiters))) . ' '; // append space to simplify search
 [290]     $offset = 0;
 [291]     $output = array();
 [292]     for ($piece=0; $piece<$pieces && $offset<$length; $piece++) {
 [293]         $preferred = (int) (($length - $offset) / ($pieces - $piece) + 1); // split remaining string equally
 [294]         if ($offset+$preferred >= $length) $piece_length = $length - $offset;
 [295]         else {
 [296]             $before = strrpos(substr($search,$offset,$preferred),' '); // find last delimiter before or at preferred length
 [297]             $after = strpos(substr($search,$offset + $preferred),' '); // and first delimiter after preferred length
 [298]             $piece_length = ($before!==FALSE && $after<$preferred-$before-1) ? $preferred+$after+1 : $before+1; // break at closest delimiter
 [299]             if (abs($piece_length-$preferred) > $preferred/2) $piece_length = $preferred; // if no delimiter near preferred length, break at preferred length
 [300]         }
 [301]         $output[] = trim(substr($string,$offset,$piece_length));
 [302]         $offset += $piece_length;
 [303]     }
 [304]     trace('count,length for chunked_string output',count($output). ', ' . strlen(implode('',$output)));
 [305]     return $output;
 [306] } [
Top]   _general_utilities.php
 [307] function folded_string($string,$preferred=80,$glue="<br>\n",$delimiters=" \n\r\t") {
 [308]     return implode($glue,chunked_string($string,$preferred,$delimiters));
 [309] }

 [310] //// MAIL [
Top]   _general_utilities.php
 [311] function mlink($text='',$address='',$subject='') {
 [312]     if (!$text) {$text = $address; if (!$address) return '';}
 [313]     if (!$address) $address = extract_emails($text);
 [314]     if (is_array($address)) $address = implode(', ',$address);
 [315]     if ($subject) $subject = '?subject=' . h($subject);
 [316]     return "<a href=\"mailto:$address$subject\">$text</a>";
 [317] } [
Top]   _general_utilities.php
 [318] function mail_link($text,$subject='',$to='',$cc='',$bcc='') {
 [319]     if (!$text) $text = after($GLOBALS['system_email'],'@');
 [320]     return "<a href=\"mailto:?subject=" & urlencode($subject) . url_join('to',$to) . url_join('cc',$cc) . url_join('bcc',$bcc) . "\">$text</a>";
 [321] } [
Top]   _general_utilities.php
 [322] function url_join($tag,$addresses) {return ($addresses ? "&$tag=" . urlencode(implode(', ',make_array($addresses))) : '');} [
Top]   _general_utilities.php
 [323] function message_field_lines($record,$field_sequence) { // return a message line for each non-blank field specified
 [324]     $text = '';
 [325]     $args = func_get_args();
 [326]     for ($i=1; $i<count($args); $i++) {if ($arg[$i]) $text .= $args[$i] . ": " . $record[strtolower($args[$i])] . "\n";}
 [327]     return $text;
 [328] } [
Top]   _general_utilities.php
 [329] function extract_email($text) {
 [330]     $email_name_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.';
 [331]     $i = strpos($text,'@');
 [332]     if ($i === FALSE) return '';
 [333]     $a = $b = '';
 [334]     $j = $k = $i;
 [335]     while (--$j >= 0) {$c = substr($text,$j,1); if (strpos($email_name_letters,$c) === FALSE) break; $a = $c . $a;}
 [336]     while ($k++ < strlen($text)) {$c = substr($text,$k,1); if (strpos($email_name_letters,$c) === FALSE) break; $b .= $c;}
 [337]     $i = strpos($b,'.');
 [338]     if (!$a || !$i || (strlen($b)-$i)<3) return '';
 [339]     return "$a@$b";
 [340] } [
Top]   _general_utilities.php
 [341] function extract_emails($text) {
 [342]     $email_addresses_found = array();
 [343]     $email_name_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.';
 [344]     do {
 [345]         $i = strpos($text,'@');
 [346]         if ($i === FALSE) return $email_addresses_found;
 [347]         $a = $b = '';
 [348]         $j = $k = $i;
 [349]         while (--$j >= 0) {$c = substr($text,$j,1); if (strpos($email_name_letters,$c) === FALSE) break; $a = $c . $a;}
 [350]         while ($k++ < strlen($text)) {$c = substr($text,$k,1); if (strpos($email_name_letters,$c) === FALSE) break; $b .= $c;}
 [351]         $i = strpos($b,'.');
 [352]         if ($a && $i && (strlen($b)-$i)>2) $email_addresses_found[] = "$a@$b";
 [353]         $text = substr($text,$k);
 [354]     } while ($text);
 [355]     return $email_addresses_found;
 [356] } [
Top]   _general_utilities.php
 [357] function send_mail($target,$subject,$message,$reply='') {
 [358]     if (same($target,"psheller@tx.rr.com")) return '';
 [359]     global $site_email_domain,$site_email_reply_domain,$site_email_reply_address,$system_email,$no_mail_copy;
 [360]     if (!$reply && $site_email_reply_address) $reply = $site_email_reply_address;
 [361]     if (!$reply && $site_email_reply_domain) $reply = "mail@$site_email_reply_domain";
 [362]     if (!$reply && $site_email_domain) $reply = "mail@$site_email_domain";
 [363]     $target = extract_email($target);
 [364]     if (!$target) return '';
 [365]     $mail_headers = "From: website@$site_email_domain\r\n";
 [366]     if ($reply) $mail_headers .= "Reply-To: $reply\r\n";
 [367]     $mail_headers .= "X-Mailer: PHP/" . phpversion();
 [368]     $message = stripslashes($message);
 [369]     if ($target!==$system_email && !$no_mail_copy) {
 [370]         $result = mail($system_email, "COPY: $subject", "SENT TO: $target\n\n$message", $mail_headers);
 [371]         if (!result) error("mail failure for $system_email");
 [372]     }
 [373]     $result = mail($target, $subject, $message, $mail_headers);
 [374]     if (!$result) error("mail failure for $target");
 [375]     return $result;
 [376] } [
Top]   _general_utilities.php
 [377] function site_mail($subject='',$text='',$target='webmaster') {
 [378]     global $site_email_domain,$site_abbr;
 [379]     if (!contains($target,'@')) $target = "$target@$site_email_domain";
 [380]     if (!$text) $text = $target;
 [381]     return mlink($text,$target,"$site_abbr $subject");
 [382] } [
Top]   _general_utilities.php
 [383] function system_mail($subject,$message) {
 [384]     global $site_abbr,$system_email;
 [385]     return send_mail($system_email,"$site_abbr SYSTEM: $subject",$message);
 [386] }

 [387] //// INPUT WIDGETS [
Top]   _general_utilities.php
 [388] function textbox($name,$value='~',$size=30,$maxlength='') { // returns HTML text input widget
 [389]     $value = plain($value);
 [390]     if ($value === '~') $value = rq($name);
 [391]     return textbox_raw($name,h($value),$size,$maxlength);
 [392] } [
Top]   _general_utilities.php
 [393] function textbox_raw($name,$value='~',$size=30,$maxlength='') {
 [394]     if ($size < 0) $maxlength = $size = abs($size);
 [395]     if ($maxlength) $maxlength = " maxlength=$maxlength";
 [396]     return "<input type=text name=$name id=$name value=\"$value\" size=$size$maxchars>";
 [397] } [
Top]   _general_utilities.php
 [398] function filebox($name,$value='~',$size=20,$mimetypes='') { // returns HTML filename input widget
 [399]     $value = plain($value);
 [400]     if ($value === '~') $value = rq($name);
 [401]     if ($maxchars) $maxchars = " maxchars=$maxchars";
 [402]     return ("<input type=file name=$name id=$name value=\"" . h($value) . "\" size=$size accept=\"$mimetypes\"");
 [403] } [
Top]   _general_utilities.php
 [404] function passwordbox($name='password',$value='',$size=20) {
 [405]     return ("<input type=password name=\"$name\" size=$width value=\"". h($value) . "\">");
 [406] } [
Top]   _general_utilities.php
 [407] function textarea_head($name,$rows=5,$columns=80,$wrap=FALSE) {
 [408]     return ("<textarea name='$name' id='$name' rows=$rows cols=$columns wrap='" . ($wrap ? 'soft' : 'off')) . "'>";
 [409] } [
Top]   _general_utilities.php
 [410] function textarea($name,$value='',$rows=5,$columns=80,$wrap=TRUE) {return textarea_raw($name,h($value),$rows,$columns,$wrap);} [
Top]   _general_utilities.php
 [411] function textarea_raw($name,$value='',$rows=5,$columns=80,$wrap=FALSE) { // returns HTML textarea widget
 [412]     return (textarea_head($name,$rows,$columns,$wrap) . $value . "</textarea>\n");
 [413] } [
Top]   _general_utilities.php
 [414] function checkbox($name,$checked='~',$value=1,$label='~') {
 [415]     if ($checked === '~') $check = rq1($name);
 [416]     $label = str_replace('~',$value,$label);
 [417]     return "<label><input type=checkbox name=\"$name\" value=\"" . h($value) ."\"".($checked? ' checked' : '').">$label</label> ";
 [418] } [
Top]   _general_utilities.php
 [419] function checkbox_set($name,$values=array(),$checked='~',$delimiter='<br>',$label='~',$prefix='') {
 [420]     if ($checked === '~') $checked = rq_array($name);
 [421]     $doubletag = strpos($delimiter,'><');
 [422]     if ($doubletag) {$prefix = substr($delimiter,0,$doubletag+1); $delimiter = substr($delimiter,$doubletag+1);}
 [423]     $text = '';
 [424]     foreach ($values as $key => $value) {
 [425]         $check = isset($checked[$key]) ? ' checked' : '';
 [426]         $labeltext = str_replace('~',$value,$label);
 [427]         $text .= " $prefix <label><input type=checkbox name=\"{$name}[$key]\" value=\"" . h($value) . "\"$check>$labeltext</label> $delimiter \n";
 [428]     }
 [429]     return $text;
 [430] } [
Top]   _general_utilities.php
 [431] function radio($name,$value,$current='~',$label='',$extra='') { // returns enhanced HTML radiobutton widget
 [432]     $current = $current==='~' ? rq($name) : plain($current);
 [433]     $checked = ("$value" === "$current")? ' checked' : '';
 [434]     if ($label === '') $label = $value;
 [435]     if ($extra) $extra = " $extra";
 [436]     $wid = $name . '_' . nameletters_only("$value");
 [437]     return ("&nbsp;<label><input$checked$extra type=radio name=$name value=\"" . h($value) . "\" id=$wid>$label</label>&nbsp;\n");
 [438] } [
Top]   _general_utilities.php
 [439] function radioset($name,$values,$current='',$separator=' &nbsp; ') { // default to horizontal layout
 [440]     if (!is_array($values)) { // support supply of values list in string form
 [441]         $values = ssplit($values); // try a,aa;b,bb;c,cc literal-list convention
 [442]         if (count($values) == 1) $values = $values[0]; // if no semicolons, use a,b,c convention
 [443]     }
 [444]     $widgets = '';
 [445]     foreach ($values as $value) {
 [446]         if (is_array($value)) {$v = $label = $value[0]; if (count($value) > 1) $v = $value[1];}
 [447]         else {$v = $label = $value;}
 [448]         $widgets .= $separator . radio($name,$v,$current,$label);
 [449]     }
 [450]     return substr($widgets,strlen($separator)); // drop leading separator
 [451] } [
Top]   _general_utilities.php
 [452] function selectset($name,$list,$current,$extra='') {
 [453]     if (!is_array($list)) { // support supply of values list in string form
 [454]         $list = ssplit($list); // try a,aa;b,bb;c,cc literal-list convention
 [455]         if (count($list) == 1) $list = $list[0]; // if no semicolons, use a,b,c convention
 [456]     }
 [457]     $widget = "<select name=\"$name\"$extra>\n";
 [458]     $sequence = 0;
 [459]     foreach ($list as $key => $text) {
 [460]         $selected = ("$current"==="$key" ? " selected" : "");
 [461]         $widget .= "<option value=\"" . h($key) . "\"$selected>$text</option>\n";
 [462]     }
 [463]     return "$widget</select>\n";
 [464] } [
Top]   _general_utilities.php
 [465] function selectlist($name,$current,$list,$extra='') {
 [466]     if (!is_array($list)) { // support supply of values list in string form
 [467]         $list = ssplit($list); // try a,aa;b,bb;c,cc literal-list convention
 [468]         if (count($list) == 1) $list = $list[0]; // if no semicolons, use a,b,c convention
 [469]     }
 [470]     $widget = "<select name=\"$name\"$extra>\n";
 [471]     $sequence = 0;
 [472]     foreach ($list as $option) {
 [473]         if (is_array($option)) {$value = $text = $option[0]; if (count($option) > 1) $value = $option[1];}
 [474]         else {$text = $option; $value = $sequence++;}
 [475]         $selected = ("$current"==="$value" ? " selected" : "");
 [476]         $widget .= "<option value=\"" . h($value) . "\"$selected>$text</option>\n";
 [477]     }
 [478]     return "$widget</select>\n";
 [479] } [
Top]   _general_utilities.php
 [480] function selectvalues($name,$current,$list,$extra='') {
 [481]     if (!is_array($list)) { // support supply of values list in string form
 [482]         $list = ssplit($list); // try a,aa;b,bb;c,cc literal-list convention
 [483]         if (count($list) == 1) $list = $list[0]; // if no semicolons, use a,b,c convention
 [484]     }
 [485]     $widget = "<select name=\"$name\"$extra>\n";
 [486]     $sequence = 0;
 [487]     foreach ($list as $option) {
 [488]         if (is_array($option)) {$value = $text = $option[0]; if (count($option) > 1) $value = $option[1];}
 [489]         else $text = $value = $option;
 [490]         $selected = ("$current"==="$value" ? " selected" : "");
 [491]         $widget .= "<option value=\"" . h($value) . "\"$selected>$text</option>\n";
 [492]     }
 [493]     return "$widget</select>\n";
 [494] } [
Top]   _general_utilities.php
 [495] function commandbutton($label='Submit',$name='command') { // returns HTML text for form-submission button
 [496]     return "<input type=submit name=$name id=$name value=\"" . h($label) . "\">\n";
 [497] } [
Top]   _general_utilities.php
 [498] function hidden($name,$value='~') { // returns HTML for hidden variable
 [499]     if ($value === '~') $value = $_REQUEST[$name];
 [500]     if (!is_array($value)) return "<input type=hidden name=$name value=\"".addslashes($value)."\">\n";
 [501]     $result = '';
 [502]     foreach ($value as $key => $v) $result .= "<input type=hidden name='{$name}[$key]' value=\"".addslashes($v)."\">\n";
 [503]     return $result;
 [504] } [
Top]   _general_utilities.php
 [505] function hidden_rq() { // returns hidden-field HTML for all request parameters whose names are supplied as arguments
 [506]     for ($i=0,$result=''; $i<func_num_args(); $i++) {$s = func_get_arg($i); $result .= hidden($s);} // value from rq($s)
 [507] return $result;
 [508] } [
Top]   _general_utilities.php
 [509] function hidden_globals() { // returns hidden-field HTML for all global variables whose names are supplied as arguments
 [510]     for ($i=0,$result=''; $i<func_num_args(); $i++) {$s = func_get_arg($i); $result .= hidden($s,$GLOBALS[$s]);}
 [511] return $result;
 [512] } [
Top]   _general_utilities.php
 [513] function formheader($action='',$name='form1') {
 [514]     if (!$action) $action = $_SERVER[SCRIPT_NAME];
 [515]     return "<form name='$name' id='$name' method=POST action='$action'>";
 [516] } [
Top]   _general_utilities.php
 [517] function entry_text($label,$size=30,$name='',$extra='') {
 [518]     global $record;
 [519]     if (!$name) $name = str_replace(' ','_',strtolower($label));
 [520]     $value = $record[$name] ? $record[$name] : rq($name);
 [521]     return entry_row($label,textbox($name,$record[$name],$size) . $extra);
 [522] } [
Top]   _general_utilities.php
 [523] function entry_row($label,$widget) { // returns HTML for two-column row with right-justified label
 [524]     return "<tr><td align=right>$label</td><td>$widget<td></tr>\n";
 [525] } [
Top]   _general_utilities.php
 [526] function print_entry($label,$content='~') {
 [527]     if ($content === '~') {
 [528]         $name = str_replace(' ','_',strtolower($label));
 [529]         $content = rq($name,$GLOBALS['record'][$name]);
 [530]     }
 [531]     if ($content) print "<tr><td align=right><i>$label</td><td>$content</td></tr>\n";
 [532]     return $content;
 [533] }

 [534] //// REQUEST, SESSION, and GLOBAL [
Top]   _general_utilities.php
 [535] function register_request($request_parameter_list) {
 [536]     foreach (csplit($request_parameter_list) as $item) {
 [537]         $pieces = explode('/',$item);
 [538]         $name = $pieces[0];
 [539]         $type = substr($name,-1);
 [540]         $default = count($pieces)>1 ? $pieces[1] : '';
 [541]         if ($type==='?' || $type==='#') $name = substr($name,0,-1);
 [542]         if ($type === '#') $value = rqn($name,$default);
 [543]         elseif ($type === '?') $value = rq1($name,$default);
 [544]         else $value = rq($name,$default);
 [545]         $GLOBALS[$name] = $value;
 [546]     }
 [547] } [
Top]   _general_utilities.php
 [548] function posted($name='') {return ($name? isset($_POST[$name]) : count($_POST));} [
Top]   _general_utilities.php
 [549] function rqn($name='id',$default=0) {return num($_REQUEST[$name],$default);} // integer value from request [
Top]   _general_utilities.php
 [550] function rqf($name='id',$default=0.0) {$f = $_REQUEST[$name]; return (is_numeric($f) ? (float)$f : $default);} [
Top]   _general_utilities.php
 [551] function rq1($name) {return ($name && rq($name));} // returns clean logical value from request [
Top]   _general_utilities.php
 [552] function rq($name='id', $default='', $maxlength='') { // get trimmed value(s) from request (flatten joined with commas if array)
 [553]     $index = between($name,'[',']');
 [554]     $name = before($name,'[');
 [555]     $value = array_key_exists($name,$_REQUEST) ? $_REQUEST[$name] : $default;
 [556]     if (is_array($value)) $value = $index==='' ? implode(',',$value) : $value[$index];
 [557]     //$value = str_replace('\\','',$value);
 [558]     if ($maxlength) $value = substr($value,0,$maxlength);
 [559]     return $value;
 [560] } [
Top]   _general_utilities.php
 [561] function rq_array($name='id',$default=array(),$prefix='',$suffix='') { // get posted array of values
 [562]     $array = array();
 [563]     foreach (make_array(array_key_exists($name,$_REQUEST) ? $_REQUEST[$name] : $default) as $key => $value) {
 [564]         //$array[$key] = $prefix . str_replace('\\','',$value) . $suffix;
 [565]         $array[$key] = "$prefix$value$suffix";
 [566]     }
 [567]     return $array;
 [568] } [
Top]   _general_utilities.php
 [569] function rq_fields($record) { // returns array with values of corresponding $_REQUEST parameters for keys in input record
 [570]     $result = array();
 [571]     foreach ($record as $field => $value) {if (isset($_POST[$field])) $result[$field] = rq($field);}
 [572]     return $result;
 [573] } [
Top]   _general_utilities.php
 [574] function gv($name, $default='') {$value = $GLOBALS[$name]; return ($value? $value : $default);} [
Top]   _general_utilities.php
 [575] function gv_set($name, $value='', $default='') {$old = gv($name,$default); $GLOBAL[$name] = $value; return $old;} [
Top]   _general_utilities.php
 [576] function sv($name, $default='') {$value = @$_SESSION[$name] ? $_SESSION[$name] : $default; return ($value? $value : $default);} [
Top]   _general_utilities.php
 [577] function sv_set($name, $value='', $default='') {$old = sv($name,$default); $_SESSION[$name] = $value; return $old;}

 [578] //// LOGIC-DRIVEN PARSING [
Top]   _general_utilities.php
 [579] function tf($test,$if_true='',$if_false='') {return ($test ? $if_true : $if_false);} [
Top]   _general_utilities.php
 [580] function wrap_if($text,$prefix='',$suffix='') {return (strlen($text) ? "$prefix$text$suffix" : '');} [
Top]   _general_utilities.php
 [581] function wrap_array($array,$prefix='',$suffix='',$before='',$after='') {
 [582]     return ($array ? "$before$prefix" . implode("$suffix$prefix") . "$suffix$after" : '');
 [583] } [
Top]   _general_utilities.php
 [584] function more_if($text,$suffix='') {return (strlen($text) ? "$text$suffix" : '');} [
Top]   _general_utilities.php
 [585] function coalesce() { // return first non-FALSE argument from variable-length list
 [586]     $arg = ''; // default return if no arguments
 [587]     foreach (func_get_args() as $item) {if ($item) return $item; $arg = $item;}
 [588]     return $arg; // if no TRUE arguments, return last argument or '' if no arguments
 [589] } [
Top]   _general_utilities.php
 [590] function choice($index, $value_sequence) { // return indexed value from sequence
 [591]     return ($index<0 || $index>func_num_args()) ? FALSE : func_get_arg($index);
 [592] }

 [593] //// STRING PARSING [
Top]   _general_utilities.php
 [594] function concatenate($args) {$text = ''; foreach (func_get_args() as $arg) $text .= "$arg"; return $text;} [
Top]   _general_utilities.php
 [595] function num($value,$default=0) {return (is_numeric($value) ? (int)$value : $default);} // forces to integer [
Top]   _general_utilities.php
 [596] function title_case($text) {
 [597]     $words = explode(' ',str_replace('_',' ',strtolower($text)));
 [598]     $text = '';
 [599]     foreach ($words as $word) $text .= ' ' . ucfirst($word);
 [600]     return substr($text,1); // drop leading space
 [601] } [
Top]   _general_utilities.php
 [602] function detab($text,$spacing=8) {
 [603]     $detabbed = '';
 [604] for ($i = 0; $i < strlen($text); $i++) {
 [605] if ($text[$i] === "\t") do {$detabbed .= ' ';} while (strlen($detabbed) % $spacing != 0);
 [606] else $detabbed .= $text[$i];
 [607] }
 [608] return $detabbed;
 [609] } [
Top]   _general_utilities.php
 [610] function plural($count,$singular,$plural='') { // returns numeric value followed by text with appropriate plural form
 [611]     if (is_array($count)) $count = count($count);
 [612]     return (number_format($count) . ' ' . pluralize($singular,$count,$plural)); // number_format adds commas if appropriate
 [613] } [
Top]   _general_utilities.php
 [614] function pluralize($word,$count=0,$plural='') { // does not change capitalization, handles y-ended and s-ended words
 [615]     if (is_array($count)) $count = count($count);
 [616]     if ($count == 1) return $word;
 [617]     if ($plural) return str_replace('~',$word,$plural);
 [618]     $lastchar = substr($word,-1);
 [619]     if (same($lastchar,'y')) {$word = substr($word,0,-1); $suffix = 'ies';}
 [620]     elseif (same($lastchar,'s')) $suffix = 'es';
 [621]     else $suffix = 's';
 [622]     if ($lastchar === strtoupper($lastchar)) $suffix = strtoupper($suffix);
 [623]     return ($word . $suffix);
 [624] } [
Top]   _general_utilities.php
 [625] function singularize($word) { // does not change initial-letter capitalization
 [626]     if (substr($word,-3) === 'ses') return (substr($word,0,strlen($word)-2));
 [627]     if (substr($word,-3) === 'ies') return (substr($word,0,strlen($word)-3) . ($word[-4]===strtolower($word[-4]) ? 'y' : 'Y'));
 [628]     if (substr($word,-1) === 's') return (substr($word,0,strlen($word)-1));
 [629]     return $word;
 [630] } [
Top]   _general_utilities.php
 [631] function limit_text($text,$limit,$more) {
 [632]     if ($limit>0 && strlen($text)>$limit) $text = h(substr($text,0,$limit)) . $more;
 [633]     return ($limit ? $text : ''); // return empty string for zero limit, full string for negative limit
 [634] } [
Top]   _general_utilities.php
 [635] function limited($value,$width=0,$lower_bound=0) { // adjust value if needed to stay within range
 [636]     if ($value<$lower_bound) return $lower_bound; // no lower than zero or specified bound
 [637]     if ($width>0 && $value>=$lower_bound+$width) return $lower_bound+$width-1;
 [638]     return $value; // no change if within specified range
 [639] } [
Top]   _general_utilities.php
 [640] function significant_digits($value,$digits=3) { // limits text from numeric value to specified number of significant digits
 [641]     if (PHP_VERSION > '5.2.1') $digits++; // because in PHP 5 the # in '%e#' format is decimals rather than significant digits
 [642]     if ($digits <= 0) return ($value ? '1' : '0');
 [643]     if ($digits > 9) $digits = 9;
 [644]     $text = sprintf("%e$digits",$value); // let library handle rounding
 [645]     $parts = split($text,'e',2);
 [646]     $mantissa = digits_only($parts[0]); // get digits; drop sign and decimal
 [647]     $exponent = num($parts[1]) + 1; // implied decimal point is now before first digit
 [648]     if ($exponent>-6 && $exponent<9) { // replace e-format text if feasible
 [649]         if ($exponent > 0) { // absolute value is one or larger
 [650]             if ($exponent < $digits) { // embedded decimal needed
 [651]                 $text = substr($mantissa,0,$exponent) . '.' . substr($mantissa,$exponent);
 [652]             } else { // zero or more appended zeros needed
 [653]                 $text = $mantissa . str_repeat('0',$exponent-$digits);
 [654]             }
 [655]         } else { // absolute value is less than one, so prepend leading zeros
 [656]             $text = '0.' . str_repeat('0',-$exponent) . $mantissa;
 [657]         }
 [658]         if ($value<0) $text = "-$text"; // prepend minus sign if needed
 [659]     } // text is left in e-format if number magnitude too big or small
 [660]     return $text;
 [661] } [
Top]   _general_utilities.php
 [662] function fieldname_case($text) {return strtolower(str_replace(' ','_',$text));}

 [663] //// HMTL GENERATION [
Top]   _general_utilities.php
 [664] function nf($number,$tag='') {$n = number_format($number); if ($tag) $n = "<$tag>$n</$tag>"; return $n;} [
Top]   _general_utilities.php
 [665] function h($text) {
 [666]     if (is_null($text)) $text = '';
 [667]     return htmlspecialchars($text,ENT_QUOTES);
 [668] } [
Top]   _general_utilities.php
 [669] function plain($text='') {return is_null($text)? '': "$text";} [
Top]   _general_utilities.php
 [670] function nbsp($text) {return str_replace(' ','&nbsp;',$text);} [
Top]   _general_utilities.php
 [671] function spaces($spaces) {return ($spaces > 0 ? str_repeat('&nbsp;',$spaces) : '');} [
Top]   _general_utilities.php
 [672] function nospace($text) {return str_replace(' ','',$text);} [
Top]   _general_utilities.php
 [673] function br($text='',$before=0,$after=1) {return (str_repeat('<br>',$before) . $text . str_repeat('<br>',$after) . "\n");} [
Top]   _general_utilities.php
 [674] function tag($tag,$text='',$test=TRUE) {return $test ? wrap($text,"<$tag>") : $text;} [
Top]   _general_utilities.php
 [675] function bold($text,$test=TRUE) {return tag('b',$text,$test);} [
Top]   _general_utilities.php
 [676] function italic($text,$test=TRUE) {return tag('i',$text,$test);} [
Top]   _general_utilities.php
 [677] function big($text,$test=TRUE) {return tag('big',$text,$test);} [
Top]   _general_utilities.php
 [678] function small($text,$test=TRUE) {return tag('small',$text,$test);} [
Top]   _general_utilities.php
 [679] function span($text,$class,$test=TRUE) {return tag("span class=$class",$text,$test);} [
Top]   _general_utilities.php
 [680] function br_list($heading,$array,$indent=0) {
 [681]     if (!$array) return '';
 [682]     $delim = "\n<br>" . spaces($indent);
 [683]     return ("$heading$delim" . implode($delim,$array));
 [684] } [
Top]   _general_utilities.php
 [685] function p($text='&nbsp;',$padding=3,$margin=0) {return "<p style='padding: {$padding}pt {$margin}pt;'>$text</p>\n";} [
Top]   _general_utilities.php
 [686] function pc($text='',$padding=3) {return "<p align=center style='padding: {$padding}pt;'>$text</p>\n";} [
Top]   _general_utilities.php
 [687] function titled($text,$title,$tag='span') {
 [688]     return ($title ? "<$tag title=\"" . str_replace('"','&quot;',$title) . "\">$text</$tag>" : $text);
 [689] } [
Top]   _general_utilities.php
 [690] function wrap($valuearray,$prefix,$suffix='',$preamble='',$postscript='',$test=TRUE) { // wrap scalar or array with text
 [691]     if (!$suffix) { // wrap in prefix if suffix omitted
 [692]         $suffix = $prefix;
 [693]         // if suffix omitted for tag prefix, use appropriate closing tag as suffix
 [694]         $i = position($prefix,'<');
 [695]         $j = position($prefix,'>');
 [696]         if ($i!==FALSE && $j!==FALSE && $i<$j) {
 [697]             $k = position($prefix,' ');
 [698]             if ($k!==FALSE && $k<$j) $suffix = substr($suffix,0,$k) . substr($suffix,$j); // drop tag parameters
 [699]             $suffix = substr($suffix,0,$i+1) . '/' . substr($suffix,$i+1); // insert slash close character
 [700]         }
 [701]     }
 [702]     $a = '';
 [703]     if ($test) {
 [704]         if (is_array($valuearray)) foreach ($valuearray as $value) $a .= $prefix . $value . $suffix;
 [705]         else $a = $prefix . $valuearray . $suffix; // scalar value is treated as if single-element array
 [706]     }
 [707]     return ($preamble . $a . $postscript);
 [708] } [
Top]   _general_utilities.php
 [709] function paragraph($text,$class='paragraph',$delimiter="\n") {
 [710]     $p = $class ? "<p class=$class>" : "<p>";
 [711]     if (contains($class,'=')) $p = "<p $class>"; // to support direct style declarations
 [712]     $output = '';
 [713]     foreach (explode($delimiter,str_replace("\r",'',$text)) as $line) {
 [714]         $output .= $p . str_replace(' ','&nbsp; ',str_replace("\n",' ',str_replace(" \n",' ',trim($line)))) . "</p>\n";
 [715]     }
 [716]     return $output;
 [717] } [
Top]   _general_utilities.php
 [718] function paragraphed($text) {
 [719]     $output = '';
 [720]     foreach (explode("\n",str_replace("\r",'',$text)) as $line) {
 [721]         $line = str_replace(' ','&nbsp; ',trim($line));
 [722]         if ($line) $output .= " &nbsp; &nbsp; $line<br>\n";
 [723]     }
 [724]     return $output;
 [725] }

 [726] //// CASE-INSENSITIVE FIND & COMPARE [
Top]   _general_utilities.php
 [727] function position($haystack,$needle,$offset=0) {
 [728]     if ("$needle"==='' || "$haystack"==='') return FALSE;
 [729]     return strpos(strtolower($haystack),strtolower($needle),$offset);
 [730] } [
Top]   _general_utilities.php
 [731] function last_position($haystack,$needle,$offset=0) {
 [732]     if ("$needle"==='' || "$haystack"==='') return FALSE;
 [733]     return strrpos(strtolower($haystack),strtolower($needle),$offset);
 [734] } [
Top]   _general_utilities.php
 [735] function same($firststring,$secondstring) { // any additional arguments are also checked, returns TRUE if any match
 [736]     $firststring = strtolower("$firststring");
 [737]     if (!is_array($secondstring)) $secondstring = array_slice(func_get_args(),1);
 [738]     foreach ($secondstring as $string) {if (strtolower("$string") === $firststring) return TRUE;}
 [739]     return FALSE;
 [740] } [
Top]   _general_utilities.php
 [741] function contains($haystack,$needle,$offset=0) {
 [742]     if ("$needle"==='' || "$haystack"==='') return FALSE;
 [743]     return (position($haystack,$needle,$offset) !== FALSE);
 [744] } [
Top]   _general_utilities.php
 [745] function begins($full,$start,$offset=0) {
 [746]     if ("$full"==='' || "$start"==='') return FALSE;
 [747]     return (position($full,$start,$offset) === 0);
 [748] }

 [749] //// SUBSTRING EXTRACTION [
Top]   _general_utilities.php
 [750] function phrase($text,$offset=0,$length=FALSE) {return implode(' ',words($text,$offset,$length));} [
Top]   _general_utilities.php
 [751] function words($text,$offset=0,$length=FALSE) {
 [752]     $words = explode(' ',trim("$text"));
 [753]     return ($length!==FALSE ? array_slice($words,$offset,$length) : array_slice($words,$offset));
 [754] } [
Top]   _general_utilities.php
 [755] function before($text,$match,$prefix='') { // return the first substring, if any, before match (back to the optional prefix)
 [756]     // $text -- the string from which the substring is to be extracted
 [757]     // $match -- the search substring; $text before $match will be returned
 [758]     // $prefix -- if a match is found, returned text up to and including the last instance of $prefix is dropped
 [759]     $text_new = before_with($text,$match,$prefix);
 [760]     if ($text !== $text_new) $text_new = substr($text_new,0,-strlen($match));
 [761]     return $text_new;
 [762] } [
Top]   _general_utilities.php
 [763] function before_with($text,$match,$prefix='') { // drops text after match if found
 [764]     // $text -- the string from which the substring is to be extracted
 [765]     // $match -- the search substring
 [766]     if ("$match"==='' || "$text"==='') return '';
 [767]     $j = position($text,$match);
 [768]     if ($j !== FALSE) {
 [769]         $text = substr($text,0,$j+strlen($match));
 [770]         $i = last_position($text,$prefix);
 [771]         if ($i !== FALSE) $text = substr($text,$i+1);
 [772]     }
 [773]     return $text;
 [774] } [
Top]   _general_utilities.php
 [775] function before_last($text,$match,$prefix='') {
 [776]     $j = last_position($text,$match);
 [777]     if ($j === FALSE) return $text;
 [778]     $i = 0;
 [779]     if ($prefix !== '') {
 [780]         $k = last_position(substr($text,0,$i),$prefix);
 [781]         if ($k !== FALSE) $i = $k;
 [782]     }
 [783]     return substr($text,$i,$j-$i);
 [784] } [
Top]   _general_utilities.php
 [785] function after($text,$match,$suffix='') { // returns the first substring, if any, after the match (but before the optional suffix)
 [786]     // $text -- the string from which the substring is to be extracted
 [787]     // $match -- the search substring; $text after the first instance of $match will be returned
 [788]     // $suffix -- if a match is found, returned text after and including the next instance of $suffix is dropped
 [789]     $text = after_with($text,$match,$suffix);
 [790]     if ($text !== '') $text = substr($text,strlen($match)); // drop match from returned string
 [791]     return $text;
 [792] } [
Top]   _general_utilities.php
 [793] function after_with($text,$match,$suffix='') { // drops text until match is found
 [794]     // $text -- the string from which the substring is to be extracted
 [795]     // $match -- the search substring
 [796]     // $suffix -- if a match is found, returned text after the next instance of $suffix is dropped
 [797]     if ("$text"==='' || "$match"==='') return '';
 [798]     $i = position($text,$match);
 [799]     if ($i === FALSE) return '';
 [800]     $j = strlen($text);
 [801]     if ($suffix !== '') {
 [802]         $k = position($text,$suffix,$i);
 [803]         if ($k !== FALSE) $j = $k;
 [804]     }
 [805]     return substr($text,$i,$j-$i);
 [806] } [
Top]   _general_utilities.php
 [807] function after_last($text,$match,$suffix='') {
 [808]     $i = last_position($text,$match);
 [809]     if ($i === FALSE) return '';
 [810]     $i += strlen($match); // space past match
 [811]     $j = strlen($text);
 [812]     if ($suffix !== ''){
 [813]         $k = position($text,$suffix,$i);
 [814]         if ($k !== FALSE) $j = $k;
 [815]     }
 [816]     return substr($text,$i,$j-$i);
 [817] } [
Top]   _general_utilities.php
 [818] function around($text,$match,$prefix='',$suffix='') { // searches outward from match
 [819]     // $text -- the string from which the substring is to be extracted
 [820]     // $match -- the search substring; $text around the first instance of $match will be returned
 [821]     // $prefix -- limits the returned text before the match to that after the closest previous instance of the prefix
 [822]     // $suffix -- limits the returned text after the match to that before the next instance of the suffix
 [823]     $text = around_with($text,$match,$prefix,$suffix);
 [824]     if ($text !== '') $text = substr($text,strlen($prefix),-strlen($suffix)); // prefix and suffix are not part of returned text
 [825]     return $text;
 [826] } [
Top]   _general_utilities.php
 [827] function around_with($text,$match,$prefix='',$suffix='') { // searches outward from match
 [828]     // $text -- the string from which the substring is to be extracted
 [829]     // $match -- the search substring; $text around the first instance of $match will be returned
 [830]     // $prefix -- drops text before the closest previous instance of the prefix
 [831]     // $suffix -- drops text after the next instance of the suffix
 [832]     if ("$text"==='' || "$match"==='' || "$prefix"==='' || "$suffix"==='') return '';
 [833]     $i = position($text,$prefix);
 [834]     if ($i === FALSE) return '';
 [835]     $m = position($text,$match,$i);
 [836]     if ($m === FALSE) return '';
 [837]     // matched text is included in search for prefix or suffix
 [838]     $i += last_position(substr($text,$i,$m-$i+strlen($match)),$prefix); // find closer prefix if possible
 [839]     $j = position($text,$suffix,$m);
 [840]     if ($j === FALSE) return '';
 [841]     return substr($text,$i,$j-$i+strlen($suffix)); // prefix and suffix included in returned text
 [842] } [
Top]   _general_utilities.php
 [843] function arounds($text,$match,$prefix,$suffix,$limit=1000) { // extracts array of substrings around successive matches
 [844]     // $text -- the string from which the substring is to be extracted
 [845]     // $match -- the search substring; text around instances of $match will be returned
 [846]     // $prefix -- drops text before the closest previous instance of the prefix
 [847]     // $suffix -- drops text after the next instance of the suffix
 [848]     // $limit -- maximum number of substrings to return
 [849]     $items = array();
 [850]     if ("$text"!=='' && "$match"!=='' && "$prefix"!=='' && "$suffix"!=='') { // avoid null-string ambiguities
 [851]         $text_lower = strtolower($text);
 [852]         $match = strtolower($match);
 [853]         $prefix = strtolower($prefix);
 [854]         $suffix = strtolower($suffix);
 [855]         $n = strlen($text);
 [856]         $c = strlen($match);
 [857]         $b = strlen($prefix);
 [858]         $a = strlen($suffix);
 [859]         $offset = 0;
 [860]         while ($limit-- && $offset<$n) {
 [861]             $m = strpos($text_lower,$match,$offset);
 [862]             if ($m === FALSE) break;
 [863]             $i = strrpos(substr($text_lower,$offset,$m-$offset),$prefix); // find prefix before match
 [864]             if ($i === FALSE) break;
 [865]             $i += $offset + $b; // adjust index for substring used in strrpos, and for prefix length
 [866]             $j = strpos($text_lower,$suffix,$m+$c); // find suffix after match
 [867]             if ($j === FALSE) break;
 [868]             $items[] = substr($text,$i,$j-$i); // extract contained text segment for list
 [869]             $offset = $j + $a; // move offset to after this suffix
 [870]         }
 [871]     }
 [872]     return $items;
 [873] } [
Top]   _general_utilities.php
 [874] function drop_before($text,$match) { // drops text until match is found
 [875]     // $text -- the string from which the substring is to be extracted
 [876]     // $match -- the search substring
 [877]     $i = position($text,$match);
 [878]     if ($i === FALSE) return '';
 [879]     return substr($text,$i);
 [880] } [
Top]   _general_utilities.php
 [881] function drop_after($text,$match) { // drops text after match if found
 [882]     // $text -- the string from which the substring is to be extracted
 [883]     // $match -- the search substring
 [884]     $i = position($text,$match);
 [885]     if ($i === FALSE) return $text;
 [886]     return substr($text,0,$i+strlen($match));
 [887] } [
Top]   _general_utilities.php
 [888] function keep_before($text,$match) { // keeps text until match is found
 [889]     // $text -- the string from which the substring is to be extracted
 [890]     // $match -- the search substring
 [891]     $i = position($text,$match);
 [892]     if ($i === FALSE) return $text;
 [893]     return substr($text,0,$i);
 [894] } [
Top]   _general_utilities.php
 [895] function keep_after($text,$match) { // keeps text after match if found
 [896]     // $text -- the string from which the substring is to be extracted
 [897]     // $match -- the search substring
 [898]     $i = position($text,$match);
 [899]     if ($i === FALSE) return '';
 [900]     return substr($text,$i+strlen($match));
 [901] } [
Top]   _general_utilities.php
 [902] function between($text,$before,$after,$offset=0) {
 [903]     // extracts text between $before and $after strings, exclusive, starting $offset characters deep
 [904]     // $text -- the string from which the substring is to be extracted
 [905]     // $before -- the first search substring
 [906]     // $after -- the second substring
 [907]     // $offset -- where to start in $text
 [908]     $text = between_with($text,$before,$after,$offset);
 [909]     if ($text) $text = substr($text,strlen($before),-strlen($after));
 [910]     return $text;
 [911] } [
Top]   _general_utilities.php
 [912] function between_with($text,$before,$after,$offset=0) {
 [913]     // extracts text between $before and $after strings, inclusive, starting $offset characters deep
 [914]     // $text -- the string from which the substring is to be extracted
 [915]     // $before -- the first search substring
 [916]     // $after -- the second substring
 [917]     // $offset -- where to start in $text
 [918]     if ("$text"==='' || "$before"==='' || "$after"==='') return '';
 [919]     $text_lower = strtolower($text);
 [920]     $i = strpos($text_lower,strtolower($before),$offset);
 [921]     if ($i === FALSE) return '';
 [922]     $j = strpos($text_lower,strtolower($after),$i+strlen($before));
 [923]     if ($j === FALSE) return '';
 [924]     $i += strrpos(substr($text_lower,$i,$j-$i),strtolower($before)); // in case another 'before' match is closer to 'after' match
 [925]     return substr($text,$i,$j-$i+strlen($after));
 [926] } [
Top]   _general_utilities.php
 [927] function betweens($text,$before,$after,$limit=1000) { // extracts array of substrings between successive $before/$after pairs
 [928]     // $text -- the string from which the substring is to be extracted
 [929]     // $before -- the first search substring
 [930]     // $after -- the second substring
 [931]     // $limit -- maximum number of substrings to return
 [932]     $items = array();
 [933]     if ("$text"!=='' && "$before"!=='' && "$after"!=='') { // avoid null-string ambiguities
 [934]         $text_lower = strtolower($text);
 [935]         $before = strtolower($before);
 [936]         $after = strtolower($after);
 [937]         $offset = 0;
 [938]         while ($limit-- && $offset<strlen($text)) {
 [939]             $i = strpos($text_lower,$before,$offset);
 [940]             if ($i === FALSE) break;
 [941]             $j = strpos($text_lower,$after,$i+strlen($before)); // find next "after" tag
 [942]             if ($j === FALSE) break;
 [943]             $i += strrpos(substr($text_lower,$i,$j-$i),$before) + strlen($before); // move past last 'before' before 'after'
 [944]             $items[] = substr($text,$i,$j-$i); // extract contained text segment for item list
 [945]             $offset = $j + strlen($after); // move offset to after this "after" tag
 [946]         }
 [947]     }
 [948]     return $items;
 [949] }

 [950] //// STRING FILTERS [
Top]   _general_utilities.php
 [951] function digits_only($text) {$n = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_digit($text[$i])) $n .= $text[$i];} return $n;} [
Top]   _general_utilities.php
 [952] function letters_only($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_alpha($text[$i])) $a .= $text[$i];} return $a;} [
Top]   _general_utilities.php
 [953] function letters_and_spaces_only($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_alpha($text[$i]) || $text[$i]===' ') $a .= $text[$i];} return $a;} [
Top]   _general_utilities.php
 [954] function alphanumeric_only($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_alnum($text[$i])) $a .= $text[$i];} return $a;} [
Top]   _general_utilities.php
 [955] function alphanumeric_and_spaces_only($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_alnum($text[$i]) || $text[$i]===' ') $a .= $text[$i];} return $a;} [
Top]   _general_utilities.php
 [956] function nameletters_only($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (ctype_alnum($text[$i]) || $text[$i]==='_') $a .= $text[$i];} return $a;} [
Top]   _general_utilities.php
 [957] function nameletters_underscore($text) {return nameletters_only(str_replace(' ','_',$text));} [
Top]   _general_utilities.php
 [958] function nameletters_instead($text) {$a = ''; for ($i=0; $i<strlen($text); $i++) {if (!ctype_alnum($text[$i])) $text[$i] = '_';} return $text;} [
Top]   _general_utilities.php
 [959] function namealphanumeric_only($text) { // drops non-alphanumeric except single-quote, comma, hyphen, and first imbedded space
 [960]     for ($a='',$c='',$i=0; $i<strlen($text); $i++) {
 [961]         $b = $text[$i];
 [962]         if (ctype_alnum($b) || $b==="'" || $b===',' || $b==='-' || ($b===' '&&$c!==' ')) {$a .= $b; $c = $b;}
 [963]         else $c = $c ? '' : ' ';
 [964]     }
 [965]     return trim($a);
 [966] } [
Top]   _general_utilities.php
 [967] function emailnameletters_only($text) {
 [968]     $email_name_letters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.';
 [969]     $a = ''; for ($i=0; $i<strlen($text); $i++) {if (strpos($email_name_letters,$text[$i]) !== FALSE) $a .= $text[$i];}
 [970]     return $a;
 [971] } [
Top]   _general_utilities.php
 [972] function respace($text) {return str_replace('&nbsp;',' ',str_replace('_',' ',$text));} [
Top]   _general_utilities.php
 [973] function drop_chars($text,$chars) {for ($i=0; $i<strlen($chars); $i++) $text = str_replace($chars[$i],'',$text); return $text;} [
Top]   _general_utilities.php
 [974] function replace_chars($text,$chars,$replacement='') {
 [975]     for ($i=0; $i<strlen($chars); $i++) {
 [976]         $c = ($i < strlen($replacement) ? $replacement[$i] : '');
 [977]         $text = str_replace($chars[$i],$c,$text);
 [978]     }
 [979]     return $text;
 [980] } [
Top]   _general_utilities.php
 [981] function drop_string($text,$string) {
 [982]     $args = array_slice(func_get_args(),1);
 [983]     foreach ($args as $arg) $text = str_replace($arg,'',$text);
 [984]     return $text;
 [985] } [
Top]   _general_utilities.php
 [986] function dequote($text) {return drop_chars($text,"\"'`\\");} [
Top]   _general_utilities.php
 [987] function deslash($text) { // removes unguarded backslashes
 [988]     if (strpos($text,'\\') !== FALSE) {
 [989]         $pieces = explode('\\',$text); // break string apart at each backslash
 [990]         $$text = ''; // will be rebuilt from pieces
 [991]         $was_bs = FALSE; // be used to include a backslash when a doubled backslash is encountered
 [992]         foreach ($pieces as $piece) {
 [993]             if ($piece === '') { // if successive backslashes in input text, save only 2nd, 4th, etc.
 [994]                 if ($was_bs) {$v .= '\\'; $was_bs = FALSE;}
 [995]                 else $was_bs = TRUE;
 [996]             } else {$text .= $piece; $was_bs = FALSE;}
 [997]         }
 [998]     }
 [999]     return $text;
[1000] }

[1001] //// TABLE CONSTRUCTION [
Top]   _general_utilities.php
[1002] function table($parameters=3,$content_args='') {
[1003]     $rows = array();
[1004]     foreach (array_slice(func_get_args(),1) as $contents) { // arguments after the first are row content
[1005]         if (!is_array($contents)) $contents = array($contents); // treat scalars as one-element arrays
[1006]         foreach ($contents as $content) { // an array argument is treated as an array of row content
[1007]             if (!begins($content,'<tr')) $content = tr($content); // ensure proper table-component tags
[1008]             $rows[] = $content;
[1009]         }
[1010]     }
[1011]     return (table_begin($parameters) . implode("\n",$rows) . $GLOBALS['table_end']);
[1012] } [
Top]   _general_utilities.php
[1013] function table_begin($parameters=3) {
[1014]     if (!is_array($parameters)) $parameters = func_get_args(); // multi-set parameters can be either array or sequential
[1015]     $text = '';
[1016]     foreach ($parameters as $parameter_set) { // one parameter set for each table when nested
[1017]         if ($text) {$text .= '<tr><td>'; $endtext = "</td></tr>$endtext";} // except for first pass, add html to nest tables
[1018]         $text .= "<table";
[1019]         foreach (explode(' ',"$parameter_set") as $parameter) {
[1020]             if ($parameter !== '') {
[1021]                 if (is_numeric($parameter)) $text .= ' cellpadding=' . abs($parameter) . ' border=' . ($parameter>0 ? 1 : 0);
[1022]                 else $text .= ' ' . str_replace('"',"'",$parameter);
[1023]             }
[1024]         }
[1025]         $text .= '>'; $endtext = "</table>$endtext";
[1026]     }
[1027]     $GLOBALS['table_end'] = "$endtext\n";
[1028]     return "$text\n";
[1029] } [
Top]   _general_utilities.php
[1030] function th($text='&nbsp;',$extra='') {return td("<i>$text</i>","$extra center");} // return HTML for a table-header column
[1031] $implicit_td_parameters = array('left'=>'align','center'=>'align','right'=>'align','top'=>'valign','middle'=>'valign','bottom'=>'valign','nowrap'=>''); [
Top]   _general_utilities.php
[1032] function td($text='&nbsp;',$extra='') { // return HTML for a table-body column
[1033]     if ($text === '') $text = '&nbsp;';
[1034]     $pieces = array('td');
[1035]     foreach (explode(' ',trim($extra)) as $piece) {
[1036]         if (strpos($piece,'=') !== FALSE) $pieces[] = $piece; // include any explicit parameters unchanged
[1037]         if (isset($GLOBALS['implicit_td_parameters'][$piece])) {
[1038]             $parameter = $GLOBALS['implicit_td_parameters'][$piece];
[1039]             $pieces[$piece] = $parameter ? "$parameter=$piece" : $piece;
[1040]         } else if ($piece) {
[1041]             if (is_numeric($piece)) $pieces['colspan'] = "colspan=$piece";
[1042]             else $pieces['class'] = "class='$piece'";
[1043]         }
[1044]     }
[1045]     return ("<" . implode(' ',$pieces) . ">$text</td>");
[1046] } [
Top]   _general_utilities.php
[1047] function tdc($text='&nbsp;',$extra='') {return td($text,"$extra center");} [
Top]   _general_utilities.php
[1048] function tdr($text='&nbsp;',$extra='') {return td($text,"$extra right");} [
Top]   _general_utilities.php
[1049] function tdn($value='',$places='',$extra='') { // prints datum, right-justified and formatted if numeric
[1050]     if ($class) $class = " class='$class'";
[1051]     if (is_numeric($value)) {
[1052]         // if numeric with unspecified precision, use more precision for smaller numbers
[1053]         if ($places==='' && $value!=round($value)) $places = abs($value)>100 ? 0 : 2;
[1054]         $text = $places>=0 ? number_format($value,$places) : significant_digits($value,-$places);
[1055]         return td($text,"$extra right");
[1056]     } else return td($value,$extra);
[1057] } [
Top]   _general_utilities.php
[1058] function tr($text,$extra='') { // return HTML for a table row
[1059]     // $text -- row-body text (one or more td fields)
[1060]     // $extra -- optional row parameters (e.g. bgcolor)
[1061]     if ($extra) $extra = " $extra";
[1062]     if (!begins($text,'<td') && !begins($text,'<th')) $text = td($text);
[1063]     return "<tr$extra>$text</tr>\n";
[1064] } [
Top]   _general_utilities.php
[1065] function print_table($records,$keys='',$class='',$headings=20) { // print table from record array, based on key list
[1066]     if (!$records || !is_array($records)) return; // print nothing at all for empty arrays
[1067]     $rec = $records[array_rand($records)]; // get a record to use for key extraction
[1068]     if (!is_array($rec)) $rec = array('Contents'); // to tolerate scalar records
[1069]     if (!$keys) $keys = array_keys($rec); // use all record keys if no key-list supplied
[1070]     if (!is_array($keys)) $keys = ksplit($keys); // parse keys from string if not already in array format
[1071]     $fields = array(); // initialize array that will be used to access data from record
[1072]     foreach ($keys as $key => $text) { // build field list from keys that best match record keys
[1073]         if (array_key_exists($key,$rec)) $fields[$key] = $text;
[1074]         elseif (array_key_exists($text,$rec)) $fields[$text] = $text;
[1075]         // if no exact key match, use first field that contains text (case-insensitive)
[1076]         else {foreach ($rec as $field) {if (contains($field,$text) && !in_array($field,$fields)) {$fields[$field] = $text; break;}}}
[1077]     }
[1078]     print "<table>\n";
[1079]     // build header row
[1080]     $header = '';
[1081]     foreach ($fields as $key => $field) {
[1082]         $text = str_replace('_',' ',$field); // make fieldnames print-friendly
[1083]         if ($key === $field) $text = ucfirst($text); // capitalize unless custom header provided
[1084]         $header .= th($text,$class);
[1085]     }
[1086]     $recordcount = 0;
[1087]     foreach ($records as $record) { // print rows, using columns and order implied by keys
[1088]         if ($recordcount++ % $headings == 0) print tr($header);
[1089]         print "<tr>";
[1090]         if (!is_array($record)) {print tdn($record,$class); continue;}
[1091]         foreach (array_keys($fields) as $key) print tdn($record[$key],$class);
[1092]         print "</tr>\n";
[1093]     }
[1094]     print "</table>\n";
[1095] } [
Top]   _general_utilities.php
[1096] function table_headings($headings) {
[1097]     if (!is_array($headings)) $headings = func_get_args(); // support array or sequential input
[1098]     $text = '';
[1099]     foreach ($headings as $heading) $text .= "<td align=center><i>$heading</i></td>";
[1100]     return "<tr>$text</tr>\n";
[1101] } [
Top]   _general_utilities.php
[1102] function tablerow($contentarray,$alignment='',$prefix='',$suffix='') { // return table heading row, using variable argument list
[1103]     if (!is_array($contentarray)) {
[1104]         $contentarray = func_get_args(); // use arg list as contentarray if array not supplied
[1105]         $alignment = $prefix = $suffix = ''; // use defaults, since args are actually contents
[1106]     }
[1107]     if (!is_array($alignment)) $alignment = array($alignment);
[1108]     $k = count($alignment) - 1;
[1109]     for ($i=0,$j=0,$text='<tr>'; $i<count($contentarray); $i++) {
[1110]         $text .= td($prefix . $contentarray[$i] . $suffix, $alignment[$j]);
[1111]         if ($j < $k) $j++; // last alignment value supplied used for leftover content
[1112]     }
[1113]     return ($text . "</tr>\n");
[1114] } [
Top]   _general_utilities.php
[1115] function centered_row($text,$cols=2) {return "<tr><td align=center colspan=$cols>$text</td></tr>\n";} [
Top]   _general_utilities.php
[1116] function textbox_row($label,$name,$size=30,$value='~') {return ("<tr><td align=right>$label</td><td>" . textbox($name,$value,$size) . "</td></tr>\n");} [
Top]   _general_utilities.php
[1117] function tableheading() { // return HTML for the table row with centered, italic values in variable argument list
[1118]     $labels = func_get_args();
[1119]     return tablerow($labels,'center','<i>','</i>');
[1120] } [
Top]   _general_utilities.php
[1121] function number_cell($count,$word,$padding='&nbsp; ') {
[1122]     return td(plural($count,$word) . $padding,'right');
[1123] } [
Top]   _general_utilities.php
[1124] function distribution_table($label,$info,$places=-1,$label_width=150) {
[1125]     if (!$info) return '';
[1126]     ksort($info);
[1127]     $text = "<table border=1 cellpadding=2><tr>" .
[1128]         td("Distribution&nbsp;of&nbsp;<br>$label&nbsp;","rowspan=2 middle right nowrap width=$label_width");
[1129]     foreach ($info as $index => $count) {$text .= tdc(italic($index));     if ($places > -1) $sum += $index * $count;}
[1130]     if ($places > -1) $text .= "<td rowspan=2 align=center nowrap> &nbsp; Average &nbsp; <br>" . quotient($sum,array_sum($info),$places) . "</td>\n";
[1131]     $text .= "</tr>\n<tr>";
[1132]     foreach ($info as $index => $count) $text .= tdc(bold($count));
[1133]     return "$text</tr></table>\n";
[1134] }

[1135] //// TIME & DATE CONVERSIONS [
Top]   _general_utilities.php
[1136] function datetimetoSQL($when, $scale=1) { // returns datetime in format suitable for SQL
[1137]     // $when -- integer time indicator (from time() or microtime()); default
[1138]     // $scale -- the number of $when tics that equal 1 second (e.g., 1000 if $when is in milliseconds)
[1139]     if ($scale) $when = (int)($when/$scale);
[1140]     return date('Y-m-d G:i:s',$when);
[1141] } [
Top]   _general_utilities.php
[1142] function minsec($seconds) { // returns min:sec text string from number of seconds
[1143]     // $seconds -- time in seconds (may be in float format with decimal-fraction part)
[1144]     $seconds = round($seconds);
[1145]     $mimutes = (int)($seconds/60);
[1146]     $seconds = $seconds % 60;
[1147]     if (!$minutes) $minutes = ''; // suppress leading 0 if interval is less than a minute
[1148]     return ("$minutes:" . substr("0$s",-2)); // ensure that seconds have tens-place zero if needed
[1149] } [
Top]   _general_utilities.php
[1150] function msminsec($milliseconds) { // returns compact time-interval description with at least two significant digits
[1151]     // $milliseconds -- time interval in thousanths of a second
[1152]     if ($milliseconds < 995) return number_format($milliseconds/1000, 2); // sub-second intervals to 10-ms precision
[1153]     if ($milliseconds < 9950) return number_format($milliseconds/1000, 1); // intervals less than 10 seconds to 100-ms precision
[1154]     if ($milliseconds < 59500) return round($milliseconds/1000); // intervals less than a minute as integer seconds
[1155]     return minsec($milliseconds/1000); // for intervals of a minute or more, use min:sec notation
[1156] } [
Top]   _general_utilities.php
[1157] function time_floated() { // return high-precision time value [in PHP 5, this can be done directly in time()]
[1158]     $a = explode(' ',microtime());
[1159]     return (float)$a[1] + (float)$a[0]; // combine second and fraction-of-second values into a 64-bit floating-point number
[1160] } [
Top]   _general_utilities.php
[1161] function shortdatetime($time='') {return date('G:i n/j',make_time($time));} [
Top]   _general_utilities.php
[1162] function numberdatetime($time='') {return date('G:i n/j/y',make_time($time));} [
Top]   _general_utilities.php
[1163] function longdatetime($time='') {return date('g:i:s a T, F j Y',make_time($time));} [
Top]   _general_utilities.php
[1164] function numberdate($time='') {return date('n/j/y',make_time($time));} [
Top]   _general_utilities.php
[1165] function make_time($time) {if (!$time) $time = time(); if (!is_numeric($time)) $time = strtotime($time); return $time;} [
Top]   _general_utilities.php
[1166] function generaldatetime($time='',$format='n/j/y') { // uses m/d/yy format if more than six months ago
[1167]     $time = make_time($time);
[1168]     $ago = time() - $time;
[1169]     if (!$format) $format = 'g:i:s a T, l F j Y'; // show long & complete version with format of 0 or ''
[1170]     elseif ($ago < 72000) $format = "g:i a"; // show only time if in last 20 hours
[1171]     elseif ($ago < 432000) $format = "D H:i"; // show day of week plus time if in last five days
[1172]     elseif ($ago < 16000000) $format = "n/j"; // drop year if in the last six months
[1173]     return date($format,$time);
[1174] } [
Top]   _general_utilities.php
[1175] function regularize_year($text='',$firstyear='1900',$lastyear='') { // extracts four-digit year from text
[1176]     $yyyy = date('Y'); // four-digit text for current year
[1177]     $letters = char_array(strrev(trim($text))); // reversed to work from ending digits
[1178]     if ($lastyear === '') $lastyear = plain(num($yyyy)+1); // by default, top limit is next year
[1179]     $y = ''; // extract consecutive trailing digits (including zeros) from $text, dropping preceding oontent
[1180]     foreach ($letters as $letter) {if (ctype_digit($letter)) $y = $letter . $y; else break;} // undo reverse
[1181]     if (strlen($y) == 2) { // extend two-digit year to include appropriate century
[1182]         $y = substr($yyyy,0,2) . $y; // use current century if possible
[1183]         if ($y > $lastyear) $y = plain(num($y)-100); // otherwise, use previous century
[1184]     }
[1185]     return (($y>=$firstyear || $y<=$lastyear) ? $y : ''); // return four-digit year text (or empty string)
[1186] } [
Top]   _general_utilities.php
[1187] function time24($time) { // converts datetime or text (eg: 'h:mmAM', 'hh:mm pm') into 'HH:MM' if not already like that
[1188]     if (is_numeric($time)) return date('H:i',$time);
[1189]     $time = nospace($time);
[1190]     if (!$time) return '';
[1191]     $ampm = substr($time,-2);
[1192]     if (same($ampm,'am','pm')) $time = substr($time,0,-2); else $ampm = '';
[1193]     if (substr($time,-3,1) === ':') {$minutes = substr($time,-2); $hours = substr($time,0,-3);}
[1194]     else {$hours = $time; $minutes = 0;}
[1195]     if (!is_numeric($hours) || !is_numeric($minutes)) return ''; // return "[$raw_time => $hours:$minutes $ampm]";
[1196]     if ($hours==12 && $ampm) $hours = 0; // so that 12:mm AM and 12:mm PM are correctly handled
[1197]     if ($ampm === 'pm') $hours += 12;
[1198]     return (substr("0$hours",-2) . ':' . substr("0$minutes",-2)); // HH:MM format
[1199] } [
Top]   _general_utilities.php
[1200] function time12($time) { // converts datetime or 24-hour-time text into 12-hour-time text if not already like that
[1201]     if (!$time) return '';
[1202]     $raw_time = $time;
[1203]     if (is_numeric($time)) return date('G:i a',$time);
[1204]     $time = nospace($time);
[1205]     $ampm = substr($time,-2); // leave AM/PM case as is if already 12-hour format
[1206]     if (same($ampm,'am','pm')) $time = substr($time,0,-2); else $ampm = '';
[1207]     if (substr($time,-3,1) === ':') {$minutes = substr($time,-2); $hours = substr($time,0,-3);}
[1208]     else {$hours = $time; $minutes = 0;}
[1209]     if (!is_numeric($hours) || !is_numeric($minutes) || $hours>23 || $hours<0) return "[$raw_time => $hours:$minutes $ampm]";
[1210]     if (!$ampm) $ampm = ($hours < 12) ? 'am' : 'pm';
[1211]     $hours = (($hours - 1) % 12) + 1;
[1212]     return (substr(" $hours",-2) . ':' . substr("0$minutes",-2) . " $ampm");
[1213] } [
Top]   _general_utilities.php
[1214] function minute_of_day($time) { // returns minutes since midnight
[1215]     $time24 = time24($time); // convert to HH:MM
[1216]     return (60 * num(substr($time24,0,2)) + num(substr($time24,3,2)));
[1217] } [
Top]   _general_utilities.php
[1218] function duration($seconds) { // return minutes:seconds (or hours:minutes:seconds if longer than an hour)
[1219]     $hours = (int) ($seconds / 3600);
[1220]     $min = (int) (($seconds % 3600) / 60);
[1221]     $sec = (int) ($seconds % 60);
[1222]     $sec = substr("00$sec",-2);
[1223]     if ($hours == 0) return "$min:$sec";
[1224]     $min = substr("00$min",-2);
[1225]     return "$hours:$min:$sec";
[1226] }

[1227] //// NUMERIC [
Top]   _general_utilities.php
[1228] function quotient($numerator,$denominator=1,$places='') {
[1229]     if (!$denominator) return 0;
[1230]     $quotient = $numerator / $denominator;
[1231]     return (is_numeric($places) ? round($quotient,$places) : $quotient);
[1232] } [
Top]   _general_utilities.php
[1233] function percentage($numerator,$denominator=1,$places=0) {
[1234]     return (is_numeric($denominator) ? round(100*quotient($numerator,$denominator),$places) : '');
[1235] } [
Top]   _general_utilities.php
[1236] function histogram_modes($array) {
[1237]     if (!is_array($array)) return array();
[1238]     $max = -1;
[1239]     $modes = array();
[1240]     foreach ($array as $index => $count) {if ($count >= $max) {$mode = $index; $max = $count;}}
[1241]     foreach ($array as $index => $count) {if ($count == $max) $modes[] = $index;}
[1242]     return $modes;
[1243] } [
Top]   _general_utilities.php
[1244] function histogram_mode($array) {
[1245]     $modes = histogram_modes($array);
[1246]     return (count($modes) ? $modes[0] : FALSE);
[1247] } [
Top]   _general_utilities.php
[1248] function asymptotic_squeeze($value,$center=0,$halfwidth=1) {
[1249]     if ($halfwidth == 0) return $center;
[1250]     return (atan(($value-$center)/$halfwidth*1.5708) / 1.5708 * $halfwidth + $center);
[1251] }
[1257] ?>

FILE: _gpl.php - 49 lines, 0 functions [
Top]
  [1] <?php // show GPL and provide code distribution
  [2] include '_all_includes.php';
  [3] $file_separator = "\n~~~~~~~~~~ combined by _gpl.php - ";
  [4] page_start('General Public License');
  [5] $filenames = fileset(array('*.php','*.txt'));
  [6] $version_link = alink('version 3','_license.txt');
  [7] $gnu_link = alink('GNU General Public License','http://www.gnu.org/licenses/');
  [8] $show_code_link = alink('Show Code','_code_show.php');
  [9] $unzip = '_site_unzip.php';
  [10] print <<<HTML
  [11] <table border=1 width='90%' cellpadding=10><tr><td>
  [12] <p> &nbsp; &nbsp; This site is free software: you can redistribute it and/or modify it under the terms of the
  [13] GNU General Public License as published by the Free Software Foundation, either $version_link of the License,
  [14] or (at your option) any later version.&nbsp; This program is distributed in the hope that it will be useful,
  [15] but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.&nbsp;
  [16] See the $gnu_link for more details.</p>
  [17] <p> &nbsp; &nbsp; The site source code is made available both via the $show_code_link dynamic listing/index and as a block
  [18] of text in the CODE textarea below.&nbsp; A separate no-dependencies <i>$unzip</i> script that regenerates the site files
  [19] from that text is displayed in a separate UNZIP textarea.&nbsp; To replicate the site on a separate server,
  [20] [1] copy <i>$unzip</i> from the "UNZIP" textarea to the destination directory on new server,
  [21] [2] make a copy of the contents of the "CODE" textarea below,
  [22] [3] run the <i>$unzip</i> script on the new server,
  [23] [4] paste the code into the "CODE" textarea in the new server, and
  [24] [5] press the "Install" button to unzip the files.</p>
  [25] </td></tr></table><br>
  [26]
  [27] HTML;
  [28] print br("<b>UNZIP</b> (<i>$unzip</i> script to be copied to the new server, where it can process the code in the next textarea)",1);
  [29] print br(textarea('unzip',file_get_contents($unzip),10,120,FALSE));
  [30] print br("<b>CODE</b> (contents to be copied and pasted into the corresponding textarea on <i>$unzip</i> on the new server)",1);
  [31] print textarea_head('code',10,120);
  [32] print "SITE CODE AS OF " . longdatetime(); // preamble to show time and prevent trim of separator
  [33] foreach ($filenames as $filename) {
  [34]     if ($filename[0] === '~') continue;
  [35]     print h("$file_separator$filename\n");
  [36]     print h(file_get_contents($filename));
  [37] }
  [38] print "</textarea>\n";
  [39] if (file_exists('_create_database_tables.sql')) {
  [40]     print br("<b>DATABASE TABLES</b> (contents to be copied run as SQL script to create needed tables in new database)",2);
  [41]     print textarea('sql_tables',file_get_contents('_create_database_tables.sql'),120,10);
  [42] }
  [43] page_end();
  [49] ?>
FILE: _page_routines.php - 146 lines, 18 functions [
Top]
  [1] <?php // standardized routines and settings for web-page handling
  [2] require_once '_general_utilities.php';
  [3] // standard values
  [4] $top_link = "<small>[<a href='#Top'>Top</a>]</small>";
  [5] // END OF AUTO-RUN STATEMENTS -- after this, execution chains back to _site_routines.php
  [6] // page template routines [Top]   _page_routines.php
  [7] function site_navigation_info() {
  [8]     $pages['Changes'] = 'schedule_changes|Detect changes (except enrollment) between two versions of a schedule';
  [9]     $pages['Courses'] = 'schedule_courses|Provide distribution and enrollment information by course';
  [10]     if ($GLOBALS['privileged']) $pages['Email'] = 'schedule_emails|List selected instructor emails, with instructor course lists';
  [11]     $pages['Enrollment'] = 'schedule_enrollment|List sections in order of enrollment level';
  [12]     $pages['Faculty'] = 'schedule_faculty|List faculty, with courseload and sections';
  [13]     $pages['Filter'] = 'schedule_filter|List sections meeting specific conditions';
  [14]     $pages['Frequencies'] = 'schedule_frequencies|Summarize sections by campus, course, times, etc.';
  [15]     if ($GLOBALS['development_site']) $pages['Growth'] = 'schedule_growth|Show enrollment growth over several schedule versions';
  [16]     $pages['Limits'] = 'schedule_limits|Analyze room class-size limits';
  [17]     if ($GLOBALS['user_id']) $pages['Manage'] = 'schedule_management|Import/enable/disable schedule snapshots';
  [18]     $pages['Rooms'] = 'schedule_rooms|List room-usage statistics';
  [19]     if ($GLOBALS['user_id']) $pages['Snapshot'] = 'schedule_snapshot|Save a copy of the current version of a schedule';
  [20]     $pages['Spreadsheet'] = 'schedule_to_spreadsheet|Extract schedule information to be copied into a spreadsheet';
  [21]     return $pages;
  [22] } [
Top]   _page_routines.php
  [23] function site_navigation_links() {
  [24]     $page = $_SERVER[SCRIPT_NAME];
  [25]     $pages = site_navigation_info();
  [26]     foreach ($pages as $label => $info) {$url = before($info,'|'); $links[] = alink(bold($label,contains($page,$url)),"$url.php");}
  [27]     $links[] = $GLOBALS['user_id'] ? alink('Log off','logoff.php') : alink('Log on','index.php');
  [28]     return $links;
  [29] } [
Top]   _page_routines.php
  [30] function site_navigation() {
  [31]     $text = br(small(implode(' &nbsp; ',site_navigation_links())));
  [32]     $page = $_SERVER[SCRIPT_NAME];
  [33]     $last_slash = strrpos($page,'/');
  [34]     if (has_privilege('Administrator')) $text .= br(small('<i>Administration:</i> &nbsp; ' . alink('accounts','accounts.php') . ' &nbsp; ' .
  [35]         alink('discipline groups','schedule_discipline_groups.php') . ' &nbsp; ' . alink('snapshots','schedule_management.php') . ' &nbsp; (' .
  [36]         (contains($page,'_development/') ? alink('production site',str_replace('_development/','/',"$page?developer=1")) :
  [37]             alink('development site',substr($page,0,$last_slash) . '_development' . substr($page,$last_slash))) . ')'));
  [38]     return $text;
  [39] } [
Top]   _page_routines.php
  [40] function page_start($title='',$titlelinks='') { // called to start page output
  [41]     if ($GLOBALS['trace_page']) trace_page();
  [42]     print page_start_top($title,$GLOBALS['extra_head_text'],"bgcolor='$GLOBALS[page_background_color]' style='margin-top:6pt'");
  [43]     if (function_exists('site_banner') && !$GLOBALS['suppress_site_banner']) print site_banner();
  [44]     $width = ($GLOBALS['page_width'] ? " width=$GLOBALS[page_width]" : '');
  [45]     print "<table$width cellpadding=0><tr><td align=center>";
  [46]     print "<font face='$GLOBALS[page_font_style]'>\n";
  [47]     if (function_exists('site_navigation') && $GLOBALS['site_navigation']) print site_navigation();
  [48]     $GLOBALS['site_navigation'] = FALSE; // by default, navigation is only printed at the top of the page
  [49]     if ($title) print pc("<span class=title>$title</span>" . ($titlelinks ? " &nbsp; $titlelinks" : ''));
  [50]     print_flash('error');
  [51] } [
Top]   _page_routines.php
  [52] function page_start_top($title='',$head_extra='',$body_extra='') { // called to start page output
  [53]     global $user_id,$user,$current_page_name,$site_abbr,$superuser_id;
  [54]     $title = $title ? $title : $site_abbr;
  [55]     if (!$GLOBALS['site_css']) $GLOBALS['site_css'] = '_site.css';
  [56]     ob_start(); // buffer output
  [57]     print <<<HTML
  [58] <html>
  [59] <head>
  [60] <title>$title</title>
  [61] <link href="$GLOBALS[site_css]" media="all" rel="stylesheet" type="text/css" />
  [62] $head_extra</head>
  [63] <body $body_extra>
  [64] <div align=center>
  [65] <a name='Top' />
  [66]
  [67] HTML;
  [68]     print formheader();
  [69] } [
Top]   _page_routines.php
  [70] function page_end($footer=' ') {
  [71]     if ($GLOBALS['database_connection']) mysql_close($GLOBALS['database_connection']);
  [72]     print "</td></tr></table>\n";
  [73]     print_flash('notice');
  [74]     print_flash('error');
  [75]     print_flash('trace');
  [76]     if (function_exists('site_navigation') && $GLOBALS['site_navigation']) print '<br>' . site_navigation();
  [77]     if ($footer === ' ') $footer = "<i>An " . alink('open-source','_gpl.php') . " site &nbsp;--&nbsp; " .
  [78]         "Problems/suggestions?&nbsp; Notify <a href='mailto:hunter@ellinger.org'>hunter@ellinger.org</a></i>";
  [79]     print "\n<br>\n$footer\n</font>\n</form>\n</div>\n</body>\n</html>\n";
  [80]     ob_end_flush();
  [81] } [
Top]   _page_routines.php
  [82] function print_flash($tag) {
  [83]     $s = sv_set($tag);
  [84]     if ($s) print table(15,tr(td(substr($s,0,-5),$tag)));
  [85]     return $s;
  [86] } [
Top]   _page_routines.php
  [87] function bailout($text='') {error($text); redirect('index.php');} [
Top]   _page_routines.php
  [88] function error($text) {if ($text) $_SESSION['error'] .= "$text<br>\n"; $GLOBALS['error'] = $_SESSION['error'];} [
Top]   _page_routines.php
  [89] function notice($text) {if ($text) $_SESSION['notice'] .= "$text<br>\n";} [
Top]   _page_routines.php
  [90] function trace($tag='',$text='~~~') {
  [91]     if ($tag !== '') {
  [92]         if ($text==='~~~' && substr($tag,0,1)=='$') $text = $GLOBALS[substr($tag,1)];
  [93]         if (is_array($text)) $text = string_r($text);
  [94]         if ($text !== '~~~') $tag .= ': '; else $text = '';
  [95]         $_SESSION['trace'] .= bold(htmlspecialchars($tag)) . htmlspecialchars($text) . "<br>\n";
  [96]     } else {
  [97]         trace('GLOBALS',$GLOBALS);
  [98]         if ($_GET) trace('GET',$_GET);
  [99]         if ($_POST) trace('POST',$_POST);
 [100]     }
 [101] } [
Top]   _page_routines.php
 [102] function logoff() {
 [103]     $_SESSION = array();
 [104]     if (isset($_COOKIE[session_name()])) setcookie(session_name(),'',time()-42000,'/');
 [105]     session_destroy();
 [106] } [
Top]   _page_routines.php
 [107] function logon_required($reason='') {if (!$GLOBALS['user_id']) bailout("User lacks privilege to " . coalesce($reason,"view $GLOBALS[current_page]"));} [
Top]   _page_routines.php
 [108] function has_privilege($privilege) {return (contains($_SESSION['privileges'],$privilege) || contains($_SESSION['privileges'],'All'));} [
Top]   _page_routines.php
 [109] function privilege_required($privilege,$reason='') {
 [110]     if (!has_privilege($privilege)) bailout("User lacks privilege to " . coalesce($reason,"view $GLOBALS[current_page]"));
 [111] } [
Top]   _page_routines.php
 [112] function account_filename($identifier) {return "accounts/$identifier.txt";} [
Top]   _page_routines.php
 [113] function set_session_variables_from_user_account($identifier,$prefix='') { // set session variable to values specified in an account file
 [114]     if (!$identifier || !file_exists(account_filename($identifier))) return ''; // leave session unchanged if user identifier or account not supplied
 [115]     foreach (nsplit(trim(file_read_contents(account_filename($identifier)))) as $line) { // a session variable can be set with each line
 [116]         $equals = strpos($line,'=');
 [117]         $tab = strpos($line,"\t");
 [118]         if ($equals || $tab) { // first tab or equals separates name from value (if neither, line ignored)
 [119]             $position = ($equals && (!$tab || $equal<$tab)) ? $equals : $tab;
 [120]             $value = trim(substr($line,$position+1));
 [121]             $fullname = trim(substr($line,0,$position));
 [122]             $name = trim(before($fullname,'['));
 [123]             if ($name === $fullname) $_SESSION["$prefix$name"] = $value;
 [124]             else {
 [125]                 $index = between($fullname,'[',']');
 [126]                 if ($index !== '') $_SESSION["$prefix$name"][$index] = $value;
 [127]             }
 [128]         }
 [129]     }
 [130]     return $identifier;
 [131] } [
Top]   _page_routines.php
 [132] function write_user_account_variables($identifier,$array_of_variables) {
 [133]     if (!$identifier) return FALSE;
 [134]     $lines = array();
 [135]     foreach ($array_of_variables as $name => $values) {
 [136]         if (!is_array($values)) $lines[] = "$name = $values";
 [137]         else {foreach ($values as $key => $value) $lines[] = "{$name}[{$key}] = $value";}
 [138]     }
 [139]     return file_write_contents(account_filename($identifier),implode("\n",$lines));
 [140] }
 [146] ?>

FILE: _schedule_routines.php - 568 lines, 41 functions [
Top]
  [1] <? // site-specific routines supporting multiple pages
  [2] require_once '_general_utilities.php';
  [3] $schedule_server = 'http://www6.austincc.edu';
  [4] $disciplines_directory = './disciplines/';
  [5] $disciplines_extension = 'txt';
  [6] $staff_directory_url = 'http://www6.austincc.edu/directory/info.php?id=';
  [7]
  [8] //// SCHEDULE [
Top]   _schedule_routines.php
  [9] function read_mathFTnames() {return explode("\n",trim(readfile('math_FTfaculty_schedule_names.txt')));} [
Top]   _schedule_routines.php
  [10] function timeACC($time) {
  [11]     if (is_numeric($time) && $time<2500) {
  [12]         if ($time < 25) $time *= 100;
  [13]         if ($time < 630) $time += 1200;
  [14]         $time = substr("00$time",-4,2) . ':' . $time = substr("00$time",-2);
  [15]     }
  [16]     return time24($time);
  [17] } [
Top]   _schedule_routines.php
  [18] function semester_name_to_term_number($semester_name) {
  [19]     $term_sequence = array('Spring'=>1,'Summer'=>2,'Fall'=>3);
  [20]     $year = num(phrase($semester_name,-1));
  [21]     $term_name = ucfirst(strtolower(phrase($semester_name,-2,1)));
  [22]     if (array_key_exists($term_name,$term_sequence)) {
  [23]         $term_number = (3 * ($year - 1973) - 2 + $term_sequence[$term_name]);
  [24]         if ($term_number > 0) return $term_number; // conversion success
  [25]     }
  [26]     return 0; // conversion failure
  [27] } [
Top]   _schedule_routines.php
  [28] function term_number_to_semester_name($term_number) {
  [29]     if (!is_numeric($term_number) || $term_number<=0) return '';
  [30]     $term_names = array(1=>'Spring',2=>'Summer',3=>'Fall');
  [31]     $year = (int)(1973 + ($term_number + 1) / 3);
  [32]     $term_name = $term_names[($term_number + 1) % 3 + 1];
  [33]     return "$term_name $year";
  [34] } [
Top]   _schedule_routines.php
  [35] function semester_name_to_code($semester_name) {
  [36]     $year = digits_only($semester_name);
  [37]     $term_code = contains($semester_name,'Spring') ? 's' : (contains($semester_name,'Summer') ? 'u' : 'f');
  [38]     return "$year$term_code";
  [39] } [
Top]   _schedule_routines.php
  [40] function semester_code_to_name($semester_code) {
  [41]     $year = num(digits_only($semester_code));
  [42]     if (!$year) return '';
  [43]     if ($year < 100) {$year += 1900; if ($year < 1970) $year += 100;} // allow two-digit years
  [44]     $term_names = array('s'=>'Spring','u'=>'Summer','f'=>'Fall');
  [45]     $code = strtolower(substr($semester_code,-1));
  [46]     $term_name = array_key_exists($code,$term_names) ? $term_names[$code] : '';
  [47]     return trim("$term_name $year");
  [48] } [
Top]   _schedule_routines.php
  [49] function term_number_to_code($term_number) {return semester_name_to_code(term_number_to_semester_name($term_number));} [
Top]   _schedule_routines.php
  [50] function check_schedule_semester() {
  [51]     $semester = sv('schedule_semester');
  [52]     if (!$semester) { // if not set, see if only one semester is represented in schedules in this directory
  [53]         $semesters = array();
  [54]         foreach (datenamed_files('*.schedule') as $file) $semesters[substr($file,0,-25)]++;
  [55]         if (count($semesters) != 1) redirect_return('select_schedule_semester.php'); // none or several semesters
  [56]         $_SESSION['schedule_semester'] = $semester = $semesters[0]; // a single semester, so use it
  [57]     }
  [58]     return $semester;
  [59] } [
Top]   _schedule_routines.php
  [60] function schedule_link($dept='',$discipline_id='') {
  [61]     if (!$discipline_id) $discipline_id = $dept;
  [62]     if (!$dept) $dept = 'ACC Course';
  [63]     return target_link("$dept Schedule",schedule_url($discipline_id));
  [64] } [
Top]   _schedule_routines.php
  [65] function schedule_snapshots($disabled=FALSE,$directory='general') {
  [66]     if (!$directory) $directory = ($user_id && has_privilege('Administrator')) ? 'general' : nameletters_instead($user_id);
  [67]     if (!$directory) return array();
  [68]     return datenamed_files("schedule_snapshots/$directory/*." . ($disabled ? 'xhtm' : 'htm'));
  [69] } [
Top]   _schedule_routines.php
  [70] function schedule_url($url='') {
  [71]     if (!$url) $url='index.php';
  [72]     if (!begins($url,'http://')) {
  [73]         if ($url[0]!=='/') $url = "/schedule/$url";
  [74]         $url = "$GLOBALS[schedule_server]$url";
  [75]     }
  [76]     return $url;
  [77] } [
Top]   _schedule_routines.php
  [78] function get_schedule_info_from_spreedsheet($text,$label) {
  [79]     $first_line = before($text,"\n");
  [80]     if (strlen($first_line) - strlen(str_replace("\t",'',$first_line)) < 3) return ''; // not spreadsheet
  [81]     $column = strpos($fields,$label);
  [82]     return ($column===FALSE ? '~' : between("$first_line\t","\t$label: ","\t"));
  [83] } [
Top]   _schedule_routines.php
  [84] function get_schedule_version_datetext($text) {
  [85]     $version = get_schedule_info_from_spreedsheet($text,"Version");
  [86]     if ($version) $version = 'Derived from ' . drop_string($version,'Derived from '); // mark as derivative
  [87]     return $version ? $version : trim(drop_chars(before(between($text,'Course Listings as of ',"\n"),'<'),'.-'));
  [88] } [
Top]   _schedule_routines.php
  [89] function get_schedule_semester($text) {
  [90]     $semester = get_schedule_info_from_spreedsheet($text,"Semester");
  [91]     return $semester ? $semester : between(between($text,'Course Schedule by ',"\n"),'(',')');
  [92] } [
Top]   _schedule_routines.php
  [93] function get_schedule_discipline($text) {
  [94]     $discipline = get_schedule_info_from_spreedsheet($text,"Discipline");
  [95]     if ($discipline) return $discipline;
  [96]     $h3 = strpos($text,'<h3>');
  [97]     if ($h3) {$h3end = strpos($text,'</h3>',$h3); return trim(substr($text,$h3+4,$h3end-$h3-4));}
  [98]     $lines = array_slice(explode("\n",between($text,'Course Listings as of ','Session')),1);
  [99]     foreach ($lines as $line) {
 [100]         $line = trim($line);
 [101]         if ($line && !contains($line,'Section')) return $line;
 [102]     }
 [103]     return ''; // failed to find discipline name
 [104] } [
Top]   _schedule_routines.php
 [105] function refresh_checkbox() {return (' &nbsp; ' . checkbox('refresh',FALSE,1,'Refresh'));} [
Top]   _schedule_routines.php
 [106] function schedule_date_format($datetime) {return date('H:i D M j Y',$datetime);} [
Top]   _schedule_routines.php
 [107] function schedule_filename_start($discipline,$semester,$directory='general') {
 [108]     $text = "schedule_snapshots/$directory/" . nameletters_underscore($discipline) . '_' . nameletters_underscore($semester);
 [109]     $text = str_replace('__','_',$text); // because some discipline names have spaces separated by a hyphen
 [110]     return $text;
 [111] } [
Top]   _schedule_routines.php
 [112] function get_schedule_index_page($url='') { // get HTML source of a schedule index page (cache updated hourly)
 [113]     return str_replace('"',"'",read_cached_url(schedule_url($url),3600)); // adjust to single-quote convention, refresh main index hourly
 [114] } [
Top]   _schedule_routines.php
 [115] function fetch_schedule_index($semester='') { // reads and processes the index page for a semester
 [116]     $html = get_schedule_index_page();
 [117]     $texts = array();
 [118]     foreach (betweens(after($html,'<body'),'<h','</h') as $text) {
 [119]         $text = trim(substr($text,2));
 [120]         if (in_array(before($text,' '),array('Spring','Summer','Fall'))) $texts[] = $text;
 [121]     }
 [122]     $page_semester = $texts[0];
 [123]     $GLOBALS['semester_choices'][semester_name_to_term_number($page_semester)] = $page_semester;
 [124]     foreach ($texts as $text) { // find other semesters referred to on main page
 [125]         $text = trim($text);
 [126]         if (in_array(before($text,' '),array('Spring','Summer','Fall'))) {
 [127]             $GLOBALS['semester_choices'][semester_name_to_term_number($text)] = $text;
 [128]             if ($text === $semester) {
 [129]             $url = between(between($html,"<h3>$semester",'>Discipline'),"href='","'");
 [130]             if ($url) {$html = get_schedule_index_page($url); $page_semester = $semester;}
 [131]             }
 [132]         }
 [133]     }
 [134]     krsort($GLOBALS['semester_choices']); // order semesters from future to past
 [135]     $GLOBALS['discipline_urls'] = $GLOBALS['disciplines_listed'] = array();
 [136]     $discipline_lines = arounds($html,'&disciplineid=',"<a ","</a>"); // extract html for discipline links
 [137]     foreach ($discipline_lines as $discipline_line) {
 [138]         $discipline_id = between($discipline_line,'&disciplineid=','&'); // get five-letter discipline code
 [139]         if (!$_SESSION['disciplines_permitted'] || array_key_exists($discipline_id,$_SESSION['discipline_options'])) {
 [140]             $GLOBALS['discipline_urls'][$discipline_id] = between($discipline_line,"href='","'"); // save url of schedule page
 [141]             $GLOBALS['disciplines_listed'][$discipline_id] = $name = trim(after($discipline_line,'>')); // save discipline name
 [142]             $GLOBALS['discipline_prefix_to_id'][nameletters_underscore($name)] = $discipline_id;
 [143]         }
 [144]     }
 [145]     $GLOBALS['schedule_index_html'] = $html;
 [146]     return $page_semester;
 [147] } [
Top]   _schedule_routines.php
 [148] function reset_schedule_settings() {
 [149]     $_SESSION['schedule_semester'] = $_SESSION['schedule_disciplines'] = ''; // forget old settings
 [150] } [
Top]   _schedule_routines.php
 [151] function discipline_prefix($name_or_id) {
 [152]     if (array_key_exists($name_or_id,$GLOBALS['disciplines_listed'])) $name_or_id = $GLOBALS['disciplines_listed'][$name_or_id];
 [153]     return nameletters_underscore($name_or_id);
 [154] } [
Top]   _schedule_routines.php
 [155] function discipline_group_filename($group_name) {
 [156]     if (!contains($group_name,'*')) $group_name = nameletters_underscore(trim($group_name));
 [157]     return "$GLOBALS[disciplines_directory]$group_name.$GLOBALS[disciplines_extension]";
 [158] } [
Top]   _schedule_routines.php
 [159] function discipline_group_members($group_name) {
 [160]     $members = array();
 [161]     foreach ($GLOBALS['discipline_groups'][$group_name] as $ids) $members[$id] = $GLOBALS['disciplines_listed'][$id];
 [162]     return $members;
 [163] } [
Top]   _schedule_routines.php
 [164] function get_discipline_groups($group_name='') {
 [165]     if ($group_name === $GLOBALS['discipline_groups_name']) return asplit($GLOBALS['discipline_groups']); // re-use earlier call
 [166]     if ($group_name===TRUE || $group_name==='new') $group_name = ''; // TRUE used as signal to force all-groups lookup
 [167]     $GLOBALS['discipline_groups_name'] = $group_name;
 [168]     $groups = array();
 [169]     foreach (fileset(discipline_group_filename('*')) as $filename) {
 [170]         $lines = explode("\n",trim(file_read_contents($filename)));
 [171]         $name = array_shift($lines); // first line of file is group name - may include non-nameletter characters
 [172]         $include = TRUE; // omit group if a member is not an option for this user
 [173]         if ($_SESSION['disciplines_permitted']) foreach ($lines as $id) {if (!$GLOBALS['disciplines_listed'][$id]) $include = FALSE;}
 [174]         if ($include) $groups[$name] = $lines; // other lines are five-letter discipline id codes
 [175]     }
 [176]     $GLOBALS['discipline_groups'] = ajoin($groups); // for use by later calls during this page hit
 [177]     return $groups; // each element of return array has the group name as a key to an array of included disciplines
 [178] } [
Top]   _schedule_routines.php
 [179] function expanded_disciplines($disciplines='',$groups='') { // expands any discipline-group selections
 [180]     if (!is_array($disciplines)) $disciplines = rq_array('disciplines'); // by default, get selected values from posted form
 [181]     if (!$disciplines) $disciplines = asplit(sv('schedule_disciplines'));
 [182]     if (array_key_exists('All',$disciplines)) return $GLOBALS['disciplines_listed'];
 [183]     if (!is_array($groups)) $groups = get_discipline_groups($groups);
 [184]     foreach ($groups as $name => $discipline_ids) {
 [185]         $group_id = nameletters_underscore($name);
 [186]         if (array_key_exists($group_id,$disciplines)) { // add specific disciplines implied by any selected discipline groups
 [187]             foreach ($discipline_ids as $id) $disciplines[$id] = $GLOBALS['disciplines_listed'][$id];
 [188]         }
 [189]     }
 [190]     $_SESSION['schedule_disciplines'] = ajoin($disciplines);
 [191]     return $disciplines;
 [192] } [
Top]   _schedule_routines.php
 [193] function asplit($value_string,$item_glue='|',$key_glue='~') {
 [194]     $output = array();
 [195]     $glue_length = strlen($key_glue);
 [196]     foreach (explode($item_glue,$value_string) as $item) {
 [197]         $index = strpos($item,$key_glue);
 [198]         if ($index !== FALSE) $output[substr($item,0,$index)] = substr($item,$index + $glue_length);
 [199]     }
 [200]     return $output;
 [201] } [
Top]   _schedule_routines.php
 [202] function ajoin($array,$item_glue='|',$key_glue='~') {
 [203]     $output = array();
 [204]     foreach (make_array($array) as $key=>$value) $output[] = "$key$key_glue$value";
 [205]     return implode($item_glue,$output);
 [206] } [
Top]   _schedule_routines.php
 [207] function drop_empty($array) { // drops empty strings or empty subarrays from an array
 [208]     $output = array();
 [209]     foreach ($array as $key=>$value) {if ($value || is_numeric($value)) $output[$key] = $value;}
 [210]     return $output;
 [211] } [
Top]   _schedule_routines.php
 [212] function discipline_choices() {
 [213]     if ($_SESSION['disciplines_permitted']) return $_SESSION['discipline_options'];
 [214]     $discipline_choices = array('All' => 'ALL DISCIPLINES');
 [215]     foreach (get_discipline_groups() as $name => $discipline_ids) $discipline_choices[nameletters_underscore($name)] = $name;
 [216]     foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) $discipline_choices[$id] = $discipline;
 [217]     return $discipline_choices;
 [218] } [
Top]   _schedule_routines.php
 [219] function semester_name_from_text($text) { // cleans up user-entered text specifying semester
 [220]     $term = semester_name_to_term_number($text);
 [221]     if (!term) $term = semester_name_to_term_number(semester_code_to_name($text));
 [222]     return term_number_to_semester_name($term);
 [223] } [
Top]   _schedule_routines.php
 [224] function extract_schedule_information($page_title='',$current_only=FALSE,$widgets='',$save_html_directory=FALSE) {
 [225]     // displays and processes form to select one or more schedules
 [226]     $schedule_information = array();
 [227]     $main_semester = fetch_schedule_index();
 [228]     $semesters = rq_array('semesters');
 [229]     //$semester_text = semester_name_from_text(rq('semester_text'));
 [230]     //if ($semester_text) $semesters = array($semester_text);
 [231]     if (!$semesters) $semesters = array(coalesce(sv('schedule_semester'),$main_semester));
 [232]     sv_set('schedule_semester',$semesters[0]);
 [233]     $disciplines = ($current_only && $GLOBALS['disciplines_permitted']) ? $GLOBALS['disciplines_listed'] : expanded_disciplines();
 [234]     $disciplines = drop_empty($disciplines);
 [235]     sv_set('schedule_disciplines',ajoin($disciplines));
 [236]     if (posted()) {if (!$semesters) error('No semester was selected'); if (!$disciplines) error('No discipline was selected');}
 [237]     page_start($page_title);
 [238]     if ($widgets) print br($widgets);
 [239]     if ($semesters && $disciplines) { // fetch and process selected schedules
 [240]         if (!$current_only) print br(alink('Change Schedule Selection','?reset=1'),1,2);
 [241]         print italic(pluralize('Semester',$semesters) . ': ') . implode(', ',$semesters);
 [242]         if (!$current_only) {
 [243]             print (count($semesters)+count($disciplines) > 3) ? '<br>' : spaces(5);
 [244]             print br(italic(pluralize('Discipline',$disciplines) . ': ') . implode(', ',$disciplines));
 [245]         }
 [246]         foreach ($semesters as $semester) {
 [247]             fetch_schedule_index($semester);
 [248]             foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) {
 [249]                 $discipline_url = $GLOBALS['discipline_urls'][$id];
 [250]                 if (array_key_exists('All',$disciplines) || array_key_exists($id,$disciplines)) {
 [251]                     $schedule_url = schedule_url($discipline_url);
 [252]                     if ($save_html_directory) {
 [253]                         $schedule_html = read_url($schedule_url);
 [254]                         list($version,$discipline,$semester) = extract_schedule_designators($schedule_html);
 [255]                         $version = strtotime("$version");
 [256]                         $filename = filename_from_datetime($version,'htm',schedule_filename_start($discipline,$semester,$save_html_directory));
 [257]                         file_write_contents($filename,$schedule_html);
 [258]                         $schedule_information[$discipline][$semester] = file_exists($filename) ?
 [259]                             target_link("$discipline $semester " . schedule_date_format($version), $filename) : italic("File not written - $filename");
 [260]                     } else $schedule_information[$discipline][$semester] = extract_schedule_info($schedule_url);
 [261]                 }
 [262]             }
 [263]         }
 [264]     } else { // display schedule-selection form
 [265]         print "<table border=1 cellpadding=10><tr><td align=center>";
 [266]         if ($current_only) print pc("<i>Semester:</i> $main_semester" . hidden('semesters',$main_semester));
 [267]         else {
 [268]             $choice_lines = array();
 [269]             foreach (chunked_array($GLOBALS['semester_choices'],5) as $row) $choice_lines[] = radioset('semesters',$row,$main_semester,'&nbsp;');
 [270]             //$choice_lines[count($choice_lines)-1] .= ' ' . textbox('semester_text',$main_semester,11);
 [271]             foreach ($choice_lines as $choice_line) print pc($choice_line);
 [272]         }
 [273]         print pc(commandbutton('Extract Schedule Information For Specified Semesters & Disciplines') . refresh_checkbox());
 [274]         print "</td></tr>\n<tr><td align=center>\n";
 [275]         display_discipline_choices();
 [276]         print "</td></tr></table><br>";
 [277]     }
 [278]     return $schedule_information;
 [279] } [
Top]   _schedule_routines.php
 [280] function display_discipline_choices($group='',$group_edit=FALSE) {
 [281]     if ($_SESSION['disciplines_permitted'] == 1) {print pc(bold('Discipline: ' . italic($_SESSION['discipline_options'][0]))); return;}
 [282]     if (!$GLOBALS['disciplines_listed']) fetch_schedule_index();
 [283]     $discipline_choices = array();
 [284]     $disciplines_checked = expanded_disciplines();
 [285]     print "<table border=1 cellpadding=5>\n";
 [286]     if ($group) { // display group-management row if group is new or specified
 [287]         $text = bold('Group Name: ');
 [288]         if ($group_edit) {
 [289]             if ($group===TRUE || $group==='new') $text .= textbox('group','') . spaces(7) . commandbutton("Define selected disciplines as group");
 [290]             else {
 [291]                 $text .= textbox('group',$group) . spaces(7) . commandbutton("Update group disciplines") . spaces(12) . commandbutton('Delete');
 [292]                 foreach (make_array($GLOBALS['discipline_groups'][$group]) as $id) $disciplines_checked[$id] = TRUE;
 [293]             }
 [294]         } else {
 [295]             $text .= $group;
 [296]         }
 [297]         print tr(tdc($text,2));
 [298]     } else { // include discipline groups in the form only when a group is not specified
 [299]         $discipline_choices['All'] = $_SESSION['disciplines_permitted'] ? 'All listed disciplines' : 'ALL DISCIPLINES';
 [300]         foreach (get_discipline_groups() as $name => $discipline_ids) $discipline_choices[nameletters_underscore($name)] = $name;
 [301]     }
 [302]     if (!$group_edit) get_discipline_groups(coalesce($group,$_SESSION['account_discipline_group']));
 [303]     foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) $discipline_choices[$id] = $discipline;
 [304]     print "<tr>\n";
 [305]     list($chunk,$delimiter) = (count($discipline_choices) > 7) ? array(-2,'<br>') : array(-1,'<p></p>'); // use two columns if 8 or more choices
 [306]     foreach (chunked_array($discipline_choices,$chunk) as $column) {
 [307]         print td(checkbox_set('disciplines',$column,$disciplines_checked,$delimiter));
 [308]     }
 [309]     print "</tr></table></td></tr></table><br>\n";
 [310] } [
Top]   _schedule_routines.php
 [311] function latest_snapshots($namepart='') {
 [312]     $snapshots = array();
 [313]     foreach (array_reverse(schedule_snapshots()) as $filename) { // reversed so that most recent value dominates
 [314]         $schedule = datenamedfile_prefix($filename);
 [315]         if (!$namepart || contains($filename,$namepart)) $snapshots[$schedule] = $filename;
 [316]     }
 [317]     sort($snapshots);
 [318]     return $snapshots;
 [319] } [
Top]   _schedule_routines.php
 [320] function section_line_expand($line) {
 [321]     $skype = '_of_the_skype_highlighting';
 [322]     if (strpos($line,$skype)) $line = before($line,"begin$skype") . after($line,"end$skype ");
 [323]     $line = str_replace('- ','-',$line); // tighten up time section if needed
 [324]     $line = str_replace(' ',"\t",$line);
 [325]     return $line;
 [326] } [
Top]   _schedule_routines.php
 [327] function remove_tags($text) {return implode('',betweens(">$text<",'>','<'));} // blindly removes angle-bracketed content [
Top]   _schedule_routines.php
 [328] function extract_td_content($text) {
 [329]     $fields = array();
 [330]     foreach (betweens($text,'<td','</td>') as $field) {
 [331]         $fields[] = trim(str_replace('&nbsp;',' ',remove_tags(after($field,'>'))));
 [332]     }
 [333]     return $fields;
 [334] } [
Top]   _schedule_routines.php
 [335] function extract_schedule_designators($schedule_html) {
 [336]     $semester = trim(between(between($schedule_html,'Course Schedule by ',"\n"),'(',')'));
 [337]     $discipline = trim(between($schedule_html,'<h3>','</h3>'));
 [338]     $version = trim(drop_chars(between($schedule_html,'Course Listings as of ','<'),'.-'));
 [339]     return array($version,$discipline,$semester);
 [340] } [
Top]   _schedule_routines.php
 [341] function extract_schedule_info($text) {
 [342]     $lines = $description = $schedule_info = array();
 [343]     if (begins($text,'http://')) $text = read_cached_url($text,3600); // use one-hour caching for schedules
 [344]     $html = strpos($text,'</h4>');
 [345]     if ($html) { // schedule html source code
 [346]         list($description['version'],$description['discipline'],$description['semester']) = extract_schedule_designators($text);
 [347]         foreach (array_slice(explode('teach_term',"$text<teach_term"),1,-1) as $session_group) {
 [348]             $session = trim(drop_chars(between($session_group,'>','</p>'),'()'));
 [349]             foreach (array_slice(explode('<h4>',"<$session_group>"),1) as $line_group) {
 [350]                 $coursename = trim(remove_tags(before($line_group,'</h4>')));
 [351]                 $course = trim(substr($coursename,0,9));
 [352]                 foreach (array_slice(explode(" class='section_line'",$line_group),1) as $line) {
 [353]                     $fields = extract_td_content($line);
 [354]                     if (count($fields) < 16) { // shorter lines used for distance-learning sections
 [355]                         $fields[15] = $fields[12]; // copy instructor to standard position
 [356]                         $fields[8] = $fields[9] = $fields[10] = $fields[11] = '';
 [357]                     }
 [358]                     $email = between($line,$GLOBALS['staff_directory_url'],' ');
 [359]                     $lines[] = array(
 [360]                         'Course' => $course,
 [361]                         'Remain' => $fields[0],
 [362]                         'TSI' => $fields[1],
 [363]                         'Prereq' => $fields[2],
 [364]                         'bracketed' => between($fields[3],'[',']'),
 [365]                         'Synonym' => $fields[4],
 [366]                         'Type' => $fields[5],
 [367]                         'Section' => $fields[6],
 [368]                         'Campus' => $fields[7],
 [369]                         'Building' => $fields[8],
 [370]                         'Room' => $fields[9],
 [371]                         'Days' => $fields[10],
 [372]                         'Times' => nospace($fields[11]),
 [373]                         'Instructor' => $fields[15],
 [374]                         'Email' => $email,
 [375]                         'Session' => $session
 [376]                     );
 [377]                 }
 [378]             }
 [379]         }
 [380]     } else { // either spreadsheet or copied webpage
 [381]         $t = explode("\n",$text);
 [382]         if (strpos($t[0],"\t")) { // text from spreadsheet
 [383]             foreach (array('semester','discipline','version') as $d) $description[$d] = trim(between("$t[0]\t","\t$label: ","\t"));
 [384]             $fields = explode("\t",$t[0]);
 [385]             array_shift($t); // drop field-name line
 [386]             foreach ($t as $line) {
 [387]                 if (!trim($line)) continue; // skip blank lines
 [388]                 $values = explode("\t",$line);
 [389]                 $record = array();
 [390]                 for ($i=0; $i<count($fields) && $i<count($values); $i++) {
 [391]                     $field = $fields[$i];
 [392]                     if ($field) $record[$field] = $values[$i];
 [393]                 }
 [394]                 $lines[] = $record;
 [395]             }
 [396]         } else { // text copied with cut-and-paste from schedule
 [397]             $description['semester'] = trim(after(between($text,'Course Schedule by ',')'),'('));
 [398]             $description_lines = explode("\n",between($text,'Course Listings as of ','Session'));
 [399]             $description['version'] = trim(drop_chars($description_lines[0],'.-'));
 [400]             $description['discipline'] = '';
 [401]             for ($i=1; $i<count($description_lines); $i++) {
 [402]                 $line = trim($line);
 [403]                 if ($line && !contains($line,'Section')) {$description['discipline'] = $line; break;}
 [404]             }
 [405]             // support various web-version formats
 [406]             $old = strpos($text," OH "); // no OH in new format, so use old format
 [407]             $old2011 = $old && contains($text,'2011 Course Schedule');
 [408]             $alternate = (!$old && strpos($text,"\t")===FALSE);
 [409]             $sessionstartmarker = $old ? " Week Session =>" : " Week Session:";
 [410]             $sessionmiddlemarker = $old ? " THRU " : " - ";
 [411]             $instructormarker = $old ? " OH " : " Directory ";
 [412]             $labcolumn = $old ? 24 : ($alternate ? 48: 40);
 [413]             $tsicolumn = $old ? 4 : 8;
 [414]             $prereqcolumn = $old ? 6: 16;
 [415]             $bracketcolumn = $old ? 8 : 24;
 [416]             $synonymcolumn = $old ? 18 : 32;
 [417]             $sectioncolumn = $old ? 28 : ($alternate ? 56 : 48);
 [418]             $pipecolumn = $old ? 31 : 0;
 [419]             $campuscolumn = $old ? 38 : ($alternate ? 72 :56);
 [420]             $buildingcolumn = $old ? 43 : ($campuscolumn + 8);
 [421]             $roomcolumn = $old ? 48 : ($buildingcolumn + 8);
 [422]             $dayscolumn = $old ? ($old2011 ? 54: 58) : ($alternate ? 96: 80);
 [423]             $timecolumn = $old ? ($old2011 ? 63 : 67) : ($dayscolumn + 8);
 [424]             $syllabuscolumn = $old ? 0: ($alternate ? 128 : 104);
 [425]             //
 [426]             $n = 0;
 [427]             $lastsectionline = -1;
 [428]             foreach ($t as $s) {
 [429]                 $n++;
 [430]                 $a = rtrim($s);
 [431]         $bracketed = between($a,"[","]");
 [432]                 $k = strpos($a,$sessionstartmarker);
 [433]                 $j = $k>0 ? strpos($a,$sessionmiddlemarker,$k) : 0;
 [434]                 if ($k>0 && $j>$k) { // session indicator line
 [435]                 $session_text = trim(between($a,$sessionstartmarker,$sessionmiddlemarker)) . " - " .
 [436]                     trim(after($a,$sessionmiddlemarker)) . " (" . trim(substr($a,0,$k)) . "-week)";
 [437]                     if (substr($session_text,1,1) === "/") $session_text = " " . $session_text; // to align starting months
 [438]                 } else {
 [439]                     $i = num(substr($a,5,4)); // look at course-number position
 [440]                     if (strlen($a)>9 && substr($a,4,1)===" " && $i>0 & $i<3000 && ctype_alpha(substr($a,0,4))) { // course indicator line
 [441]                         $course = substr($a,0,9);
 [442]                         $coursename = trim(substr($a,10));
 [443]                     } else {
 [444]                         if (!$old) {
 [445]                             if ($alternate) {
 [446]                                 if (strpos($a,' DIL ')===FALSE) $a = str_replace('] ',']',$a);
 [447]                                 $a = section_line_expand($a); // convert missing-tab format into tabbed format
 [448]                             } else $a = str_replace("[$bracketed] ","[$bracketed]",$a); // guard against trailing-space glitch
 [449]                             $a = detab($a); // expand tabs in new-format lines so items in dependable positions
 [450]                         }
 [451]                         $type = $sectiontype = substr($a, $labcolumn, 3);
 [452]             $lab = $lastsectionline==($n-1) && $sectiontype==="Lab";
 [453]                         $sec = strlen($bracketed)>0 && (!$old || contains($a,"|"));
 [454]                         if ($sec) { // section line
 [455]                             $remain = trim(substr($a,0,3));
 [456]                             $tsi = substr($a,$tsicolumn,1);
 [457]                             $prereq = substr($a,$prereqcolumn,1);
 [458]                             $synonym = substr($a,$synonymcolumn,5);
 [459]                             $section = substr($a,$sectioncolumn,3);
 [460]                             $campus = substr($a,$campuscolumn,3);
 [461]             $instructor = trim(after($a,$instructormarker));
 [462]             if (!$old) $syllabus = strpos($a,"Syllabus") ? 'Posted' : 'Missing';
 [463]                             $lastsectionline = $n;
 [464]                         }
 [465]                         if ($sec || $lab) {
 [466]                             if ($sectiontype!=="OPC" && $sectiontype!=="DIL" && $campus!=="PCM" && $campus!=="ITV" && $campus!=="PRN") {
 [467]                                 if ($lab && $old) $a = " " + $a; // repair 1-character offset in listing
 [468]                                 $building = trim(substr($a,$buildingcolumn,5));
 [469]                                 $room = trim(substr($a,$roomcolumn,6));
 [470]                                 $days = trim(substr($a,$dayscolumn,8));
 [471]                                 $times = nospace(substr($a,$timecolumn,16));
 [472]                             } else {$days = $times = $sectiontype = $building = $room = '';}
 [473]                             $location = "$campus $room";
 [474]                             if ($building!==$campus && begins($building,$campus)) $location .= " (" . substr($building,strlen($campus)) . ")";
 [475]                             if (strlen($location) < 8) $location .= " ";
 [476]                             $labtext = $lab ? 'Lab':'';
 [477]                             $instructor = str_replace(',',', ',str_replace(', ',',',$instructor)); // regularize comma-space usage
 [478]                             $lines[] = array('Course'=>$course,'Section'=>$section,'Type'=>$type,'Lab'=>$labtext,'TSI'=>$tsi,
 [479]                                 'Prereq'=>$prereq,'Remain'=>$remain,'bracketed'=>$bracketed,'Synonym'=>$synonym,'Campus'=>$campus,
 [480]                                 'Room'=>$room,'Days'=>$days,'Times'=>$times,'Instructor'=>$instructor,'Session'=>$session_text);
 [481]                         }
 [482]                     }
 [483]                 }
 [484]             }
 [485]         }
 [486]     }
 [487]     $GLOBALS['schedule_description'] = $description; // make schedule-identification info available
 [488]     $discipline = $description['discipline'];
 [489]     $semester = $description['semester'];
 [490]     $version = date('Y-m-d H:i',strtotime($description['version']));
 [491]     $last_key = '~';
 [492]     foreach ($lines as $line) { // use extracted schedule-section values (from whatever source) to make derived fields
 [493] $remain = (strpos($line['Remain'],'X')!==FALSE || $line['Remain']==='killed')? 'killed' : num($line['Remain']);
 [494]         $bracketed = $line['bracketed'];
 [495] $taken = num($bracketed ? before($bracketed,"/") : $line['Taken']);
 [496]         $limit = num($bracketed ? before(after($bracketed,'/'),'/') : $line['Limit']);
 [497]         if ($remain !== 'killed') $remain = $limit - $taken;
 [498] $dept = trim(substr($line['Course'],0,4));
 [499] $coursenumber = substr("000$line[Course]",-4);
 [500]     $instructor = $line['Instructor'] ?     $line['Instructor'] : 'Staff';
 [501]         $type = $line['Type'];
 [502]         $location = $campus = $line['Campus'];
 [503]     if ($type!=='OPC' && $type!=='DIL' && $campus!=='PCM' && $campus!=='ITV' && $campus!=='PRN') {
 [504]             $room = $line['Room'];
 [505]             $i = strpos($room,'.0');
 [506]             if ($i !== FALSE) $room = substr($room,0,$i);        
 [507]         $location .= " $room";
 [508]         $building = $line['Building'];
 [509]         $days = $line['Days'];
 [510]             $times = $line['Times'];
 [511]     $timehyphen = strpos($times,'-');
 [512]     $start_time = $end_time = $minutes = $time24 = $hour = '';
 [513]             if ($timehyphen !== FALSE) {
 [514]             $start_time = trim(substr($times,0,$timehyphen));
 [515]                 $end_time = trim(substr($times,$timehyphen+1));
 [516]                 $time24 = time24($start_time);
 [517]                 $hour = substr($time24,0,2) . ':';
 [518]                 $minutes = minute_of_day($end_time) - minute_of_day($start_time);
 [519]             }
 [520]             $sectiontype = ($sectiontype==='Lec' ? ' ' : $sectiontype[0]);
 [521]     } else {$campus = 'ONL'; $days = $start_time = $end_time = $time24 = $times = $sectiontype = $building = $room = $hour = $location = '';}
 [522]         if (strlen($location) < 8) $location .= " "; // to help line up columns within textarea
 [523]         $instructor = str_replace(',',', ',str_replace(', ',',',$line['Instructor'])); // regularize comma-space usage
 [524]         if (!$instructor) $instructor = 'STAFF';
 [525]         $email = "$line[Email]";
 [526]         if ($email) $email = "$email@austincc.edu";
 [527]         // save info for this section (key has ~ prefixed to synonym to avoid numeric-key issues)
 [528]         $key = "~$line[Synonym]";
 [529]         if ($key !== '~') {
 [530]             $schedule_info[$key] = array('Course'=>$line['Course'],'Dept'=>$dept,'Number'=>$coursenumber,
 [531]                 'Section'=>$line['Section'],'Type'=>$line['Type'],'Lab'=>$line['Lab'],'Time'=>$time24,'Minutes'=>$minutes,
 [532]                 'Hour'=>$hour,'TSI'=>$line['TSI'],'Prereq'=>$line['Prereq'],'Remain'=>$remain,'Taken'=>$taken,'Limit'=>$limit,
 [533]                 'Synonym'=>$line['Synonym'],'Location'=>$location,'Campus'=>$campus,'Room'=>$line['Room'],'Building'=>$building,
 [534]                 'Days'=>$days,'Start'=>$start_time,'End'=>$end_time,'Times'=>"$days$times",'Instructor'=>$instructor,
 [535]                 'Session'=>$line['Session'],'Email'=>$email,'Semester'=>$semester,'Version'=>$version,'Discipline'=>$discipline);
 [536]             $last_key = $key;
 [537]         } elseif ($last_key !== '~') {
 [538]             if ($times && "$days$times") $schedule_info[$last_key]['Times'] .= "/$days$times";
 [539]             if ($schedule_info[$last_key] && "$line[Type]" && !contains($schedule_info[$last_key]['Type'],$line['Type'])) {
 [540]                 $schedule_info[$last_key]['Type'] .= "/$line[Type]";
 [541]             }
 [542]         }
 [543]     }
 [544]     return $schedule_info;
 [545] }
 [546] $default_schedule_fields = array('Discipline','Course','Section','Type','Remain','Taken','Limit','Synonym',
 [547]     'Campus','Location','Days','Start','End','Minutes','Time','Instructor','Session','Semester','Version'); [
Top]   _schedule_routines.php
 [548] function schedule_heading($fields='',$version='',$semester='',$discipline='') {
 [549]     if (!is_array($fields)) $fields = $GLOBALS['default_schedule_fields'];
 [550]     $heading = implode("\t",$fields) . "\t";
 [551]     if ($version) $heading .= "\tVersion: $version";
 [552]     if ($semester) $heading .= "\tSemester: $semester";
 [553]     if ($discipline) $heading .= "\tDiscipline: $discipline";
 [554]     return "$heading\n";
 [555] } [
Top]   _schedule_routines.php
 [556] function schedule_row($record) {
 [557]     $fields = array();
 [558]     if (func_num_args() > 1) {for ($i=1; $i<func_num_args(); $i++) $fields[] = func_get_arg($i);}
 [559]     else $fields = $GLOBALS['default_schedule_fields'];
 [560]     foreach ($fields as $field) $columns[] = $record[$field];
 [561]     return (implode("\t",$columns) . "\n");
 [562] }
 [568] ?>

FILE: _schedule_routines_new.php - 569 lines, 41 functions [
Top]
  [1] <? // site-specific routines supporting multiple pages
  [2] require_once '_general_utilities.php';
  [3] $schedule_server = 'http://www6.austincc.edu';
  [4] $disciplines_directory = './disciplines/';
  [5] $disciplines_extension = 'txt';
  [6] $staff_directory_url = 'http://www6.austincc.edu/directory/info.php?id=';
  [7]
  [8] //// SCHEDULE [
Top]   _schedule_routines_new.php
  [9] function read_mathFTnames() {return explode("\n",trim(readfile('math_FTfaculty_schedule_names.txt')));} [
Top]   _schedule_routines_new.php
  [10] function timeACC($time) {
  [11]     if (is_numeric($time) && $time<2500) {
  [12]         if ($time < 25) $time *= 100;
  [13]         if ($time < 630) $time += 1200;
  [14]         $time = substr("00$time",-4,2) . ':' . $time = substr("00$time",-2);
  [15]     }
  [16]     return time24($time);
  [17] } [
Top]   _schedule_routines_new.php
  [18] function semester_name_to_term_number($semester_name) {
  [19]     $term_sequence = array('Spring'=>1,'Summer'=>2,'Fall'=>3);
  [20]     $year = num(phrase($semester_name,-1));
  [21]     $term_name = ucfirst(strtolower(phrase($semester_name,-2,1)));
  [22]     if (array_key_exists($term_name,$term_sequence)) {
  [23]         $term_number = (3 * ($year - 1973) - 2 + $term_sequence[$term_name]);
  [24]         if ($term_number > 0) return $term_number; // conversion success
  [25]     }
  [26]     return 0; // conversion failure
  [27] } [
Top]   _schedule_routines_new.php
  [28] function term_number_to_semester_name($term_number) {
  [29]     if (!is_numeric($term_number) || $term_number<=0) return '';
  [30]     $term_names = array(1=>'Spring',2=>'Summer',3=>'Fall');
  [31]     $year = (int)(1973 + ($term_number + 1) / 3);
  [32]     $term_name = $term_names[($term_number + 1) % 3 + 1];
  [33]     return "$term_name $year";
  [34] } [
Top]   _schedule_routines_new.php
  [35] function semester_name_to_code($semester_name) {
  [36]     $year = digits_only($semester_name);
  [37]     $term_code = contains($semester_name,'Spring') ? 's' : (contains($semester_name,'Summer') ? 'u' : 'f');
  [38]     return "$year$term_code";
  [39] } [
Top]   _schedule_routines_new.php
  [40] function semester_code_to_name($semester_code) {
  [41]     $year = num(digits_only($semester_code));
  [42]     if (!$year) return '';
  [43]     if ($year < 100) {$year += 1900; if ($year < 1970) $year += 100;} // allow two-digit years
  [44]     $term_names = array('s'=>'Spring','u'=>'Summer','f'=>'Fall');
  [45]     $code = strtolower(substr($semester_code,-1));
  [46]     $term_name = array_key_exists($code,$term_names) ? $term_names[$code] : '';
  [47]     return trim("$term_name $year");
  [48] } [
Top]   _schedule_routines_new.php
  [49] function term_number_to_code($term_number) {return semester_name_to_code(term_number_to_semester_name($term_number));} [
Top]   _schedule_routines_new.php
  [50] function check_schedule_semester() {
  [51]     $semester = sv('schedule_semester');
  [52]     if (!$semester) { // if not set, see if only one semester is represented in schedules in this directory
  [53]         $semesters = array();
  [54]         foreach (datenamed_files('*.schedule') as $file) $semesters[substr($file,0,-25)]++;
  [55]         if (count($semesters) != 1) redirect_return('select_schedule_semester.php'); // none or several semesters
  [56]         $_SESSION['schedule_semester'] = $semester = $semesters[0]; // a single semester, so use it
  [57]     }
  [58]     return $semester;
  [59] } [
Top]   _schedule_routines_new.php
  [60] function schedule_link($dept='',$discipline_id='') {
  [61]     if (!$discipline_id) $discipline_id = $dept;
  [62]     if (!$dept) $dept = 'ACC Course';
  [63]     return target_link("$dept Schedule",schedule_url($discipline_id));
  [64] } [
Top]   _schedule_routines_new.php
  [65] function schedule_snapshots($disabled=FALSE,$directory='general') {
  [66]     if (!$directory) $directory = ($user_id && has_privilege('Administrator')) ? 'general' : nameletters_instead($user_id);
  [67]     if (!$directory) return array();
  [68]     return datenamed_files("schedule_snapshots/$directory/*." . ($disabled ? 'xhtm' : 'htm'));
  [69] } [
Top]   _schedule_routines_new.php
  [70] function schedule_url($url='') {
  [71]     if (!$url) $url='index.php';
  [72]     if (!begins($url,'http://')) {
  [73]         if ($url[0] !== '/') $url = "/schedule/$url";
  [74]         $url = "$GLOBALS[schedule_server]$url";
  [75]     }
  [76]     return $url;
  [77] } [
Top]   _schedule_routines_new.php
  [78] function get_schedule_info_from_spreedsheet($text,$label) {
  [79]     $first_line = before($text,"\n");
  [80]     if (strlen($first_line) - strlen(str_replace("\t",'',$first_line)) < 3) return ''; // not spreadsheet
  [81]     $column = strpos($fields,$label);
  [82]     return ($column===FALSE ? '~' : between("$first_line\t","\t$label: ","\t"));
  [83] } [
Top]   _schedule_routines_new.php
  [84] function get_schedule_version_datetext($text) {
  [85]     $version = get_schedule_info_from_spreedsheet($text,"Version");
  [86]     if ($version) $version = 'Derived from ' . drop_string($version,'Derived from '); // mark as derivative
  [87]     return $version ? $version : trim(drop_chars(before(between($text,'Course Listings as of ',"\n"),'<'),'.-'));
  [88] } [
Top]   _schedule_routines_new.php
  [89] function get_schedule_semester($text) {
  [90]     $semester = get_schedule_info_from_spreedsheet($text,"Semester");
  [91]     return $semester ? $semester : between(between($text,'Course Schedule by ',"\n"),'(',')');
  [92] } [
Top]   _schedule_routines_new.php
  [93] function get_schedule_discipline($text) {
  [94]     $discipline = get_schedule_info_from_spreedsheet($text,"Discipline");
  [95]     if ($discipline) return $discipline;
  [96]     $h3 = strpos($text,'<h3>');
  [97]     if ($h3) {$h3end = strpos($text,'</h3>',$h3); return trim(substr($text,$h3+4,$h3end-$h3-4));}
  [98]     $lines = array_slice(explode("\n",between($text,'Course Listings as of ','Session')),1);
  [99]     foreach ($lines as $line) {
 [100]         $line = trim($line);
 [101]         if ($line && !contains($line,'Section')) return $line;
 [102]     }
 [103]     return ''; // failed to find discipline name
 [104] } [
Top]   _schedule_routines_new.php
 [105] function refresh_checkbox() {return (' &nbsp; ' . checkbox('refresh',FALSE,1,'Refresh'));} [
Top]   _schedule_routines_new.php
 [106] function schedule_date_format($datetime) {return date('H:i D M j Y',$datetime);} [
Top]   _schedule_routines_new.php
 [107] function schedule_filename_start($discipline,$semester,$directory='general') {
 [108]     $text = "schedule_snapshots/$directory/" . nameletters_underscore($discipline) . '_' . nameletters_underscore($semester);
 [109]     $text = str_replace('__','_',$text); // because some discipline names have spaces separated by a hyphen
 [110]     return $text;
 [111] } [
Top]   _schedule_routines_new.php
 [112] function get_schedule_index_page($url='') { // get HTML source of a schedule index page (cache updated hourly)
 [113]     return str_replace('"',"'",read_cached_url(schedule_url($url),3600)); // adjust to single-quote convention, refresh main index hourly
 [114] } [
Top]   _schedule_routines_new.php
 [115] function fetch_schedule_index($semester='') { // reads and processes the index page for a semester
 [116]     $html = get_schedule_index_page(); // the discipline links on this page will be used if the selected semester is not listed in the sidebar
 [117]     $texts = array();
 [118]     foreach (betweens(after($html,'<body'),'<h','</h') as $text) {
 [119]         $text = trim(substr($text,2));
 [120]         if (in_array(before($text,' '),array('Spring','Summer','Fall'))) $texts[] = $text;
 [121]     }
 [122]     $page_semester = $texts[0];
 [123]     $GLOBALS['semester_choices'][semester_name_to_term_number($page_semester)] = $page_semester;
 [124]     foreach ($texts as $text) { // find other semesters referred to on main page
 [125]         $text = trim($text);
 [126]         if (in_array(before($text,' '),array('Spring','Summer','Fall'))) {
 [127]             $GLOBALS['semester_choices'][semester_name_to_term_number($text)] = $text;
 [128]             if ($text === $semester) { // if the selected semester is listed in the sidebar, replace the main-page html with the page for that semester
 [129]                 $html = get_schedule_index_page(between(between($html,">$page_semester",'>Discipline'),"href='","'"));
 [130]                 $page_semester = $semester;
 [131]             }
 [132]         }
 [133]     }
 [134]     $GLOBALS['semester_link'][$page_semester] = after(between($html,"$text</h","'>Discipline"),"<a href='"); // link to discipline-based index page for the associated semester
 [135]     krsort($GLOBALS['semester_choices']); // order semesters from future to past
 [136]     $GLOBALS['discipline_urls'] = $GLOBALS['disciplines_listed'] = array();
 [137]     $discipline_lines = arounds($html,'&disciplineid=',"<a ","</a>"); // extract html for discipline links
 [138]     foreach ($discipline_lines as $discipline_line) {
 [139]         $discipline_id = between($discipline_line,'&disciplineid=','&'); // get five-letter discipline code
 [140]         if (!$_SESSION['disciplines_permitted'] || array_key_exists($discipline_id,$_SESSION['discipline_options'])) {
 [141]             $GLOBALS['discipline_urls'][$discipline_id] = between($discipline_line,"href='","'"); // save url of schedule page
 [142]             $GLOBALS['disciplines_listed'][$discipline_id] = $name = trim(after($discipline_line,'>')); // save discipline name
 [143]             $GLOBALS['discipline_prefix_to_id'][nameletters_underscore($name)] = $discipline_id;
 [144]         }
 [145]     }
 [146]     $GLOBALS['schedule_index_html'] = $html;
 [147]     return $page_semester;
 [148] } [
Top]   _schedule_routines_new.php
 [149] function reset_schedule_settings() {
 [150]     $_SESSION['schedule_semester'] = $_SESSION['schedule_disciplines'] = ''; // forget old settings
 [151] } [
Top]   _schedule_routines_new.php
 [152] function discipline_prefix($name_or_id) {
 [153]     if (array_key_exists($name_or_id,$GLOBALS['disciplines_listed'])) $name_or_id = $GLOBALS['disciplines_listed'][$name_or_id];
 [154]     return nameletters_underscore($name_or_id);
 [155] } [
Top]   _schedule_routines_new.php
 [156] function discipline_group_filename($group_name) {
 [157]     if (!contains($group_name,'*')) $group_name = nameletters_underscore(trim($group_name));
 [158]     return "$GLOBALS[disciplines_directory]$group_name.$GLOBALS[disciplines_extension]";
 [159] } [
Top]   _schedule_routines_new.php
 [160] function discipline_group_members($group_name) {
 [161]     $members = array();
 [162]     foreach ($GLOBALS['discipline_groups'][$group_name] as $ids) $members[$id] = $GLOBALS['disciplines_listed'][$id];
 [163]     return $members;
 [164] } [
Top]   _schedule_routines_new.php
 [165] function get_discipline_groups($group_name='') {
 [166]     if ($group_name === $GLOBALS['discipline_groups_name']) return asplit($GLOBALS['discipline_groups']); // re-use earlier call
 [167]     if ($group_name===TRUE || $group_name==='new') $group_name = ''; // TRUE used as signal to force all-groups lookup
 [168]     $GLOBALS['discipline_groups_name'] = $group_name;
 [169]     $groups = array();
 [170]     foreach (fileset(discipline_group_filename('*')) as $filename) {
 [171]         $lines = explode("\n",trim(file_read_contents($filename)));
 [172]         $name = array_shift($lines); // first line of file is group name - may include non-nameletter characters
 [173]         $include = TRUE; // omit group if a member is not an option for this user
 [174]         if ($_SESSION['disciplines_permitted']) foreach ($lines as $id) {if (!$GLOBALS['disciplines_listed'][$id]) $include = FALSE;}
 [175]         if ($include) $groups[$name] = $lines; // other lines are five-letter discipline id codes
 [176]     }
 [177]     $GLOBALS['discipline_groups'] = ajoin($groups); // for use by later calls during this page hit
 [178]     return $groups; // each element of return array has the group name as a key to an array of included disciplines
 [179] } [
Top]   _schedule_routines_new.php
 [180] function expanded_disciplines($disciplines='',$groups='') { // expands any discipline-group selections
 [181]     if (!is_array($disciplines)) $disciplines = rq_array('disciplines'); // by default, get selected values from posted form
 [182]     if (!$disciplines) $disciplines = asplit(sv('schedule_disciplines'));
 [183]     if (array_key_exists('All',$disciplines)) return $GLOBALS['disciplines_listed'];
 [184]     if (!is_array($groups)) $groups = get_discipline_groups($groups);
 [185]     foreach ($groups as $name => $discipline_ids) {
 [186]         $group_id = nameletters_underscore($name);
 [187]         if (array_key_exists($group_id,$disciplines)) { // add specific disciplines implied by any selected discipline groups
 [188]             foreach ($discipline_ids as $id) $disciplines[$id] = $GLOBALS['disciplines_listed'][$id];
 [189]         }
 [190]     }
 [191]     $_SESSION['schedule_disciplines'] = ajoin($disciplines);
 [192]     return $disciplines;
 [193] } [
Top]   _schedule_routines_new.php
 [194] function asplit($value_string,$item_glue='|',$key_glue='~') {
 [195]     $output = array();
 [196]     $glue_length = strlen($key_glue);
 [197]     foreach (explode($item_glue,$value_string) as $item) {
 [198]         $index = strpos($item,$key_glue);
 [199]         if ($index !== FALSE) $output[substr($item,0,$index)] = substr($item,$index + $glue_length);
 [200]     }
 [201]     return $output;
 [202] } [
Top]   _schedule_routines_new.php
 [203] function ajoin($array,$item_glue='|',$key_glue='~') {
 [204]     $output = array();
 [205]     foreach (make_array($array) as $key=>$value) $output[] = "$key$key_glue$value";
 [206]     return implode($item_glue,$output);
 [207] } [
Top]   _schedule_routines_new.php
 [208] function drop_empty($array) { // drops empty strings or empty subarrays from an array
 [209]     $output = array();
 [210]     foreach ($array as $key=>$value) {if ($value || is_numeric($value)) $output[$key] = $value;}
 [211]     return $output;
 [212] } [
Top]   _schedule_routines_new.php
 [213] function discipline_choices() {
 [214]     if ($_SESSION['disciplines_permitted']) return $_SESSION['discipline_options'];
 [215]     $discipline_choices = array('All' => 'ALL DISCIPLINES');
 [216]     foreach (get_discipline_groups() as $name => $discipline_ids) $discipline_choices[nameletters_underscore($name)] = $name;
 [217]     foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) $discipline_choices[$id] = $discipline;
 [218]     return $discipline_choices;
 [219] } [
Top]   _schedule_routines_new.php
 [220] function semester_name_from_text($text) { // cleans up user-entered text specifying semester
 [221]     $term = semester_name_to_term_number($text);
 [222]     if (!term) $term = semester_name_to_term_number(semester_code_to_name($text));
 [223]     return term_number_to_semester_name($term);
 [224] } [
Top]   _schedule_routines_new.php
 [225] function extract_schedule_information($page_title='',$current_only=FALSE,$widgets='',$save_html_directory=FALSE) {
 [226]     // displays and processes form to select one or more schedules
 [227]     $schedule_information = array();
 [228]     $main_semester = fetch_schedule_index();
 [229]     $semesters = rq_array('semesters');
 [230]     //$semester_text = semester_name_from_text(rq('semester_text'));
 [231]     //if ($semester_text) $semesters = array($semester_text);
 [232]     if (!$semesters) $semesters = array(coalesce(sv('schedule_semester'),$main_semester));
 [233]     sv_set('schedule_semester',$semesters[0]);
 [234]     $disciplines = ($current_only && $GLOBALS['disciplines_permitted']) ? $GLOBALS['disciplines_listed'] : expanded_disciplines();
 [235]     $disciplines = drop_empty($disciplines);
 [236]     sv_set('schedule_disciplines',ajoin($disciplines));
 [237]     if (posted()) {if (!$semesters) error('No semester was selected'); if (!$disciplines) error('No discipline was selected');}
 [238]     page_start($page_title);
 [239]     if ($widgets) print br($widgets);
 [240]     if ($semesters && $disciplines) { // fetch and process selected schedules
 [241]         if (!$current_only) print br(alink('Change Schedule Selection','?reset=1'),1,2);
 [242]         print italic(pluralize('Semester',$semesters) . ': ') . implode(', ',$semesters);
 [243]         if (!$current_only) {
 [244]             print (count($semesters)+count($disciplines) > 3) ? '<br>' : spaces(5);
 [245]             print br(italic(pluralize('Discipline',$disciplines) . ': ') . implode(', ',$disciplines));
 [246]         }
 [247]         foreach ($semesters as $semester) {
 [248]             fetch_schedule_index($semester);
 [249]             foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) {
 [250]                 $discipline_url = $GLOBALS['discipline_urls'][$id];
 [251]                 if (array_key_exists('All',$disciplines) || array_key_exists($id,$disciplines)) {
 [252]                     $schedule_url = schedule_url($discipline_url);
 [253]                     if ($save_html_directory) {
 [254]                         $schedule_html = read_url($schedule_url);
 [255]                         list($version,$discipline,$semester) = extract_schedule_designators($schedule_html);
 [256]                         $version = strtotime("$version");
 [257]                         $filename = filename_from_datetime($version,'htm',schedule_filename_start($discipline,$semester,$save_html_directory));
 [258]                         file_write_contents($filename,$schedule_html);
 [259]                         $schedule_information[$discipline][$semester] = file_exists($filename) ?
 [260]                             target_link("$discipline $semester " . schedule_date_format($version), $filename) : italic("File not written - $filename");
 [261]                     } else $schedule_information[$discipline][$semester] = extract_schedule_info($schedule_url);
 [262]                 }
 [263]             }
 [264]         }
 [265]     } else { // display schedule-selection form
 [266]         print "<table border=1 cellpadding=10><tr><td align=center>";
 [267]         if ($current_only) print pc("<i>Semester:</i> $main_semester" . hidden('semesters',$main_semester));
 [268]         else {
 [269]             $choice_lines = array();
 [270]             foreach (chunked_array($GLOBALS['semester_choices'],5) as $row) $choice_lines[] = radioset('semesters',$row,$main_semester,'&nbsp;');
 [271]             //$choice_lines[count($choice_lines)-1] .= ' ' . textbox('semester_text',$main_semester,11);
 [272]             foreach ($choice_lines as $choice_line) print pc($choice_line);
 [273]         }
 [274]         print pc(commandbutton('Extract Schedule Information For Specified Semesters & Disciplines') . refresh_checkbox());
 [275]         print "</td></tr>\n<tr><td align=center>\n";
 [276]         display_discipline_choices();
 [277]         print "</td></tr></table><br>";
 [278]     }
 [279]     return $schedule_information;
 [280] } [
Top]   _schedule_routines_new.php
 [281] function display_discipline_choices($group='',$group_edit=FALSE) {
 [282]     if ($_SESSION['disciplines_permitted'] == 1) {print pc(bold('Discipline: ' . italic($_SESSION['discipline_options'][0]))); return;}
 [283]     if (!$GLOBALS['disciplines_listed']) fetch_schedule_index();
 [284]     $discipline_choices = array();
 [285]     $disciplines_checked = expanded_disciplines();
 [286]     print "<table border=1 cellpadding=5>\n";
 [287]     if ($group) { // display group-management row if group is new or specified
 [288]         $text = bold('Group Name: ');
 [289]         if ($group_edit) {
 [290]             if ($group===TRUE || $group==='new') $text .= textbox('group','') . spaces(7) . commandbutton("Define selected disciplines as group");
 [291]             else {
 [292]                 $text .= textbox('group',$group) . spaces(7) . commandbutton("Update group disciplines") . spaces(12) . commandbutton('Delete');
 [293]                 foreach (make_array($GLOBALS['discipline_groups'][$group]) as $id) $disciplines_checked[$id] = TRUE;
 [294]             }
 [295]         } else {
 [296]             $text .= $group;
 [297]         }
 [298]         print tr(tdc($text,2));
 [299]     } else { // include discipline groups in the form only when a group is not specified
 [300]         $discipline_choices['All'] = $_SESSION['disciplines_permitted'] ? 'All listed disciplines' : 'ALL DISCIPLINES';
 [301]         foreach (get_discipline_groups() as $name => $discipline_ids) $discipline_choices[nameletters_underscore($name)] = $name;
 [302]     }
 [303]     if (!$group_edit) get_discipline_groups(coalesce($group,$_SESSION['account_discipline_group']));
 [304]     foreach ($GLOBALS['disciplines_listed'] as $id => $discipline) $discipline_choices[$id] = $discipline;
 [305]     print "<tr>\n";
 [306]     list($chunk,$delimiter) = (count($discipline_choices) > 7) ? array(-2,'<br>') : array(-1,'<p></p>'); // use two columns if 8 or more choices
 [307]     foreach (chunked_array($discipline_choices,$chunk) as $column) {
 [308]         print td(checkbox_set('disciplines',$column,$disciplines_checked,$delimiter));
 [309]     }
 [310]     print "</tr></table></td></tr></table><br>\n";
 [311] } [
Top]   _schedule_routines_new.php
 [312] function latest_snapshots($namepart='') {
 [313]     $snapshots = array();
 [314]     foreach (array_reverse(schedule_snapshots()) as $filename) { // reversed so that most recent value dominates
 [315]         $schedule = datenamedfile_prefix($filename);
 [316]         if (!$namepart || contains($filename,$namepart)) $snapshots[$schedule] = $filename;
 [317]     }
 [318]     sort($snapshots);
 [319]     return $snapshots;
 [320] } [
Top]   _schedule_routines_new.php
 [321] function section_line_expand($line) {
 [322]     $skype = '_of_the_skype_highlighting';
 [323]     if (strpos($line,$skype)) $line = before($line,"begin$skype") . after($line,"end$skype ");
 [324]     $line = str_replace('- ','-',$line); // tighten up time section if needed
 [325]     $line = str_replace(' ',"\t",$line);
 [326]     return $line;
 [327] } [
Top]   _schedule_routines_new.php
 [328] function remove_tags($text) {return implode('',betweens(">$text<",'>','<'));} // blindly removes angle-bracketed content [
Top]   _schedule_routines_new.php
 [329] function extract_td_content($text) {
 [330]     $fields = array();
 [331]     foreach (betweens($text,'<td','</td>') as $field) {
 [332]         $fields[] = trim(str_replace('&nbsp;',' ',remove_tags(after($field,'>'))));
 [333]     }
 [334]     return $fields;
 [335] } [
Top]   _schedule_routines_new.php
 [336] function extract_schedule_designators($schedule_html) {
 [337]     $semester = trim(between(between($schedule_html,'Course Schedule by ',"\n"),'(',')'));
 [338]     $discipline = trim(between($schedule_html,'<h3>','</h3>'));
 [339]     $version = trim(drop_chars(between($schedule_html,'Course Listings as of ','<'),'.-'));
 [340]     return array($version,$discipline,$semester);
 [341] } [
Top]   _schedule_routines_new.php
 [342] function extract_schedule_info($text) {
 [343]     $lines = $description = $schedule_info = array();
 [344]     if (begins($text,'http://')) $text = read_cached_url($text,3600); // use one-hour caching for schedules
 [345]     $html = strpos($text,'</h4>');
 [346]     if ($html) { // schedule html source code
 [347]         list($description['version'],$description['discipline'],$description['semester']) = extract_schedule_designators($text);
 [348]         foreach (array_slice(explode('teach_term',"$text<teach_term"),1,-1) as $session_group) {
 [349]             $session = trim(drop_chars(between($session_group,'>','</p>'),'()'));
 [350]             foreach (array_slice(explode('<h4>',"<$session_group>"),1) as $line_group) {
 [351]                 $coursename = trim(remove_tags(before($line_group,'</h4>')));
 [352]                 $course = trim(substr($coursename,0,9));
 [353]                 foreach (array_slice(explode(" class='section_line'",$line_group),1) as $line) {
 [354]                     $fields = extract_td_content($line);
 [355]                     if (count($fields) < 16) { // shorter lines used for distance-learning sections
 [356]                         $fields[15] = $fields[12]; // copy instructor to standard position
 [357]                         $fields[8] = $fields[9] = $fields[10] = $fields[11] = '';
 [358]                     }
 [359]                     $email = between($line,$GLOBALS['staff_directory_url'],' ');
 [360]                     $lines[] = array(
 [361]                         'Course' => $course,
 [362]                         'Remain' => $fields[0],
 [363]                         'TSI' => $fields[1],
 [364]                         'Prereq' => $fields[2],
 [365]                         'bracketed' => between($fields[3],'[',']'),
 [366]                         'Synonym' => $fields[4],
 [367]                         'Type' => $fields[5],
 [368]                         'Section' => $fields[6],
 [369]                         'Campus' => $fields[7],
 [370]                         'Building' => $fields[8],
 [371]                         'Room' => $fields[9],
 [372]                         'Days' => $fields[10],
 [373]                         'Times' => nospace($fields[11]),
 [374]                         'Instructor' => $fields[15],
 [375]                         'Email' => $email,
 [376]                         'Session' => $session
 [377]                     );
 [378]                 }
 [379]             }
 [380]         }
 [381]     } else { // either spreadsheet or copied webpage
 [382]         $t = explode("\n",$text);
 [383]         if (strpos($t[0],"\t")) { // text from spreadsheet
 [384]             foreach (array('semester','discipline','version') as $d) $description[$d] = trim(between("$t[0]\t","\t$label: ","\t"));
 [385]             $fields = explode("\t",$t[0]);
 [386]             array_shift($t); // drop field-name line
 [387]             foreach ($t as $line) {
 [388]                 if (!trim($line)) continue; // skip blank lines
 [389]                 $values = explode("\t",$line);
 [390]                 $record = array();
 [391]                 for ($i=0; $i<count($fields) && $i<count($values); $i++) {
 [392]                     $field = $fields[$i];
 [393]                     if ($field) $record[$field] = $values[$i];
 [394]                 }
 [395]                 $lines[] = $record;
 [396]             }
 [397]         } else { // text copied with cut-and-paste from schedule
 [398]             $description['semester'] = trim(after(between($text,'Course Schedule by ',')'),'('));
 [399]             $description_lines = explode("\n",between($text,'Course Listings as of ','Session'));
 [400]             $description['version'] = trim(drop_chars($description_lines[0],'.-'));
 [401]             $description['discipline'] = '';
 [402]             for ($i=1; $i<count($description_lines); $i++) {
 [403]                 $line = trim($line);
 [404]                 if ($line && !contains($line,'Section')) {$description['discipline'] = $line; break;}
 [405]             }
 [406]             // support various web-version formats
 [407]             $old = strpos($text," OH "); // no OH in new format, so use old format
 [408]             $old2011 = $old && contains($text,'2011 Course Schedule');
 [409]             $alternate = (!$old && strpos($text,"\t")===FALSE);
 [410]             $sessionstartmarker = $old ? " Week Session =>" : " Week Session:";
 [411]             $sessionmiddlemarker = $old ? " THRU " : " - ";
 [412]             $instructormarker = $old ? " OH " : " Directory ";
 [413]             $labcolumn = $old ? 24 : ($alternate ? 48: 40);
 [414]             $tsicolumn = $old ? 4 : 8;
 [415]             $prereqcolumn = $old ? 6: 16;
 [416]             $bracketcolumn = $old ? 8 : 24;
 [417]             $synonymcolumn = $old ? 18 : 32;
 [418]             $sectioncolumn = $old ? 28 : ($alternate ? 56 : 48);
 [419]             $pipecolumn = $old ? 31 : 0;
 [420]             $campuscolumn = $old ? 38 : ($alternate ? 72 :56);
 [421]             $buildingcolumn = $old ? 43 : ($campuscolumn + 8);
 [422]             $roomcolumn = $old ? 48 : ($buildingcolumn + 8);
 [423]             $dayscolumn = $old ? ($old2011 ? 54: 58) : ($alternate ? 96: 80);
 [424]             $timecolumn = $old ? ($old2011 ? 63 : 67) : ($dayscolumn + 8);
 [425]             $syllabuscolumn = $old ? 0: ($alternate ? 128 : 104);
 [426]             //
 [427]             $n = 0;
 [428]             $lastsectionline = -1;
 [429]             foreach ($t as $s) {
 [430]                 $n++;
 [431]                 $a = rtrim($s);
 [432]         $bracketed = between($a,"[","]");
 [433]                 $k = strpos($a,$sessionstartmarker);
 [434]                 $j = $k>0 ? strpos($a,$sessionmiddlemarker,$k) : 0;
 [435]                 if ($k>0 && $j>$k) { // session indicator line
 [436]                 $session_text = trim(between($a,$sessionstartmarker,$sessionmiddlemarker)) . " - " .
 [437]                     trim(after($a,$sessionmiddlemarker)) . " (" . trim(substr($a,0,$k)) . "-week)";
 [438]                     if (substr($session_text,1,1) === "/") $session_text = " " . $session_text; // to align starting months
 [439]                 } else {
 [440]                     $i = num(substr($a,5,4)); // look at course-number position
 [441]                     if (strlen($a)>9 && substr($a,4,1)===" " && $i>0 & $i<3000 && ctype_alpha(substr($a,0,4))) { // course indicator line
 [442]                         $course = substr($a,0,9);
 [443]                         $coursename = trim(substr($a,10));
 [444]                     } else {
 [445]                         if (!$old) {
 [446]                             if ($alternate) {
 [447]                                 if (strpos($a,' DIL ')===FALSE) $a = str_replace('] ',']',$a);
 [448]                                 $a = section_line_expand($a); // convert missing-tab format into tabbed format
 [449]                             } else $a = str_replace("[$bracketed] ","[$bracketed]",$a); // guard against trailing-space glitch
 [450]                             $a = detab($a); // expand tabs in new-format lines so items in dependable positions
 [451]                         }
 [452]                         $type = $sectiontype = substr($a, $labcolumn, 3);
 [453]             $lab = $lastsectionline==($n-1) && $sectiontype==="Lab";
 [454]                         $sec = strlen($bracketed)>0 && (!$old || contains($a,"|"));
 [455]                         if ($sec) { // section line
 [456]                             $remain = trim(substr($a,0,3));
 [457]                             $tsi = substr($a,$tsicolumn,1);
 [458]                             $prereq = substr($a,$prereqcolumn,1);
 [459]                             $synonym = substr($a,$synonymcolumn,5);
 [460]                             $section = substr($a,$sectioncolumn,3);
 [461]                             $campus = substr($a,$campuscolumn,3);
 [462]             $instructor = trim(after($a,$instructormarker));
 [463]             if (!$old) $syllabus = strpos($a,"Syllabus") ? 'Posted' : 'Missing';
 [464]                             $lastsectionline = $n;
 [465]                         }
 [466]                         if ($sec || $lab) {
 [467]                             if ($sectiontype!=="OPC" && $sectiontype!=="DIL" && $campus!=="PCM" && $campus!=="ITV" && $campus!=="PRN") {
 [468]                                 if ($lab && $old) $a = " " + $a; // repair 1-character offset in listing
 [469]                                 $building = trim(substr($a,$buildingcolumn,5));
 [470]                                 $room = trim(substr($a,$roomcolumn,6));
 [471]                                 $days = trim(substr($a,$dayscolumn,8));
 [472]                                 $times = nospace(substr($a,$timecolumn,16));
 [473]                             } else {$days = $times = $sectiontype = $building = $room = '';}
 [474]                             $location = "$campus $room";
 [475]                             if ($building!==$campus && begins($building,$campus)) $location .= " (" . substr($building,strlen($campus)) . ")";
 [476]                             if (strlen($location) < 8) $location .= " ";
 [477]                             $labtext = $lab ? 'Lab':'';
 [478]                             $instructor = str_replace(',',', ',str_replace(', ',',',$instructor)); // regularize comma-space usage
 [479]                             $lines[] = array('Course'=>$course,'Section'=>$section,'Type'=>$type,'Lab'=>$labtext,'TSI'=>$tsi,
 [480]                                 'Prereq'=>$prereq,'Remain'=>$remain,'bracketed'=>$bracketed,'Synonym'=>$synonym,'Campus'=>$campus,
 [481]                                 'Room'=>$room,'Days'=>$days,'Times'=>$times,'Instructor'=>$instructor,'Session'=>$session_text);
 [482]                         }
 [483]                     }
 [484]                 }
 [485]             }
 [486]         }
 [487]     }
 [488]     $GLOBALS['schedule_description'] = $description; // make schedule-identification info available
 [489]     $discipline = $description['discipline'];
 [490]     $semester = $description['semester'];
 [491]     $version = date('Y-m-d H:i',strtotime($description['version']));
 [492]     $last_key = '~';
 [493]     foreach ($lines as $line) { // use extracted schedule-section values (from whatever source) to make derived fields
 [494] $remain = (strpos($line['Remain'],'X')!==FALSE || $line['Remain']==='killed')? 'killed' : num($line['Remain']);
 [495]         $bracketed = $line['bracketed'];
 [496] $taken = num($bracketed ? before($bracketed,"/") : $line['Taken']);
 [497]         $limit = num($bracketed ? before(after($bracketed,'/'),'/') : $line['Limit']);
 [498]         if ($remain !== 'killed') $remain = $limit - $taken;
 [499] $dept = trim(substr($line['Course'],0,4));
 [500] $coursenumber = substr("000$line[Course]",-4);
 [501]     $instructor = $line['Instructor'] ?     $line['Instructor'] : 'Staff';
 [502]         $type = $line['Type'];
 [503]         $location = $campus = $line['Campus'];
 [504]     if ($type!=='OPC' && $type!=='DIL' && $campus!=='PCM' && $campus!=='ITV' && $campus!=='PRN') {
 [505]             $room = $line['Room'];
 [506]             $i = strpos($room,'.0');
 [507]             if ($i !== FALSE) $room = substr($room,0,$i);        
 [508]         $location .= " $room";
 [509]         $building = $line['Building'];
 [510]         $days = $line['Days'];
 [511]             $times = $line['Times'];
 [512]     $timehyphen = strpos($times,'-');
 [513]     $start_time = $end_time = $minutes = $time24 = $hour = '';
 [514]             if ($timehyphen !== FALSE) {
 [515]             $start_time = trim(substr($times,0,$timehyphen));
 [516]                 $end_time = trim(substr($times,$timehyphen+1));
 [517]                 $time24 = time24($start_time);
 [518]                 $hour = substr($time24,0,2) . ':';
 [519]                 $minutes = minute_of_day($end_time) - minute_of_day($start_time);
 [520]             }
 [521]             $sectiontype = ($sectiontype==='Lec' ? ' ' : $sectiontype[0]);
 [522]     } else {$campus = 'ONL'; $days = $start_time = $end_time = $time24 = $times = $sectiontype = $building = $room = $hour = $location = '';}
 [523]         if (strlen($location) < 8) $location .= " "; // to help line up columns within textarea
 [524]         $instructor = str_replace(',',', ',str_replace(', ',',',$line['Instructor'])); // regularize comma-space usage
 [525]         if (!$instructor) $instructor = 'STAFF';
 [526]         $email = "$line[Email]";
 [527]         if ($email) $email = "$email@austincc.edu";
 [528]         // save info for this section (key has ~ prefixed to synonym to avoid numeric-key issues)
 [529]         $key = "~$line[Synonym]";
 [530]         if ($key !== '~') {
 [531]             $schedule_info[$key] = array('Course'=>$line['Course'],'Dept'=>$dept,'Number'=>$coursenumber,
 [532]                 'Section'=>$line['Section'],'Type'=>$line['Type'],'Lab'=>$line['Lab'],'Time'=>$time24,'Minutes'=>$minutes,
 [533]                 'Hour'=>$hour,'TSI'=>$line['TSI'],'Prereq'=>$line['Prereq'],'Remain'=>$remain,'Taken'=>$taken,'Limit'=>$limit,
 [534]                 'Synonym'=>$line['Synonym'],'Location'=>$location,'Campus'=>$campus,'Room'=>$line['Room'],'Building'=>$building,
 [535]                 'Days'=>$days,'Start'=>$start_time,'End'=>$end_time,'Times'=>"$days$times",'Instructor'=>$instructor,
 [536]                 'Session'=>$line['Session'],'Email'=>$email,'Semester'=>$semester,'Version'=>$version,'Discipline'=>$discipline);
 [537]             $last_key = $key;
 [538]         } elseif ($last_key !== '~') {
 [539]             if ($times && "$days$times") $schedule_info[$last_key]['Times'] .= "/$days$times";
 [540]             if ($schedule_info[$last_key] && "$line[Type]" && !contains($schedule_info[$last_key]['Type'],$line['Type'])) {
 [541]                 $schedule_info[$last_key]['Type'] .= "/$line[Type]";
 [542]             }
 [543]         }
 [544]     }
 [545]     return $schedule_info;
 [546] }
 [547] $default_schedule_fields = array('Discipline','Course','Section','Type','Remain','Taken','Limit','Synonym',
 [548]     'Campus','Location','Days','Start','End','Minutes','Time','Instructor','Session','Semester','Version'); [
Top]   _schedule_routines_new.php
 [549] function schedule_heading($fields='',$version='',$semester='',$discipline='') {
 [550]     if (!is_array($fields)) $fields = $GLOBALS['default_schedule_fields'];
 [551]     $heading = implode("\t",$fields) . "\t";
 [552]     if ($version) $heading .= "\tVersion: $version";
 [553]     if ($semester) $heading .= "\tSemester: $semester";
 [554]     if ($discipline) $heading .= "\tDiscipline: $discipline";
 [555]     return "$heading\n";
 [556] } [
Top]   _schedule_routines_new.php
 [557] function schedule_row($record) {
 [558]     $fields = array();
 [559]     if (func_num_args() > 1) {for ($i=1; $i<func_num_args(); $i++) $fields[] = func_get_arg($i);}
 [560]     else $fields = $GLOBALS['default_schedule_fields'];
 [561]     foreach ($fields as $field) $columns[] = $record[$field];
 [562]     return (implode("\t",$columns) . "\n");
 [563] }
 [569] ?>

FILE: _site_unzip.php - 53 lines, 0 functions [
Top]
  [1] <html>
  [2] <head><title>Site Unzip</title></head>
  [3] <body bgcolor=aqua>
  [4] <form method=POST action='_unzip_site.php'>
  [5] <div align=center>
  [6] <font face="Verdana">
  [7] <h3>UNZIP WEBSITE</h3>
  [8] Copy the contents of the CODE textarea in the _gpl.php page on the source website into this textarea<br>
  [9] <textarea name='code' id='code' rows=10 cols=120 wrap=off></textarea><br><br>
  [10] <input name='command' type=submit value='Install Files From Code Copy'>
  [11] &nbsp; &nbsp; &nbsp; <label><input type=check name='replace' value=1>Replace existing files</label><br>
  [12] <?php // This is a no-dependencies script for use in copying a website; it will not replace existing files unless specified
  [13] if ($_POST) {
  [14]     $file_separator = "\n~~~~~~~~~~ combined by _gpl.php - "; // must match that in _gpl.php
  [15]     print "<table><tr><td>\n";
  [16]     $files = $created = $already = $replaced = $errors = 0;
  [17]     $replace = $_POST['replace'];
  [18]     $file_contents = explode($file_separator,$_POST['code']);
  [19]     array_shift($file_contents); // discard first, before-separator content piece
  [20]     foreach ($file_contents as $file_content) {
  [21]         $newline = strpos($file_content,"\n");
  [22]         if (!$newline) continue;
  [23]         $filename = trim(substr($file_content,0,$newline));
  [24]         if (!ctype_alnum($filename[0]) && $filename[0]!=='_' && $filename[0]!=='/' && $filename[0]!=='.') continue;
  [25]         $files++;
  [26]         $exists = file_exists($filename);
  [27]         if (!$replace && $exists) {$already++; print "Already exists in this directory: <b>$filename</b>";}
  [28]         else {
  [29]             $handle = fopen($filename,'w');
  [30]             $size = fwrite($handle,substr($file_content,$newline+1));
  [31]             if ($size !== FALSE) {
  [32]                 print ($exists ? 'Replaced' : 'Created') . " <b>$filename</b> (" . number_format($size) . " bytes)";
  [33]                 if ($exists) $replaced++; else $created++;
  [34]             } else {$errors++; print "Error when writing: <b>$filename</b>";}
  [35]             fclose($handle);
  [36]         }
  [37]         print "<br>\n";
  [38]     }
  [39]     print "</td></tr></table>\n<br><br>\n";
  [40]     print "INSTALLATION COMPLETE<br>Files: $files, Created: $created, Replaced $replaced, Retained: $already, Errors: $errors<br>\n";
  [41] }
  [47] ?>
  [48] </font>
  [49] </div>
  [50] </form>
  [51] </body>
  [52] </html>
  [53]
FILE: accounts.php - 27 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] privilege_required('Administrator');
  [4] if (contains($command,'Delete')) {unlink(account_filename($id)); redirect();}
  [5] page_start('Registered Accounts');
  [6] if ($id) { // view/edit account
  [7]     print pc(bold("Account: $id &nbsp; "));
  [8]     print table(5,"<i>Contents of account file:</i><br>" . paragraph(h(file_read_contents(account_filename($id)))));
  [9]     print hidden('id',$id);
  [10]     print br(commandbutton('Delete this account'),2);
  [11] } else {
  [12]     $account_files = fileset(account_filename('*'));
  [13]     if ($account_files) {
  [14]         print "<table>\n";
  [15]         foreach ($account_files as $account_file) {$id = between($account_file,'/','.txt'); print tr(alink($id,"?id=$id"));}
  [16]         print "</table>\n";
  [17]     } else pc('No users are currently registered');
  [18] }
  [19] print br();    
  [20] $site_navigation = TRUE;
  [21] page_end();
  [27] ?>
FILE: code_compare.php - 95 lines, 4 functions [
Top]
  [1] <?php // display specified source code, with function-name indexes into a bookmarked listing
  [2] include '_all_includes.php';
  [3] $page_width="'96%'";
  [4] $suppress_banner = TRUE;
  [5] $site_navigation = FALSE;
  [6] page_start('Code Comparison');
  [7] $atext = rq('atext');
  [8] $btext = rq('btext');
  [9] print br('Paste text from two sources into the textareas below, then press ' . commandbutton('Compare'),1);
  [10] print table(-5,tr(tdc(textarea('atext',$atext,5,50,FALSE)) . tdc(textarea('btext',$btext,5,50,FALSE))));
  [11] if ($command) {
  [12]     $afunctions = get_functions($atext);
  [13]     $aother = explode("\n",array_shift($afunctions));
  [14]     $bfunctions = get_functions($btext);
  [15]     $bother = explode("\n",array_shift($bfunctions));
  [16]     $anames = array_keys($afunctions);
  [17]     $bnames = array_keys($bfunctions);
  [18]     $different = array();
  [19]     foreach ($anames as $name) {if (in_array($name,$bnames) && $afunctions[$name]!==$bfunctions[$name]) $different[] = $name;}
  [20]     $functions = $different;
  [21]     sort($functions);
  [22]     print extra_functions('left',$anames,$bnames);
  [23]     print extra_functions('right',$bnames,$anames);
  [24]     $n = 0;
  [25]     print "<a name='__function_index'>\n<table border=0><tr><td>\n";
  [26]     foreach ($functions as $name) {$n += strlen($name) + 3; if ($n > 100) {print "<br>\n"; $n = 0;} print ' &nbsp; ' . alink($name,"#_name");}
  [27]     print "</td></tr></table>\n";
  [28]     print br('Functions found: ' . count($afunctions) . ', ' . count($bfunctions) . spaces(5) . 'Differing functions: ' . count($functions));
  [29]     print "<table border=1 cellpadding=5 bgcolor='#DDDDDD'>\n";
  [30]     print tr(th('Left code differences',"width='50%'") . th('Right code differences',"width='50%'"));
  [31]     foreach ($different as $name) {
  [32]         $alines = explode("\n",$afunctions[$name]);
  [33]         $blines = explode("\n",$bfunctions[$name]);
  [34]         print tr(td(line_compare($alines,$blines)) . td(line_compare($blines,$alines)));
  [35]         print tr(tdc(small(alink('Index','#__function_index')) . spaces(10) . $top_link,2));
  [36]     }
  [37]     trace('counts of $aother,$bother',count($aother) . ',' . count($bother));
  [38]     $adiff = line_different($aother,$bother);
  [39]     $bdiff = line_different($bother,$aother);
  [40]     if ($adiff || $bdiff) {
  [41]         print tr(th("Differing code lines outside function definitions: " . count(nsplit($adiff)) . ', ' . count(nsplit($bdiff)),2));
  [42]         print tr(td("$adiff&nbsp;") . td("$bdiff&nbsp;"));
  [43]         print tr(th($top_link,2));
  [44]     }
  [45]     print "</table>\n";
  [46] }
  [47] page_end();
  [48] [Top]   code_compare.php
  [49] function get_functions($text) {
  [50]     $code_lines = explode("\n",trim($text));
  [51]     $line = 0;
  [52]     $functions['_other_'] = ''; // will be reset to outside-of-functions text
  [53]     $outside = $name = '';
  [54]     foreach ($code_lines as $code) {
  [55]         $code = rtrim($code);
  [56]         if (substr($code,0,9) === 'function ') { // start of function definition
  [57]             $name = trim(between($code,'function','('));
  [58]             $function_code = $code;
  [59]             if (strpos($code,'}')) {$functions[$name] = $function_code; $name = '';} // single-line function definition
  [60]         } else {
  [61]             if ($name && substr($code,0,1) === '}') { // end of function definition
  [62]                 if ($name) $functions[$name] = $function_code . "\n$code";
  [63]                 $name = '';
  [64]             } else {
  [65]                 if ($code) {
  [66]                     if ($name) $function_code .= "\n$code";
  [67]                     else $outside .= "$code\n";
  [68]                 }
  [69]             }
  [70]         }
  [71]     }
  [72]     $functions['_other_'] = trim($outside);
  [73]     return $functions;
  [74] } [
Top]   code_compare.php
  [75] function line_compare($alines,$blines) {
  [76]     $output = '';
  [77]     foreach ($alines as $line) {$output .= br(in_array($line,$blines) ? h($line) : bold(h($line)));}
  [78]     return $output;
  [79] } [
Top]   code_compare.php
  [80] function line_different($alines,$blines) {
  [81]     $output = '';
  [82]     foreach ($alines as $line) {if (!in_array($line,$blines)) $output .= br(h($line));}
  [83]     return $output;
  [84] } [
Top]   code_compare.php
  [85] function extra_functions($tag,$anames,$bnames) {
  [86]     $a_not_b = array_diff($anames,$bnames);
  [87]     if (!$a_not_b) return '';
  [88]     br(italic("Extra $tag functions: ") . (count($a_not_b)>10 ? '<br>' : '') . bold(implode(', ',$a_not_b)));
  [89] }
  [95] ?>

FILE: copy_instructions.php - 42 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] page_start('Instructions For Copying Schedule Data');
  [4] $schedule_link = alink('ACC Course Schedule',schedule_url());
  [5] $indent = ' &nbsp; &nbsp; &nbsp;';
  [6] print <<<HTML
  [7] <table cellPadding=10 border=1><tr><td>
  [8] TO COPY FROM THE COURSE SCHEDULE TO THIS WEBSITE:<br>
  [9] $indent [1] Display a departmental course-schedule page from an $schedule_link.<br>
  [10] $indent [2] Focus on the schedule page by putting the cursor over the page and clicking.<BR>
  [11] $indent [3] Press the "A" key while holding down the "Ctrl" key.<BR>
  [12] $indent [4] Press the "C" key while holding down the "Ctrl" key.<BR>
  [13] $indent [5] Display the destination web page on this site.<BR>
  [14] $indent [6] Put the cursor over the target text area.<BR>
  [15] $indent [7] Click on the target to make it the keyboard focus.<BR>
  [16] $indent [8] Press the "V" key while holding down the "Ctrl" key.<BR>
  [17] </td></tr></table>
  [18] <table border=0 cellpadding=3>
  [19] <tr><td></td></tr>
  [20] <tr><td>After the input has been copied, press the appropriate button to process it.</td></tr>
  [21] <tr><td>If a page produces spreadsheet output, it will be in a text area below the input.</td></tr>
  [22] <tr><td></td></tr>
  [23] </table>
  [24] <table cellPadding=10 border=1><tr><td>
  [25] TO COPY FROM THE RESULT TEXT AREA TO A SPREADSHEET:<br>
  [26] $indent [1] Focus on the text area that contains the result by clicking on it.<BR>
  [27] $indent [2] Press the "A" key while holding down the "Ctrl" key.<BR>
  [28] $indent [3] Press the "C" key while holding down the "Ctrl" key.<BR>
  [29] $indent [4] Display the destination worksheet in a spreadsheet program such as Excel.<BR>
  [30] $indent [5] Select the top-left cell (typically A1).<BR>
  [31] $indent [6] Press the "V" key while holding down the "Ctrl" key.<BR>
  [32] $indent [7] Label the worksheet appropriately and save the spreadsheet.<BR>
  [33] </td></tr></table><br>
  [34]
  [35] HTML;
  [36] page_end();
  [42] ?>
FILE: document_feedback.php - 188 lines, 2 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $sql_now = '(DATE_ADD(NOW(), INTERVAL 2 HOUR))';
  [4] $table = $svtag = 'feedback';
  [5] $note_table = $table . '_notes';
  [6] $document_table = $table . '_documents';
  [7] register_request('command,content,old_content,edit#,annote#,page#,comment_id#,edit_id#,enable#,disable#,logoff?');
  [8] if ($enable) {sql_update($table,'enabled=1',$enable); redirect();}
  [9] if ($disable) {sql_update($table,'enabled=0',$disable); redirect();}
  [10] if ($logoff) {logoff(); redirect();}
  [11] $document_count = DBC($document_table,'enabled=1');
  [12] if ($document_count == 1) $document_id = DBN($document_table,'id','enabled=1');
  [13] else $document_id = rqn('document_id',num(sv("document_id_$svtag")));
  [14] $document = DBR($document_table,$document_id);
  [15] if ($document) list($docname,$document_url) = array($document['name'],$document['url']);
  [16] $user_email_domain = 'austincc.edu';
  [17] $author = sv("author_$svtag");
  [18] $email = sv("email_$svtag");
  [19] if ($author && !$email) $_SESSION["email_$svtag"] = $email = "$author@$user_email_domain";
  [20] $table_with_notes = "$table left join $note_table on id={$table}_id AND note_author='$author'";
  [21]
  [22] if (begins($command,'Provide')) redirect('?edit=-1'); // convert POST into GET (button used for prominence -- no actual content)
  [23] elseif ($command) { // form submission by user
  [24]     if (contains($command,'Cancel')) redirect();
  [25]     if ($command === 'Select Document') {
  [26]         $document_id = rqn('document_id');
  [27]         if (!$document_id) error('No document selected');
  [28]         else $_SESSION["document_id_$sv_tag"] = $document_id;
  [29]     }
  [30]     if ($command === 'Log On') {
  [31]         $email = rq('email');
  [32]         if (!contains($email,'@')) $email = "$email@$user_email_domain";
  [33]         $email = extract_email($email);
  [34]         if (same($email,$system_email)) $author = 'administrator';
  [35]         elseif (contains($email,$user_email_domain)) $author = alphanumeric_only(before($email,'@'));
  [36]         if (!$author) error("An email address at $user_email_domain must be supplied");
  [37]         else {
  [38]             $_SESSION["author_$svtag"] = strtolower($author);
  [39]             $_SESSION["email_$svtag"] = $email;
  [40]             $_SESSION["document_id_$svtag"] = $document_id;
  [41]         }
  [42]     }
  [43]     if (contains($command,'it Comment')) { // submit or edit comment
  [44]         if ($content) {
  [45]             $feedback = array('document_id'=>$document_id,'author'=>$author,'page'=>$page,'comment'=>$content);
  [46]             $id = sql_update_or_insert($table,$feedback,$edit_id);
  [47]             if ($id) sql_update($table,"created_at=$sql_now",$id);
  [48]             if ($id && !$page) notice("A page was not specified for your last comment.&nbsp; " . alink('Edit',"?edit=$id") . '?');
  [49]             else $command .= " (page $page)";
  [50]             $command .= " $_SERVER[PHP_SELF]#C$id";
  [51]         } elseif ($edit_id) {
  [52]             sql_update($table,'enabled=0',$edit_id);
  [53]             $command = "Disable comment (restore with $_SERVER[PHP_SELF]?enable=$edit_id)";
  [54]         } else redirect(); // no email if blank and not edit
  [55]     }
  [56]     if ($command === 'Submit Note') { // submit or edit note
  [57]         if ($content) {
  [58]             if ($edit_id) {$id = $edit_id; sql_update($note_table,'note=' . sq($content),"note_id=$id");}
  [59]             else {
  [60]                 $note_record = array("{$table}_id"=>$comment_id,'note_author'=>$author,'note'=>$content);
  [61]                 $id = sql_update_or_insert($note_table,$note_record,0);
  [62]             }
  [63]             if ($id) sql_update($note_table,"note_created_at=$sql_now","note_id=$id");
  [64]             $command .= " $_SERVER[PHP_SELF]#C$comment_id";
  [65]         } elseif ($edit_id) {
  [66]             $command = "Delete Note\n\nDELETED CONTENT";
  [67]             $content = $old_content;
  [68]             sql_delete($note_table,"note_id=$edit_id");
  [69]         } else redirect(); // no email if blank and not edit
  [70]     }
  [71]     send_mail($email,'Document feedback confirmation',"$docname " . numberdatetime() . "\n$command\n\n$content");
  [72]     redirect();
  [73] }
  [74]
  [75] $maxwidth = 900;
  [76] $hide_site_banner = TRUE;
  [77] $no_mail_copy = TRUE;
  [78] $site_navigation = FALSE;
  [79] $site_css = 'document_feedback.css';
  [80] $page_font_style = 'Georgia';
  [81] if (!$author) {$title = 'Log On'; $logon = $select = TRUE;}
  [82] else if (!$docname) {$title = "Select Document"; $select = $TRUE;}
  [83] else {
  [84]     if ($annote) $title = "Make Individual Note";
  [85]     elseif ($edit) $title = ($edit>0 ? 'Edit' : 'Add') . " Feedback";
  [86]     else {$title = "Feedback Comments"; $subtitle = spaces(5) . big(commandbutton('Provide feedback on the document'));}
  [87] }
  [88]
  [89] $doc_text = italic('Document Feedback: ');
  [90] if ($docname) $doc_text .= ($document_url ? alink($docname,$document_url) : $docname);
  [91] else $doc_text .= italic('not selected');
  [92] if ($document_count > 1) $doc_text = alink('change',"?newdoc=1") . ' ' . $doc_text;
  [93] if ($author) $doc_text .= spaces(10) . "($author) " . small(alink('Log off','?logoff=1'));
  [94]
  [95] print page_start(); print pc($doc_text); print br(pc(big(bold($title)) . "$subtitle")); print_flash($notice);
  [96]
  [97] if ($logon || $select) { // setup needed
  [98]     print "<br><br><table cellpadding=10 border=1><tr><td align=center>\n";
  [99]     if ($select) {
 [100]         $documents = DBE($document_table,'','name');
 [101]         if (!$documents) print br('No documents have been registered on this site',2);
 [102]         if (count($documents)==1 && $documents[0]) { // if only one active document, use it
 [103]             $_SESSION['feedback_document_id'] = $documents[0]['id'];
 [104]             if (!$logon) redirect();
 [105]         } else {
 [106]             print "<br>Select document for feedback:<br>\n<table cellpadding=3>\n";
 [107]             foreach ($documents as $d) print tr(td(radio('document_id',$d['id'],$document_id,$d['name'])));
 [108]             print "</table>\n";
 [109]         }
 [110]     }
 [111]     if ($logon) print br(bold('ACC email address: ') . textbox('email',$email,20),1) .
 [112]         pc(small(italic("A confirming message will be sent to this email address for each log-on or feedback entry")));
 [113]     print pc(commandbutton($logon ? 'Log On' : 'Select Document'));
 [114]     print "</td></tr></table>\n";
 [115]
 [116] } elseif ($edit) { // display entry form for feedback comment
 [117]     if ($edit > 0) {
 [118]         $feedback = DBR($table,"id=$edit AND author='$author'"); // users can edit only their own submissions
 [119]         if ($feedback) {
 [120]             list($id,$page,$content,$note) = array($feedback['id'],$feedback['page'],$feedback['comment'],$feedback['note']);
 [121]             print hidden('edit_id',num($id)) . hidden('old_content',$content);
 [122]         }
 [123]     }
 [124]     print pc("<table border=1><tr><td><table cellpadding=10 border=0>\n" .
 [125]         tr(tdc('<b>Feedback Comment</b> (will be visible to everyone who views the site)<br>' . textarea('content',$content,10,80))) .
 [126]         tr(tdc('Page: ' . textbox('page',$page,4) . spaces(10) . commandbutton('Submit Comment') . spaces(10) . commandbutton('Cancel'),2)) .
 [127]         "</table></td></tr></table>");
 [128]
 [129] } elseif ($annote) { // display entry form for private note about a comment
 [130]     $fb = DBR($table_with_notes,$annote);
 [131]     if ($fb) { // edit of an existing note
 [132]         print hidden('edit_id',$fb['note_id']) . hidden('old_content',$content);
 [133]         $content = $fb['note'];
 [134]     }
 [135]     print hidden('comment_id',$annote);
 [136]     $page_text = $fb['page'] ? "page $fb[page]" : '';
 [137]     print pc("<table width=$maxwidth border=0><tr><td align=center><table border=1>\n" .
 [138]         tr(td(bold('Annotate this ' . short_datetime($fb['created_at']) . " $page_text comment by <i>$fb[author]</i>\n") . paragraph("$fb[comment]<br>&nbsp;",'feedback'))) .
 [139]         tr(tdc("Individual note on this comment</b><br>(shown only when <i>$author</i> is logged on)<br>" . textarea('content',$fb['note'],4,50) .
 [140]             br() . commandbutton('Submit Note') . spaces(10) . commandbutton('Cancel'))) .
 [141]         "</table></td></tr></table>");
 [142]
 [143] } else { // list existing feedback
 [144]     $sort = rq('sort');
 [145]     $order = 'id desc'; // by default, sort with most recent first
 [146]     if ($sort === 'Author') {$order = "author,id desc"; $mode = 'author';}
 [147]     if ($sort === 'Page') {$order = "page,id desc"; $mode = 'page';}
 [148]     if ($sort === 'Note') $order = "note,page,id desc";
 [149]     $feedback = DBA($table_with_notes,"enabled=1 AND document_id=$document_id",$order);
 [150]     if ($feedback) {
 [151]         if ($mode) {
 [152]             foreach ($feedback as $fb) $bookmarks[$fb[$mode]]++;
 [153]             ksort($bookmarks);
 [154]             print ucfirst($mode) . 's:';
 [155]             foreach (array_keys($bookmarks) as $b) print ' ' . alink($b,"#_$b");
 [156]             print "<br>\n";
 [157]         }
 [158]         print "<table width=$maxwidth border=0><tr><td align=center><table border=1 cellpadding=3>\n";
 [159]         if (!$mode) print feedback_heading(); // not printed here for bookmark mode because header will be printed before each bookmark
 [160]         foreach ($feedback as $fb) {
 [161]             if ($mode && $fb[$mode]!==$bookmark) {
 [162]                 $bookmark = $fb[$mode];
 [163]                 print feedback_heading("<a name='_$bookmark'>");
 [164]                 $lines = 0;
 [165]             }
 [166]             $comment_text = h($fb['comment']);
 [167]             $lines += (int) (strlen($comment_text)/80) + 2;
 [168]             if ($fb['author'] === $author) $comment_text .= ' &nbsp; ' . alink('Edit',"?edit=$fb[id]");
 [169]             $note_text = alink(('Add note'),"?annote=$fb[id]");
 [170]             $bm = "<a name='C$fb[id]'>"; // bookmark to comment listing
 [171]             if ($fb['note_author'] === $author) {
 [172]                 $note_text = short_datetime($fb['note_created_at']) . ' &nbsp; ' . alink('Edit note',"?annote=$fb[id]") . '<br>' . h($fb['note']);
 [173]             }
 [174]             print tr(tdc($bm . trim($fb['page'])) . td($fb['author']) . tdc(short_datetime($fb['created_at'])) .
 [175]                 td($comment_text,'class=feedback') . td($note_text));
 [176]         }
 [177]         if ($lines > 10) print feedback_heading(); // repeat heading at bottom of long list
 [178]         print "</table></td></tr></table>\n";
 [179]     } else print bold('No feedback has been submitted for this document.');
 [180] }
 [181]
 [182] page_end('');
 [183] [Top]   document_feedback.php
 [184] function sort_th($tag) {return th(alink($tag,"?sort=$tag"));} [
Top]   document_feedback.php
 [185] function feedback_heading($firstcolumn='&nbsp;') {
 [186]     return tr(sort_th('Page') . sort_th('Author') . sort_th('Time') . th('Feedback Comment') . sort_th('Note'));
 [187] }
 [188] ?>

FILE: evaluation_address_labels.php - 111 lines, 6 functions [
Top]
  [1] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
  [2] <html>
  [3] <head>
  [4] <title>Evaluation Address Labels</title>
  [5] </head>
  [6] <body bgColor="#ffffcc">
  [7] <FONT face="Verdana">
  [8] <?php
  [9] require_once '_general_utilities.php'; [Top]   evaluation_address_labels.php
  [10] function extract_courses($text,$semester='') {
  [11]     $courses = array();
  [12]     foreach (explode('/',$text) as $piece) {
  [13]         $coursenumber = course_digits($piece);
  [14]         $s = substr(trim($piece),-1);
  [15]         if ($s==='f' || $s==='s' || $s==='u') $semester = $s;
  [16]         if ($coursenumber !== '') $courses[] = "$coursenumber$semester";
  [17]     }
  [18]     return $courses;
  [19] } [
Top]   evaluation_address_labels.php
  [20] function dept($course) {
  [21]     if (!$course || begins($course,'M')) return $course;
  [22]     return ((course_digits($course)<'1000' ? 'MATD ' : 'MATH ') . $course);
  [23] } [
Top]   evaluation_address_labels.php
  [24] function course_digits($course) {
  [25]     $number = substr('0000' . digits_only($course), -4);
  [26]     return ($number!=='0000' ? $number : '');
  [27] } [
Top]   evaluation_address_labels.php
  [28] function expand_semester($course) {
  [29]     if (substr($course,-1) === 'f') return str_replace('f'," (Fall '10)",$course);
  [30]     if (substr($course,-1) === 's') return str_replace('s'," (Spring '10)",$course);
  [31]     if (substr($course,-1) === 'u') return str_replace('u'," (Summer '10)",$course);
  [32]     return $course;
  [33] } [
Top]   evaluation_address_labels.php
  [34] function remove_semester($course) {
  [35]     $course = trim($course);
  [36]     $s = substr($course,-1);
  [37]     if ($s==='f' || $s==='s' || $s==='u') $course = substr($course,0,-1);
  [38]     return $course;    
  [39] } [
Top]   evaluation_address_labels.php
  [40] function best_semester($course) {
  [41]     global $f;
  [42]     $number = course_digits($course);
  [43]     if (!$number) return $course;
  [44]     foreach (extract_courses($f['Fall']) as $c) {if (course_digits($c) == $number) return ($number . 'f');}
  [45]     foreach (extract_courses($f['Spring']) as $c) {if (course_digits($c) == $number) return ($number . 's');}
  [46]     foreach (extract_courses($f['Summer']) as $c) {if (course_digits($c) == $number) return ($number . 'u');}
  [47]     return "$course (NOT FOUND)";
  [48] }
  [49] print <<<HTML
  [50] <form method=POST action='$_SERVER[PHP_SELF]'>
  [51] <div align=center>
  [52] <form name="form1" method="post" action="evaluation_labels.php" id="form1">
  [53] <P align="center">Extracts name and campus, eliminating duplicates<br>
  [54]     Copy the raw evaluation spreadsheet into the text area below.<BR>
  [55]     Press "Convert Text" to convert that text to a processed form suitable to print labels.</P>
  [56] <P>Column headings containing these words will be used: First, Last, & Campus</P>
  [57] <P align="center">
  [58]     <input type="submit" name="command" value="Convert Text" id="command"
  [59]         style="background-color:Lime;font-weight:bold;" /><BR>
  [60] </P>
  [61] <P align="center"><textarea name="text" rows="20" cols="120" wrap="off" id="text">
  [62]
  [63] HTML;
  [64] $text = rq("text");
  [65] $lines = explode("\n",$text);
  [66] if ($_POST) {
  [67]     $columnwords = array("Last","First","Campus");
  [68]     $headings = explode("\t",$lines[0]);
  [69]     $old_headings = '';
  [70]     for ($i=0; $i<count($headings); $i++) { // map raw names to meanings
  [71]         foreach ($columnwords as $w) {if (contains($headings[$i],$w)) $columnindex[$w] = $i;}
  [72]         $old_headings .= "\t^" . $headings[$i];
  [73]     }
  [74]     print "Name\tCampus\n";
  [75]     for ($j=1; $j<count($lines); $j++) { // extract data from each line
  [76]         $f = array();
  [77]         $line = $lines[$j];
  [78]         $columnvalues = explode("\t",$line);
  [79]         foreach ($columnwords as $w) {
  [80]             $v = ucfirst(trim(before(before($columnvalues[$columnindex[$w]],"("),","))); // truncate before , or (
  [81]             $f[$w] = $v;
  [82]         }
  [83]         $name = "$f[Last], $f[First]";
  [84]         if ($name === ', ') continue;
  [85]         if ($name === $previous_name) continue;
  [86]         $campus = "$f[Campus]";
  [87]         print "$name\t$campus\n";
  [88]         $labels++;
  [89]         if (!$campus) $no_campus[] = $name;
  [90]         $previous_name = $name;
  [91]     }
  [92] }
  [93] print "</textarea></P><br>";
  [94] if ($labels) print plural($labels,'label') . " prepared<br>\n";
  [95] print "<table><tr><td>\n";
  [96] if (count($no_campus)) {
  [97]     print "NO CAMPUS GIVEN:<i>";
  [98]     foreach ($no_campus as $name) print "<br>\n$name";
  [99] }
 [100] print "\n</td></tr></table>\n";
 [106] ?>
 [107] </form>
 [108] </FONT>
 [109] </body>
 [110] </HTML>
 [111]

FILE: evaluation_labels.php - 157 lines, 6 functions [
Top]
  [1] <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >
  [2] <html>
  [3] <head>
  [4] <title>Evaluation Labels</title>
  [5] </head>
  [6] <body bgColor="#ffffcc">
  [7] <FONT face="Verdana">
  [8] <?php
  [9] require_once '_general_utilities.php'; [Top]   evaluation_labels.php
  [10] function extract_courses($text,$semester='') {
  [11]     $courses = array();
  [12]     foreach (explode('/',$text) as $piece) {
  [13]         $coursenumber = course_digits($piece);
  [14]         $s = substr(trim($piece),-1);
  [15]         if ($s==='f' || $s==='s' || $s==='u') $semester = $s;
  [16]         if ($coursenumber !== '') $courses[] = "$coursenumber$semester";
  [17]     }
  [18]     return $courses;
  [19] } [
Top]   evaluation_labels.php
  [20] function dept($course) {
  [21]     if (!$course || begins($course,'M')) return $course;
  [22]     return ((course_digits($course)<'1000' ? 'MATD ' : 'MATH ') . $course);
  [23] } [
Top]   evaluation_labels.php
  [24] function course_digits($course) {
  [25]     $number = substr('0000' . digits_only($course), -4);
  [26]     return ($number!=='0000' ? $number : '');
  [27] } [
Top]   evaluation_labels.php
  [28] function expand_semester($course) {
  [29]     if (substr($course,-1) === 'f') return str_replace('f'," (Fall '10)",$course);
  [30]     if (substr($course,-1) === 's') return str_replace('s'," (Spring '10)",$course);
  [31]     if (substr($course,-1) === 'u') return str_replace('u'," (Summer '10)",$course);
  [32]     return $course;
  [33] } [
Top]   evaluation_labels.php
  [34] function remove_semester($course) {
  [35]     $course = trim($course);
  [36]     $s = substr($course,-1);
  [37]     if ($s==='f' || $s==='s' || $s==='u') $course = substr($course,0,-1);
  [38]     return $course;    
  [39] } [
Top]   evaluation_labels.php
  [40] function best_semester($course) {
  [41]     global $f;
  [42]     $number = course_digits($course);
  [43]     if (!$number) return $course;
  [44]     foreach (extract_courses($f['Fall']) as $c) {if (course_digits($c) == $number) return ($number . 'f');}
  [45]     foreach (extract_courses($f['Spring']) as $c) {if (course_digits($c) == $number) return ($number . 's');}
  [46]     foreach (extract_courses($f['Summer']) as $c) {if (course_digits($c) == $number) return ($number . 'u');}
  [47]     return "$course (NOT FOUND)";
  [48] }
  [49] print <<<HTML
  [50] <form method=POST action='$_SERVER[PHP_SELF]'>
  [51] <div align=center>
  [52] <form name="form1" method="post" action="evaluation_labels.php" id="form1">
  [53] <P align="center">Copy the raw evaluation spreadsheet into the text area below.<BR>
  [54]     Press "Convert Text" to convert that text to a processed form suitable to print labels.</P>
  [55] <P>Column headings containing these words will be used:<br>
  [56] Last, First, Portfolio, Spring, Summer, Fall, & Requirement</P>
  [57] <P align="center">
  [58]     <input type="submit" name="command" value="Convert Text" id="command"
  [59]         style="background-color:Lime;font-weight:bold;" /><BR>
  [60] </P>
  [61] <P align="center"><textarea name="text" rows="20" cols="120" wrap="off" id="text">
  [62]
  [63] HTML;
  [64] $text = rq("text");
  [65] $lines = explode("\n",$text);
  [66] if ($_POST) {
  [67]     $columnwords = array("Last","First","Portfolio","Spring","Summer","Fall","Requirement");
  [68]     $headings = explode("\t",$lines[0]);
  [69]     $old_headings = '';
  [70]     for ($i=0; $i<count($headings); $i++) { // map raw names to meanings
  [71]         foreach ($columnwords as $w) {if (contains($headings[$i],$w)) $columnindex[$w] = $i;}
  [72]         $old_headings .= "\t^" . $headings[$i];
  [73]     }
  [74]     print "Name\tCourse\tPortfolio\tPacket\t$old_headings\n";
  [75]     for ($j=1; $j<count($lines); $j++) { // extract data from each line
  [76]         $f = array();
  [77]         $line = $lines[$j];
  [78]         $columnvalues = explode("\t",$line);
  [79]         foreach ($columnwords as $w) {
  [80]             $v = ucfirst(trim(before(before($columnvalues[$columnindex[$w]],"("),","))); // truncate before , or (
  [81]             if (contains($v,'Year')) {
  [82]                 if (!contains($v,'Year ')) $v = str_replace('Year','Year ',$v);
  [83]                 if (!contains($v,'Major')) $v .= ' Major';    
  [84]             } else if (contains($v,'Major')) $v = 'Major';
  [85]             $f[$w] = $v;
  [86]         }
  [87]         $name = "$f[Last], $f[First]";
  [88]         if ($name === ', ') continue;
  [89]         $portfolio = "$f[Portfolio]";
  [90]         $packets = contains($portfolio,'Annual') ? 1 : 2;
  [91]         $requirement = "$f[Requirement]";
  [92]         $requirement = str_replace(' or ','/',$requirement);
  [93]         $requirement = str_replace(' or ','/',$requirement);
  [94]         $requirement = str_replace('instructor',(contains($requirement,'+') ? '' : '+'),$requirement);
  [95]         $fasttrack = contains($requirement,'FT') || contains($requirement,'fast');
  [96]         $required = extract_courses(before($requirement,'+'));
  [97]         $used = array();
  [98]         foreach ($required as $i=>$r) {
  [99]             $used[course_digits($r)]++;
 [100]             $required[$i] = dept(expand_semester(best_semester($r)));
 [101]         }
 [102]         $choice = contains($requirement,'choice');
 [103]         if ($choice) {
 [104]             $choices = num(digits_only(between($requirement,'+','choice')));
 [105]             if ($choices == 0) $choices = 1;
 [106]             $choice_options = extract_courses(after($requirement,'choice'));
 [107]             if ($choice_options) { // explicit choice options
 [108]                 foreach ($choice_options as $i=>$c) {$choice_options[$i] = dept(expand_semester($c));}
 [109]                 $trace .= tr(td("explicit choices: " . count($choice_options) . " ($choices) $choice_options[0] -- $requirement"));
 [110]             } else { // choice, but not explicit options
 [111]                 $allcourses = array_merge(extract_courses($f['Summer']),extract_courses($f['Spring']),extract_courses($f['Fall']));
 [112]                 $trace .= tr(td("all courses: " . count($allcourses) . " ($choices) $choice_options[0] -- $requirement"));
 [113]                 foreach ($allcourses as $c) {if (!$used[course_digits($c)]++) $choice_options[] = $c;}
 [114]             }
 [115]             sort($choice_options);
 [116]         } else {$choices = 0; $choice_options = array(); $trace .= tr(td("no choices -- $requirement"));}
 [117]         if (count($choice_options) < 3) foreach ($choice_options as $k=>$c) $choice_options[$k] = dept($c);
 [118]         if ($fasttrack) $required[] = "Fast-Track";
 [119]         foreach ($required as $course) { // first print explicit requirements
 [120]             for ($n=1; $n<=$packets; $n++) {
 [121]                 if (!$course) continue;
 [122]                 print "$name\t$course\t$portfolio\tpkt #$n of $packets\t\t$line\n";
 [123]                 $labels++;
 [124]             }
 [125]         }
 [126]         $course = implode(' or ',$choice_options);
 [127]         for ($c=0; $c<$choices; $c++) {
 [128]             for ($n=1; $n<=$packets; $n++) {
 [129]                 print "$name\t$course\t$portfolio\tpkt #$n of $packets\t\t$line\n";
 [130]                 $labels++;
 [131]             }
 [132]         }
 [133]         if ($labels == 0) {
 [134]             $skipped[] = "packets=$packets choices=$choices required=" . count(required) . " ** " . str_replace("\t",' | ',$line);
 [135]         }
 [136]     }
 [137] }
 [138] print "</textarea></P><br>";
 [139] if ($labels) print plural($labels,'label') . " prepared<br>\n";
 [140] print "<table><tr><td>\n";
 [141] if ($skipped) {
 [142]     print "<i>" . plural(count($skipped),'faculty member') . " had no course evaluations assigned:</i>";
 [143]     foreach ($skipped as $skip) {print "<br>\n$skip";}
 [144] } else {if ($labels) print "<i>All faculty were assigned course evaluations</i>\n";}
 [145] print "\n</td></tr></table>\n";
 [146] print "<table>$trace</table>\n";
 [152] ?>
 [153] </form>
 [154] </FONT>
 [155] </body>
 [156] </HTML>
 [157]

FILE: index.php - 45 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] reset_schedule_settings();
  [4] if (rq('user_email') && !$user_id) redirect('register.php');
  [5] page_start('Schedule Examination System',alink('Memo','ScheduleAbstract.htm'));
  [6] $course_schedules = alink('ACC course schedules',schedule_url());
  [7] if ($user_id) {
  [8]     print pc("<br><b>Account: <i>$user_id</i></b><br>");
  [9]     if ($_SESSION['discipline_options']) {
  [10]         print table_begin(10) . "<tr><td><i><b>Schedule Discipline Options:</b></i><br>\n";
  [11]         foreach ($_SESSION['discipline_options'] as $discipline) print br(spaces(3) . $discipline);
  [12]         print spaces(3) . small(alink('Change discipline options','register.php'));
  [13]         print "</td></tr>$table_end<br>\n";
  [14]     }
  [15] }
  [16] print "<table border=0 cellpadding=3>\n";
  [17] foreach (site_navigation_info() as $label => $info) {
  [18]     list($url,$text) = explode('|',$info);
  [19]     print tr(tdr(alink($label,"$url.php")) . td(" &nbsp; $text"));
  [20] }
  [21] print "</table><br>\n";
  [22] if (!$user_id) {
  [23]     $text = 'Account Email Address: ' . textbox('user_email') . ' &nbsp; ' . commandbutton('Optional Log On');
  [24]     print <<<HTML
  [25] <table border=1 cellpadding=5 width=900><tr><td>
  [26] <p style='text-indent:30;font-size:10pt'>This site is designed to provide efficient access to the information in the
  [27] $course_schedules. It does this by directly reading the Austin Community College schedule website and presenting its information
  [28] to users in a variety of forms adapted for specific uses, especially for further analysis in spreadsheet programs.</p>
  [29] <p style='text-indent:30;font-size:10pt'>The site uses a stored copy of an ACC schedule page if more than one reference
  [30] to it is made within an hour. This speeds site response and ensures that the site does not place a significant burden
  [31] on ACC servers. Changes to the schedule are thus not immediately visible, although the site will be no more than an hour
  [32] out of date. It is possible to explicitly refresh a page.</p>
  [33]
  [34] <p align=center style='text-indent:30;font-size:10pt'><i>You may register to restrict the list of disciplines to only those which interest you</i>
  [35] <br>$text
  [36]
  [37] HTML;
  [38] }
  [39] page_end();
  [45] ?>
FILE: logoff.php - 15 lines, 0 functions [
Top]
  [1] <?php
  [2] include '_all_includes.php';
  [3] $_SESSION = array();
  [4] if (isset($_COOKIE[session_name()])) setcookie(session_name(),'',time()-42000,'/');
  [5] session_destroy();
  [6] page_start('Log Off');
  [7] print br("<div class=bigtitle>Session Complete</div>",3,2);
  [8] print br(alink('Go to log-on page','index.php'));
  [9] page_end();
  [15] ?>
FILE: make_oiea_script.php - 104 lines, 2 functions [
Top]
  [1] <?php // SQL script generation for ACC Study Group
  [2] include '_all_includes.php';
  [3] $keyname = 'personid'; // name of field to be systematically replaced in all tables containing it to ensure student anonymity
  [4] $suppress_banner = TRUE;
  [5] $site_navigation = FALSE;
  [6] page_start('Make OIEA SQL Scripts');
  [7] $where = rq('where');
  [8] $table = rq('table');
  [9] $schema = fetch_oiea_data_schema($table);
  [10] print "<table cellpadding=5 width=700>\n";
  [11] if ($table) { // table-specific listing
  [12]     print "<tr><td align=center><i>Fields in </i><b>$table</b> &nbsp; " . small(alink('List All Tables')) . "</td></tr>\n";
  [13]     print "<tr><td align=center><table><tr><td>\n";
  [14]     foreach (fetch_oiea_data_schema($table) as $fields) {
  [15]         $checked_fields = $public_fields = $selected_fields = array();
  [16]         foreach ($fields as $field=>$parameters) {
  [17]             $sequence = $parameters['sequence'];
  [18]             $checked = rq1("$table_$sequence");
  [19]             if ($checked) {$selectfields[] = $parameters['selectfield']; $groupfields[] = $parameters['groupfield'];}
  [20]             $box = $parameters['private'] ? "&nbsp; &nbsp; &nbsp;$field" : checkbox("$table_$sequence",$checked,1,$field);
  [21]             if (!$parameters['private']) $publicfields[] = $parameters['selectfield'];
  [22]             $type = $parameters['type'];
  [23]             //if (is_numeric($parameters['size'])) $type = "$type($parameters[size])";
  [24]             print small($sequence) . " $box &nbsp; <small>$type $parameters[comment]</small><br>\n";
  [25]         }
  [26]         print "</td></tr></table\n</td></tr>\n";
  [27]         print "<tr><td>" . commandbutton('Update SQL') . " &nbsp; <small><i>Optional WHERE clause: </i></small>" . textbox('where',$where,40) . "</td></tr>\n";
  [28]         $where = "FROM $table" . ($where? " WHERE $where" : "");
  [29]         if (!$selectfields) $selectfields = $publicfields;
  [30]         $sql .= "SELECT '$table'," . implode(', ',$selectfields)
  [31]             . ($groupfields ? ", COUNT(*) AS group_count $where GROUP BY " . implode(', ',$groupfields) : " $where")
  [32]             . ";\n\n";
  [33]         $rows = strlen($sql)/60;
  [34]     }
  [35]     print hidden('table',$table);
  [36]     $textarea_title = "SQL script to list selected fields in <i>$table</i> table";
  [37] } else { // list all tables, with links to specific-table listings
  [38]     $copy_sql = <<<SQL
  [39] IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'IDT')
  [40] DROP TABLE IDT
  [41] GO
  [42] CREATE TABLE IDT (pid int PRIMARY KEY IDENTITY, varchar(11) $keyname)
  [43] INSERT INTO IDT SELECT $keyname FROM student_main;
  [44] -- The arbitrary sequential pid values will be used to systematically replace all $keyname values in the copied tables
  [45] -- For student privacy, any field marked 'private' is excluded from the copy; birthdates are replaced by the birth year
  [46]
  [47] SQL;
  [48]     foreach ($schema as $table=>$fields) $sets[before($table,'_')][$table] = $fields; // aggregate table sets
  [49]     foreach ($sets as $set=>$tables) {
  [50]         print "<tr><td align=right><i><b>$set</b>&nbsp;table&nbsp;set</i> </td><td>";
  [51]         foreach ($tables as $table=>$fields) {
  [52]             print ' ' . alink(uc_underscore(after($table,'_')),"?table=$table");
  [53]             if ($set === 'L') {
  [54]                 $selectfields = implode(', ',array_keys($fields));
  [55]                 $lookup_sql .= "SELECT '$table',$selectfields FROM $table;\n";
  [56]             }
  [57]             $copy_sql .= "\nDROP TABLE ASG_$table;\nSELECT ";
  [58]             $copyfields = array();
  [59]             if ($fields[$keyname]) $copyfields[] = 'pid';
  [60]             foreach ($fields as $field=>$parameters) if (!$parameters['private']) $copyfields[] = $parameters['selectfield'];
  [61]             $copy_sql .= implode(', ',$copyfields) . " INTO ASG_$table FROM $table";
  [62]             if ($fields[$keyname]) $copy_sql .= " JOIN IDT ON IDT.$keyname=$table.$keyname";
  [63]             $copy_sql .= ";\n";
  [64]         }
  [65]         print "</td></tr>\n";
  [66]     }
  [67]     $copy_sql .= "\nDROP TABLE IDT; -- Discard $keyname translation table\n";
  [68]     print "<tr><td align=center colspan=2>" . commandbutton('Generate script for anonymous database copy') .
  [69]         spaces(10) . commandbutton('Generate script to list look-up table contents') . "</td></tr>\n";
  [70] }
  [71] print "</table>\n";
  [72] if (contains($command,'copy')) print "<br><i>SQL script to copy database, dropping identifying data</i><br>\n" . textarea('sql',$copy_sql,25,120);
  [73] if (contains($command,'look-up')) print "<br><i>SQL script to list all entries in lookup tables</i><br>\n" . textarea('sql',$lookup_sql,30,120);
  [74] page_end();
  [75] [Top]   make_oiea_script.php
  [76] function fetch_oiea_data_schema($prefix='') {
  [77]     $schema = $publicfieldcount = array();
  [78]     foreach (nsplit(file_get_contents('oiea_data_schema.txt')) as $line) {
  [79]         $line = str_replace('personid','pid',$line); // use anonymized student id number
  [80]         $table = before($line,"\t"); $line = after($line,"\t");
  [81]         $field = $groupfield = $selectfield = before($line,"\t"); $line = after($line,"\t");
  [82]         $sequence = before($line,"\t"); $line = after($line,"\t");
  [83]         $nullable = begins($line,'NO') ? 'NOT NULL' : ''; $line = after($line,"\t");
  [84]         $type = before($line,"\t"); $line = after($line,"\t");
  [85]         $size = before($line,"\t"); if (is_numeric($size)) {$type = "$type($size)"; $line = after($line,"\t");}
  [86]         $comment = trim($line);
  [87]         if (!contains($table,'_') || !$field || !is_numeric($sequence)) continue;
  [88]         if ($prefix && !begins($table,$prefix)) continue;
  [89]         $private = contains($comment,'private') || $field===$keyname;
  [90]         if (contains($comment,'year only')) {$groupfield = "YEAR($field)"; $alias = "year_$field"; $selectfield = "$groupfield as $alias";}
  [91]         $schema[$table][$field] = array('sequence'=>$sequence,'nullable'=>$nullable,'type'=>$type,'size'=>$size,'comment'=>$comment,
  [92]             'groupfield'=>$groupfield,'alias'=>$alias,'selectfield'=>$selectfield,'private'=>$private);
  [93]         if (!$private && !contains($comment,'key')) $publicfieldcount[$table]++;
  [94]     }
  [95]     foreach ($schema as $table=>$fields) {if (!$publicfieldcount[$table]) unset($schema[$table]);}
  [96]     return $schema;
  [97] } [
Top]   make_oiea_script.php
  [98] function uc_underscore($text) {$output = ''; foreach (explode('_',$text) as $word) $output .= ucfirst($word); return $output;}
 [104] ?>

FILE: make_oiea_sql_script.php - 105 lines, 2 functions [
Top]
  [1] <?php // SQL script generation for ACC Study Group
  [2] include '_all_includes.php';
  [3] $keyname = 'personid'; // name of field to be systematically replaced in all tables containing it to ensure student anonymity
  [4] $newkeyname = 'pid';
  [5] $suppress_banner = TRUE;
  [6] $site_navigation = FALSE;
  [7] page_start('Make OIEA SQL Scripts');
  [8] print br(small(alink('Display data schema description file','oiea_data_schema.txt')));
  [9] $where = rq('where');
  [10] $table = rq('table');
  [11] $anonymous = rq1('anonymous');
  [12] $schema = fetch_oiea_data_schema($table);
  [13] print "<table cellpadding=5 width=700>\n";
  [14] if ($table) { // table-specific listing
  [15]     print "<tr><td align=center><i>Fields in </i><b>$table</b> &nbsp; " . small(alink('List All Tables')) . "</td></tr>\n";
  [16]     print "<tr><td align=center><table><tr><td>\n";
  [17]     foreach (fetch_oiea_data_schema($table) as $fields) {
  [18]         $selectfields = $groupfields = array();
  [19]         foreach ($fields as $field=>$parameters) {
  [20]             $name = "$table_$parameters[sequence]";
  [21]             $checked = rq1($name);
  [22]             if ($checked) {$selectfields[] = $parameters['selectfield']; $groupfields[] = $parameters['groupfield'];}
  [23]             $box = ($parameters['private'] || $field===$keyname) ? "&nbsp; &nbsp; &nbsp;$field" : checkbox($name,$checked,1,$field);
  [24]             print "$box &nbsp; <small>$parameters[type] &nbsp; $parameters[comment]</small><br>\n";
  [25]         }
  [26]         print "</td></tr></table\n</td></tr>\n";
  [27]         print "<tr><td align=center>" . " &nbsp; <small><i>Optional WHERE clause: </i></small>" . textbox('where',$where,40) . "</td></tr>\n";
  [28]         print "<tr><td align=center>" . commandbutton('Generate SQL to summarize table, grouping by checked fields') . "</td></tr>\n";
  [29]         $where = "FROM $table" . ($where? " WHERE $where" : "");
  [30]         $table_sql .= "\nSELECT '$table', COUNT(*) AS record_count";
  [31]         $table_sql .= ($groupfields ? "," . implode(', ',$selectfields) . ", $where GROUP BY " . implode(', ',$groupfields) : " $where") . ";\n";
  [32]     }
  [33]     print hidden('table',$table);
  [34] } else { // list all tables, with links to specific-table listings
  [35]     $copy_sql = <<<SQL
  [36] IF EXISTS(SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME = 'IDT')
  [37] DROP TABLE IDT
  [38] GO
  [39] CREATE TABLE IDT ($newkeyname int PRIMARY KEY IDENTITY, varchar(11) $keyname)
  [40] INSERT INTO IDT SELECT $keyname FROM student_main;
  [41] -- The arbitrary sequential pid values will be used to systematically replace all $keyname values in the copied tables
  [42] -- For student privacy, fields marked 'private' are excluded from the copy; birthdates are replaced by the birth year
  [43]
  [44] SQL;
  [45]     foreach ($schema as $table=>$fields) $sets[before($table,'_')][$table] = $fields; // aggregate table sets
  [46]     foreach ($sets as $set=>$tables) {
  [47]         print "<tr><td align=right><i><b>$set</b>&nbsp;table&nbsp;set</i> </td><td>";
  [48]         foreach ($tables as $table=>$fields) {
  [49]             print ' ' . alink(uc_underscore(after($table,'_')),"?table=$table");
  [50]             if ($set === 'L') {
  [51]                 $selectfields = implode(', ',array_keys($fields));
  [52]                 $lookup_sql .= "SELECT '$table',$selectfields FROM $table;\n";
  [53]             }
  [54]             $copy_sql .= "\nDROP TABLE ASG_$table;\nSELECT ";
  [55]             $copyfields = array();
  [56]             if ($fields[$keyname]) $copyfields[] = 'pid';
  [57]             foreach ($fields as $field=>$parameters) if (!$parameters['private']) $copyfields[] = $parameters['selectfield'];
  [58]             $copy_sql .= implode(', ',$copyfields) . " INTO ASG_$table FROM $table";
  [59]             if ($fields[$newkeyname]) $copy_sql .= " JOIN IDT ON IDT.$keyname=$table.$keyname";
  [60]             $copy_sql .= ";\n";
  [61]         }
  [62]         print "</td></tr>\n";
  [63]     }
  [64]     $copy_sql .= "\nDROP TABLE IDT; -- Discard $keyname translation table\n";
  [65]     print "<tr><td align=center colspan=2>" . commandbutton('Generate script for anonymized database copy') .
  [66]         spaces(10) . commandbutton('Generate script to list look-up table contents') . "</td></tr>\n";
  [67] }
  [68] print "</table>\n";
  [69] if (contains($command,'copy')) print "<br><i>SQL script to copy database, dropping identifying data</i><br>\n" . textarea('sql',$copy_sql,30,120);
  [70] if (contains($command,'look-up')) print "<br><i>SQL script to list all entries in lookup tables</i><br>\n" . textarea('sql',$lookup_sql,30,120);
  [71] if ($table_sql) print "<br><i>SQL script to count records, grouped by any checked fields</i><br>\n" . textarea('sql',$table_sql,5,80);
  [72]
  [73] page_end();
  [74] [Top]   make_oiea_sql_script.php
  [75] function fetch_oiea_data_schema($prefix='') {
  [76]     global $keyname,$newkeyname;
  [77]     $schema = $publicfieldcount = array();
  [78]     foreach (nsplit(file_get_contents('oiea_data_schema.txt')) as $line) {
  [79]         $table = before($line,"\t"); $line = after($line,"\t");
  [80]         $field = before($line,"\t"); $line = after($line,"\t");
  [81]         if ($field === $keyname) $field = $newkeyname;
  [82]         $groupfield = $selectfield = $field;
  [83]         $sequence = before($line,"\t"); $line = after($line,"\t");
  [84]         $nullable = begins($line,'NO') ? 'NOT NULL' : ''; $line = after($line,"\t");
  [85]         $type = before($line,"\t"); $line = after($line,"\t");
  [86]         $size = before($line,"\t"); if (is_numeric($size)) {$type = "$type($size)"; $line = after($line,"\t");}
  [87]         $comment = trim($line);
  [88]         if (!contains($table,'_') || !$field || !is_numeric($sequence)) continue;
  [89]         if ($prefix && !begins($table,$prefix)) continue;
  [90]         $private = contains($comment,'private');
  [91]         if (contains($comment,'year only')) {$groupfield = "YEAR($field)"; $alias = "year_$field"; $selectfield = "$groupfield as $alias";}
  [92]         $schema[$table][$field] = array('sequence'=>$sequence,'nullable'=>$nullable,'type'=>$type,'size'=>$size,'comment'=>$comment,
  [93]             'groupfield'=>$groupfield,'alias'=>$alias,'selectfield'=>$selectfield,'private'=>$private);
  [94]         if (!$private && !contains($comment,'key')) $publicfieldcount[$table]++;
  [95]     }
  [96]     foreach ($schema as $table=>$fields) {if (!$publicfieldcount[$table]) unset($schema[$table]);}
  [97]     return $schema;
  [98] } [
Top]   make_oiea_sql_script.php
  [99] function uc_underscore($text) {$output = ''; foreach (explode('_',$text) as $word) $output .= ucfirst($word); return $output;}
 [105] ?>

FILE: make_table.php - 130 lines, 3 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] page_start('Database Table Creation Script');
  [4] $tablename = rq('tablename');
  [5] // define standard field-name arrays
  [6] $always = array('enabled?','created_at','modified_at');
  [7] $sometimes = array('user_id','superuser_id','parent_id','name',"label'",'title','discussion"','commentary"');
  [8] $sql = rq('TableSQL'); // previous output
  [9] $selected_fields = array();
  [10] $previous_fields = csplit(rq('previous_fields'));
  [11] if ($_POST) {
  [12]     $script = <<<SQL
  [13] CREATE TABLE $tablename (
  [14] id int NOT NULL AUTO_INCREMENT,
  [15] SQL;
  [16]     foreach (explode(' ',str_replace(',',' ',rq('foreignkeys'))) as $field) {
  [17]         $name = nameletters_only($field);
  [18]         if ($name) {
  [19]             if (substr($name,-3) !== '_id') $name .= '_id';
  [20]             $script .= "\n `$name` int NOT NULL,";
  [21]             $selected_fields[$name] = "int";
  [22]         }
  [23]     }
  [24]     foreach (explode("\n",rq('otherfields')) as $field) {
  [25]         list($name,$type)= field_name_type($field);
  [26]         if ($name) {
  [27]             $script .= "\n `$name` $type NOT NULL,";
  [28]             $selected_fields[$name] = $type;
  [29]         }
  [30]     }
  [31]     foreach (array_merge($sometimes,$always) as $field) {
  [32]         list($name,$type) = field_name_type($field);
  [33]         if (rq1($name) && !array_key_exists($name,$selected_fields)) {
  [34]             $script .= "\n `$name` $type NOT NULL,";
  [35]             $selected_fields[$name] = '';
  [36]         }
  [37]     }
  [38]     foreach ($previous_fields as $field) {
  [39]         list($name,$type) = name_type($field);
  [40]         if (rq1($name) && !array_key_exists($name,$selected_fields)) {
  [41]             $script .= "\n `$name` $type NOT NULL,";
  [42]             $selected_fields[$name] = $type;
  [43]         }
  [44]     }
  [45]     $script .= <<<SQL
  [46]
  [47] PRIMARY KEY (id)
  [48] ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
  [49] SQL;
  [50]     $sql = "$script\n\n$sql";
  [51] }
  [52] // build table of field names based on previous output
  [53] foreach ($selected_fields as $name => $type) {if ($name && $type) $previous_fields[] = "$name $type";
  [54] print hidden('previous_fields',implode(',',$previous_fields));
  [55] $sql_type = $sql_count = $sql_name = array();
  [56] foreach ($previous_fields as $field) {
  [57]     list($name,$type) = name_type($field);
  [58]     if ($name!=='id' && !in_array($name,$always) && !in_array($name,$sometimes)) {
  [59]             $sql_count[$name]++; $sql_type[$name] = $type; $sql_name[$name] = $name;
  [60]         }
  [61]     }
  [62] }
  [63] if ($sql_name) {
  [64]     natcasesort($sql_name); // alphabetize field names
  [65]     // set qualifying usage-count threshold for listing field as a checkbox option
  [66]     $max = 0; foreach ($sql_name as $n) {$c = $sql_count[$n]; $dist[$c]++; if ($c > $max) $max = $c;}
  [67]     $sum = 0; for ($i=1; $i<=$max; $i++) {if ($dist[$i]) $sum += $dist[$i]; $cumulative[$i] = $sum;}
  [68]     $sql_list_budget = 15;
  [69]     if (count($sql_name)<$sql_list_budget) { // enough space for all previously mentioned fields
  [70]         $sql_count_threshold = 1;
  [71]     } else { // set threshold high enough to exclude less-frequent fields, if total list exceeds budget
  [72]         $n = 0; for ($k=$max; $k>0; $k--) {$sql_count_threshold = $k; if ($cumulative[$k] <= $sql_list_budget) break;}
  [73]     }
  [74] }
  [75] //
  [76] print "<table cellpadding=15><tr><td align=center>";
  [77] print br("Table Name: " . textbox('tablename',''),1);
  [78] print br("Foreign Keys: " . textbox('foreignkeys','',40),1);
  [79] print br("Other fields<br><small>(one per line, with data type)</small>") .
  [80]     br(textarea('otherfields','',5,30));
  [81] print br(commandbutton($sql ? 'Add To Script' : 'Create Script'),1);
  [82] print br("<table cellpadding=1>",1);
  [83] print "<tr>\n<td width=30>&nbsp;</td>\n<td valign=top><i>Standard Fields</i>";
  [84] foreach ($always as $field) {
  [85]     list($name,$type) = field_name_type($field);
  [86]     print "<br>\n" . checkbox($name,TRUE,1," $name");
  [87] }
  [88] foreach ($sometimes as $field) {
  [89]     list($name,$type) = field_name_type($field);
  [90]     print "<br>\n" . checkbox($name,FALSE,1," $name");
  [91] }
  [92] if ($sql_name) {
  [93]     print "</td>\n<td width=20>&nbsp;</td>\n<td valign=top><i>Previous Fields</i>";
  [94]     foreach ($sql_name as $name) if ($sql_count[$name] >= $sql_count_threshold) print br(checkbox($name,FALSE,1," $name"),1,0);
  [95] }
  [96] print "\n</td></tr>\n";
  [97] print tr(tdc("<small><b>id</b> primary key always included</small>",4));
  [98] print "</table>\n</td>\n";
  [99] print "<td align=center valign=top>\n" . textarea('TableSQL',$sql,25,50);
 [100] if ($sql) print br(alink('Clear accumulated script','?'),2,0);
 [101] print "</td></tr></table>\n";
 [102] page_end();
 [103] [Top]   make_table.php
 [104] function name_type($field) {
 [105]     $field = drop_chars($field,"'");
 [106]     $name = before($field,' ');
 [107]     $type = after($field,' ');
 [108]     return ($name && $type && strtolower($name)!=='id') ? array($name,$type) : array('','');
 [109] } [
Top]   make_table.php
 [110] function field_name_type($field) {return name_type(type_sql_field($field));} [
Top]   make_table.php
 [111] function type_sql_field($text) { // support shortcut data-type designations
 [112]     $text = trim(drop_chars($text,"`\\,[]\{\}")); // remove meta-characters from text
 [113]     if (strpos($text,' ') || $text==='') return $text; // data type is already second word of text, or empty text
 [114]     foreach (array("' varchar(50)",'# int','. float','? tinyint','" text') as $shortcut) {
 [115]         $symbol = substr($shortcut,0,1);
 [116]         if (strpos($text,$symbol) !== FALSE) return (trim(str_replace($symbol,'',$text)) . substr($shortcut,1));
 [117]     }
 [118]     foreach (array('_id int','_at datetime','_by datetime','_on date','_flag tinyint') as $shortcut) { // support standard suffixes
 [119]         $suffix = before($shortcut,' ');
 [120]         $type = after($shortcut,' ');
 [121]         if (strtolower(substr($text,-strlen($suffix))) === $suffix) return "$text $type";
 [122]     }
 [123]     return ($text . ' varchar(200)'); // default data type is mid-length string
 [124] }
 [130] ?>

FILE: math_scheduling_feedback.php - 185 lines, 5 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $sql_now = '(DATE_ADD(NOW(), INTERVAL 2 HOUR))';
  [4] $table = $svtag = 'math_scheduling_feedback';
  [5] $campuses = array('','CYP','EVC','NRG','OPC','PIN','RGC','RRC','RVS','SAC','Other');
  [6] $semesters = array('','Summer 2011','Fall 2011','Spring 2012','Summer 2012');
  [7] $statuses = array('New','Pending','Resolved');
  [8] $administrators = array('admin','mparker');
  [9] $bookmark_base = 'http://www.tlok.org/' . $_SERVER[PHP_SELF] . '#';
  [10]
  [11] register_request('command,content,parent#,cid#,edit_id#,parent_id#,logoff?');
  [12] if ($logoff) {logoff(); redirect();}
  [13] $new_button_text = 'Add new feedback about the schedule';
  [14] if ($command === $new_button_text) redirect('?parent=-1'); // convert new-comment POST into GET (button used just for prominence -- no actual form content)
  [15] $fb = fetch_feedback_parameters($parent);
  [16]
  [17] $user_email_domain = 'austincc.edu';
  [18] $author = sv("author_$svtag");
  [19] $email = author_email($author);
  [20] $administrator = in_array($author,$administrators);
  [21]
  [22] foreach ($statuses as $status) { // note any changes made in comment status
  [23]     $id = rqn($status);
  [24]     if ($id) {
  [25]         $fb = fetch_feedback_parameters($id);
  [26]         if ($fb && !same($fb['status'],$status)) {
  [27]             sql_update($table,"status='$status'",$id);
  [28]             $id = write_feedback($id,$author,$course,$campus,$semester,"[status changed to $status]",'');
  [29]             redirect();
  [30]         }
  [31]     }
  [32] }
  [33] if ($command) { // form submission by user
  [34]     if (contains($command,'Cancel')) redirect();
  [35]     if ($command === 'Log On') {
  [36]         $email = rq('email');
  [37]         if (!contains($email,'@')) $email = "$email@$user_email_domain";
  [38]         $email = extract_email($email);
  [39]         if (same($email,$system_email)) $author = 'admin';
  [40]         elseif (contains($email,$user_email_domain)) $author = alphanumeric_only(before($email,'@'));
  [41]         if (!$author) error("An email address at $user_email_domain must be supplied");
  [42]         else {
  [43]             $_SESSION["author_$svtag"] = strtolower($author);
  [44]             redirect();
  [45]         }
  [46]     } elseif ($semester) { // feedback submission
  [47]         if ($content) {
  [48]             $id = write_feedback($parent,$author,$course,$campus,$semester,$content);
  [49]             send_mail($email,'Math-schedule feedback confirmation',numberdatetime() .
  [50]                 " -- Your feedback on the math schedule has been recorded\n\n$semester $campus $course\n\n$content",'math@austincc.edu');
  [51]             redirect();
  [52]         } else $parent = 0;
  [53]     } else {error('A semester must be specified'); $edit = -1;}
  [54] }
  [55]
  [56] $maxwidth = 900;
  [57] $hide_site_banner = TRUE;
  [58] $no_mail_copy = TRUE;
  [59] $site_navigation = FALSE;
  [60] $site_css = 'document_feedback.css';
  [61] $page_font_style = 'Georgia';
  [62] if (!$author) {$title = 'Log On'; $logon = TRUE;}
  [63] else {
  [64]     if ($parent) $title = $parent>0 ? 'Remark on Feedback' : 'Provide Feedback';
  [65]     else {$title = "Schedule Feedback"; $subtitle = spaces(5) . big(commandbutton($new_button_text));}
  [66] }
  [67] $doc_text = 'Math-department feedback on ' . alink('ACC Course Schedules',"http://www6.austincc.edu/schedule/");
  [68] if ($author) $doc_text .= spaces(10) . "($author) " . small(alink('Log off','?logoff=1'));
  [69]
  [70] print page_start(); print pc($doc_text); print br(pc(big(bold($title)) . "$subtitle")); print_flash($notice);
  [71]
  [72] if ($logon) { // setup needed
  [73]     print "<br><br><table cellpadding=10 border=1><tr><td align=center>\n";
  [74]     print br(bold('ACC email address: ') . textbox('email',$email,20),1);
  [75]     print pc(small(italic("A confirming message will be sent to this email address for each feedback entry<br>[These will probably go to your spam folder until you tell your mail client differently]")));
  [76]     print pc(commandbutton('Log On'));
  [77]     print "</td></tr></table>\n";
  [78]
  [79] } elseif ($parent) { // display entry form for feedback comment
  [80]     if ($parent > 0) {
  [81]         $button = 'Remark on';
  [82]         $text = td('<b>' . short_datetime($parent_created_at) . " feedback by <i>$parent_author</i> $semester $campus $course ($parent_status)</b>" .
  [83]             paragraph($parent_content) . pc(textarea('content',$content,6,80)));
  [84]         print hidden('parent',$parent);
  [85]     } else {
  [86]         $button = 'Submit';
  [87]         $text = tdc(textarea('content',$content,10,80));
  [88]     }
  [89]     print pc("<table border=1><tr><td><table cellpadding=10 border=0>\n" . tr($text) .
  [90]         tr(tdc('Semester: ' . selectvalues('semester',$semester,$semesters) . spaces(5) .
  [91]             'Campus: ' . selectvalues('campus',$campus,$campuses) . spaces(5) .
  [92]             'Course Number: ' . textbox('course',$course,4) .
  [93]             pc(commandbutton("$button Feedback") . spaces(10) . commandbutton('Cancel'),2))) .
  [94]         "</table></td></tr></table>");
  [95]
  [96] } else { // list existing feedback
  [97]     $_SESSION["sort_$svtag"] = $sort = rq('sort',$_SESSION["sort_$svtag"]);
  [98]     $order = 'id desc'; // by default, sort with most recent first
  [99]     if ($sort === 'Semester') {$order = "semester,parent_id desc,id"; $mode = 'semester';}
 [100]     if ($sort === 'Author') {$order = "author,parent_id desc,id"; $mode = 'author';}
 [101]     if ($sort === 'Course') {$order = "course,parent_id desc,id"; $mode = 'course';}
 [102]     if ($sort === 'Campus') {$order = "campus,parent_id desc,id"; $mode = 'campus';}
 [103]     if ($sort === 'Status') {$order = "status,parent_id desc,id"; $mode = 'status';}
 [104]     $feedback = DBA($table,"1=1",$order);
 [105]     if ($feedback) {
 [106]         if ($mode) {
 [107]             foreach ($feedback as $fb) $bookmarks[$fb[$mode]]++;
 [108]             ksort($bookmarks);
 [109]             if (count($bookmarks) > 1) {
 [110]                 print pluralize(ucfirst($mode)) . ':';
 [111]                 foreach (array_keys($bookmarks) as $b) print ' ' . alink($b,"#_$b");
 [112]                 print "<br>\n";
 [113]             }
 [114]         }
 [115]         $bgcolors = array('#00FFDD','#00DDFF');
 [116]         $last_parent_id = $parent_count = 0;
 [117]         print "<table width=$maxwidth border=0><tr><td align=center><table border=1 cellpadding=3>\n";
 [118]         if (!$mode) print feedback_heading(); // not printed here for bookmark mode because header will be printed before each bookmark
 [119]         foreach ($feedback as $fb) {
 [120]             if ($mode) {
 [121]                 if ($fb['parent_id'] != $last_parent_id) {$parent_count++; $last_parent_id = $fb['parent_id'];}
 [122]                 $bg = "bgcolor='" . $bgcolors[$parent_count % 2] . "'";
 [123]                 if ($fb[$mode]!==$bookmark) {
 [124]                     $bookmark = $fb[$mode];
 [125]                     print feedback_heading("<a name='_$bookmark'>");
 [126]                     $lines = 0;
 [127]                 }
 [128]             }
 [129]             $comment_text = h($fb['content']);
 [130]             $lines += (int) (strlen($comment_text)/80) + 2;
 [131]             if ($fb['status']) {
 [132]                 $comment_text .= '<br><i><small><small> &nbsp; ' . alink('Remark on this comment',"?parent=$fb[id]");
 [133]                 if ($administrator) {
 [134]                     $comment_text .= '<br> &nbsp; <i>Change status to</i>';
 [135]                     foreach ($statuses as $status) {if ($status !== $fb['status']) $comment_text .= ' ' . alink($status,"?$status=$fb[id]");}
 [136]                 }
 [137]                 $comment_text .= '</small></small></i>';
 [138]             } elseif (!$administrator) continue; // display status-change lines only to administrators
 [139]             $text = $administrator ? td(italic($fb['status']),'top') : '';
 [140]             $bm = "<a name='C$fb[id]'>"; // bookmark to comment listing
 [141]             print tr(tdc($bm . $fb['semester'],'top') . tdc($fb['campus'],'top') . tdc($fb['course'],'top') . td($fb['author'],'top') .
 [142]                 tdc(short_datetime($fb['created_at']),'top') . td($comment_text,'top class=feedback') . $text,"$bg");
 [143]         }
 [144]         if ($lines > 20) print feedback_heading(); // repeat heading at bottom of long list
 [145]         print "</table></td></tr></table>\n";
 [146]     } else print bold('No feedback has been submitted');
 [147] }
 [148] page_end('');
 [149] [Top]   math_scheduling_feedback.php
 [150] function sort_th($tag) {return th(alink($tag,"?sort=$tag"));} [
Top]   math_scheduling_feedback.php
 [151] function feedback_heading() {
 [152]     $text = $GLOBALS['administrator'] ? sort_th('Status') : '';
 [153]     return tr(sort_th('Semester') . sort_th('Campus') . sort_th('Course') . sort_th('Author') . sort_th('Time') . th('Feedback Comment') . $text);
 [154] } [
Top]   math_scheduling_feedback.php
 [155] function author_email($author) {
 [156]     if ($author === 'admin') $email = $GLOBALS['system_email'];
 [157]     else $email = ($author ? "$author@$GLOBALS[user_email_domain]" : '');
 [158]     return $email;
 [159] } [
Top]   math_scheduling_feedback.php
 [160] function write_feedback($parent_id,$author,$course,$campus,$semester,$content,$status='New') {
 [161]     $id = sql_insert($GLOBALS['table'],'author,course,campus,semester,content,status',$author,$course,$campus,$semester,$content,$status);
 [162]     if ($parent_id == 0) $parent_id = $id;
 [163]     if ($id) sql_update($GLOBALS['table'],"created_at=$GLOBALS[sql_now],parent_id=$parent_id",$id);
 [164]     return $id;
 [165] } [
Top]   math_scheduling_feedback.php
 [166] function fetch_feedback_parameters($id) {
 [167]     global $course, $campus, $semester, $parent_id, $parent_content, $parent_author, $parent_created_at, $parent_status;
 [168]     $fb = DBR($GLOBALS['table'],max($id,0));
 [169]     if ($fb) {
 [170]         $course = $fb['course'];
 [171]         $parent_id = $fb['parent_id'];
 [172]         $parent_author = $fb['author'];
 [173]         $parent_content = $fb['content'];
 [174]         $parent_status = $fb['status'];
 [175]         $parent_created_at = $fb['created_at'];
 [176]     }
 [177]     else {$course = $campus = $semester = $parent_author = $parent_content = $parent_status = $parent_created_at = ''; $id = $parent_id = 0;}
 [178]     if (!$parent_id) $parent_id = $id;
 [179]     $course = digits_only(rq('course',$course)); if ($course) $course = substr("0000$course",-4);
 [180]     $campus = rq('campus'); if (!$campus && $fb) $campus = $fb['campus'];
 [181]     $semester = rq('semester'); if (!$semester && $fb) $semester = $fb['semester'];
 [182]     return $fb;
 [183] }
 [184] ?>
 [185]

FILE: register.php - 27 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] if (posted()) {
  [4]     $disciplines = expanded_disciplines();
  [5]     $email = rq('email');
  [6]     if ($email && $disciplines) {
  [7]         write_user_account_variables($email,array('privileges'=>'Snapshot','discipline_options'=>$disciplines));
  [8]         $_SESSION['discipline_options'] = array(); // reset previous settings
  [9]         send_mail($email,"$site_name Registration","Use this link to log on to $site_name:\nhttp://$site_domain/index.php?email=$email");
  [10]         redirect('index.php');
  [11]     }
  [12]     if (!$email) error('An email address is required for registration');
  [13]     if (!$disciplines) error('Designation of disciplines is required for registration');
  [14] }
  [15] page_start('Site Registration');
  [16] print pc(bold('Email Address: ') . textbox('email',$_SESSION['user_email'])) . ' ' . commandbutton('Register email address and discipline list');
  [17] print "<p><table border=1 cellpadding=5>\n";
  [18] print tr(tdc("<i>Check the disciplines whose schedules you may wish to view</i><br><small>(you can later change your list of designated disciplines)",2)) . "<tr><td>\n";
  [19] display_discipline_choices();
  [20] print "</td></tr></table></p>\n";
  [21] page_end();
  [27] ?>
FILE: sample_cardset.php - 43 lines, 0 functions [
Top]
  [1] <?php // create spreadsheet/mailmerge-friendly output duplicating user-supplied data with label and index fields
  [2] include '_all_includes.php';
  [3] $suppress_banner = TRUE;
  [4] $site_navigation = FALSE;
  [5] page_start('Replicate Data With Indexed Labels');
  [6]
  [7] print "<table cellpadding=5 border=1>\n";
  [8] $labels = rq('labels');
  [9] print "<tr><td align=right><i>Group Labels:</i></td><td>" . textbox('labels',$labels,30) . " <small>(comma delimited)</small></td></tr>\n";
  [10] $start = rq('start',1);
  [11] print "<tr><td align=right><i>First Index:</i></td><td>" . textbox('start',$start,3) . "</td></tr>\n";
  [12] $data = rq('data');
  [13] print "<tr><td align=right><i>Input data values:<br><small>(repeated for each label)</small></i></td><td>" . textarea('data',$data,25,40) . "</td></tr>\n";
  [14] $count = 0;
  [15] if ($data) {
  [16]     $output = "Index\tLabel\tValue\n";
  [17]     foreach (csplit(str_replace("\t",",",$labels)) as $label) {
  [18]         $label = trim($label);
  [19]         if ($label) {
  [20]             $index = $start;
  [21]             foreach (nsplit(str_replace("\t","\n",$data)) as $datum) {
  [22]                 $datum = trim($datum);
  [23]                 if ($datum) {
  [24]                     $output .= "$index\t$label\t$datum\n";
  [25]                     if (is_numeric($start)) $index++;
  [26]                     $count++;
  [27]                 }
  [28]             }
  [29]         }
  [30]     }
  [31] }
  [32] print "<tr><td align=center colspan=2>" . commandbutton('Create Output') . "</td></tr>\n";
  [33] if ($count) print "<tr><td align=right><i>Output data values:</i><br><small>(copy to spreadsheet)</small></td><td>" .
  [34]     textarea('output',$output,25,$count+1) . "</td></tr>\n";
  [35] print "</table>\n";
  [36] page_end();
  [37]
  [43] ?>
FILE: schedule_changes.php - 121 lines, 2 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $filesets = $semester_snapshots = $discipline_snapshots = array();
  [4] foreach (schedule_snapshots() as $filename) {
  [5]     $schedule = datenamedfile_prefix($filename);
  [6]     $semester = phrase($schedule,-2);
  [7]     $filesets[$schedule][] = $filename;
  [8]     $semester_snapshots[phrase($schedule,-2)]++;
  [9]     $discipline_snapshots[phrase($schedule,0,-2)]++;
  [10] }
  [11] $disciplines = expanded_disciplines(array_keys($discipline_snapshots));
  [12] $semesters = array_keys($semester_snapshots);
  [13] if (posted() && !$command) {
  [14]     foreach ($_POST as $name => $value) {
  [15]         $semester_name = semester_code_to_name($value);
  [16]         if ($semester_name && $name!=='schedule') $schedule = "$name $semester_name";
  [17]     }
  [18] } else $schedule = rq('schedule');
  [19] page_start("Compare " . ($schedule ? $schedule : 'Schedule') . " Snapshots");
  [20] if (count($filesets) == 0) print "NO SCHEDULE SNAPSHOTS ARE YET AVAILABLE";
  [21] else {
  [22]     if (!$schedule) { // if choices, require schedule specification
  [23]         print "<table cellpadding=3 border=1>\n";
  [24]         print tr(tdc("<b>Select Discipline & Semester</b>"));
  [25]         print "<tr><td><table border=0 cellpadding=3>\n";
  [26]         $choices = FALSE;
  [27]         $discipline_terms = array();
  [28]         foreach ($filesets as $schedule => $fileset) { // groups of snapshots for same discipline and semester
  [29]             if (count($fileset) > 1) {
  [30]                 $choices = TRUE;
  [31]                 $discipline_terms[phrase($schedule,0,-2)][] = semester_name_to_term_number(phrase($schedule,-2));
  [32]             }
  [33]             else $only_one[] = "$schedule <small>(" . date('n/j/y',datetime_from_filename($fileset[0])) . ")</small>";
  [34]         }
  [35]         ksort($discipline_terms); // order list by discipline
  [36]         foreach ($discipline_terms as $discipline => $terms) {
  [37]             print '<tr><td>';
  [38]             sort($terms); // order by term-number
  [39]             foreach ($terms as $term_number) {
  [40]                 print commandbutton(substr(term_number_to_code($term_number),-3),$discipline);
  [41]             }
  [42]             print "</td><td>$discipline</td></tr>\n";
  [43]         }
  [44]         print tr(th($choices ? commandbutton('Specify Schedule') : "<b>No schedule has more than one snapshot</b>"));
  [45]         print br("</table></td></tr>\n");
  [46]         if ($only_one) print tr(td(br_list('<i><b>Only one version has been saved for:</b></i>',$only_one,3)));
  [47]         print "</table>\n";
  [48]         if (count($filesets) > 10) $site_navigation = TRUE;
  [49]     } else { // specific semester selected
  [50]         print "<table cellpadding=3 border=1>\n";
  [51]         $fileset = $filesets[$schedule];
  [52]         $newfile = rq('newfile',$fileset[0]);
  [53]         $oldfile = rq('oldfile',$fileset[1]);
  [54]         print tr(tdc("<b>Select versions to compare</b>",4));
  [55]         print "<tr><td><table border=0 cellpadding=3>\n";
  [56]         print tr(th('New') . th('Old') . th('Schedule Version'));
  [57]         foreach ($fileset as $filename) {
  [58]             $file_link = alink(schedule_date_format(datetime_from_filename($filename)),$filename);
  [59]             print tr(td(radio('newfile',$filename,$newfile,' ')) . td(radio('oldfile',$filename,$oldfile,' ')) . td($file_link));
  [60]         }
  [61]         print tr(tdc(commandbutton('Compare Selected Snapshots'),3));
  [62]         if (count($filesets) > 1) print tr(tdc(alink('<small>Choose a different schedule</small>'),3));
  [63]         print br("</table></td></tr></table>");
  [64]         print hidden('schedule',$schedule);
  [65]     }
  [66]     if (count($fileset) > 10) $site_navigation = TRUE;
  [67] }
  [68] // process the indicated schedules if form has been posted
  [69] if (begins($command,'Compare')) {
  [70]     if ($oldfile === $newfile) print br("DISTINCT SNAPSHOTS MUST BE CHOSEN");
  [71]     else if ($oldfile && $newfile) { // valid snapshot choices, so compare them
  [72]         $newinfo = schedule_comparison_info($newfile);
  [73]         $oldinfo = schedule_comparison_info($oldfile);
  [74]         foreach ($newinfo as $key => $info) {if (!$oldinfo[$key]) $added[$key] = $info;}
  [75]         foreach ($oldinfo as $key => $info) {if (!$newinfo[$key]) $dropped[$key] = $info;}
  [76]         foreach ($newinfo as $key => $info) {
  [77]             if ($info === $oldinfo[$key]) $unchanged++;
  [78]             else if (!$added[$key]) $changed[$key] = "\n" . $oldinfo[$key] . "\n" . $info; // blank line before pair
  [79]         }
  [80]         print br("<big><b>$schedule</b></big>");
  [81]         $before = schedule_date_format(datetime_from_filename($oldfile));
  [82]         $after = schedule_date_format(datetime_from_filename($newfile));
  [83]         if ($unchanged > 0) print br("<b>" . plural($unchanged,'section was','sections were') .
  [84]             " unchanged</b> between $after and $before",1);
  [85]         print_changes($added,'added',"between $before and $after");
  [86]         print_changes($dropped,'dropped',"between $before and $after");
  [87]         print_changes($changed,'changed',"between $before (upper row) and $after (lower row)");
  [88]         $site_navigation = TRUE;
  [89]     } else if ($oldfile || $newfile) print br("CHOOSE BOTH A NEW AND AN OLD SNAPSHOT");
  [90] }
  [91] page_end();
  [92] [Top]   schedule_changes.php
  [93] function print_changes($array,$mode,$period) {
  [94]     if (!$array) return;
  [95]     $rows = count($array);
  [96]     if ($mode === 'changed') $rows *= 3; // change records are multi-line
  [97]     $rows++; // allow for field-name header row
  [98]     if ($rows > 20) $rows = 20; // limit height of textarea
  [99]     print br(plural(count($array),'section was','sections were') . " <b>$mode</b> $period",1);
 [100]     $text = "Dept\tCourse\tSection\tType\tLimit\tSynonym\tLocation\tDays\tStart\tEnd\tInstructor\tSession\n" .
 [101]         implode("\n",$array) . "\n";
 [102]     if (count($array)) print textarea($mode,$text,$rows,120,FALSE); // field-name line, then all the info lines
 [103] } [
Top]   schedule_changes.php
 [104] function schedule_comparison_info($filename) { // get info, then select some fields & combine them into a tab-delimited comparison record
 [105]     if (!file_exists("./$filename")) return array();
 [106]     $text = file_get_contents("./$filename");
 [107]     $schedule_info = extract_schedule_info($text);
 [108]     $comparison_info = array();
 [109]     foreach ($schedule_info as $v) {
 [110]         if ($v['Taken'] === 'killed') $v['Limit'] = 'killed'; // because Taken is not being used in the comparisons
 [111]         $key = "@$v[Synonym]";
 [112]         $comparison_info[$key] = "$v[Dept]\t#$v[Number]\t$v[Section]\t$v[Type]\t$v[Limit]\t$v[Synonym]\t$v[Location]\t$v[Days]\t$v[Start]\t$v[End]\t$v[Instructor]\t$v[Session]";
 [113]     }
 [114]     return $comparison_info;
 [115] }
 [121] ?>

FILE: schedule_copy_to_spreadsheet.php - 27 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_text = rq("schedule_text");
  [4] page_start('ACC schedule copy => spreadsheet');
  [5] print pc("Paste a copy of an " . alink('old ACC schedule page','http://www.austincc.edu/mparker/tools/oldschedules.htm') .
  [6]     " into the text area below, press 'Convert', <br>then copy the result to a spreadsheet. &nbsp; <small>(" .
  [7]     alink('How to copy','copy_instructions.php'). ")</small>");
  [8] print br(textarea('schedule_text',$schedule_text,10,120,FALSE));
  [9] print br("<p align=center>" . commandbutton("Convert Schedule To Spreadsheet") . "</p>");
  [10] $schedule_info = extract_schedule_info($schedule_text);
  [11] if ($schedule_info) {
  [12]     $version = get_schedule_version_datetext($schedule_text);
  [13]     $semester = get_schedule_semester($schedule_text);
  [14]     $discipline = get_schedule_discipline($schedule_text);
  [15]     print textarea_head('spreadsheet_text',15,120,FALSE);
  [16]     print schedule_heading('',$version,$semester,$discipline);
  [17]     foreach ($schedule_info as $section) print schedule_row($section);
  [18]     print br('</textarea>');
  [19]     $site_navigation = TRUE;
  [20] }
  [21] page_end();
  [27] ?>
FILE: schedule_courses.php - 55 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Scheduled Courses');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $fields = array('Course','Type','Campus','Hour','Days','Minutes','Remain','Taken','Limit','Session','Instructor');
  [6]     foreach ($schedule_info as $discipline => $semester_info) {
  [7]         foreach ($semester_info as $semester => $section_info) {
  [8]             foreach ($section_info as $section) {
  [9]                 $course = $section['Course'];
  [10]                 if ($section['Remain'] === 'killed') {$courses[$course]['killed']++; continue;}
  [11]                 $courses[$course]['Enrollment'] += $section['Taken'];
  [12]                 $courses[$course]['Empty'] += max($section['Limit'] - $section['Taken'], 0);
  [13]                 $courses[$course]['Sections']++;
  [14]                 $courses[$course]['Taken'][$section['Taken']]++;
  [15]                 $courses[$course]['Remain'][$section['Remain']]++;
  [16]                 $courses[$course]['Campus'][$section['Campus']]++;
  [17]                 $courses[$course]['Instructor'][$section['Instructor']]++;
  [18]             }
  [19]         }
  [20]     }
  [21]     ksort($courses);
  [22]     print "<p align=center><b><i>Courses</i></b>";
  [23]     foreach (chunked_array($courses,10) as $row_of_courses) {
  [24]         print "<br>\n";
  [25]         foreach ($row_of_courses as $course => $info) print " &nbsp;<a href='#$course'>$course</a>&nbsp; ";
  [26]     }
  [27]     print "</p>\n<table border=1 cellpadding=5>\n";
  [28]     foreach ($courses as $course => $info) {
  [29]         if ($info['Sections']) {
  [30]             $text = plural($info['Sections'],'section');
  [31]             if ($info['killed']) $text .= " (plus $info[killed] killed)";
  [32]             $text .= " with " . plural($info['Enrollment'],'student');
  [33]             if ($info['Sections']<2) $text .= " ($info[Empty] empty)";
  [34]             else $text .= " (avg " . round($info['Enrollment']/$info['Sections'],1) . " students, " .
  [35]                 round($info['Empty']/$info['Sections'],1) . " empty) by " .
  [36]                 plural(count($info['Instructor']),'instructor') .
  [37]                 " at " . plural(count($info['Campus']),'campus','campuses');
  [38]         } else $text = plural($info['killed'],'section') . ' killed, none offered';
  [39]         print "<tr><td><a name='$course'><b>$course:</b> $text &nbsp; $top_link<br>\n";
  [40]         if (count($info['Taken']) > 1) {
  [41]             print distribution_table('Section Sizes',$info['Taken'],1);
  [42]             print distribution_table('Empty Seats',$info['Remain'],1);
  [43]         }
  [44]         print "</td></tr>\n";
  [45]     }
  [46]     print "</table><br>\n";
  [47]     $site_navigation = TRUE;
  [48] }
  [49] page_end();
  [55] ?>
FILE: schedule_discipline_groups.php - 34 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] privilege_required('Administrator');
  [4] $group = rq('group');
  [5] $disciplines = rq_array('disciplines');
  [6] $filename = discipline_group_filename($group);
  [7] if (contains($command,'Delete')) {if (file_exists($filename)) unlink($filename); redirect();}
  [8] else if ($disciplines) {
  [9]     if ($group) {
  [10]         file_write_contents($filename,"$group\n" . njoin(array_keys($disciplines)));
  [11]         notice("Definition saved for discipline group <i>$group</i>");
  [12]         redirect();
  [13]     }
  [14]     else error('A group name must be provided');
  [15] }
  [16] page_start('Manage Discipline Groups',alink('Add new group','?group=new'));
  [17] if ($group) display_discipline_choices($group,TRUE);
  [18] else {
  [19]     $groups = get_discipline_groups();
  [20]     if ($groups) {
  [21]         print br() . table_begin(10) . tr(tdc('<i>Discipline Groups</i>'));
  [22]         print "<tr><td>\n";
  [23]         foreach ($groups as $name => $ids) print br(small(alink('Edit',"?group=" . urlencode($name))) . " &nbsp; $name");
  [24]         print "</td></tr>$table_end";
  [25]     }
  [26] }
  [27] $site_navigation = TRUE;
  [28] page_end();
  [34] ?>
FILE: schedule_emails.php - 85 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $emails = rq_array('emails');
  [4] if (!$emails) {
  [5]     $schedule_info = extract_schedule_information('Get Faculty Emails');
  [6]     if ($schedule_info) { // schedule contents ready to analyze
  [7]         print hidden_rq('semesters','disciplines');
  [8]         // provide form for filter parameters
  [9]         $campuses = cjoin(csplit(strtoupper(rq('campuses'))));
  [10]         foreach (csplit(rq('courses')) as $course) $courses[] = strtoupper(letters_only($course) . ' ' . digits_only($course));
  [11]         $courses_text = cjoin($courses);
  [12]         $days = cjoin(csplit(strtoupper(rq('days'))));
  [13]         $earliest = time24(rq('earliest')); $earliest_text = time12($earliest);
  [14]         $latest = time24(rq('latest')); $latest_text = time12($latest);
  [15]         $times = $earliest || $latest;
  [16]         print table_begin(5,-3) . tr(tdc('<b>Specify Filters</b> <small>(separate multiple entries with commas)</small>',2)) .
  [17]             tr(tdr('Campuses: ' . textbox('campuses',$campuses)) .
  [18]             td(' &nbsp; Courses: ' . textbox('courses',$courses_text))) .
  [19]             tr(tdr('Days: ' . textbox('days',$days) .
  [20]                 td(' &nbsp; Start between ' . textbox('earliest',$earliest_text,6) . ' and ' . textbox('latest',$latest_text,6))) .
  [21]             tr(tdc(commandbutton('Filter Again'),2))) . "$table_end<br>\n";
  [22]         // use the filter parameters to drop sections from the selected schedules
  [23]         foreach ($schedule_info as $discipline => $semester_info) {
  [24]             foreach ($semester_info as $semester => $section_info) {
  [25]                 foreach ($section_info as $key => $section) {
  [26]                     $instructor = $section['Instructor'];
  [27]                     $instructor_classes[$instructor][$key] = nospace("$section[Campus]/$section[Course]($section[Days]$section[Start])");
  [28]                     if ($campuses) {if (strpos($campuses,$section['Campus']) === FALSE) continue;}
  [29]                     if ($courses) {
  [30]                         $match = FALSE;
  [31]                         foreach ($courses as $course) {if (strpos($section[Course],$course) !== FALSE) $match = TRUE;}
  [32]                         if (!$match) continue;
  [33]                     }
  [34]                     if ($days) {if (contains(",$days,",",$section[Days],") === FALSE) continue;}
  [35]                     if ($times) {if ($section['Time'] && (($earliest && $section['Time']<$earliest) || ($latest && $section['Time']>$latest))) continue;}
  [36]                     if (same($instructor,'Staff')) continue;
  [37]                     if ($section['Email']) $instructor_emails[$instructor] = $section['Email'];
  [38]                 }
  [39]             }
  [40]         }
  [41]         if ($instructor_emails) {
  [42]             $count = count($instructor_emails);
  [43]             ksort($instructor_emails);
  [44]             print br("<a href=\"mailto:?bcc=" . implode(', ',$instructor_emails) . "\"><big>Faculty email addresses</big></a>");
  [45]             if ($count >= 20) {
  [46]                 $end = 0;
  [47]                 foreach (chunked_array($instructor_emails,20,FALSE) as $chunk) {
  [48]                     $start = $end + 1;
  [49]                     $end += count($chunk);
  [50]                     print " <a href=\"mailto:?bcc=" . implode(', ',$chunk) . "\">$start-$end</a>&nbsp;" ;
  [51]                 }
  [52]                 print "<br>\n";
  [53]             }
  [54]             if ($count > 10) $count = 10;
  [55]             print "<table border=0 cellpadding=0><tr>\n";
  [56]             print tr(td('<br>To accommodate different email programs, each textarea contains the full list but has different separators',5));
  [57]             print td(textarea('email_list',implode("\n",$instructor_emails),$count,30)) . td('&nbsp;');
  [58]             print td(textarea('email_list',implode(", ",$instructor_emails),$count,30)) . td('&nbsp;');
  [59]             print td(textarea('email_list',implode(", \n",$instructor_emails),$count,30));
  [60]             print "</tr></table>\n";
  [61]             print br('Spreadsheet-ready information on scheduled instructors') . textarea_head('instructors',10,80,FALSE);
  [62]             foreach ($instructor_emails as $instructor=>$email) {
  [63]                 print "$instructor\t$email";
  [64]                 foreach ($instructor_classes[$instructor] as $class) print "\t$class";
  [65]                 print "\n";
  [66]             }
  [67]             print "</textarea>\n";
  [68]             print "<table cellpadding=3 width=700>\n" . tr(th('Instructor') . th('Sections'));
  [69]             foreach ($instructor_emails as $instructor => $email) {
  [70]                 $checked = !$emails || isset($emails[$instructor]);
  [71]                 print tr(td(checkbox("email[$instructor]",TRUE,$email,small(mlink($instructor,$email))),'nowrap') .
  [72]                     td(small(implode(' ',$instructor_classes[$instructor]))));
  [73]             }
  [74]             print "</table><br>\n";
  [75]         }
  [76]     }
  [77]     $site_navigation = TRUE;
  [78] }
  [79] page_end();
  [85] ?>
FILE: schedule_enrollment.php - 57 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Course Enrollment');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $fields = array('Course','Section','Type','Remain','Taken','Limit','Synonym','Location','Days','Times','Instructor'); // shorten standard field list
  [6]     $session_sections = array();
  [7]     foreach ($schedule_info as $discipline => $semester_info) {
  [8]         foreach ($semester_info as $semester => $section_info) {
  [9]             foreach ($section_info as $key => $section) {
  [10]                 $session = before_with($section['Session'],'Session');
  [11]                 if (contains($session,'Session')) $session_sections[$session][] = $section;
  [12]             }
  [13]         }
  [14]     }
  [15]     print "<table border=1 cellpadding=10>";
  [16]     $sessions = array_keys($session_sections);
  [17]     foreach ($session_sections as $session => $sections) {
  [18]         print "<tr><td align=center><a name='" . bookmark($session) . "'><p><b>$session</b> (" . plural(count($sections),'section') . ')';
  [19]         foreach ($sessions as $s) if (!same($s,$session)) print ' &nbsp; ' . alink($s,'#' . bookmark($s));
  [20]         print " &nbsp; &nbsp; $top_link</p><br>\n";
  [21]         $takens = array_vector($sections,'Taken');
  [22]         array_multisort($takens,$sections);
  [23]         $taken_distribution = $remain_distribution = $limit_distribution = array();
  [24]         foreach ($sections as $section) {
  [25]             if ($section['Limit']) {
  [26]                 $taken_distribution[$section['Taken']]++;
  [27]                 $remain_distribution[$section['Limit'] - $section['Taken']]++;
  [28]                 $limit_distribution[$section['Limit']]++;
  [29]             }
  [30]         }
  [31]         print distribution_table('Enrollment',$taken_distribution,1);
  [32]         print distribution_table('Empty&nbsp;Seats',$remain_distribution,1);
  [33]         print "<p>Section class limits:";
  [34]         ksort($limit_distribution);
  [35]         foreach ($limit_distribution as $limit => $count) print " <b>$count</b>@$limit";
  [36]         print "</p><br>\n";
  [37]         print "<table border=1 cellpadding=3>\n";
  [38]         print table_headings($fields);
  [39]         foreach ($sections as $s) {
  [40]             $times = $s['Start'] ? "$s[Start]-$s[End]" : '&nbsp;';
  [41]             $days = $s['Days'] ? $s['Days'] : '&nbsp;';
  [42]             print "<tr><td>$s[Course]</td><td align=center>$s[Section]</td><td align=center>$s[Type]</td>" .
  [43]                 "<td align=center>$s[Remain]</td><td align=center><b>$s[Taken]</b></td><td align=center>$s[Limit]</td>" .
  [44]                 "<td>$s[Synonym]</td><td>$s[Location]</td><td>$days</td><td>$times</td><td>$s[Instructor]</td></tr>\n";
  [45]         }
  [46]         print "</table>\n</td></tr>\n";
  [47]     }
  [48]     print "</table>\n<br>$top_link\n";
  [49]     $site_navigation = TRUE;
  [50] }
  [51] page_end();
  [57] ?>
FILE: schedule_enrollment_old.php - 53 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Course Enrollment');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $fields = array('Course','Section','Type','Remain','Taken','Limit','Synonym','Location','Days','Times','Instructor'); // shorten standard field list
  [6]     foreach ($schedule_info as $discipline => $semester_info) {
  [7]         foreach ($semester_info as $semester => $section_info) {
  [8]             foreach ($section_info as $key => $section) $session_sections[before_with($section['Session'],'Session')][] = $section;
  [9]         }
  [10]     }
  [11]     print "<table border=1 cellpadding=10>";
  [12]     $sessions = array_keys($session_sections);
  [13]     foreach ($session_sections as $session => $sections) {
  [14]         print "<tr><td align=center><a name='" . bookmark($session) . "'><p><b>$session</b> (" . plural(count($sections),'section') . ')';
  [15]         foreach ($sessions as $s) if (!same($s,$session)) print ' &nbsp; ' . alink($s,'#' . bookmark($s));
  [16]         print " &nbsp; &nbsp; $top_link</p><br>\n";
  [17]         $takens = array_vector($sections,'Taken');
  [18]         array_multisort($takens,$sections);
  [19]         $taken_distribution = $remain_distribution = $limit_distribution = array();
  [20]         foreach ($sections as $section) {
  [21]             if ($section['Limit']) {
  [22]                 $taken_distribution[$section['Taken']]++;
  [23]                 $remain_distribution[$section['Limit'] - $section['Taken']]++;
  [24]                 $limit_distribution[$section['Limit']]++;
  [25]             }
  [26]         }
  [27]         print distribution_table('Enrollment',$taken_distribution,1);
  [28]         print distribution_table('Empty&nbsp;Seats',$remain_distribution,1);
  [29]         print "<p>Section class limits:";
  [30]         ksort($limit_distribution);
  [31]         foreach ($limit_distribution as $limit => $count) print " <b>$count</b>@$limit";
  [32]         print "</p><br>\n";
  [33]         print "<table border=1 cellpadding=3>\n";
  [34]         print table_headings($fields);
  [35]         foreach ($sections as $s) {
  [36]             $times = $s['Start'] ? "$s[Start]-$s[End]" : '&nbsp;';
  [37]             $days = $s['Days'] ? $s['Days'] : '&nbsp;';
  [38]             print "<tr><td>$s[Course]</td><td align=center>$s[Section]</td><td align=center>$s[Type]</td>" .
  [39]                 "<td align=center>$s[Remain]</td><td align=center><b>$s[Taken]</b></td><td align=center>$s[Limit]</td>" .
  [40]                 "<td>$s[Synonym]</td><td>$s[Location]</td><td>$days</td><td>$times</td><td>$s[Instructor]</td></tr>\n";
  [41]         }
  [42]         print "</table>\n</td></tr>\n";
  [43]     }
  [44]     print "</table>\n<br>$top_link\n";
  [45]     $site_navigation = TRUE;
  [46] }
  [47] page_end();
  [53] ?>
FILE: schedule_faculty.php - 101 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Scheduled Faculty');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $instructors = array();
  [6]     foreach ($schedule_info as $discipline => $semester_info) {
  [7]         foreach ($semester_info as $semester => $section_info) {
  [8]             foreach ($section_info as $section) {
  [9]                 $course = $section['Course'];
  [10]                 $instructor = $section['Instructor'];
  [11]                 $campus = $section['Campus'];
  [12]                 // compute course hours from course number
  [13]                 $level = num(substr($course,5,1)); // 0 or 1 or 2
  [14]                 $sch = num(substr($course,6,1)); // 1 or 2 or 3 or 4
  [15]                 $leh = $sch; // default case
  [16]                 if (in_array($course,array('MATD 0330','MATD 0370','MATD 0390'))) $leh = 4; // allow for discounted developmental courses
  [17]                 if ($level==0 and $sch==1) $leh = 1.5; // allow for developmental labs
  [18]                 if ($course === 'MATD 0011') {$sch = 1; $leh = 1.5;} // special-case developmental-math lab
  [19]                 $killed = ($section['Remain']==='killed' || $section['Limit']==0);
  [20]                 if (!$killed && !same($instructor,'Staff')) { // collect extracted values into facultyname-indexed arrays
  [21]                     $days_time = "$section[Days] $section[Begin]-$section[End]";
  [22]                     $overlap = $section['Days'] && isset($class_time[$instructor][$days_time]);
  [23]                     if ($overlap) {
  [24]                         $overlaps[$instructor]++;
  [25]                     } else {
  [26]                         $sections[$instructor]++;
  [27]                         $limits[$instructor] += $section['Limit'];
  [28]                         $limits_leh[$instructor] += $section['Limit'] * ($section['Taken'] ? $leh : 0);
  [29]                         $lehs[$instructor] += $leh;
  [30]                         $schs[$instructor] += $sch;
  [31]                         $section_count++;
  [32]                     }
  [33]                     $class_time[$instructor][$days_time]++;
  [34]                     $instructors[$instructor] = $instructor;
  [35]                     $enrolls[$instructor] += $section['Taken'];
  [36]                     $enrolls_leh[$instructor] += $section['Taken'] * $leh;
  [37]                     $syllabuses[$instructor] = $syllabus;
  [38]                     $courses[$instructor] .= substr($course,-4) . "($campus) ";
  [39]                     $instructor_campuses[$instructor][$campus]++;
  [40]                     $taken_total += $section['Taken'];
  [41]                     $limit_total += $section['Limit'];
  [42]                 } else {
  [43]                     $row = schedule_row($section);
  [44]                     if ($killed) $killedsections[] = $row; else $staffsections[] = $row;
  [45]                 }
  [46]             }
  [47]         }
  [48]     }
  [49]     sort($instructors);
  [50]     $text = "Secs\tSCH\tLEH\tEnroll\tSize\tLimit%\tInstructor\tCourses\n";
  [51]     print "<br><i>Load tabulated for " . plural(count($instructors),'instructor') . " (" . plural($section_count,'section') .
  [52]         " - average size " . quotient($taken_total,$section_count,1) . ", " . quotient(100*$taken_total,$limit_total) . "% of limits)</i><br>\n";
  [53]     foreach ($instructors as $i) {
  [54]         $percent = quotient(100*$enrolls_leh[$i],$limits_leh[$i]);
  [55]         $text .= implode("\t",array($sections[$i],$schs[$i],$lehs[$i],$enrolls[$i],
  [56]             quotient($enrolls[$i],$sections[$i],1),"$percent%",$i,' Courses: ' . $courses[$i])) . "\n";
  [57]     }
  [58]     print textarea('faculty_spreadsheet_text',$text,15,120,FALSE) . "<br><br>\n";
  [59]     $site_navigation = TRUE;
  [60] }
  [61] if ($staffsections) {
  [62]     print "<i>" . plural(count($staffsections),'section is','sections are') . " currently listed as 'STAFF'</i><br>\n";
  [63]     print textarea('staff_sections',schedule_heading() . implode('',$staffsections),10,120,FALSE) . "<br>\n";
  [64] }
  [65] if ($killedsections) {
  [66]     print "<i>" . plural(count($killedsections),'section is','sections are') . " listed as killed</i><br>\n";
  [67]     print textarea('staff_sections',schedule_heading() . implode('',$killedsections),10,120,FALSE) . "<br>\n";
  [68] }
  [69] if ($instructor_campuses) {
  [70]     ksort($instructor_campuses);
  [71]     print pc(small('All campuses') . spaces(10) . italic('Instructors and their campuses') . spaces(10) . small('Main campus'));
  [72]     print "<table cellpadding=3><tr><td>" .     textarea_head('staff_campuses',3,40) . "Campus\tInstructor\n";
  [73]     $maincampuses = textarea_head('staff_main_campuses',3,40) . "Campus\tInstructor\n";
  [74]     foreach ($instructor_campuses as $instructor => $campuses) {
  [75]         arsort($campuses);
  [76]         $maincampuses .= key($campuses) . "\t$instructor\n";
  [77]         foreach ($campuses as $campus => $count) print "$campus\t$instructor\n";
  [78]     }
  [79]     print "</textarea></td>\n<td width=50>&nbsp;</td><td>$maincampuses</textarea></td></tr>\n</table><br>\n";
  [80] }
  [81] if ($instructors) {
  [82]     print '<br>' . site_navigation();
  [83]     foreach ($instructors as $instructor) $limit_percent[$instructor] = quotient(100*$enrolls_leh[$instructor],$limits_leh[$instructor],0);
  [84]     asort($limit_percent);
  [85]     print "<br><table border=1>\n";
  [86]     $count = count($limit_percent);
  [87]     foreach ($limit_percent as $instructor => $percent) {
  [88]         if ((($count-count($limit_percent)) % 25) == 0)     print tr(th('Rank') . th('Limit %') . th('Sections') . th('Students') . th('&nbsp; LEH &nbsp;') . th('&nbsp; SCH &nbsp;') . th('Instructor'));
  [89]         if ($percent > 0) print tr(tdc(small($count)) . tdc("$percent% ") . tdc($sections[$instructor]) .
  [90]             tdc($enrolls[$instructor]) . tdc($lehs[$instructor]) . tdc($schs[$instructor]) . td("&nbsp; $instructor"));
  [91]         $count--;
  [92]     }
  [93]     print "</table>\n";
  [94] }
  [95] page_end();
 [101] ?>
FILE: schedule_filter.php - 47 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Filter Scheduled Sections');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     print hidden_rq('semesters','disciplines');
  [6]     // provide form for filter parameters
  [7]     $campuses = cjoin(csplit(strtoupper(rq('campuses'))));
  [8]     foreach (csplit(rq('courses')) as $course) $courses[] = strtoupper(letters_only($course) . ' ' . digits_only($course));
  [9]     $courses_text = cjoin($courses);
  [10]     $days = cjoin(csplit(strtoupper(rq('days'))));
  [11]     $earliest = timeACC(rq('earliest')); $earliest_text = time12($earliest);
  [12]     $latest = timeACC(rq('latest')); $latest_text = time12($latest);
  [13]     $times = $earliest || $latest;
  [14]     print table_begin(5,-3) . tr(tdc('<b>Specify Filters</b> <small>(separate multiple entries with commas)</small>',2)) .
  [15]         tr(tdr('Campuses: ' . textbox('campuses',$campuses)) .
  [16]         td(' &nbsp; Courses: ' . textbox('courses',$courses_text))) .
  [17]         tr(tdr('Days: ' . textbox('days',$days) .
  [18]             td(' &nbsp; Start between ' . textbox('earliest',$earliest_text,6) . ' and ' . textbox('latest',$latest_text,6))) .
  [19]         tr(tdc(commandbutton('Filter Again'),2))) . "$table_end<br>\n";
  [20]     $output = array();
  [21]     // use the filter parameter to drop sections from the selected schedules
  [22]     foreach ($schedule_info as $discipline => $semester_info) {
  [23]         foreach ($semester_info as $semester => $section_info) {
  [24]             foreach ($section_info as $section) {
  [25]                 if ($campuses) {if (strpos($campuses,$section['Campus']) === FALSE) continue;}
  [26]                 if ($courses) {
  [27]                     $match = FALSE;
  [28]                     foreach ($courses as $course) {if (strpos($section[Course],$course) !== FALSE) $match = TRUE;}
  [29]                     if (!$match) continue;
  [30]                 }
  [31]                 if ($days) {if (contains(",$days,",",$section[Days],") === FALSE) continue;}
  [32]                 if ($times) {if ($section['Time'] && (($earliest && $section['Time']<$earliest) || ($latest && $section['Time']>$latest))) continue;}
  [33]                 $output[] = schedule_row($section); // save rows that pass all filters for output
  [34]             }
  [35]         }
  [36]     }
  [37]     print br(italic(plural(count($output),'section meets','sections meet') . " the selection criteria"));
  [38]     print br(textarea('sections',schedule_heading() . implode('',$output),min(count($output)+2,15),120,FALSE),0,2);
  [39]     $site_navigation = TRUE;
  [40] }
  [41] page_end();
  [47] ?>
FILE: schedule_frequencies.php - 44 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Frequency of Schedule Elements');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $fields = array('Course','Type','Campus','Days','Time','Minutes','Hour','Remain','Taken','Limit','TSI','Prereq','Instructor','Session','Discipline','Semester');
  [6]     $allcounts = array();
  [7]     foreach ($schedule_info as $discipline => $semester_info) {
  [8]         foreach ($semester_info as $semester => $section_info) {
  [9]             foreach ($section_info as $section) {
  [10]                 foreach ($fields as $field) {$allcounts[$field]["~" . $section[$field]]++;} // prefix ~ to avoid number-index issues
  [11]             }
  [12]         }
  [13]     }
  [14]     $fields_link = "<small>[<a href='#Fields'>Fields</a>]</small>";
  [15]     print "<table border=1 cellpadding=5>\n";
  [16]     // print leftmost column of field names, with links to field value-count columns
  [17]     print "<tr><td valign=top nowrap=1><a name='Fields'><b>Fields:</b><br><table border=0 cellpadding=2>\n";
  [18]     foreach($fields as $field) print tr(td("<a href='#$field'>$field</a>"));
  [19]     print tr(td("<br>$top_link"));
  [20]     print "</table></td><td valign=top nowrap>\n";
  [21]     // print a value-count column for each field
  [22]     foreach($fields as $field) {
  [23]         print "<b>$field</b><br>$fields_link<br><table border=0 cellpadding=2>\n";
  [24]         $counts = $allcounts[$field];
  [25]         $values = array_keys($counts);
  [26]         natsort($values);
  [27]         foreach ($values as $value) {
  [28]             $count = $counts[$value];
  [29]             $value = substr($value,1);
  [30]             print tr(tdr("<b>$count</b> ",'nowrap') . td(" $value",'nowrap'));
  [31]         }
  [32]         if (count($counts) > 15) print tr(td("<br><small>[<a href='#$field'>$field</a>]</small><br>$fields_link<br>$top_link",2));
  [33]         print "</table></td>\n<td valign=top nowrap><a name='$field'>\n";
  [34]     }
  [35]     print "</td>\n</tr>\n</table><br>\n";
  [36]     $site_navigation = TRUE;
  [37] }
  [38] page_end();
  [44] ?>
FILE: schedule_growth.php - 142 lines, 1 function [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $versions = rq_array('versions');
  [4] $measure = rq('measure','Taken');
  [5] $filesets = array();
  [6] foreach (schedule_snapshots() as $filename) {
  [7]     $schedule = datenamedfile_prefix($filename);
  [8]     $filesets[$schedule][] = $filename;
  [9] }
  [10] if (count($filesets) > 1) $schedule = rq('schedule');
  [11] page_start("Trace " . ($schedule ? $schedule : 'Schedule') . ($measure==='Remain' ? ' Remaining Seats' : ' Enrollment'));
  [12] if (count($filesets) == 0) print "NO SCHEDULE SNAPSHOTS ARE YET AVAILABLE";
  [13] else {
  [14]     print "<br>\n<table cellpadding=3 border=1>\n";
  [15]     if (!$schedule) { // if choices, require schedule specification
  [16]         ksort($filesets);
  [17]         print tr(tdc("<b>Select Discipline & Semester</b>"));
  [18]         print "<tr><td><table border=0 cellpadding=3>\n";
  [19]         $choices = FALSE;
  [20]         foreach ($filesets as $schedule => $fileset) { // groups of snapshots for same discipline and semester
  [21]             if (count($fileset) > 1) {print tr(td(radio('schedule',$schedule))); $choices = TRUE;}
  [22]             else $only_one[] = "$schedule <small>(" . date('n/j/y',datetime_from_filename($fileset[0])) . ")</small>";
  [23]         }
  [24]         print tr(th($choices ? commandbutton('Specify Schedule') : '<b>No schedule has more than one snapshot</b>'));
  [25]         print br("</table></td></tr>\n");
  [26]         if ($only_one) print tr(td(br_list('<i><b>Only one version has been saved for:</b></i>',$only_one,3)));
  [27]         if (count($filesets) > 10) $site_navigation = TRUE;
  [28]     } else if (begins($command,'Specify')) { // specific semester selected, but comparison snapshots not yet chosen
  [29]         $fileset = array_reverse($filesets[$schedule]);
  [30]         print tr(tdc('<b>Select versions to compare</b>',4));
  [31]         print "<tr><td><table border=0 cellpadding=3>\n";
  [32]         foreach ($fileset as $index => $filename) {
  [33]             print tr(td(checkbox("versions[$index]",TRUE,$filename,schedule_date_format(datetime_from_filename($filename)))));
  [34]         }
  [35]         print tr(tdc(commandbutton('Compare Selected Snapshots'),3));
  [36]         if (count($filesets) > 1) print tr(tdc(alink('<small>Choose a different schedule</small>'),3));
  [37]         print br("</table></td></tr>");
  [38]         print hidden('schedule',$schedule);
  [39]     } else {
  [40]         print tr(tdc(' &nbsp; ' . alink('Choose different schedules') . spaces(10) .
  [41]             radio('measure','Taken',$measure,'Taken') . radio('measure','Remain',$measure,'Remain') .
  [42]             commandbutton('Change Measure')));
  [43]         print hidden('schedule',$schedule);
  [44]         print hidden('versions',$versions);
  [45]     }
  [46]     print "</table>\n";
  [47]     if (count($fileset) > 10) $site_navigation = TRUE;
  [48] }
  [49] // process indicated schedules if form has been posted
  [50] if ($versions) {
  [51]     $dimensions = array('Course','Campus','Days','Hour','Instructor','Session');
  [52]     foreach ($versions as $version) { // save version info and each-section enrollment for each version
  [53]         $versiondatetimes[$version] = datetime_from_filename($version);
  [54]         $versiondates[$version] = date('n/j',$versiondatetimes[$version]);
  [55]         $info = extract_schedule_info(file_read_contents($version));
  [56]         foreach ($info as $key => $section) {
  [57]             $enroll[$key][$version] = $section[$measure];
  [58]             $limit[$key][$version] = $section['Limit'];
  [59]         }
  [60]     } // this leaves $info set to the final (i.e., most recent) version of the schedule
  [61]     foreach ($enroll as $key => $version_enrollments) { // form totals and subtotals from qualifying sections
  [62]         if (count($version_enrollments) < count($versions)) $missing .= ', ' . substr($key,1);
  [63]         else { // omit from totals the sections that are missing in some schedule version
  [64]             $section_overall_count++;
  [65]             $enroll_overall_total += $info[$key][$measure];
  [66]             $limit_overall_total += $info[$key]['Limit'];
  [67]             foreach ($version_enrollments as $version => $enrollment) {
  [68]                 $enroll_total[$version] += $enrollment;
  [69]                 $limit_total[$version] += $limit[$key][$version];
  [70]                 $version_sections[$version]++;
  [71]             }
  [72]             foreach ($dimensions as $dimension) {
  [73]                 $value = $info[$key][$dimension];
  [74]                 $limit_subtotal[$dimension][$value] += $info[$key]['Limit'];
  [75]                 $value_sections[$dimension][$value]++;
  [76]                 foreach ($version_enrollments as $version => $enrollment) {
  [77]                     $enroll_subtotal[$dimension][$value][$version] += $enrollment;
  [78]                     $value_version_sections[$dimension][$value][$version]++;
  [79]                     $dimension_sections[$dimension][$version]++;
  [80]                 }
  [81]             }
  [82]         }
  [83]     }
  [84]     // print all-section summary line, then textarea with sections, then list sections missing from some version
  [85]     if ($measure === 'Remain') {$avgtext = 'remaining seats'; $navtext = 'Remaining-seat';}
  [86]     else {$avgtext = 'class enrollments'; $navtext = 'Class-size';}
  [87]     print "<br>\nAverage $avgtext range from " . quotient($enroll_total[$versions[0]],$version_sections[$versions[0]],1) . ' on ' .
  [88]         $versiondates[$versions[0]] . " to " . quotient($enroll_total[$versions[count($versions)-1]],$version_sections[$versions[count($versions)-1]],1) .
  [89]         ' on ' . $versiondates[$versions[count($versions)-1]] . ' (average limit ' . quotient($limit_total[$version],$version_sections[$version],1) . ")<br>\n";
  [90]     print textarea_head('sections',15,120,FALSE);
  [91]     print implode("\t",$versiondates) . "\tLimit\tDept\tCourse\tSection\tType\tSynonym\tLocation\tDays\tStart\tEnd\tInstructor\tSession";
  [92]     foreach ($info as $key => $s) print implode("\t",$enroll[$key]) .
  [93]         "\t$s[Limit]\t$s[Dept]\t#$s[Number]\t$s[Section]\t$s[Type]\t$s[Synonym]\t$s[Location]\t$s[Days]\t$s[Start]\t$s[End]\t$s[Instructor]\t$s[Session]\n";
  [94]     print "</textarea>\n<br>\n";
  [95]     if ($missing) print br('Missing comparison synonyms: ' . substr($missing,2));
  [96]     // print header information for dimensional analyses
  [97]     foreach ($versions as $version) $dates .= th($versiondates[$version]);
  [98]     $columns = count($versions) + 3;
  [99]     $link_row = tr(tdc("&nbsp; <small><a href='#DL'>Grouping categories<a></small> &nbsp; $top_link &nbsp;",$columns));
 [100]     print "<a name='DL'><br>\n<b>$navtext averages grouped by"; // print navigation row to dimensions
 [101]     foreach ($dimensions as $index => $dimension) print "&nbsp; <a href='#$dimension'>$dimension</a>";
 [102]     print "</b><br>\n<table border=1 cellpadding=3>\n";
 [103]     // start analysis table with all-sections averages on each version
 [104]     print tr(tdc("<b><i>Overall Averages</i></b>",$columns)) . tr($dates . th('Limit') . th('Count') . th());
 [105]     print "<tr>";
 [106]     foreach ($versions as $version) print tdr(quotient($enroll_total[$version],$section_overall_count,1));
 [107]     print tdr(italic(quotient($limit_overall_total,$section_overall_count,0))) . tdc($section_overall_count) .
 [108]         td(' &nbsp; Average of all sections') . "</tr>\n$link_row";
 [109]     foreach ($enroll_subtotal as $dimension => $value_sets) { // for each dimension, add a set of rows to the analysis table
 [110]         print tr(tdc("<a name='$dimension'><b>Subtotals by <i>$dimension</i></b>",$columns));
 [111]         print tr($dates . th('Limit') . th('Count') . td(" &nbsp; <i>$dimension</i>")) . "<tr>";
 [112]         ksort($value_sets);
 [113]         if ($dimension === 'Days') $value_sets = reorder_daykeyed_array($value_sets);
 [114]         foreach ($value_sets as $value => $version_enrollments) { // add one row for each distinct value in this dimension
 [115]             print "<tr>";
 [116]             foreach ($version_enrollments as $version => $enrollment) {
 [117]                 print tdr(quotient($enrollment,$value_version_sections[$dimension][$value][$version],1));
 [118]             }
 [119]             print tdr(italic(quotient($limit_subtotal[$dimension][$value],$value_sections[$dimension][$value],0))) .
 [120]                 tdc($value_sections[$dimension][$value]) . td(" &nbsp; $value") . "</tr>";
 [121]         }
 [122]         print $link_row;
 [123]     }
 [124]     print "</table>\n";
 [125]     $site_navigation = TRUE;
 [126] }
 [127] page_end();
 [128] [Top]   schedule_growth.php
 [129] function reorder_daykeyed_array($array) {
 [130]     $newarray = array();
 [131]     foreach (array('','M','MW','MTW','MTWTh','MTWThF','MWF','T','TTh','W','Th','F','Sa','Su') as $day) {
 [132]         if ($array[$day]) {$newarray[$day] = $array[$day]; unset($array[$day]);}
 [133]     }
 [134]     if ($array) {foreach ($array as $day => $value) $newarray[$day] = $value;}
 [135]     return $newarray;
 [136] }
 [142] ?>

FILE: schedule_import.php - 43 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] logon_required('import snapshots');
  [4] if (has_privilege('Administrator')) bailout('Administrators already use the general snapshot directory');
  [5] $directory = nameletters_instead($user_id);
  [6] if (posted()) {
  [7]     foreach (rq_array('files') as $filename) copy($filename,str_replace('general',$directory,$filename));
  [8]     redirect('schedule_management.php');
  [9] }
  [10] page_start('Import Schedule Snapshots');
  [11] foreach (schedule_snapshots(FALSE,'general') as $filename) {
  [12]     if (!file_exists(str_replace('general',$directory,$filename))) { // ignore already-present versions
  [13]         $name = trim(before(datenamedfile_label($filename),'-'));
  [14]         $discipline = phrase($name,0,-2);
  [15]         $term_number = semester_name_to_term_number(phrase($name,-2));
  [16]         $files[$term_number][$discipline][] = $filename;
  [17]         $display_text[$filename] = datenamedfile_label($filename);
  [18]     }
  [19] }
  [20] if (!$files) print pc(bold('No schedule snapshots are available for import'));
  [21] else {
  [22]     if (count($files) > 1) {
  [23]         $text .= 'Semesters:';
  [24]         foreach (array_keys($files) as $term_number) $text .= ' &nbsp; ' . alink(term_number_to_semester_name($term_number),"#Term$termnumber");
  [25]         print pc($text);
  [26]     }
  [27]     $index = 0;
  [28]     print "<br><table border=1 cellpadding=3>\n";
  [29]     foreach ($files as $term_number => $discipline_files) {
  [30]         print tr(th("<a name='Term$term_number'>" . term_number_to_semester_name($term_number)));
  [31]         foreach ($discipline_files as $discipline => $filename) print tr(td(checkbox("files[$index]",FALSE,$filename,$display_text[$filename])));
  [32]         print tr(tdc($top_link));
  [33]     }
  [34]     print "</table>\n";
  [35]     $site_navigation = TRUE;
  [36] }
  [37] page_end();
  [43] ?>
FILE: schedule_limits.php - 183 lines, 6 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Room Class-Size Limits',FALSE,'Department Filter: ' . textbox('filter'));
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $filter = rq('filter');
  [6]     // extract information from schedule data
  [7]     $sections = array();
  [8]     foreach ($schedule_info as $discipline => $semester_info) {
  [9]         foreach ($semester_info as $semester => $section_info) {
  [10]             foreach ($section_info as $key => $section) { // extract classroom sections into unified array
  [11]                 if (trim($section['Location']) && $section['Limit'] && $section['Remain']!=='killed') $sections[$key] = $section;
  [12]             }
  [13]         }
  [14]     }
  [15]     $rooms = $filtered = $campuses = array();
  [16]     foreach ($sections as $key => $section) { // determine rooms and courses of interest
  [17]         if (!$filter || contains($filter,$section['Dept']) || contains($filter,"@$section[Campus]")) {
  [18]             $rooms[$section['Location']]++;
  [19]             $campuses[$section['Campus']]++;
  [20]             $courses[$section['Course']]++;
  [21]         }
  [22]         if (contains($filter,$section['Dept']) || contains($filter,"@$section[Campus]")) $filtered[$key] = $section;
  [23]     }
  [24]     $roomcourselimits = $roomlimitdistribution = $roomlimitsum = $roomsectioncount = $courselimits =
  [25]         $courselimitdistribution = $courselimitsum = $coursesectioncount = array();
  [26]     foreach ($sections as $key => $section) { // build arrays based on revelant-section data
  [27]         $room = $section['Location'];
  [28]         $limit = $section['Limit'];
  [29]         $course = $section['Course'];
  [30]         $roomcourselimits[$room][$course][$key] = $limit;
  [31]         $roomlimitdistribution[$room][$limit]++;
  [32]         $roomlimitsum[$room] += $limit;
  [33]         $courselimits[$course][$key] = $limit;
  [34]         $courselimitdistribution[$course][$limit]++;
  [35]         $courselimitsum[$course] += $limit;
  [36]     }
  [37]     // compute typical and maximum limits for each room and course
  [38]     $roomtypicallimit = $coursetypicallimit = $roomlimit_max = $courselimit_max = array();
  [39]     foreach ($rooms as $room => $sectioncount) {
  [40]         $roomlimit_max[$room] = max(array_keys($roomlimitdistribution[$room]));
  [41]         $roomtypicallimit[$room] = percentile($roomlimitdistribution[$room],0.9,$sectioncount);
  [42]     }
  [43]     foreach ($courses as $course => $sectioncount) {
  [44]         $courselimit_max[$course] = max(array_keys($courselimitdistribution[$course]));
  [45]         $coursetypicallimit[$course] = percentile($courselimitdistribution[$course],0.9,$sectioncount);
  [46]     }
  [47]     // note anomolies
  [48]     $room_anomoly_list = $course_anomoly_list = $sameroomcourse_anomoly = array();
  [49]     foreach ($roomcourselimits as $room => $coursekeylimits) {
  [50]         if (!array_key_exists($room,$rooms)) continue; // tabulate anomolies only for rooms implied by filter
  [51]         foreach ($coursekeylimits as $course => $keylimits) {
  [52]             $filtercourse = contains($filter,trim(substr($course,0,4)));
  [53]             if (max($keylimits) != min($keylimits)) $sameroomcourse_anomoly[$room][$course] = $keylimits;
  [54]             foreach ($keylimits as $key => $limit) {
  [55]                 $room_anomoly = $limit - $roomtypicallimit[$room];
  [56]                 $course_anomoly = $limit - $coursetypicallimit[$course];
  [57]                 $anomoly = (abs($room_anomoly) < abs($course_anomoly)) ? $room_anomoly : $course_anomoly;
  [58]                 if ($filtercourse && $room_anomoly && $course_anomoly) { // omit from anomoly lists if either anomoly is zero
  [59]                     $room_anomoly_list[$key] = $room_anomoly;
  [60]                     $course_anomoly_list[$key] = $course_anomoly;
  [61]                 }
  [62]             }
  [63]         }
  [64]     }
  [65]     // print anomoly tables
  [66]     if ($sameroomcourse_anomoly) {
  [67]         print "<table border=1 cellpadding=5>\n" . tr(tdc(bold('Sections with different limits for the same course and room') .
  [68]             " [format: course(limit-list)@room, hover over limit for full section info]")) . "<tr><td>";
  [69]         asort($sameroomcourse_anomoly);
  [70]         foreach ($sameroomcourse_anomoly as $room => $coursekey) {
  [71]             foreach ($coursekey as $course => $keylimits) {
  [72]                 asort($keylimits);
  [73]                 $limittext = array();
  [74]                 foreach ($keylimits as $key => $limit) $limittext[] = titled($limit,section_title($sections[$key]));
  [75]                 $text = nospace($course);
  [76]                 if (contains($filter,trim(substr($course,0,4)))) $text = bold($text);
  [77]                 print "$text(" . implode(',',$limittext) . ')@<i>' . roomlink($room) . "</i> \n";
  [78]             }
  [79]         }
  [80]         print "</td></tr>\n</table>\n" . br(limit_navigation(),1,2);
  [81]     }
  [82]     print_anomolous_sections($room_anomoly_list,'room');
  [83]     print_anomolous_sections($course_anomoly_list,'course');
  [84]     // list all relevant rooms, showing limits for each section offered in that room
  [85]     ksort($rooms);
  [86]     ksort($campuses);
  [87]     print "<table border=0 cellpadding=0><td><a name='location'>\n<p><b>Room List</b></td><td>";
  [88]     foreach (chunked_array($campuses,18) as $campusrow) {
  [89]         foreach ($campusrow as $campus => $count) print ' &nbsp; ' . alink($campus,"#$campus");
  [90]         print "<br>\n";
  [91]     }
  [92]     print "</td></tr></table>\n";
  [93]     print "<br>\n<table border=1 cellpadding=2>\n" . tr(th('Location') . th('Limit') . th('Sections'));
  [94]     $lastcampus = '';
  [95]     foreach ($rooms as $room => $count) {
  [96]         $text = '';
  [97]         $campus = substr($room,0,3);
  [98]         if ($campus !== $lastcampus) {
  [99]             $lastcampus = $campus;
 [100]             print "<tr><td align=center colspan=3><a name='$campus'><b>$campus Campus</b>" . spaces(5) . limit_navigation() . "</td></tr>\n";
 [101]         }
 [102]         foreach ($roomcourselimits[$room] as $course => $limits) {
 [103]             asort($limits);
 [104]             $subtext = small(italic($course));
 [105]             if ($filter && contains($filter,trim(substr($course,0,4)))) $subtext = bold($subtext);
 [106]             $text .= $subtext;
 [107]             foreach ($limits as $key => $limit) {
 [108]                 if (array_key_exists($key,$filtered) && $limit!=$coursetypicallimit[$course]) $limit = bold($limit);
 [109]                 $text .= ' ' . titled($limit,section_title($sections[$key]));
 [110]             }
 [111]             $text .= '; ';
 [112]         }
 [113]         $limit = $roomtypicallimit[$room];
 [114]         if ($roomlimit_max[$room] > $limit) $limit = "$limit+";
 [115]         print tr(td("<a name='" . nospace($room) . "'>$room",'nowrap') . td(" $limit") . td($text));
 [116]     }
 [117]     print "</table>\n" . br(limit_navigation(),1);
 [118]     if ($filter && $courselimitdistribution){     // print course table if filtered
 [119]         print "<a name='limits'><table border=1 cellpadding=5>\n" .
 [120]             tr(tdc(bold("Limit distributions of $filter courses") . ' [<i>format:</i> sections@<b>limit</b>]')) . "<tr><td>\n";
 [121]         foreach ($courselimitdistribution as $course => $limitdistribution) {
 [122]             if (contains($filter,trim(substr($course,0,4)))) {
 [123]                 ksort($limitdistribution);
 [124]                 print "<b>$course</b> (" . $courses[$course] . ")";
 [125]                 foreach ($limitdistribution as $limit => $count) print " $count@<b>$limit</b>";
 [126]                 print "<br>\n";
 [127]             }
 [128]         }
 [129]         print "</td></tr>\n</table>\n" . br(limit_navigation(),1,2);
 [130]     }
 [131]     print "<a name='Bottom'>\n";
 [132]     $site_navigation = TRUE;
 [133] }
 [134] page_end();
 [135] [Top]   schedule_limits.php
 [136] function percentile($distribution,$percentile,$total=0) {
 [137]     if ($total == 0) foreach ($distribution as $bin) $total += $bin;
 [138]     ksort($distribution);
 [139]     $threshold = $percentage * $total;
 [140]     if ($threshold < 0) return 0;
 [141]     if ($threshold > $total) $threshold = $total;
 [142]     $sum = 0;
 [143]     foreach ($distribution as $index => $bin) {
 [144]         $sum += $bin;
 [145]         if ($sum >= $threshold) return $index;
 [146]     }
 [147] }     [
Top]   schedule_limits.php
 [148] function print_anomolous_sections($anomoly_list,$type='room') {
 [149]     global $filter,$sections,$roomtypicallimit,$coursetypicallimit;
 [150]     if ($anomoly_list) {
 [151]         asort($anomoly_list);
 [152]         print "<a name='$type'>\n<table border=1 cellpadding=5>\n" .
 [153]             tr(tdc(bold("<i>$filter</i> sections whose limits unexpectedly differ from $type limit") .
 [154]             " [format: course(<b>limit</b>/expected)@room, hover over item for full info]")) .
 [155]             "\n<tr><td>\n";
 [156]         foreach ($anomoly_list as $key => $anomoly) print section_text($key,$type);
 [157]         print "\n</td></tr>\n</table>";
 [158]         print br(limit_navigation(),1);
 [159]     }
 [160] } [
Top]   schedule_limits.php
 [161] function section_text($key,$type='course') {
 [162]     global $sections,$roomtypicallimit,$coursetypicallimit;
 [163]     $s = $sections[$key];
 [164]     $expected = $type==='room' ? $roomtypicallimit[$s['Location']] : $coursetypicallimit[$s['Course']];
 [165]     return titled(nospace($s['Course']) . "(<b>$s[Limit]</b>/$expected)@" . roomlink($s['Location']),section_title($s)) . ' ';
 [166] } [
Top]   schedule_limits.php
 [167] function roomlink($room) {$room = nospace($room); return alink($room,"#$room");} [
Top]   schedule_limits.php
 [168] function section_title($s) {
 [169]     global $roomtypicallimit,$coursetypicallimit;
 [170]     $courselimit = $coursetypicallimit[$s['Course']];
 [171]     $roomlimit = $roomtypicallimit[$s['Location']];
 [172]     return "($s[Synonym]) $s[Course] @ $s[Location], $s[Days] $s[Start]-$s[End] $s[Session] $s[Instructor] Limits -- $s[Limit] section, $roomlimit room, $courselimit course";
 [173] } [
Top]   schedule_limits.php
 [174] function limit_navigation() {
 [175]     return alink('Top','#Top') . ' &nbsp; ' . alink('Bottom','#Bottom') . ' &nbsp; ' . alink('Room List','#location') . ' &nbsp; ' .
 [176]         alink('Course List','#limits') . ' &nbsp; &nbsp; Anomolies vis-a-vis:&nbsp; ' . alink('room limit','#room') . '&nbsp; ' . alink('course limit','#course');
 [177] }
 [183] ?>

FILE: schedule_management.php - 55 lines, 1 function [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] if (!$user_id) bailout('Snapshot management requires user log-on');
  [4] $disable = rq('Disable');
  [5] $enable = rq('Enable');
  [6] if ($disable) {rename($disable,str_replace('.schedule','.xschedule',$disable)); redirect();}
  [7] if ($enable) {rename($enable,str_replace('.xschedule','.schedule',$enable)); redirect();}
  [8] page_start('Manage Schedule Snapshots');
  [9] if (!has_privilege('Administrator')) print pc(alink('Import snapshots','schedule_import'));
  [10] print "<br><table border=1 cellpadding=3>\n";
  [11] $enabled = manage_schedule_list();
  [12] $disabled = manage_schedule_list(TRUE);
  [13] if (!$enabled && !$disabled) print tr(td(bold(' &nbsp; There are no schedule snapshots in the directory for this account &nbsp; ')));
  [14] print "</table>\n";
  [15] if ($enabled+$disabled > 10) $site_navigation = TRUE;
  [16] page_end();
  [17] [Top]   schedule_management.php
  [18] function manage_schedule_list($disabled=FALSE) {
  [19]     $schedules = schedule_snapshots($disabled);
  [20]     $title = $disabled ? 'Disabled' : 'Enabled';
  [21]     $command_text = $disabled ? 'Enable' : 'Disable';
  [22]     $count = 0;
  [23]     if ($schedules) {
  [24]         if ($disabled) print tr(td('&nbsp;'));
  [25]         print tr(th("<b>$title Schedule Snapshots</b>"));
  [26]         foreach ($schedules as $schedule) {
  [27]             $name = trim(before(datenamedfile_label($schedule),'-'));
  [28]             $discipline = phrase($name,0,-2);
  [29]             $term_number = semester_name_to_term_number(phrase($name,-2));
  [30]             $files[$term_number][$discipline][] = $schedule;
  [31]             $count++;
  [32]         }
  [33]     }
  [34]     if ($files) {
  [35]         arsort($files); // sorts by term number, oldest last
  [36]         foreach ($files as $term_number => $discipline_files) { // list is grouped by term desc, then discipline, then version desc
  [37]             print tr(tdc(bold(term_number_to_semester_name($term_number))));
  [38]             ksort($discipline_files); // order by discipline, within this term
  [39]             foreach ($discipline_files as $discipline => $versions) {
  [40]                 print tr(tdc(italic($discipline),2));
  [41]                 rsort($versions); // most recent first for this terms snapshots for this discipline
  [42]                 foreach ($versions as $filename) print tr(td(table("-1 width='100%'",
  [43]                     td(' &nbsp; ' .alink($command_text,"?$text=$filename") . ' &nbsp; ' . after(datenamedfile_label($filename),'-')) .
  [44]                     tdr('&nbsp; [' . alink('View',$filename) . '] &nbsp; '))));
  [45]             }
  [46]         }
  [47]     }
  [48]     return $count;
  [49] }
  [55] ?>

FILE: schedule_rooms.php - 51 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('Scheduled Room Usage');
  [4] if ($schedule_info) { // schedule contents ready to analyze
  [5]     $total_sections = $total_hours = 0;
  [6]     $rooms = $campuses = $sections = $hours = $courses = array();
  [7]     foreach ($schedule_info as $discipline => $semester_info) {
  [8]         foreach ($semester_info as $semester => $section_info) {
  [9]             foreach ($section_info as $section) {
  [10]                 $room = "$section[Campus]$section[Room]";
  [11]                 $course = $section['Course'];
  [12]                 $hrs = num(substr($course,-3,1)); // default case
  [13]                 if (in_array($course,array('MATD 0330','MATD 0370','MATD 0390'))) $leh = 4; // allow for discounted courses
  [14]                 if ($hrs == 1) $hrs = 2; // allow for labs
  [15]                 $rooms[$room] = $room;
  [16]                 $campuses[$section[Campus]]++;
  [17]                 $sections[$room]++;
  [18]                 $hours[$room] += $hrs;
  [19]                 $courses[$room][$course]++;
  [20]                 $totalsections++;
  [21]                 $totalhours += $hrs;
  [22]             }
  [23]         }
  [24]     }
  [25]     sort($rooms);
  [26]     $text = "Room\tSecs\tHours\tCourses\t\t$schedule_version\n";
  [27]     foreach ($rooms as $room) {
  [28]         $courselist = '';
  [29]         foreach ($courses[$room] as $course => $count) $courselist .= str_replace(' ','',$course) . "[$count] ";
  [30]         $text .= implode("\t",array($room,$sections[$room],$hours[$room],$courselist)) . "\n";
  [31]     }
  [32]     print "<p align=center>\n";
  [33]     if ($rooms) {
  [34]         print "Courses: " . plural(count($rooms),'room') . " on " . plural(count($campuses),'campus','campuses') .
  [35]             "; " . plural($totalsections,'section') . "; " . plural($totalhours,' class hour') . " per week<br>\n";
  [36]         print textarea('schedule_text',$text,20,120,FALSE) . "</p><br>\n";
  [37]         asort($campuses);
  [38]         print "<br><table border=1 cellpadding=3>\n";
  [39]         print "<tr>" . tdr("<i>Campus<br>Sections</i>");
  [40]         foreach (array_reverse($campuses) as $campus => $count) print tdc("$campus<br>$count");
  [41]         print "</tr></table><br>\n";
  [42]     }
  [43]     $site_navigation = TRUE;
  [44] }
  [45] page_end();
  [51] ?>
FILE: schedule_snapshot.php - 25 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] if (!$user_id) bailout('Snapshots require logged-on user');
  [4] $directory = 'general'; // (has_privilege('Administrator') ? 'general' : nameletters_instead($user_id));
  [5] $_REQUEST['refresh'] = 1; // force internet download (don't use cached copies)
  [6] $save_html_snapshot = TRUE;
  [7] $schedule_info = extract_schedule_information('Save Schedule Snapshot',FALSE,'',$directory);
  [8] $site_navigation = TRUE;
  [9] if ($schedule_info) {
  [10]     $count = 0;
  [11]     print "<table cellpadding=5 border=1>\n";
  [12]     foreach ($schedule_info as $discipline => $semester_info) {
  [13]         foreach ($semester_info as $semester => $listing) print tr($listing);
  [14]         $count++;
  [15]     }
  [16]     print br(bold(plural($count,'schedule snapshot') . ' saved'),1);
  [17]     if ($count < 5) $site_navigation = FALSE;
  [18] }
  [19] page_end();
  [25] ?>
FILE: schedule_to_spreadsheet.php - 37 lines, 1 function [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $schedule_info = extract_schedule_information('ACC schedule => spreadsheet' .
  [4]     ' &nbsp; ' . small(alink('older schedules','schedule_copy_to_spreadsheet.php')));
  [5] if ($schedule_info) {
  [6]     print textarea_head('sections',15,120,FALSE) . schedule_heading();
  [7]     foreach ($schedule_info as $discipline => $semester_info) {
  [8]         foreach ($semester_info as $semester => $section_info) {
  [9]             foreach ($section_info as $section) print schedule_row($section);        
  [10]         }
  [11]     }
  [12]     print "</textarea><br>\n" . copy_to_spreadsheet_instructions();
  [13] }
  [14] $site_navigation = TRUE;
  [15] page_end(); [Top]   schedule_to_spreadsheet.php
  [16] function copy_to_spreadsheet_instructions() {
  [17]     $indent = spaces(5);
  [18]     return <<<HTML
  [19] <table cellPadding=20><tr><td>
  [20] TO COPY THIS RESULT TO A SPREADSHEET:<br>
  [21] $indent [1] Focus on the text area above by clicking on it.<BR>
  [22] $indent [2] Press the "A" key while holding down the "Ctrl" key.<BR>
  [23] $indent [3] Press the "C" key while holding down the "Ctrl" key.<BR>
  [24] $indent [4] Display the destination worksheet in a spreadsheet program such as Excel.<BR>
  [25] $indent [5] Select the top-left cell (typically A1).<BR>
  [26] $indent [6] Press the "V" key while holding down the "Ctrl" key.<BR>
  [27] $indent [7] Label the worksheet appropriately and save the spreadsheet.<BR>
  [28] </td></tr></table><br>
  [29]
  [30] HTML;
  [31] }
  [37] ?>

FILE: search.php - 182 lines, 3 functions [
Top]
  [1] <?php
  [2] //$domains = array('http://www.austincc.edu'=>array('/math/','/mthdept','/mathlabs/'),
  [3] //     'https://sites.google.com/a/austincc.edu'=>array('/math/','/statway/'));
  [4] $domains = array('http://www.austincc.edu'=>array('/math/','/mthdept1/','/mthdept2/','/mthdept4/','/mthdept5/'));
  [5] $start_hrefs = array('http://www.austincc.edu/math/internal/TF_top.htm');
  [6] $extensions = array('doc','docx','txt','rtf','htm','html','php'); // must be lowercase in this list
  [7] $excluded_directories = array('/mman','/tfcourses'); // will be excluded if matches anywhere in directory chain (so use slashes if needed)
  [8] $excluded_pagestrings = array('javascript'); // will be excluded if any part of the url matches
  [9] $required_prefixes = array(); // if any supplied, filename must start with one
  [10] $url_listing_shortener = 'austincc.edu/'; // in listing, portion of url prior to and including this is dropped
  [11] //
  [12] $search = trim($_REQUEST['search']);
  [13] $search_box = '<input type=text name=search size=40 value="' . htmlentities($search) . '">';
  [14] print <<<HTML
  [15] <html><head><title>MATH Search</title></head>
  [16] <body>
  [17] <div align=center>
  [18] <form method='POST' action='$_SERVER[PHP_SELF]'>
  [19] <h3>Math Department Documents</h3>
  [20] <p>Find: $search_box <input type=submit value='Search'></p>
  [21]
  [22] HTML;
  [23] //
  [24] if ($_POST) {
  [25]     set_time_limit(600);
  [26]     $search = strtolower($search); // to facilitate hit-count during search
  [27]     $hitcount = 0;
  [28]     $pages = $output_rows = $output_hits = $broken = $page_extensions = array();
  [29]     print "<big><i>Search " . ($search ? 'results for </i><b>' . htmlentities($search) . '</b>' : 'Path</i>') . "</big>\n";
  [30]     flush(); // to erase old search while new results are being computed
  [31]     foreach ($start_hrefs as $start_href) follow_links("<a href='$start_href'></a>");
  [32]     print "<br><table cellpadding=3 border=0>\n";
  [33]     if ($search) { // search for matches to input text
  [34]         if ($hitcount) {
  [35]             print "<tr><td colspan=2 align=center><i>Pages:</i> <b>" . count($output_rows) . ' from ' . count($pages) . " searched (matches: $hitcount)</td></tr>\n";
  [36]             print "<tr><td colspan=2 align=left><br><i>Hits / Links to pages containing search text</td></tr>\n";
  [37]             array_multisort($output_hits,SORT_DESC,$output_rows); // order by hit frequency
  [38]         } else print "<tr><td colspan=2 align=center><i>No matches</i></td></tr>\n";
  [39]     } else { // list search path
  [40]         print "<tr><td align=center colspan=2><big><b><i>" . count($output_rows) . " distinct links in search path (" . count($pages) . " pages)</i></b></big></td></tr>\n";
  [41]         print "<tr><td align=center><b><i>Qualified link in search path (w/ page url)</i></b></td><td align=center><b><i>Links/pages leading to the qualified link</i></b></td></tr>\n";
  [42]     }
  [43]     foreach ($output_rows as $row) print $row;
  [44]     if ($broken) {
  [45]         print "<tr><td colspan=2 align=center><br><i><b>Broken Link Summary: " . count($broken) . "</b></i></td></tr>\n";
  [46]         foreach ($broken as $row) print $row;
  [47]     }
  [48]     print "</table>\n";
  [49]     if ($directories || $page_extensions) {
  [50]         ksort($directories);
  [51]         print "<br>Directory counts:";
  [52]         foreach ($directories as $directory=>$count) {if (!$directory) $directory = '</b><i>blank</i><b>'; print " &nbsp; $count <b>$directory</b>";}
  [53]         ksort($page_extensions);
  [54]         print "<br><br>Extension counts:";
  [55]         foreach ($page_extensions as $extension=>$count) {if (!$extension) $extension = '</b><i>blank</i><b>'; print " &nbsp; $count <b>$extension</b>";}
  [56]     }
  [57] }
  [58] print <<<HTML
  [59] <br>
  [60] </form>
  [61] </div>
  [62] $trace
  [63] </body>
  [64] </html>
  [65] HTML;
  [66] [Top]   search.php
  [67] function follow_links($link,$parent_link='',$parent_site='',$parent_directory='') {
  [68]     global $search,$hitcount,$broken,$extensions,$domains,$excluded_directories,$excluded_pagestrings,$required_prefixes;
  [69]     global $pages,$page_extensions,$directories,$output_rows,$output_hits;
  [70]     // parse link into components ($page is a fully-extended url)
  [71]     list($label,$site,$directory,$page,$file,$extension,$full_link) = parse_link($link,$parent_site,$parent_directory);
  [72]     $qualified = FALSE;
  [73]     foreach ($domains as $domain=>$roots) {foreach ($roots as $root) {if (stripos($page,"$domain$root") === 0) $qualified = TRUE;}}
  [74]     if (!$qualified) return; // return if page not under one of the specified paths
  [75]     foreach ($excluded_directories as $exclusion) {if (stripos($directory,$exclusion) !== FALSE) return;}
  [76]     foreach ($excluded_pagestrings as $exclusion) {if (stripos($page,$exclusion) !== FALSE) return;}
  [77]     if ($required_prefixes) {
  [78]         $qualified = FALSE;
  [79]         foreach ($required_prefixes as $prefix) {if (stripos($file,$prefix) === 0) $qualified = TRUE;}
  [80]         if (!$qualified) return; // return if filename does not start with one of the prefixes
  [81]     }
  [82]     if ($extension && !in_array(strtolower($extension),$extensions)) return; // limit to specified extensions
  [83]     if (!$page || in_array($page,$pages)) return; // don't repeat pages (to guard cross-references from infinite recursion)
  [84]     // qualified page found -- output a row if the search text is found in the content (or for all links if no search text)
  [85]     $pages[] = $page;
  [86]     $text = @file_get_contents($page);
  [87]     $endtitle = stripos($text,'</title>');
  [88]     if ($endtitle!==FALSE && stripos(substr($text,0,$endtitle),'File Not Found')!==FALSE) $text = '';
  [89]     if (!$label) $full_link = str_replace('</a>','{blank-label link}</a>',$full_link);
  [90]     $full_link .= ' &nbsp; <small>[' . htmlentities("$directory$file") . ']</small>';
  [91]     if ($search) {
  [92]         $hits = substr_count(strtolower($text),$search);
  [93]         if ($hits) { // print link only if search text found
  [94]             $page_extensions[$extension]++;
  [95]             $directories[$directory]++;
  [96]             $output_rows[] = "<tr><td align=right><b>$hits </b></td><td align=left>$full_link</td></tr>\n";
  [97]             $output_hits[] = $hits;
  [98]             $hitcount += $hits;
  [99]         }
 [100]     } else { // if seach text is blank, list qualified links
 [101]         $page_extensions[$extension]++;
 [102]         $directories[$directory]++;
 [103]         if ($text) $output_rows[] = "<tr><td>$full_link </td><td> <i>$parent_link</i></td></tr>\n";
 [104]         else $broken[] = "<tr><td>$full_link </td><td> <i>$parent_link</i></td></tr>\n";
 [105]     }
 [106]     $linkpieces = explode('</a>',str_replace('</A>','</a>',$text));
 [107]     array_pop($linkpieces); // discard text after last </a>
 [108]     foreach ($linkpieces as $piece) {
 [109]         $a = strripos($piece,'<a ');
 [110]         if ($a !== FALSE) {
 [111]             $newlink = substr($piece,$a) . '</a>';
 [112]             follow_links($newlink,$full_link,$site,$directory); // recursive call on each link found in page content
 [113]         }
 [114]     }
 [115] } [
Top]   search.php
 [116] function parse_link($link,$parent_site='',$parent_directory='/') {
 [117]     $label = $page = $extension = $full_link = $extra = '';
 [118]     $site = $parent_site;
 [119]     $directory = $parent_directory;
 [120]     $tagbegin = stripos($link,'<a ');
 [121]     if ($tagbegin !== FALSE) {
 [122]         $hrefbegin = stripos($link,'href',$tagbegin);
 [123]         if ($hrefbegin !== FALSE) {
 [124]             $tagend = strpos($link,'>',$tagbegin);
 [125]             if ($tagend !== FALSE) {
 [126]                 $linkend = stripos($link,'</a>',$tagend);
 [127]                 if ($linkend !== FALSE) {
 [128]                     $equals = strpos($link,'=',$hrefbegin);
 [129]                     if ($equals!==FALSE && $equals<$tagend) { // extract href, dropping any post-href parameters (e.g., onclicks)
 [130]                         $href = trim(substr($link,$equals+1,$tagend-$equals-1));
 [131]                         $quote = substr($href,0,1);
 [132]                         $endquote = strpos($href,$quote,1);
 [133]                         if ($endquote!== FALSE && ($quote==='"' || $quote==="'")) {
 [134]                             $href = substr($href,1,$endquote-1);
 [135]                             $truncate = FALSE; // prepare to drop any bookmark or querystring
 [136]                             $query = strpos($href,'?'); if ($query !== FALSE) $truncate = $query;
 [137]                             $hash = strpos($href,'#'); if ($hash!==FALSE && ($query===FALSE || $hash < $query)) $truncate = $hash;
 [138]                             if ($truncate !== FALSE) {$extra = substr($href,$truncate); $href = substr($href,0,$truncate);}
 [139]                             if ($href) {
 [140]                                 $slashes = strpos($href,'//');
 [141]                                 if ($slashes !== FALSE) { // presence of // indicates explicit protocol link
 [142]                                     if (stripos($href,'http') === 0) {
 [143]                                         $slash = strpos($href,'/',$slashes+2);
 [144]                                         if ($slash === FALSE) {$slash = strlen($href); $href .= '/';}
 [145]                                         $site = substr($href,0,$slash);
 [146]                                         $href = substr($href,$slash);
 [147]                                     } else $href = ''; // treat as blank link if not http or https protocols
 [148]                                 }
 [149]                                 $firstslash = strpos($href,'/');
 [150]                                 $lastslash = strrpos($href,'/'); // $lastslash will never be FALSE if $firstslash isn't
 [151]                                 if ($firstslash === 0) { // absolute reference
 [152]                                     $directory = substr($href,0,$lastslash+1);
 [153]                                     $href = substr($href,$lastslash+1);
 [154]                                 } else { // relative reference
 [155]                                     if ($lastslash !== FALSE) { // relative reference with directories (and perhaps . and ..)
 [156]                                         $directory .= '.' . substr($href,$firstslash,$lastslash-$firstslash+1);
 [157]                                         $href = substr($href,$lastslash+1);
 [158]                                         $dirstack = array();
 [159]                                         foreach (explode('/',$directory) as $dir) {
 [160]                                             if ($dir === '..' && $dirstack) array_pop($dirstack); // move up one level for ..
 [161]                                             elseif ($dir !== '.') $dirstack[] = $dir; // add level (but leave unchanged for .)
 [162]                                         }
 [163]                                         $directory = '/' . implode('/',$dirstack); // reassemble directory without any . or ..
 [164]                                     }
 [165]                                 }
 [166]                                 $file = $href;
 [167]                                 $dot = strrpos($file,'.');
 [168]                                 if ($dot !== FALSE) $extension = strtolower(substr($file,$dot+1));
 [169]                                 $label = strip_tags($link);
 [170]                                 $page = "$site$directory$file";
 [171]                                 $full_link = "<a href=$quote$page$quote>$label</a>";
 [172]                             }
 [173]                         }
 [174]                     }
 [175]                 }
 [176]             }
 [177]         }
 [178]     }
 [179]     return array($label,$site,$directory,$page,$file,$extension,$full_link);
 [180] } [
Top]   search.php
 [181] function trace($item,$prefix="\n<br>") {$GLOBALS['trace'] .= $prefix . (is_array($item) ? print_r($item,TRUE) : $item);}
 [182] ?>

FILE: tables.php - 37 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] $url = rq('url');
  [4] page_start($url ? "Data extracted from tables in<br><i>$url</i>" : "Extract table data from web page");
  [5] if ($url) {
  [6]     $rawtext = file_get_contents($url);
  [7]     $text = strtolower($text);
  [8]     $index = $table_index = 0;
  [9]     $starts = $output = array();
  [10]     $depth = -1;
  [11]     while (TRUE) { // find all tables
  [12]         $start = strpos($text,'<table',$index);
  [13]         $end = strpos($text,'</table',$index);
  [14]         if ($start===FALSE && $end===FALSE) break;
  [15]         $start_tag = ($start < $end);
  [16]         if ($start_tag) {
  [17]             $starts[++$depth] = $start;
  [18]             $index = $start + 7;
  [19]         } else {
  [20]             $start = $starts[$depth--];
  [21]             if ($last_tag_was_start) { // this is the end of an innermost-nested table
  [22]                 $table = textarea_head("output[$table_index]",5,80,FALSE);
  [23]                 foreach (betweens($rawtext,'<tr','</tr') as $row) {
  [24]                     $table .= implode("\t",extract_td_content($row)) . "\n";
  [25]                 }
  [26]                 $output[$table_index++] = "$table</textarea>\n";
  [27]             }
  [28]             $index = $end + 8;
  [29]         }
  [30]         $last_tag_was_start = $start_tag;
  [31]     }
  [32]     print p(implode("</p><p>",$output));
  [33] } else {
  [34]     print br('URL: ' . textbox('url','',80),3,3);
  [35] }
  [36] page_end();
  [37] ?>
FILE: tabulation_filter.php - 76 lines, 4 functions [
Top]
  [1] <?php // access to the student_summary table with hard-coded filter options
  [2] require_once '_all_includes.php';
  [3] $button_text = array('specify'=>'Use Specified Filter','cancel'=>'Cancel','reset'=>'Reset to default');
  [4] $ethnicities = array('NHS'=>'Non-Hispanic','HIS'=>'Hispanic','WH'=>'White','BL'=>'Black','AS'=>'Asian','AN'=>'Native American');
  [5] $term_fields = array('first_term_number','first_developmental_term'); // support comma/dash-separated inclusive list & CY and AY abbreviations
  [6] $term_fields = array('first_year'); // support comma/dash-separated inclusive list & CY and AY abbreviations
  [7] $general_fields = array('terms_enrolled','terms_fall','terms_spring','terms_summer','developmental_terms',
  [8]     'summer_courseload','fallspring_courseload','maximum_courseload',
  [9]     'credits_attempted','credits_earned','courses_attempted','courses_passed',
  [10]     'developmental_attempted','developmental_passed','reading_attempted','reading_passed','writing_attempted','writing_passed',
  [11]     'esl_attempted','esl_passed','desl_attempted','desl_passed','hude_attempted','hude_passed','dssk_attempted','dssk_passed',
  [12]     'matd_attempted','matd_passed','matd_labs_attempted','matd_labs_passed','math_attempted','math_passed',
  [13]     'first_reading','last_reading','first_writing','last_writing','first_esl','last_esl','first_desl','last_desl',
  [14]     'first_hude','last_hude','first_dssk','last_dssk','first_matd','last_matd','first_math','last_math');
  [15] // create a WHERE clause from $_REQUEST values
  [16] $wheres = $ethnic_wheres = $terms = $years = array(); // an array of subclauses (to be separated by ANDs) will be built
  [17] $gender = rq('gender','Both'); if ($gender !== 'Both') $wheres[] = 'gender=' . sq($gender==='Male' ? 'M' : 'F');
  [18] foreach ($ethnicities as $tag=>$label) {$ethnicity[$tag] = rq1($tag); if (rq1($tag)) $ethnic_wheres[] = "race='$tag' OR ethnic='$tag'";}
  [19] if ($ethnic_wheres) $wheres[] = implode(' OR ',$ethnic_wheres);
  [20] foreach ($term_fields as $field) {$terms[$field] = rq($field); $where = make_general_where($field,rq($field)); if ($where) $wheres[] = $where;}
  [21] foreach ($general_fields as $field) {$general[$field] = rq(field); $where = make_general_where($field,rq($field)); if ($where) $wheres[] = $where;}
  [22] $where = $wheres ? ' WHERE (' . implode(') AND (',$wheres) : '';
  [23] //
  [24] if (same($command,$button_text[cancel])) redirect('student_cross_tabulation.php');
  [25] if (same($command,$button_text[reset])) {set_tabulation_filter(); redirect();}
  [26] if (same($command,$button_text['specify'])) {$_SESSION['tabulation_filter'] = $where; redirect('summary_cross_tabulation.php');}
  [27] else { // sets values for filter input based on value of WHERE clause
  [28]     $where = sv('tabulation_filter');
  [29]     $gender = contains($where,"gender=") ? (contains($where,"gender='M") ? 'Male' : 'Female') : 'Both';
  [30]     foreach ($ethnicities as $tag=>$label) $ethnicity[$tag] = (contains($where,"race='$tag'") || contains($where,"ethnic='$tag'")) ? $tag : '';
  [31]     foreach ($term_fields as $field) {$text = between($where,"$field='","'"); $term[$field] = $text ? term_number_to_semester_name($text) : '';}
  [32]     foreach ($general_fields as $field) {$text = between($where,"$field='","'"); $general[$field] = $text ? $text : '';}
  [33] }
  [34] page_start('Specify Tabulation Filter');
  [35] print "<table border=1 cellpadding=3>\n";
  [36] print tr(tdr('Gender:') . td(radioset('gender',array('Both','Female','Male'),$gender)));
  [37] print tr(tdr('Race/Ethnic:') . td(radioset('gender',array('Both','Female','Male'),$gender)));
  [38] page_end();
  [39] [Top]   tabulation_filter.php
  [40] function make_general_where($field,$text) {
  [41]     if ($text === '') return '';
  [42]     if (is_numeric($text) || !contains($text,"'")) return "$field='$text'";
  [43]     return ("$field=" . sq($text)); [
Top]   tabulation_filter.php
  [44] function make_termnumber_where($field,$text) {
  [45]     list($termcode,$termnumber,$termlabel) = make_term_values($text);
  [46]     return ($termcode ? "$field='$termnumber'" : '');
  [47] } [
Top]   tabulation_filter.php
  [48] function make_termcode_where($field,$text) {
  [49]     list($termcode,$termnumber,$termlabel) = make_term_values($text);
  [50]     return ($termcode ? "$field='$termcode'" : '');
  [51] } [
Top]   tabulation_filter.php
  [52] function make_term_values($text) { // supports input such as '212U', 'Summer 2012', or '117' (consecutive term number)
  [53]     $text = trim($text);
  [54]     $semesters = array('U'=>'Summer','F'=>'Fall','S'=>'Spring');
  [55]     if (is_numeric(substr($text,0,3)) && array_key_exists(substr($text,3,1),$semesters)) { // coded ###S format
  [56]         $semestersymbol = strtoupper(substr($text,3,1));
  [57]         $termcode = substr($text,0,4);
  [58]         $termyear = 1800 + num(substr($text,0,3));
  [59]         $termnumber = 3*($termyear-1973) - 1 + strpos("SUF",$semestersymbol);
  [60]         $termlabel = $semesters[$semestersymbol] . " $termyear";
  [61]     }
  [62]     if (is_numeric($text)) {
  [63]         if ($text>0 && $text<160) { // ACC term number
  [64]             $termnumber = $text;
  [65]             $termyear = floor(($text+1)/3 + 1973);
  [66]         } elseif ($text>1972 && $text<2032) { // year number
  [67]             $termyear = $text;
  [68]            
  [69]         }
  [70]         $semesterkey = substr("UFS",$text%3,1);
  [71]         $termcode = substr($termyear,0,1) . substr($termyear,2) . $semesterkey;
  [72]     }
  [73]     return array(($termcode,$termnumber,$termlabel);
  [74] }
  [75]    
  [76] ?>

FILE: txt_to_htm.php - 23 lines, 0 functions [
Top]
  [1] <?php
  [2] require_once '_all_includes.php';
  [3] page_start('Convert saved pages from txt to htm extensions');
  [4] $directory = rq('directory');
  [5] print br('Directory: ' . textbox('directory',$directory,50) . commandbutton('Convert'));
  [6] if ($directory) {
  [7]     $files = glob("$directory/*.txt*");
  [8]     print "<table><tr><td>\n" . implode("<br>\n",$files) . "</td><td>";
  [9]     foreach ($files as $oldname) {
  [10]         $newname = str_replace('.txt.htm','.htm',$oldname);
  [11]         $newname = str_replace('.txt','.htm',$newname);
  [12]         if ($newname && $newname!==$oldname) {rename($oldname,$newname); $newname = bold($newname);}
  [13]         print br($newname);
  [14]     }
  [15]     print "</td></tr></table>\n";
  [16] }
  [17] page_end();
  [23] ?>