The first part of this article discussed the basic design andarchitecture for an intranet document management system. In this concludingpart, get to the good stuff with a discussion of the "check in" and "checkout" process, and add a simple search engine to the system.
You'll remember from last time's article that an option to check out a file appears on the document information page, provided that the file is not checked out to someone else and the user has "modify" rights.
<?
// from details.php
$query2 = "SELECT status FROM data, perms WHERE perms.fid = '$id' AND
perms.uid = '$SESSION_UID' AND perms.rights = '2' AND data.status = '0' AND
data.id = perms.fid";
$result2 = mysql_db_query($database, $query2, $connection) or die ("Error
in query: $query2. " . mysql_error());
if(mysql_num_rows($result2) > 0)
{
// if so, display link for checkout
?>
<td align="center"><a href="check-out.php?id=<? echo $id; ?>"><img
src="images/co.jpg" width=40 height=40 alt="" border="0"><br><font
size="-1">Check Document Out</font></a></td>
<?
}
?>
Clicking the link will take the user to "check-out.php",
and also pass the script a file ID.
<?
// check-out.php - performs checkout and updates database
// check for session and $id
// includes
// verify that user has modify rights
$connection = mysql_connect($hostname, $user, $pass) or die ("Unable to
connect!");
$query = "SELECT id, realname FROM data, perms WHERE id = '$id' AND
perms.rights = '2' AND perms.uid = '$SESSION_UID' AND perms.fid = data.id
AND status = '0'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in
query: $query. " . mysql_error());
// error check
// all ok, proceed!
if (!$submit)
{
// form not yet submitted
// display information on how to initiate download
?>
<html>
<head>
<basefont face="Verdana">
</head>
<body bgcolor="white">
<? include("menu.inc");?>
<table width="100%" border="0" cellspacing="0" cellpadding="3">
<tr>
<td bgcolor="#0000A0">
<b><font face="Arial" color="White">Check Document Out</font></b>
</td>
</tr>
</table>
<p>
<form action="<? echo $PHP_SELF?>" method="post">
<input type="hidden" name="id" value="<? echo $id; ?>">
<input type="submit" name="submit" value="Click here"> to check out the
selected document and begin downloading it to your local workstation.
</form>
Once the document has completed downloading, you may <a
href="out.php">continue browsing</a> The Vault.
</body>
</html>
<?
}
// form submitted - download
else
{
list($id, $realname) = mysql_fetch_row($result);
mysql_free_result($result);
// since this user has checked it out and will modify it
// update db to reflect new status
$query = "UPDATE data SET status = '$SESSION_UID' WHERE id = '$id'";
$result = mysql_db_query($database, $query, $connection) or die ("Error in
query: $query. " . mysql_error());
// get the filename
$filename = $dataDir . $id . ".dat";
// send headers to browser to initiate file download
header ("Content-Type: application/octet-stream");
header ("Content-Disposition: attachment; filename=$realname");
readfile($filename);
}
// clean up
mysql_close($connection);
?>
After a few basic error checks, the script produces some
simple instructions - click a button to initiate file download, or click a link to go back to the main document listing. In this case, the button is actually a form (more on this later), which, once submitted, UPDATEs the database to reflect that the file has now been checked out to the current user, then generates the filename (based on the file ID), and sends HTTP headers to the browser to prepare it for a file download. Note that the filename sent in the "Content-Disposition: " header is the original name of the file, as stored in the database, and not the internal name of the file.
Once the browser receives the headers, it should pop up a "Save As" dialog box, allowing the user to save the file to his or her local workstation, where it can be modified and edited. While the file is checked out to a user, other users will not see the check-out menu option, and the file listing in "out.php" will indicate that the file is checked out to a specific user via a red storm-cloud icon (you may remember this code from the previous article).
You'll notice that I've used a form to call the script which actually initiates the download. My original stab at this was to simply call the script and pass it the file ID via the URL GET method - for example, "check-out.php?id=13". However, while this technique worked without a problem in Netscape and Lynx browsers, and even in version 5.0 of Internet Explorer, I noticed a problem with Internet Explorer 5.5; the browser chokes if asked to download a script containing GET-type parameters. Consequently, I decided to use a form and pass parameters via the POST method instead.
Some users have also reported another strange problem with Internet Explorer 5.5 - rather than downloading the target file, the browser has a nasty tendency to download the calling script instead. I plan to look into this at some point - if you have any ideas on what this is all about, let me know!
Finally, Internet Explorer may also display an annoying tendency to display the file in the browser, rather than download it, if the file is a recognized format (text, image et al). The workaround here is to change the "Content-Type" header in the script above to something the browser will not recognize - such as