Issues List - Source

up to main page

Module Structure
FilePurpose
list.phtmldisplay the issues list in a table
view.phtmlview a particular issue with all notes, and accept a new note
add.phtmlcapture a new issue
common.incsystem constants, like colours, files and titles
authenticate.incweb browser authentication
database.incfunctions to access the issue text database files

list.phtml

<?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>


view.phtml

<?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($textstripslashes($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>


add.phtml

<?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>


common.inc

<?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';

?>

authenticate.inc

<?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;
    }
}
    
?>

database.inc

<!-- $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($lock2)) {
    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($fpfilesize($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($fp2)) {
    echo 
'Failed to lock next';
    
fclose($fp);
    return 
0;
    }

    
$id fgets($fp32);
    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($fp0SEEK_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>';
}

?>

quozl@us.netrek.org, up to main page.