]> git.mjollnir.org Git - moodle.git/commitdiff
New module Attendance, by Russell Jungwirth.
authormoodler <moodler>
Tue, 16 Sep 2003 05:33:54 +0000 (05:33 +0000)
committermoodler <moodler>
Tue, 16 Sep 2003 05:33:54 +0000 (05:33 +0000)
mod/attendance/README.txt [new file with mode: 0644]
mod/attendance/db/mysql.php [new file with mode: 0644]
mod/attendance/db/mysql.sql [new file with mode: 0755]
mod/attendance/icon.gif [new file with mode: 0644]
mod/attendance/index.php [new file with mode: 0644]
mod/attendance/lib.php [new file with mode: 0755]
mod/attendance/mod.html [new file with mode: 0755]
mod/attendance/version.php [new file with mode: 0644]
mod/attendance/view.php [new file with mode: 0644]
mod/attendance/viewall.php [new file with mode: 0644]

diff --git a/mod/attendance/README.txt b/mod/attendance/README.txt
new file mode 100644 (file)
index 0000000..527c8cf
--- /dev/null
@@ -0,0 +1,23 @@
+ATTENDANCE version 0.1
+----------------------
+
+
+By Russell Jungwirth (jungwirr@surebluestudios.com)
+
+
+This is the attendance module created and maintained by Russell J. Jungwirth
+of Sureblue Studios.  (surebluestudios.com)  It allows for attendance to be
+tracked for an arbitrary number of hours per instance.  Instances are 
+labelled by date.  Attendance is tracked for all instances in a given course
+as well.
+
+Quick install instructions
+
+1)  Copy attendance.php into lang/en/attendance.php
+
+2)  Move this folder to become mod/attendance
+
+3)  Visit your admin page to install the module
+
+4)  Go to the site configuration page -> modules section -> attendance
+      to specify your preferences for the module (optional)
diff --git a/mod/attendance/db/mysql.php b/mod/attendance/db/mysql.php
new file mode 100644 (file)
index 0000000..d6b089a
--- /dev/null
@@ -0,0 +1,18 @@
+<?PHP
+
+function attendance_upgrade($oldversion) {
+/// This function does anything necessary to upgrade 
+/// older versions to match current functionality 
+
+    global $CFG;
+
+    if ($oldversion < 2003091001) {
+
+       # Do something ...
+
+    }
+
+    return true;
+}
+
+?>
diff --git a/mod/attendance/db/mysql.sql b/mod/attendance/db/mysql.sql
new file mode 100755 (executable)
index 0000000..30124b1
--- /dev/null
@@ -0,0 +1,30 @@
+#\r
+# Table structure for table `prefix_attendance`\r
+#\r
+\r
+CREATE TABLE prefix_attendance (\r
+  id int(10) unsigned NOT NULL auto_increment,\r
+  name varchar(255) NOT NULL default '',\r
+  course int(10) NOT NULL default '0',\r
+  day int(10) unsigned NOT NULL default '0',\r
+  hours tinyint(1) NOT NULL default '0',\r
+  roll tinyint(1) NOT NULL default '0',\r
+  notes varchar(64) NOT NULL default '',\r
+  timemodified int(10) unsigned NOT NULL default '0',\r
+  dynsection tinyint(1) NOT NULL default '0',\r
+  PRIMARY KEY  (id)\r
+) TYPE=MyISAM;\r
+\r
+#\r
+# Table structure for table `prefix_attendance_roll`\r
+#\r
+\r
+CREATE TABLE prefix_attendance_roll (\r
+  id int(11) NOT NULL auto_increment,\r
+  dayid int(10) unsigned NOT NULL default '0',\r
+  userid int(11) NOT NULL default '0',\r
+  hour tinyint(1) unsigned NOT NULL default '0',\r
+  status int(11) NOT NULL default '0',\r
+  notes varchar(64) NOT NULL default '',\r
+  PRIMARY KEY  (id)\r
+) TYPE=MyISAM;\r
diff --git a/mod/attendance/icon.gif b/mod/attendance/icon.gif
new file mode 100644 (file)
index 0000000..e8e21e2
Binary files /dev/null and b/mod/attendance/icon.gif differ
diff --git a/mod/attendance/index.php b/mod/attendance/index.php
new file mode 100644 (file)
index 0000000..11418e7
--- /dev/null
@@ -0,0 +1,78 @@
+<?PHP // $Id$
+
+/// index.php for attendance module
+/// This page lists all the instances of NEWMODULE in a particular course
+/// Replace NEWMODULE with the name of your module
+
+    require_once("../../config.php");
+    require_once("lib.php");
+
+    require_variable($id);   // course
+
+    if (! $course = get_record("course", "id", $id)) {
+        error("Course ID is incorrect");
+    }
+
+    require_login($course->id);
+
+    add_to_log($course->id, "attendance", "view all", "index.php?id=$course->id", "");
+
+
+/// Get all required strings
+
+    $strattendances = get_string("modulenameplural", "attendance");
+    $strattendance  = get_string("modulename", "attendance");
+
+
+/// Print the header
+
+    if ($course->category) {
+        $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+    }
+
+    print_header("$course->shortname: $strNEWMODULEs", "$course->fullname", "$navigation $strattendances");
+
+/// Get all the appropriate data
+
+    if (! $attendances = get_all_instances_in_course("attendance", $course)) {
+        notice("There are no attendances", "../../course/view.php?id=$course->id");
+        die;
+    }
+
+/// Print the list of instances (your module will probably extend this)
+
+    $timenow = time();
+    $strname  = get_string("name");
+    $strweek  = get_string("week");
+    $strtopic  = get_string("topic");
+
+    if ($course->format == "weeks") {
+        $table->head  = array ($strweek, $strname);
+        $table->align = array ("CENTER", "LEFT");
+    } else if ($course->format == "topics") {
+        $table->head  = array ($strtopic, $strname);
+        $table->align = array ("CENTER", "LEFT", "LEFT", "LEFT");
+    } else {
+        $table->head  = array ($strname);
+        $table->align = array ("LEFT", "LEFT", "LEFT");
+    }
+
+    foreach ($attendances as $attendance) {
+        $link = "<A HREF=\"view.php?id=$attendance->coursemodule\">$attendance->name</A>";
+
+        if ($course->format == "weeks" or $course->format == "topics") {
+            $table->data[] = array ($attendance->section, $link);
+        } else {
+            $table->data[] = array ($link);
+        }
+    }
+
+    echo "<BR>";
+
+    print_table($table);
+
+/// Finish the page
+
+    print_footer($course);
+
+?>
diff --git a/mod/attendance/lib.php b/mod/attendance/lib.php
new file mode 100755 (executable)
index 0000000..efbeaec
--- /dev/null
@@ -0,0 +1,302 @@
+<?PHP  // $Id$
+
+/// Library of functions and constants for attendance module
+
+// error_reporting(E_ALL);
+
+function attendance_add_instance(&$attendance) {
+     $attendance->timemodified = time();
+     $attendance->dynsection = !empty($attendance->dynsection) ? 1 : 0;
+     $attendance->day = make_timestamp($attendance->theyear, 
+                       $attendance->themonth, $attendance->theday); 
+     $attendance->name=userdate($attendance->day, get_string("strftimedate"));
+        if ($attendance->notes) { 
+               $attendance->name = $attendance->name . " - " . $attendance->notes;
+        }
+        // insert the main record first
+        return $attendance->id = insert_record("attendance", $attendance);
+}
+
+
+function attendance_update_instance(&$attendance) {
+    $attendance->timemodified = time();
+    $attendance->oldid=$attendance->id;
+    $attendance->id = $attendance->instance;
+    $attendance->dynsection = !empty($attendance->dynsection) ? 1 : 0;
+
+     $attendance->day = make_timestamp($attendance->theyear, 
+                       $attendance->themonth, $attendance->theday); 
+     $attendance->name=userdate($attendance->day, get_string("strftimedate"));
+        if ($attendance->notes) { 
+               $attendance->name = $attendance->name . " - " . 
+                 $attendance->notes;
+        }  
+       // get the data from the attendance grid
+    if ($data = data_submitted()) {      
+      // Peel out all the data from variable names.
+      $attrec->dayid = $attendance->id;
+      foreach ($data as $key => $val) {
+        $pieces = explode('_',$key);
+        if ($pieces[0] == 'student') {
+                 $attrec->userid=$pieces[1];
+          $attrec->hour=$pieces[2];
+          $attrec->status=$val;
+          // clear out any old records for the student
+                 delete_records("attendance_roll", 
+            "dayid",$attrec->dayid,
+            "hour", $attrec->hour, 
+            "userid",$attrec->userid);
+          if ($attrec->status != 0) { 
+            // student is registered as absent or tardy
+                   insert_record("attendance_roll",$attrec, false);
+          }
+       } // if we have a piece of the student roll data
+      } // foreach for all form variables
+    } // if    
+    return  update_record("attendance", $attendance);
+}
+
+function attendance_delete_instance($id) {
+    if (! $attendance = get_record("attendance", "id", "$id")) {
+        return false;
+    }
+
+    $result = true;
+
+    /// delete all the rolls for the day
+    delete_records("attendance_roll", "dayid", "$attendance->id");
+    
+    if (! delete_records("attendance", "id", "$attendance->id")) {
+        $result = false;
+    }
+
+    return $result;
+}
+
+function attendance_user_outline($course, $user, $mod, $attendance) {
+/// Return a small object with summary information about what a 
+/// user has done with a given particular instance of this module
+/// Used for user activity reports.
+/// $return->time = the time they did it
+/// $return->info = a short text description
+/// for attendance, this would be a list present and tardy for every hour of the day
+       $tardies=count_records("attendance_roll", "dayid", $attendance->id, "userid", $user->id, "status", 1);
+       $absences=count_records("attendance_roll", "dayid", $attendance->id, "userid", $user->id, "status", 2);
+       
+    // build longer string for tardies
+       if ($tardies > 0) {
+               $tardyrecs=attendance_get_records("attendance_roll", "dayid", $attendance->id, "userid", $user->id, "status", 1, "hour ASC");
+               if ($tardies == 1) {
+                       $tardystring = "Tardy in hour " . $tardyrecs[0]->hour . ". ";
+               } elseif ($tardies == $attendance->hours) { 
+                       $tardystring = "Tardy in all hours. (" . $attendance->hours . ") ";
+               } else { 
+                       // build array of all tardies
+                       $tarr = array();
+                       foreach ($tardyrecs as $tardyrec) {
+                               array_push($tarr, $tardyrec->hour);
+                               $tardystring = $tardystring . ", " . $tardyrec->hour;
+                       }
+                       $end=array_pop($tarr);
+                       $tardystring = "Tardy in hours " . implode(", ", $tarr) . " and ". $end . ". ";
+               }
+       } else { $tardystring = "";}
+    // build longer string for absences
+       if ($absences > 0) {
+               $absrecs=attendance_get_records("attendance_roll", "dayid", $attendance->id, "userid", $user->id, "status", 2, "hour ASC");
+               if ($absences == 1) {
+                       $absstring = "Absent in hour " . $absrecs[0]->hour . ".";
+               } elseif ($absences == $attendance->hours) { 
+                       $absstring = "Absent in all hours. (" . $attendance->hours . ")";
+               } else { 
+                       // build array of all absences
+                       $aarr = array();
+                       foreach ($absrecs as $absrec) {
+                               array_push($aarr, $absrec->hour);
+                       }
+                       $end=array_pop($aarr);
+                       $absstring = "Absent in hours " . implode(", ", $aarr) . " and ". $end . ".";
+               }
+       } else { $absstring = "";}
+               $return->info=$tardystring . $absstring;
+       if ($return->info == "") $return->info = "No Tardies or Absences";
+    return $return;
+}
+
+function attendance_user_complete($course, $user, $mod, $attendance) {
+/// Print a detailed representation of what a  user has done with 
+/// a given particular instance of this module, for user activity reports.
+    // get the attendance record for that day and user
+    $attrecs=attendance_get_records("attendance_roll", "dayid", $attendance->id, "userid", $user->id, "", "", "hour ASC");
+    // fill an array with the absences and tardies, as those are the only records actually stored
+    $grid = array();
+    foreach ($attrecs as $attrec) { $grid[$attrec->hour]=$attrec->status; }
+    echo "<table><tr><th>Hour:</th>\n";
+    // echo out the table header
+       for($j=1;$j<=$attendance->hours;$j++) {
+               echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$j."</th>\n";
+       }
+       echo "</tr><tr><th>Status:</th>";
+       for($j=1;$j<=$attendance->hours;$j++) {
+      // set the attendance defaults for each student
+             if (isset($grid[$j])) {
+               $status = (($grid[$j] == 1) ? "T" : "A");
+             } else {$status="X";}
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$status."</td>\n";
+       } /// for loop
+    echo "</tr></table>\n";
+
+
+    return true;
+}
+
+function attendance_print_recent_activity($course, $isteacher, $timestart) {
+/// Given a course and a time, this module should find recent activity 
+/// that has occurred in attendance activities and print it out. 
+/// Return true if there was output, or false is there was none.
+
+    global $CFG;
+
+    return false;  //  True if anything was printed, otherwise false 
+}
+
+function attendance_cron () {
+/// Function to be run periodically according to the moodle cron
+/// This function searches for things that need to be done, such 
+/// as sending out mail, toggling flags etc ... 
+
+    global $CFG;
+
+    return true;
+}
+
+function attendance_grades($attendanceid) {
+/// Must return an array of grades for a given instance of this module, 
+/// indexed by user.  It also returns a maximum allowed grade.
+/// NOT IMPLEMENTED AT THIS TIME - WILL DO GRADING BY ATTENDANCE STUFF IN A LATER VERSION
+    $return->grades = NULL;
+    $return->maxgrade = NULL;
+
+    return $return;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////////////
+/// Any other attendance functions go here.  Each of them must have a name that 
+/// starts with attendance_
+
+/**
+* get a list of all students enrolled in a given course - modified version
+* 
+*  THIS IS JUST THE GET_COURSE_STUDENTS FUNCTION WITH THE INCLUSION OF THE 
+*     STUDENT ID INTO THE RECORDSET
+* if courseid = 0 then return ALL students in all courses
+*
+* @param       int     $courseid       the id of the course
+* @param       string  $sort   a field name and ASC or DESC for a SQL 'ORDER BY' clause (optional)
+* @return      array(recorset) a list of all students in the specified course
+ Returns 
+*/
+function attendance_get_course_students($courseid, $sort="u.lastaccess DESC") {
+
+    global $CFG;
+
+    return get_records_sql("SELECT u.id, u.username, u.firstname, u.lastname, u.maildisplay, u.mailformat,
+                            u.email, u.city, u.country, u.lastaccess, u.lastlogin, u.picture, u.idnumber
+                            FROM {$CFG->prefix}user u, 
+                                 {$CFG->prefix}user_students s
+                            WHERE s.course = '$courseid' AND s.userid = u.id AND u.deleted = '0'
+                            ORDER BY $sort");
+}
+
+
+/**
+* Find total absences based on number of tardies per absence
+* 
+* Given a number of tardies and absences, determine the total
+* number of equivalent absences it adds up to.
+*
+* @param       int     $absences       the total number of absences for a span of time
+* @param       int     $tardies        the total number of tardies for a span of time
+* @return      float   the number of absences it adds up to - may be a decimal!
+*/
+function tally_overall_absences_decimal($absences, $tardies) {
+    global $CFG;
+       if (isset($CFG->attendance_tardies_per_absence) && ($CFG->attendance_tardies_per_absence>0)) {
+         return $absences + ($tardies/$CFG->attendance_tardies_per_absence);
+       } else { return $absences; }
+}
+
+/**
+* Find total absences based on number of tardies per absence and put it in a string
+* 
+* Given a number of tardies and absences, determine the total
+* number of equivalent absences it adds up to and express it as a string with
+* a possible fractional remainder
+*
+* @param       int     $absences       the total number of absences for a span of time
+* @param       int     $tardies        the total number of tardies for a span of time
+* @return      string  the number of absences it adds up to - may have a fractional component!
+*/
+function tally_overall_absences_fraction($absences, $tardies) {
+    global $CFG;
+       if (isset($CFG->attendance_tardies_per_absence) && ($CFG->attendance_tardies_per_absence>0)) {
+         $whole = floor($tardies/$CFG->attendance_tardies_per_absence);
+         $fractional=$tardies-($whole * $CFG->attendance_tardies_per_absence);
+         if ($absences + $whole > 0) {
+           return ($absences + $whole) . (($fractional > 0) ? " ". $fractional. "/". $CFG->attendance_tardies_per_absence : "");
+         } else  { 
+           return (($fractional > 0) ? $fractional. "/". $CFG->attendance_tardies_per_absence : "0");
+         }              
+       } else { 
+         return $absences.""; 
+       }
+}
+
+/**
+* get a list of records from a table with multiple criteria
+* 
+* This one is different from the datalib.php one (called get_records) in the sense that it 
+* allows for multiple criteria to be easily supplied as parameters, but doesn't
+* give the ability to specify sort, fields, or limits
+*
+*/
+function attendance_get_records($table, $field1="", $value1="", $field2="", $value2="", $field3="", $value3="", $sort="", $fields="*", $limitfrom="", $limitnum="") {
+
+    global $CFG;
+
+    if ($field1) {
+        $select = "WHERE $field1 = '$value1'";
+        if ($field2) {
+            $select .= " AND $field2 = '$value2'";
+            if ($field3) {
+                $select .= " AND $field3 = '$value3'";
+            }
+        }
+    } else {
+        $select = "";
+    }
+    
+    if ($limitfrom !== "") {
+        switch ($CFG->dbtype) {
+            case "mysql":
+                 $limit = "LIMIT $limitfrom,$limitnum";
+                 break;
+            case "postgres7":
+                 $limit = "LIMIT $limitnum OFFSET $limitfrom";
+                 break;
+            default: 
+                 $limit = "LIMIT $limitnum,$limitfrom";
+        }
+    } else {
+        $limit = "";
+    }
+
+    if ($sort != "") {
+        $sort = "ORDER BY $sort";
+    }
+
+    return get_records_sql("SELECT $fields FROM $CFG->prefix$table $select $sort $limit");
+}
+
+?>
diff --git a/mod/attendance/mod.html b/mod/attendance/mod.html
new file mode 100755 (executable)
index 0000000..ecfb48f
--- /dev/null
@@ -0,0 +1,143 @@
+<!-- This page defines the form to create or edit an instance of the attendance module -->
+<!-- It is used from /course/mod.php.  The whole instance is available as $form. -->
+
+<!-- RJJ I'm using inline CSS styles for some stuff in this page because I want to centralize -->
+<!-- the logic and styles in a single directory -->
+ <?php   @include_once("$CFG->dirroot/mod/attendance/lib.php") 
+    //require_once("lib.php")
+    ?>
+<FORM name="form" method="post" action="<?php echo $ME ?>">
+<CENTER>
+<INPUT type="submit" value="<?php  print_string("savechanges") ?>">
+<INPUT type="submit" name="cancel" value="<?php  print_string("cancel") ?>">
+<TABLE cellpadding=5>
+
+<!-- <?php  $options[0] = get_string("no"); $options[1] = get_string("yes"); ?> -->
+<!-- <TR valign=top> -->
+<!--     <TD align=right><P><B><?php  print_string("takeroll", "attendance") ?>:</B></P></TD> -->
+<!--     <TD align=left><?php  choose_from_menu($options, "roll", $form->roll, "") ?></td> -->
+<!-- </tr> -->
+
+<TR valign=top>
+    <TD align=right><P><B><?php  print_string("dayofroll", "attendance") ?>:</B></P></TD>
+    <TD colspan="3"><?php  print_date_selector("theday", "themonth", "theyear", $form->day) ?></TD>
+</TR>
+<tr valign=top>
+    <TD align="right"><P><B><?php  print_string("dynamicsection", "attendance") ?>:</B></P></TD>
+    <TD align="left">
+      <input type="checkbox" name="dynsection" <?php  echo !empty($form->dynsection) ? 'checked' : '' ?> >
+    </TD>
+</tr>
+<?php  // starting with 2 to allow for the nothing value in choose_from_menu to be the default of 1
+for ($i=2;$i<=24;$i++){ $opt[$i] = $i; } ?>
+<TR valign=top>
+    <TD align=right><P><B><?php  print_string("hoursinclass", "attendance") ?>:</B></P></TD>
+    <TD  colspan="3" align="left"><?php  choose_from_menu($opt, "hours", $form->hours, "1","","1") ?></td>
+</tr>
+<tr valign=top>
+    <td align=right><p><b><?php  print_string("notes", "attendance") ?>:</b></p></td>
+    <td colspan="3">
+        <input type="text" name="notes" size=60 value="<?php  p($form->notes) ?>">
+    </td>
+</tr>
+</TABLE>
+
+
+<?php   // if we're modifying an existing instance of attendance instead 
+    //   of creating a new one
+ if ($form->id) {
+   // get the list of attendance records for all hours of the given day and 
+   // put it in the array for use in the attendance table
+   $rolls = get_records("attendance_roll", "dayid", $form->id);
+   foreach ($rolls as $roll) {
+      $sroll[$roll->userid][$roll->hour]->status=$roll->status;
+      $sroll[$roll->userid][$roll->hour]->notes=$roll->notes;
+       }
+   // get the list of students along with student ID field
+// get back array of stdclass objects in sorted order, with members:
+// id, username,firstname,lastname,maildisplay,mailformat,email,city,country,
+//   lastaccess,lastlogin,picture (picture is null, 0, or 1), idnumber
+  // build the table for attendance roll
+  // this is the wrapper table
+  echo "<table align=\"center\" width=\"80\" class=\"generalbox\"".
+         "border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>".
+         "<td bgcolor=\"#ffffff\" class=\"generalboxcontent\">";
+  // this is the main table
+  echo "<table width=\"100%\" border=\"0\" valign=\"top\" align=\"center\" ".
+         "cellpadding=\"5\" cellspacing=\"1\" class=\"generaltable\">";
+if ($form->hours >1) {
+       echo "<tr><th valign=\"top\" align=\"right\" colspan=\"3\" nowrap class=\"generaltableheader\">".
+              "Hours:</th>\n";
+       for($i=1;$i<=$form->hours;$i++) {
+               echo "<th valign=\"top\" align=\"center\" colspan=\"3\" nowrap class=\"generaltableheader\">".
+              "$i</th>\n";
+       }
+       echo "</tr>\n";
+} // if more than one hour for each day
+       echo "<tr><th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">Last Name</th>\n";
+       echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">First Name</th>\n";
+       echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">ID</th>\n";
+    $P=get_string("presentshort","attendance");
+    $T=get_string("tardyshort","attendance");
+    $A=get_string("absentshort","attendance");
+    // generate the headers for the attendance hours
+       for($i=1;$i<=$form->hours;$i++) {
+         echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$P."</th>\n";
+         echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$T."</th>\n";
+         echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$A."</th>\n";
+       }
+       echo "</tr>\n";
+  $table->head = array("Last Name","First Name","ID",
+    get_string("presentlong","attendance"),
+    get_string("tardylong","attendance"),
+    get_string("absentlong","attendance"));
+  $table->align = array("left", "left", "left", "center","center","center");
+  $table->wrap = array("nowrap", "nowrap", "nowrap", "nowrap", "nowrap", "nowrap");
+  $table->width = "80";
+
+  $students = attendance_get_course_students($form->course, "u.lastname ASC");
+  $i=0;
+  foreach ($students as $student) {
+    echo "<tr><td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$student->lastname."</td>\n";
+    echo "<td align=\"left\" nowrap class=\"generaltablecell\"  style=\"border-top: 1px solid;\">".$student->firstname."</td>\n";
+    echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$student->idnumber."</td>\n";
+       for($j=1;$j<=$form->hours;$j++) {
+      // set the attendance defaults for each student
+         $r1c=$r2c=$r3c=" ";
+           if ($sroll[$student->id][$j]->status == 1) {$r2c="checked";}
+           elseif ($sroll[$student->id][$j]->status == 2) {$r3c="checked";}
+           else {$r1c="checked";}
+      $radio1="<input type=\"radio\" name=\"student_".$student->id."_".$j."\" value=\"0\" ".$r1c.">";
+         $radio2="<input type=\"radio\" name=\"student_".$student->id."_".$j."\" value=\"1\" ".$r2c.">";
+      $radio3="<input type=\"radio\" name=\"student_".$student->id."_".$j."\" value=\"2\" ".$r3c.">";          
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$radio1."</td>\n";
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$radio2."</td>\n";
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$radio3."</td>\n";
+       } // for loop
+    echo "</tr>\n";
+//      $radio1="<input type=\"radio\" name=\"student_".$student->id."\" value=\"0\" checked>";
+//         $radio2="<input type=\"radio\" name=\"student_".$student->id."\" value=\"1\">";
+//      $radio3="<input type=\"radio\" name=\"student_".$student->id."\" value=\"2\">";
+//      $table->data[$i]=array($student->lastname, $student->firstname,
+//           $student->idnumber, $radio1,$radio2,$radio3);
+//      $i++;
+  }
+  // doing the table manually now
+//  print_table($table);
+  // ending for both the tables
+  echo "</table></td></tr></table>\n";
+} // if ($form->id)
+?>
+<!-- These hidden variables are always the same -->
+<INPUT type="hidden" name=course        value="<?php  p($form->course) ?>">
+<INPUT type="hidden" name=coursemodule  value="<?php  p($form->coursemodule) ?>">
+<INPUT type="hidden" name=section       value="<?php  p($form->section) ?>">
+<INPUT type="hidden" name=module        value="<?php  p($form->module) ?>">
+<INPUT type="hidden" name=modulename    value="<?php  p($form->modulename) ?>">
+<INPUT type="hidden" name=instance      value="<?php  p($form->instance) ?>">
+<INPUT type="hidden" name=mode          value="<?php  p($form->mode) ?>">
+<BR />
+<INPUT type="submit" value="<?php  print_string("savechanges") ?>">
+<INPUT type="submit" name="cancel" value="<?php  print_string("cancel") ?>">
+</CENTER>
+</FORM>
diff --git a/mod/attendance/version.php b/mod/attendance/version.php
new file mode 100644 (file)
index 0000000..5a73568
--- /dev/null
@@ -0,0 +1,11 @@
+<?PHP // $Id$
+
+/////////////////////////////////////////////////////////////////////////////////
+///  Code fragment to define the version of attendance
+///  This fragment is called by moodle_needs_upgrading() and /admin/index.php
+/////////////////////////////////////////////////////////////////////////////////
+
+$module->version  = 2003091001;  // The current module version (Date: YYYYMMDDXX)
+$module->cron     = 0;           // Period for cron to check this module (secs)
+
+?>
diff --git a/mod/attendance/view.php b/mod/attendance/view.php
new file mode 100644 (file)
index 0000000..fabf3c2
--- /dev/null
@@ -0,0 +1,141 @@
+<?php   // $Id$
+/// This page prints a particular instance of attendance
+    require_once("../../config.php");
+    require_once("lib.php" );
+/// @include_once("$CFG->dirroot/mod/attendance/lib.php"); 
+// error_reporting(E_ALL);
+    optional_variable($id);    // Course Module ID, or
+    optional_variable($a);     // attendance ID
+    if ($id) {
+        if (! $cm = get_record("course_modules", "id", $id)) {
+            error("Course Module ID was incorrect");
+        }   
+        if (! $course = get_record("course", "id", $cm->course)) {
+            error("Course is misconfigured");
+        }
+        if (! $attendance = get_record("attendance", "id", $cm->instance)) {
+            error("Course module is incorrect");
+        }
+    } else {
+        if (! $attendance = get_record("attendance", "id", $a)) {
+            error("Course module is incorrect");
+        }
+        if (! $course = get_record("course", "id", $attendance->course)) {
+            error("Course is misconfigured");
+        }
+        if (! $cm = get_coursemodule_from_instance("attendance", $attendance->id, $course->id)) {
+            error("Course Module ID was incorrect");
+        }
+    }
+
+    require_login($course->id);
+
+    add_to_log($course->id, "attendance", "view", "view.php?id=$cm->id", "$attendance->id");
+
+/// Print the page header
+
+    if ($course->category) {
+        $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+    }
+
+    $strattendances = get_string("modulenameplural", "attendance");
+    $strattendance  = get_string("modulename", "attendance");
+
+    print_header("$course->shortname: $attendance->name", "$course->fullname",
+                 "$navigation <A HREF=index.php?id=$course->id>$strattendances</A> -> $attendance->name", 
+                  "", "", true, update_module_button($cm->id, $course->id, $strattendance), 
+                  navmenu($course, $cm));
+
+/// Print the main part of the page
+
+   // adaptation of mod code to view code needs this:
+   $form = $attendance;
+
+   if (isteacher($course->id)) {
+     $rolls = get_records("attendance_roll", "dayid", $form->id);
+   } else if (!$cm->visible) {
+     notice(get_string("activityiscurrentlyhidden"));
+     print_footer($course); exit;
+   } else if (isstudent($course->id)) {  // visible and a student
+     $rolls = get_records("attendance_roll", "dayid", $form->id, "userid", $USER->id);
+   } else {
+     notice(get_string("noviews", "attendance"));
+     print_footer($course); exit;
+   }
+   if ($rolls) {
+     foreach ($rolls as $roll) {
+       $sroll[$roll->userid][$roll->hour]->status=$roll->status;
+       $sroll[$roll->userid][$roll->hour]->notes=$roll->notes;
+     }
+   }
+
+   // get the list of attendance records for all hours of the given day and 
+   // put it in the array for use in the attendance table
+       $strviewall = get_string("viewall", "attendance");
+       echo "<table align=\"right\" width=\"50%\"".
+         "border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
+  echo "<tr><td align=\"right\"><a href=\"viewall.php?id=".$course->id."\">";
+  echo "$strviewall</a></td></tr></table><br \>";
+  // this is the wrapper table
+  echo "<table align=\"center\" width=\"80\" class=\"generalbox\"".
+         "border=\"0\" cellpadding=\"0\" cellspacing=\"0\">";
+  echo "<tr><td bgcolor=\"#ffffff\" class=\"generalboxcontent\">";
+  // this is the main table
+  echo "<table width=\"100%\" border=\"0\" valign=\"top\" align=\"center\" ".
+         "cellpadding=\"5\" cellspacing=\"1\" class=\"generaltable\">";
+// print the date headings at the top of the table
+       echo "<tr><th valign=\"top\" align=\"right\" colspan=\"3\" nowrap class=\"generaltableheader\">".
+              "&nbsp;</th>\n";
+    // put notes for the date in the date heading
+    $notes = ($form->notes != "") ? ":<br />".$form->notes : "";
+       echo "<th valign=\"top\" align=\"left\" colspan=\"" .$form->hours. "\" nowrap class=\"generaltableheader\">".
+              userdate($form->day,get_string("strftimedateshort")).$notes."</th>\n";
+    echo (($form->hours > 1)  ? "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">&nbsp;</th>\n" : "");
+    echo "</tr>\n";
+// print the second level headings with name and possibly hour numbers
+       echo "<tr><th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">Last Name</th>\n";
+       echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">First Name</th>\n";
+       echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">ID</th>\n";
+    // generate the headers for the attendance hours
+    if ($form->hours > 1) {
+         for($i=1;$i<=$form->hours;$i++) {
+           echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$i."</th>\n";
+         }
+               echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">total</td>";
+       } else { echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">&nbsp;</th>\n"; }
+       echo "</tr>\n";
+  // get the list of students along with student ID field
+  // get back array of stdclass objects in sorted order, with members:
+  // id, username,firstname,lastname,maildisplay,mailformat,email,city,country,
+  //   lastaccess,lastlogin,picture (picture is null, 0, or 1), idnumber
+  if (isteacher($course->id)){
+    $students = attendance_get_course_students($form->course, "u.lastname ASC");
+  } else { // must be a student
+       $students[0] = get_user_info_from_db("id", $USER->id);
+  }
+  $i=0;
+  foreach ($students as $student) {
+    echo "<tr><td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$student->lastname."</td>\n";
+    echo "<td align=\"left\" nowrap class=\"generaltablecell\"  style=\"border-top: 1px solid;\">".$student->firstname."</td>\n";
+    $studentid=(($student->idnumber != "") ? $student->idnumber : "&nbsp");
+    echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$studentid."</td>\n";
+         $abs=$tar=0;
+         for($j=1;$j<=$form->hours;$j++) {
+      // set the attendance defaults for each student
+             if ($sroll[$student->id][$j]->status == 1) {$status="T";$tar++;}
+             elseif ($sroll[$student->id][$j]->status == 2) {$status="A";$abs++;}
+           else {$status="X";}
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$status."</td>\n";
+         } /// for loop
+    if ($form->hours > 1) {
+           $tot=tally_overall_absences_fraction($abs,$tar);
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$tot."</td></tr>\n";
+    }
+  }
+  /// ending for the table
+  echo "</table></td></tr></table>\n";
+  
+/// Finish the page
+    print_footer($course);
+
+?>
diff --git a/mod/attendance/viewall.php b/mod/attendance/viewall.php
new file mode 100644 (file)
index 0000000..86e55db
--- /dev/null
@@ -0,0 +1,305 @@
+<?php   // $Id$
+/// This page prints all instances of attendance in a given course
+
+    require_once("../../config.php");
+    require_once("lib.php" );
+/// @include_once("$CFG->dirroot/mod/attendance/lib.php"); 
+/// error_reporting(E_ALL);
+
+    optional_variable($id);    // Course Module ID, or
+    optional_variable($a);     // attendance ID
+
+/// populate the appropriate objects
+    if ($id) {
+        if (! $course = get_record("course", "id", $id)) {
+            error("Course is misconfigured");
+        }
+        if (! $attendances = get_records("attendance", "course", $id)) {
+            error("Course module is incorrect");
+        }
+    } else {
+        if (! $attendance = get_record("attendance", "id", $a)) {
+            error("Course module is incorrect");
+        }
+        if (! $course = get_record("course", "id", $attendance->course)) {
+            error("Course is misconfigured");
+        }
+        if (! $cm = get_coursemodule_from_instance("attendance", $attendance->id, $course->id)) {
+            error("Course Module ID was incorrect");
+        }
+        if (! $attendances = get_records("attendance", "course", $cm->course)) {
+            error("Course module is incorrect");
+        }
+    }
+
+    require_login($course->id);
+
+    add_to_log($course->id, "attendance", "viewall", "viewall.php?id=$cm->id", "$attendance->id");
+
+/// Print the page header
+    if ($course->category) {
+        $navigation = "<A HREF=\"../../course/view.php?id=$course->id\">$course->shortname</A> ->";
+    }
+
+    $strattendances = get_string("modulenameplural", "attendance");
+    $strattendance  = get_string("modulename", "attendance");
+    $strallattendance  = get_string("allmodulename", "attendance");
+    print_header("$course->shortname: $strallattendance", "$course->fullname",
+                 "$navigation <A HREF=index.php?id=$course->id>$strattendances</A> -> $strallattendance", 
+                  "", "", true, "&nbsp;", 
+                  navmenu($course, $cm));
+/// Print the main part of the page
+if ($attendances) {
+   if ( !(isteacher($course->id) || isstudent($course->id)) )  {
+     notice(get_string("noviews", "attendance"));
+     print_footer($course); exit;
+   }
+
+// print other links at top of page
+       $strviewone = get_string("viewone", "attendance");
+       $strviewtable = get_string("viewtable", "attendance");
+       $strviewmulti = get_string("viewmulti", "attendance");
+    if ($onepage) {  // one page for all tables
+      echo "<p align=\"right\"><a href=\"viewall.php?id=".$course->id."\">";
+      echo "$strviewmulti</a><br />";
+      echo "<a href=\"viewall.php?id=".$course->id."&onetable=1\">";
+      echo "$strviewtable</a></p>";
+    } else if ($onetable) { // one table for all
+      echo "<p align=\"right\"><a href=\"viewall.php?id=".$course->id."\">";
+      echo "$strviewmulti</a><br />";
+      echo "<a href=\"viewall.php?id=".$course->id."&onepage=1\">";
+      echo "$strviewone</a></p>";
+    } else { // multiple pages
+      echo "<p align=\"right\"><a href=\"viewall.php?id=".$course->id."&onepage=1\">";
+      echo "$strviewone</a><br />";
+      echo "<a href=\"viewall.php?id=".$course->id."&onetable=1\">";
+      echo "$strviewtable</a></p>";
+    }
+
+
+/// create an array of all the attendance objects for the entire course
+   $numatt=0;
+   $numhours=0;
+   foreach ($attendances as $attendance){
+     // store the raw attendance object
+     $atts[$numatt]->attendance=$attendance;
+     // tally the hours for possible paging of the report
+     $numhours=$numhours+$attendance->hours;
+     // get the list of attendance records for all hours of the given day and 
+     // put it in the array for use in the attendance table
+     if (isstudent($course->id)) { 
+       $rolls = get_records("attendance_roll", "dayid", $form->id, "userid", $USER->id);
+     } else { // must be a teacher
+        $rolls = get_records("attendance_roll", "dayid", $attendance->id);
+     }
+     foreach ($rolls as $roll) {
+       $atts[$numatt]->sroll[$roll->userid][$roll->hour]->status=$roll->status;
+       $atts[$numatt]->sroll[$roll->userid][$roll->hour]->notes=$roll->notes;
+        }
+   $numatt++;
+   }
+
+// A LOOP FOR CREATING SINGLE-USER VERSION OF THE REPORT OR A ONE-PAGE REPORT
+   if (isstudent($course->id)) {
+     $onepage=true;
+     $multipage=false; 
+   } else if (!(isset($onepage))){
+     $onepage=false;
+     $multipage=true;
+   } else if ($onepage) {
+     $multipage=false;
+   } else {  // if onepage is set to false
+        $multilpage=true;
+   }
+
+// adjust the width for the report for students 
+
+   if (($onetable) || ($CFG->attendance_hours_in_full_report == 0)) {
+      $hoursinreport = 10000;          
+   } else if (isstudent($course->id)) {
+      $hoursinreport = $CFG->attendance_hours_in_full_report + 15;
+   } else { 
+      $hoursinreport = $CFG->attendance_hours_in_full_report;
+   }           
+while (($multipage || $onepage) && (!$endonepage)) {
+   // this makes for a one iteration loop for multipage
+        $multipage = false;
+        
+        
+   if ($numhours>=$hoursinreport) {
+        if (!isset($pagereport)) {
+               // $pagereport is used to determine whether the report needs to be paged at all
+               $pagereport=true;
+               $endatt=0;
+               $page=1;
+        } 
+        // find the last hour to have on this page of the report
+           // go to the next (or first) page
+//             $endatt++;
+//             $startatt=$endatt;
+               $curpage=1;
+               $endatt=0;
+      for($curpage=1;true;$curpage++) { // the for loop is broken from the inside
+               $pagehours=$atts[$endatt]->attendance->hours;
+               $startatt=$endatt;
+               while(($pagehours<$hoursinreport)) {
+                       if ($endatt>=$numatt) { break 2; } // end the page number calculations and trigger the end of a multi-page report!
+                       $endatt++;
+                       $pagehours=$pagehours+$atts[$endatt]->attendance->hours;
+               }
+               // if this is the page we're on, save the info
+               if ($curpage == $page) {$endatt_target = $endatt; $startatt_target = $startatt; }
+      } // hopefully at this point, startatt and endatt are set correctly for the current page
+               if ($curpage == $page) {$endatt_target = $endatt; $startatt_target = $startatt; } else {
+                  $endatt=$endatt_target; $startatt=$startatt_target; }
+               $maxpages = $curpage;
+   } else {$pagereport=false;}
+
+  $minatt=($pagereport ? $startatt : 0);
+  $maxatt=($pagereport ? $endatt : $numatt);     
+  if ((!$pagereport) || ($page == $maxpages)) {$endonepage = true;}  // end a one page display
+
+//
+//
+//  ALL PRELIMINARY STUFF DONE - MAKE THE MEAT OF THE PAGE
+//
+//
+
+  if (!$onepage) {
+
+  attendance_print_pagenav(); 
+  } 
+
+   // build the table for attendance roll
+   // this is the wrapper table
+   echo "<table align=\"center\" width=\"80\" class=\"generalbox\"".
+         "border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>".
+         "<td bgcolor=\"#ffffff\" class=\"generalboxcontent\">";
+   // this is the main table
+   echo "<table width=\"100%\" border=\"0\" valign=\"top\" align=\"center\" ".
+         "cellpadding=\"5\" cellspacing=\"1\" class=\"generaltable\">";
+   if (isteacher($course->id)) {
+   echo "<tr><th valign=\"top\" align=\"right\" colspan=\"3\" nowrap class=\"generaltableheader\">".
+              "&nbsp;</th>\n";
+   } 
+//      $minpage=0;$maxpage=$numatt;
+    // print the date headings at the top of the table
+    // for each day of attendance
+    for($k=$minatt;$k<$maxatt;$k++)  {
+    // put notes for the date in the date heading
+      $notes = ($atts[$k]->attendance->notes != "") ? ":<br />".$atts[$k]->attendance->notes : "";
+         echo "<th valign=\"top\" align=\"left\" colspan=\"" .$atts[$k]->attendance->hours. "\" nowrap class=\"generaltableheader\">".
+              userdate($atts[$k]->attendance->day,"%m/%0d").$notes."</th>\n";
+    }
+    // if we're at the end of the report
+    if ($maxatt==$numatt || !$pagereport) {
+      echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">&nbsp;</th>\n";
+    }
+    echo "</tr>\n";
+    // print the second level headings with name and possibly hour numbers
+  if (isteacher($course->id)) {
+       echo "<tr><th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">Last Name</th>\n";
+         echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">First Name</th>\n";
+         echo "<th valign=\"top\" align=\"left\" nowrap class=\"generaltableheader\">ID</th>\n";
+  }
+    // generate the headers for the attendance hours
+    for($k=$minatt;$k<$maxatt;$k++)  {
+      if ($atts[$k]->attendance->hours > 1) {
+           for($i=1;$i<=$atts[$k]->attendance->hours;$i++) {
+           echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">".$i."</th>\n";
+           }
+         } else { echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">&nbsp;</th>\n"; }
+    }
+    // if we're at the end of the report
+    if ($maxatt==$numatt || !$pagereport) {
+      echo "<th valign=\"top\" align=\"center\" nowrap class=\"generaltableheader\">total</th>";
+    }
+       echo "</tr>\n";
+
+   // get the list of students along with student ID field
+   // get back array of stdclass objects in sorted order, with members:
+   // id, username,firstname,lastname,maildisplay,mailformat,email,city,country,
+   //   lastaccess,lastlogin,picture (picture is null, 0, or 1), idnumber
+
+
+  if (isstudent($course->id)) { 
+       $students[0] = get_user_info_from_db("id", $USER->id);
+  } else { // must be a teacher
+    $students = attendance_get_course_students($attendance->course, "u.lastname ASC");
+  }
+  $i=0;
+  foreach ($students as $student) {
+    if (isteacher($course->id)) {
+      echo "<tr><td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$student->lastname."</td>\n";
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\"  style=\"border-top: 1px solid;\">".$student->firstname."</td>\n";
+      $studentid=(($student->idnumber != "") ? $student->idnumber : "&nbsp");
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-top: 1px solid;\">".$studentid."</td>\n";
+    }
+    for($k=$minatt;$k<$maxatt;$k++)  {  // for eacj day of attendance for the student
+         for($j=1;$j<=$atts[$k]->attendance->hours;$j++) {
+      // set the attendance defaults for each student
+           if ($atts[$k]->sroll[$student->id][$j]->status == 1) {$status="T";}
+           elseif ($atts[$k]->sroll[$student->id][$j]->status == 2) {$status="A";}
+           else {$status="X";}
+        echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$status."</td>\n";
+         } /// for loop
+    }
+    if ($maxatt==$numatt || !$pagereport) {
+           // tally total attendances for the students
+               $abs=$tar=0;
+           for($k=0;$k<$numatt;$k++)  {  // for eacj day of attendance for the student
+                 for($j=1;$j<=$atts[$k]->attendance->hours;$j++) {
+             // set the attendance defaults for each student
+                   if ($atts[$k]->sroll[$student->id][$j]->status == 1) {;$tar++;}
+                   elseif ($atts[$k]->sroll[$student->id][$j]->status == 2) {;$abs++;}
+                 } /// for loop
+           } // outer for for each day of attendance
+      $tot=tally_overall_absences_fraction($abs,$tar);
+      echo "<td align=\"left\" nowrap class=\"generaltablecell\" style=\"border-left: 1px dotted; border-top: 1px solid;\">".$tot."</td></tr>\n";
+    }
+  }  // foreach
+  /// doing the table manually now
+  ///  print_table($table);
+  /// ending for the table
+  echo "</table></td></tr></table>\n";
+
+if ($onepage) {$page++; echo "<br /> <br />\n"; }
+}  // while loop for multipage/one page printing
+
+  if (!$onepage) { attendance_print_pagenav(); }
+  
+ } else { error("There are no attendance rolls in this course.");} // for no attendance rolls  
+/// Finish the page
+    print_footer($course);
+
+function attendance_print_pagenav() {
+    global $pagereport, $minatt, $maxatt, $course, $page, $numatt, $maxpages;
+         if ($pagereport) {
+       $of = get_string('of','attendance');
+       $pg = get_string('page');
+       $next = get_string('next');
+       $prev = get_string('previous', 'attendance');
+
+               echo "<center><table align=\"center\" width=\"80\" class=\"generalbox\"".
+         "border=\"0\" cellpadding=\"0\" cellspacing=\"0\"><tr>".
+         "<td bgcolor=\"#ffffff\" class=\"generalboxcontent\">";
+    // this is the main table
+    echo "<table width=\"100%\" border=\"0\" valign=\"top\" align=\"center\" ".
+         "cellpadding=\"5\" cellspacing=\"1\" class=\"generaltable\">";
+    echo "<tr>";
+       if ($minatt!=0) {
+    echo "<th valign=\"top\" align=\"right\" nowrap class=\"generaltableheader\">".
+              "<a href=\"viewall.php?id=".$course->id ."&pagereport=1&page=".($page-1)."\">$prev $pg</a></th>\n";
+       }
+    echo "<th valign=\"top\" align=\"right\" nowrap class=\"generaltableheader\">".
+              "$pg $page $of $maxpages</th>\n";
+       if ($maxatt!=$numatt) {
+      echo "<th valign=\"top\" align=\"right\" nowrap class=\"generaltableheader\">".
+      "<a href=\"viewall.php?id=".$course->id ."&pagereport=1&page=". ($page+1)."\">$next $pg</a></th>";
+       }
+               echo "</tr></table></td></tr></table></center>\n";
+  }
+}
+?>