| Module Structure | |
|---|---|
| File | Purpose | 
| list.phtml | display the issues list in a table | 
| view.phtml | view a particular issue with all notes, and accept a new note | 
| add.phtml | capture a new issue | 
| common.inc | system constants, like colours, files and titles | 
| authenticate.inc | web browser authentication | 
| database.inc | functions to access the issue text database files | 
<?php include('authenticate.inc'); ?>
<html>
<head>
<title>GCTC Issues - List</title>
</head>
<body bgcolor=#ffffff link=#000000 vlink=#000000>
<!-- $Id: list.phtml,v 1.1 2001/09/04 06:30:59 james Exp james $ -->
<?php
#
#   list.phtml, issues list, list of issues
#   Copyright (C) 2000  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
include('database.inc');
head('list.jpg');
# emit and date
echo '<div align=right><i><small>'.`date`.'</small></i></div>';
function th($name, $value) {
    global $colour_heading_two;
    if ($name == $value) {
    echo '<th bgcolor='.$colour_heading_two.'>';
    echo $name;
    echo "</th>\n";
    } else {
    echo '<th>';
    echo '<a href=?order='.$name.'>'.$name.'</a>';
    echo "</th>\n";
    }
}
?>
<center>
<table border=0 cellpadding=2 cellspacing=2>
<tr bgcolor=<?php echo $colour_heading_one; ?>>
    <?php th('id', $order); ?>
<th>title</th>
    <?php th('status', $order); ?>
    <?php th('priority', $order); ?>
    <?php th('responsibility', $order); ?>
</tr>
<?php
$list = issue_list();
while (list ($key, $id) = each ($list)) {
    $issues[$id] = issue_read($id);
    $tags[$id] = $id;
    switch ($order) {
    case 'id': break;
    case 'status': $tags[$id] = $issues[$id][status]; break;
    case 'priority': $tags[$id] = $issues[$id][priority]; break;
    case 'responsibility': $tags[$id] = $issues[$id][responsibility]; break;
    }
}
if (!empty($tags)) {
    asort($tags);
    reset($tags);
    while (list ($id) = each ($tags)) {
    $issue = $issues[$id];
    
    $flag = ! ($flag);
    $colour = ($flag ? $colour_detail_green_one : $colour_detail_green_two);
    echo '<tr bgcolor='.$colour.'>';
    echo '<td><a href=view.phtml?id='.$issue['id'].'>'.$issue['id'].'</td>';
    echo '<td>'.stripslashes($issue['notes'][0]['title']).'</td>';
    echo '<td>'.stripslashes($issue[status]).'</td>';
    echo '<td>'.stripslashes($issue[priority]).'</td>';
    echo '<td>'.stripslashes($issue[responsibility]).'</td>';
    echo '</tr>';
    }
}
?>
</table>
</center>
<?php
menu();
?>
<hr noshade><div align=right><small><i>
$Revision: 1.1 $ $Date: 2001/09/04 06:30:59 $
</i></small></div>
</body>
</html>
<?php include('authenticate.inc'); ?>
<html>
<head>
<title>GCTC Issues - View <?php echo $id; ?></title>
</head>
<body bgcolor=#ffffff link=#000000 vlink=#000000>
<!-- $Id: view.phtml,v 1.1 2001/09/04 06:30:59 james Exp james $ -->
<?php
#
#   view.phtml, issues list, view specific issue
#   Copyright (C) 2000  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
include('database.inc');
head('view.jpg');
# emit and date
echo '<div align=right><i><small>'.`date`.'</small></i></div>';
# check for submit
if (issue_exists($id)) {
    if ($text != '' && $title != '') {
    $issue = issue_read($id);
    $next = $issue['next']++;
    $issue['notes'][$next]['id'] = $next;
    $issue['notes'][$next]['date'] = time();
    $issue['notes'][$next]['author'] = $user;
    $issue['notes'][$next]['title'] = $title;
    $issue['notes'][$next]['text'] = $text;
    $issue[status] = $status;
    $issue[priority] = $priority;
    $issue[responsibility] = $responsibility;
    if (issue_write($issue)) {
        echo 'Comment '.$id.'.'.$next.' added';
    }
    # clear the form
    $text = '';
    $title = '';
    }
}
?>
<center>
<table border=0 cellpadding=2 cellspacing=2>
<tr bgcolor=<?php echo $colour_heading_one; ?>>
<th colspan=2>Issue <?php echo $id; ?></th>
</tr>
<?php
function snarf($name, $value) {
    echo '<tr valign=top>';
    echo '<th align=right>'.$name.' : </th>';
    echo '<td>'.$value.'</td>';
    echo '</tr>';
}
function field($array, $name, $text) {
    if ($text == '') $text = $name;
    snarf($text, stripslashes($array[$name]));
}
function heading($title) {
    global $colour_heading_two;
    echo '<tr>';
    echo '<th colspan=2 bgcolor='.$colour_heading_two.'>'.$title.'</th>';
    echo '</tr>';
}
function note($id, $note) {
    if ($note['id'] != 0) {
    heading('Comment '.$id.'.'.$note['id']);
    }
    snarf('Date', date_to_string($note['date']));
    field($note, 'author', 'From');
    field($note, 'title', 'Subject');
    field($note, 'text', 'Text');
}
if (issue_exists($id)) {
    if (!isset($issue)) $issue = issue_read($id);
    field($issue,'status','Status');
    field($issue,'priority','Priority');
    field($issue,'responsibility','Responsibility');
    while (list ($key, $note) = each ($issue['notes'])) {
    note($id, $note);
    
    $flag = ! ($flag);
    $colour = ($flag ? $colour_detail_green_one : $colour_detail_green_two);
#    echo '<tr bgcolor='.$colour.'>';
#    echo '<td><a href=view.phtml?id='.$issue['id'].'>'.$issue['id'].'</td>';
#    echo '<td>'.$issue['notes'][0]['title'].'</td>';
#    echo '</tr>';
    
    $users[$val]['name'] = $val;
    }
heading('Add New Comment To Issue');
?>
<td colspan=2>
<form>
<input type=hidden name=id value="<?php echo $id; ?>">
Subject: <br>
<input type=text name=title size=60 value="<?php echo $title; ?>">
<p>
Text: <br>
<textarea name=text rows=6 cols=72 wrap><?php echo $text; ?></textarea>
<p>
New Status: <br>
<input type=text name=status size=60 value="<?php echo $issue[status]; ?>">
<p>
New Priority: <br>
<input type=text name=priority size=60 value="<?php echo $issue[priority]; ?>">
<p>
New Responsibility: <br>
<input type=text name=responsibility size=60 value="<?php echo $issue[responsibility]; ?>">
<p>
<input type=submit value="Add Comment">
</form>
</td>
<?php
} else {
    echo '<tr><th colspan=2>NO SUCH ISSUE</th></tr>';
}
?>
</table>
</center>
<?php
menu();
?>
<hr noshade><div align=right><small><i>
$Revision: 1.1 $ $Date: 2001/09/04 06:30:59 $
</i></small></div>
</body>
</html>
<?php include('authenticate.inc'); ?>
<html>
<head>
<title>GCTC Issues - Add</title>
</head>
<body bgcolor=#ffffff link=#000000 vlink=#000000>
<!-- $Id: add.phtml,v 1.1 2001/09/04 06:30:59 james Exp james $ -->
<?php
#
#   add.phtml, issues list, add new issue
#   Copyright (C) 2000  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
include('database.inc');
head('add.jpg');
# emit and date
echo '<div align=right><i><small>'.`date`.'</small></i></div>';
if ($text != '' && $title != '') {
    $id = issue_allocate();
    if ($id != 0) {
    $issue = issue_default($id);
    $next = $issue['next']++;
    $issue['notes'][$next]['id'] = 0;
    $issue['notes'][$next]['date'] = time();
    $issue['notes'][$next]['author'] = $user;
    $issue['notes'][$next]['title'] = $title;
    $issue['notes'][$next]['text'] = $text;
    $issue[status] = $status;
    $issue[priority] = $priority;
    $issue[responsibility] = $responsibility;
    if (issue_write($issue)) {
        echo 'Issue '.$id.' added';
    }
    }
} else {
?>
<form>
Subject: <br>
<input type=text name=title size=60 value="<?php echo $title; ?>">
<p>
Text: <br>
<textarea name=text rows=6 cols=72 wrap><?php echo $text; ?></textarea>
<p>
Status: <br>
<input type=text name=status size=60 value="<?php echo $issue[status]; ?>">
<p>
Priority: <br>
<input type=text name=priority size=60 value="<?php echo $issue[priority]; ?>">
<p>
Responsibility: <br>
<input type=text name=responsibility size=60 value="<?php echo $issue[responsibility]; ?>">
<p>
<input type=submit value="Add Issue">
</form>
<?php
}
menu();
?>
<hr noshade><div align=right><small><i>
$Revision: 1.1 $ $Date: 2001/09/04 06:30:59 $
</i></small></div>
</body>
</html>
<?php
#
#   common.inc, issues list, common constants and variables
#   Copyright (C) 2001  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# title graphic for each page
define('TITLE', '<img src=title.jpg width=517 height=31 alt="Gilgandra Community Technology Centre">');
# directory in which data is to be put, see database.inc
define('PATH_DATA', '/var/issues/data/');
# file for locking access to database
define('PATH_LOCK', '/var/issues/lock');
# file to use for new record before renaming to PATH_DATA
define('PATH_NEW', '/var/issues/new');
# file containing next allocated issue id
define('PATH_NEXT', '/var/issues/next');
$colour_heading_one = '#d0d0ef';
$colour_heading_two = '#e0e0ff';
$colour_detail_red_one = '#ffe0e0';
$colour_detail_red_two = '#efd0d0';
$colour_detail_green_one = '#e0ffe0';
$colour_detail_green_two = '#d0efd0';
?>
<?php
#
#   authenticate.inc, issues list, authentication procedure
#   Copyright (C) 2001  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# force web browser level authentication
function authenticate($message) {
    header("WWW-Authenticate: Basic realm=\"Gilgandra Community Technology Centre Issues\"");
    header("HTTP/1.0 401 Unauthorized");
    echo $message.'<p>Our system has decided not to allow you to access
this web page.<p>Speak with the person in charge if you expect this to work.';
}
# obtain the IP address of the client
$them = gethostbyaddr($REMOTE_ADDR);
if(!isset($PHP_AUTH_USER)) {
    authenticate('Access denied: no username or password provided.');
    exit;
} else {
    $user = strtolower($PHP_AUTH_USER);
    
    # obtain encoded passwords from file
    include('/var/issues/access');
    
    # check if user known
    if (!isset($admins[$user])) {
    authenticate('Access denied: user '.$user.' not known.');
    exit;
    }
    
    # check if password matches
    $pass = strtolower($PHP_AUTH_PW);
    if ($admins[$user] != md5($user.'|'.$pass)) {
    authenticate("Access denied: password incorrect.");
    exit;
    }
}
    
?>
<!-- $Id: database.inc,v 1.1 2001/09/04 06:30:59 james Exp james $ -->
<?php
#
#   database.inc, prepaid accounting, database access functions
#   Copyright (C) 2001  James Cameron (quozl@us.netrek.org)
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   You should have received a copy of the GNU General Public License
#   along with this program; if not, write to the Free Software
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
#   Filesystem data storage
#
#    /var/issues
#    /var/issues/lock - lock file, always exists
#    /var/issues/new - temporary file
#    /var/issues/data - directory containing serialized arrays
#
#   Filesystem installation steps
#
#    mkdir /var/issues
#       mkdir /var/issues/data
#       touch /var/issues/new
#       touch /var/issues/lock
#       chown -R www-data:www-data /var/issues
#
include('common.inc');
# date functions
# return the default date
function date_default () {
    return time();
}
# translate a unix date to human readable ISO8601 format
function date_to_string ($date) {
    return date('Y-m-d H:i:s', $date);
}
# translate a human readable ISO8601 date to unix date
function date_from_string ($string) {
    list($date, $time) = explode(' ', $string);
    list($year, $month, $day) = explode('-', $date);
    list($hour, $minute, $second) = explode(':', $time);
    $date = mktime($hour, $minute, $second, $month, $day, $year);
    if (date_to_string($date) == $string) return $date;
    return 0;
}
# issue functions
# translate issue id to file path
function issue_to_file ($id) {
    return (PATH_DATA.$id);
}
# check if an issue exists, returns true or false
function issue_exists ($id) {
    return (is_file(issue_to_file($id)));
}
# return a list of issues known in the database
function issue_list () {
    $directory = PATH_DATA;
    $handle = opendir($directory);
    while (($file = readdir($handle)) !== false) {
    if (!is_file($directory.$file)) continue;
    $array[] = basename($file);
    }
    closedir($handle);
    if (gettype($array) == 'array') { sort($array); return $array; }
    return array();
}
# write an issue from array to file, with interlock
function issue_write ($issue) {
    # obtain interlock
    $lock = fopen(PATH_LOCK, 'a+');
    if (!flock($lock, 2)) {
    echo 'Failed to lock database';
    fclose($lock);
    return 0;
    }
    # open the file
    if (!($fp = fopen(PATH_NEW, 'w'))) {
    echo 'Failed to open database';
    fclose($lock);
    return 0;
    }
    # write the array to the file
    if (!fwrite($fp,serialize($issue))) {
    echo 'Failed to write to database';
    fclose($fp);
    fclose($lock);
    return 0;
    }
    # close the file 
    if (!fclose($fp)) {
    echo 'Failed to close database';
    fclose($lock);
    return 0;
    }
    # derive the file name
    $file = issue_to_file($issue['id']);
    # rename the new file into place
    if (!rename(PATH_NEW, $file)) {
    echo 'Failed to move database file into place';
    fclose($lock);
    return 0;
    }
    # release the lock and return success
    fclose($lock);
    return 1;
}
# read an issue from file into array
function issue_read ($id) {
    # derive the file name
    $file = issue_to_file($id);
    # return zero if no file
    if (!is_file($file)) { return 0; }
    # open the file
    if (!($fp = fopen($file, 'r'))) {
    echo 'Failed to open database';
    return 0;
    }
    # read the file
    $issue = unserialize(fread($fp, filesize($file)));
    # close the file
    fclose($fp);
    return $issue;
}
# return a default issue
function issue_default($id) {
    $issue['id'] = $id;
    $issue['status'] = '';
    $issue['priority'] = '';
    $issue['responsibility'] = '';
    $issue['next'] = 0;
    return $issue;
}
# allocate a new issue
function issue_allocate () {
    # obtain interlock
    $fp = fopen(PATH_NEXT, 'r+');
    if (!flock($fp, 2)) {
    echo 'Failed to lock next';
    fclose($fp);
    return 0;
    }
    $id = fgets($fp, 32);
    if (is_bool($id)) {
    if ($id == FALSE) {
        echo 'Failed to read next';
        fclose($fp);
        return 0;
    }
    }
    $id = $id + 1;
    while(issue_exists($id)) {
    $id++;
    }
    
    if (fseek($fp, 0, SEEK_SET) != 0) {
    echo 'Failed to seek next';
    fclose($fp);
    return 0;
    }
    if (!fputs($fp, $id)) {
    echo 'Failed to write next';
    fclose($fp);
    return 0;
    }
    fclose($fp);
    return $id;
}
function head($name) {
    global $title;
    echo TITLE;
    echo '<br>';
    echo '
<table border=0><tr>
<td valign=top>
<img src=issues.jpg width=94 height=48 alt="Issues">
</td>
<td><img src=slash.jpg border=0></td>
<td valign=top>
<img border=0 src='.$name.' alt='.$name.'>
</td>
</tr></table>
';
}
function icon($link, $icon) {
    global $SCRIPT_NAME;
    if (eregi(basename($SCRIPT_NAME), $link)) {
    echo "<td valign=top align=center><a href=$link><img border=0 src=$icon alt=menu></a><br>^</td>";
    } else {
    echo "<td valign=top><a href=$link><img border=0 src=$icon alt=menu></a></td>";
    }
}
function slash() {
    echo '<td valign=top><img src=slash.jpg border=0></td>';
}
function menu() {
    echo '<center><table border=0><tr>';
    icon('list.phtml', 'list.jpg');
    slash();
    icon('add.phtml', 'add.jpg');
    echo '</tr></table></center>';
}
?>