<?php

require "configure.php" ;

// The session variable 'user' should be set
// only if there is an authenticated user.

if ( isset ( $_SESSION['user'] ) ) {
  
$user = $_SESSION['user'] ;
}

// Use dbname = "dms" to authenticate existing users
// and dbname = $user to handle a query from a user.

function my_connect ( $db = "dms" ) {
  global
$db_user, $db_pswd ;
  if ( !
$db ) {
    echo
"Unable to connect to the database!" ;
    return
False ;
  }
  
$str = "dbname=$db user=$db_user password=$db_pswd" ;
  if ( !
$db_connection = pg_connect (  $str  ) ) {
    echo
"Unable to connect to the database!" ;
    return
False ;
  } else {
    return
$db_connection ;
  }
}

function
valid_login ( ) {
  if ( !
$_REQUEST['username'] || ! $_REQUEST['password'] ) {
    echo
"Either user name or password missing!" ;
    return
False ;
  }
  if ( !
$db_connection = my_connect ( ) ) {
    echo
"Unable to connect to the database";
    return
False ;
  }
  
$query  = "SELECT count(*) FROM dms_user " ;
  
$query .= "WHERE username = '${_REQUEST['username']}' " ;
  
$query .= "AND password = '${_REQUEST['password']}' " ;
  
$row = pg_fetch_row ( pg_query ( $query ), 0 ) ;
  
pg_close ( $db_connection ) ;
  if (
$row[0] ) {
    
$_SESSION['user'] = $_REQUEST['username'] ;
    return
True ; }
  else {
    return
False ; }
}

function
listing_contents ( $searchstring ) {
  global
$user ;
  if ( !
$db_connection = my_connect ( $user ) ) {
    return
False ;
  }
  
$begin = $_REQUEST['begin'] ;
  
$end = $_REQUEST['end'] ;
  
$keywords = preg_split( "/\s+/", $searchstring ) ;
  
$begin = standardize_time ( $begin, "1950-11-02" ) ;
  
$end = standardize_time ( $end, "2050-11-04" ) ;

  
// Find all the ids for all keywords in the dictionary.
  
$term_query = "SELECT id FROM dictionary WHERE " ;
  foreach (
$keywords as $keyword ) {
    
$term_query .= "term = '$keyword' OR " ;
  }
  
$term_query .= "FALSE " ;
  
$result = pg_query( $db_connection, $term_query ) ;

  
// If there are no keywords, just exit signaling failure.
  
if ( pg_numrows ( $result ) == 0 ) { return False ; }

  
// Find all documents that contain all of the keys.
  
$search_query = "SELECT id, date_trunc ( 'second', mark ), description, " ;
  
$search_query .= "trunc ( score_document ( CAST ( id AS integer) ), 3 ) FROM " ;
  for (
$i = 0 ; $i < pg_numrows ( $result ) ; $i++ ) {
    
$search_query .= "occurs AS occurs_$i, " ;
  }
  
$search_query .= "document WHERE " ;
  for (
$i = 0 ; $i < pg_numrows ( $result ) - 1 ; $i++ ) {
    
$search_query .= "occurs_$i.term = " . pg_fetch_result ( $result, $i, 0 ) . " AND " ;
    
$search_query .= "occurs_$i.doc = occurs_" . ( $i + 1 ) . ".doc AND " ;
  }
  
$search_query .= "occurs_$i.term = " . pg_fetch_result ( $result, $i, 0 ) . " AND " ;
  
$search_query .= "occurs_$i.doc = id AND " ;
  
$search_query .= "mark > '$begin' AND mark < '$end' " ;
  
$search_query .= "ORDER BY score_document ( CAST ( id AS integer) ) DESC " ;
  
$result = pg_query( $db_connection, $search_query ) ;

  
// Construct the rows of the resulting html table.
  
for ( $i = 0 ; $i < pg_num_rows ( $result ) ; $i++ ) {
    
listing_item ( pg_fetch_result ( $result, $i, 0 ),
                   
pg_fetch_result ( $result, $i, 1 ),
                   
pg_fetch_result ( $result, $i, 2 ),
                   
pg_fetch_result ( $result, $i, 3 ) ) ;
  }
  
// Close the connection and exit signaling success.
  
pg_close ( $db_connection ) ;
  return
True ;
}

function
my_import ( ) {
  global
$user, $dms_dir ;
  if ( !
is_uploaded_file ( $_FILES['file']['tmp_name'] ) ) {
    echo
"Couldn't upload the file!" ;
    return
False ;
  } elseif ( !
$db_connection = my_connect ( $user ) ) {
    echo
"Couldn't open a connection!" ;
    return
False ;      
  } elseif ( !
pg_query ( $db_connection, "BEGIN" ) ||
             !
$oid = pg_lo_import ( $db_connection,
                                     
$_FILES['file']['tmp_name'] ) ) {
    echo
"Couldn't import the file!" ;
    
pg_query ( $db_connection, "COMMIT" ) ;
    return
False ;
  } else {

    
// Insert the document into the database.
    
$description = preg_replace ( "/[^a-z]/i", " ",
                                  
$_REQUEST['description'] ) ;
    
$insert = "INSERT INTO document VALUES ( $oid, now(), '" ;
    
$insert .= $description . "', '" ;
    
$insert .= $_FILES['file']['type'] . "' ) ;" ;
    
pg_query ( $db_connection, $insert ) ;

    
// Change to the users (dms) working directory
    
$usr_dir = "$dms_dir/users/$user" ;
    
chdir ( $usr_dir ) ;

    
// Delete any existing temporary word-list files.
    
$tmp_words = "$usr_dir/words.txt" ;
    if (
is_file ( $tmp_words ) ) { unlink ( $tmp_words ) ; }

    
// Apply the appropriate text filter.
    
$filter = text_filter ( $_FILES['file']['type'] ) ;
    
$tmp_upload = $_FILES['file']['tmp_name'] ;
    
exec ( "$filter $tmp_upload > $tmp_words" ) ;

    
// Append the supplied description to the word file.
    
exec ( "/bin/echo '" . $description . "' >> $tmp_words" ) ;

    
// Run the shell script that processes the word file.
    
exec ( "$dms_dir/bin/words.csh $tmp_words $oid $user" ) ;

    
// Delete the temporary file used for the upload.
    
if ( is_file ( $tmp_upload ) ) { unlink ( $tmp_upload ) ; }

    
// Complete the transaction and close the connection.
    
pg_query ( $db_connection, "COMMIT" ) ;
    
pg_close ( $db_connection ) ;
    return
True ;
  }
}

function
text_filter ( $mime_type ) {
  switch (
$mime_type ) {
  case                     
"text/html" : return "/sw/bin/lynx -dump" ;
  case                    
"text/plain" : return "/bin/cat" ;
  case      
"application/vnd.ms-excel" : return "/bin/echo" ;
  case             
"application/x-tex" : return "/sw/bin/detex" ;
  case               
"application/pdf" : return "/bin/echo" ;
  case        
"application/postscript" : return "/bin/echo" ;
  case
"application/vnd.ms-powerpoint" : return "/bin/echo" ;
  case               
"application/rtf" : return "/bin/echo" ;
  case            
"application/msword" : return "/sw/bin/antiword" ;
  case                     
"image/gif" : return "/bin/echo" ;
  case                    
"image/jpeg" : return "/bin/echo" ;
  default                              : return
"/bin/echo" ;
  }
}    

function
my_export ( $oid ) {
  global
$user ;
  if (
$db_connection = my_connect ( $user ) ) {
    
pg_query ( $db_connection, "BEGIN" ) ;
    if (
$lo = pg_lo_open ( $db_connection, $oid, "r" ) ) {
      
$type_query = "SELECT type FROM document WHERE id = $oid " ;
      if (
$result = pg_query ( $db_connection, $type_query ) ) {
        
$type = pg_fetch_result ( $result, 0, 0 ) ;
        
$file = $oid . "." . file_ext ( $type ) ;

        
// Generate appropriate http headers for the requested document.
        
header ( 'Content-Type: ' . $type . '; name="' . $file . '"' ) ;
        
header ( 'Content-Disposition: attachment; filename="' . $file . '"' ) ;
      }
      
// Send the document directly the requesting browser.
      
pg_lo_read_all ( $lo ) ;
      
pg_lo_close ( $lo ) ;
    } else {
      echo
"Couldn't find the request file!" ;
      
pg_query ( $db_connection, "COMMIT" ) ;
      
pg_close ( $db_connection ) ;
      return
False ;
    }
    
pg_query ( $db_connection, "COMMIT" ) ;
    
pg_close ( $db_connection ) ;
    return
True ;
  }
  else {
    return
False ;
  }
}

function
file_ext ( $mime_type ) {
  switch (
$mime_type ) {
  case                     
"text/html" : return "html";
  case                    
"text/plain" : return "txt" ;
  case      
"application/vnd.ms-excel" : return "xls" ;
  case             
"application/x-tex" : return "tex" ;
  case               
"application/pdf" : return "pdf" ;
  case        
"application/postscript" : return "ps"  ;
  case
"application/vnd.ms-powerpoint" : return "ppt" ;
  case               
"application/rtf" : return "rtf" ;
  case            
"application/msword" : return "doc" ;
  case                     
"image/gif" : return "gif" ;
  case                    
"image/jpeg" : return "jpg" ;
  default                              : return
"txt" ;
  }
}    

function
standardize_time ( $datestring, $default ) {
  if (
preg_match ( "/^\s*\d{1,2}-\d{1,2}-\d{4}.*/", $datestring ) ) {
    
$datestring = preg_replace ( "/^\s*(\d{1,2})-(\d{1,2})-(\d{4})(.*)/",
                                 
"$3-$2-$1$4", $datestring ) ;
  }
  if (
preg_match ( "/^\s*$/", $datestring ) ||
       (
$timestamp = strtotime ( $datestring ) ) === -1 ) {
    return
$default ;
  } else {
    return
date ( "Y-m-d H:i:s", $timestamp ) ;
  }
}

function
update_scoring_function ( ) {
  global
$user ;
  if (
$_REQUEST['score'] === "update" ) {
    if (
$db_connection = my_connect ( $user ) ) {
      
pg_query ( $db_connection, "DELETE FROM occurs WHERE doc = 0" ) ;
      
$update = "SELECT insert_occurs ( 0, sub.term, sum ( sub.count ) ) " ;
      
$update .= "FROM ( SELECT * FROM occurs WHERE " ;
      while ( list (
$key, $val ) = each ( $_REQUEST ) ) {
        if (
preg_match ( "/OID-\d*/i", $key ) ) {
          
$update .= "doc = $val OR " ;
        }
      }
      
$update .= "FALSE ) AS sub GROUP BY sub.term " ;
      
pg_query ( $db_connection, $update ) ;
      
pg_close ( $db_connection ) ;
    }
  }
}

?>