<?php
/**
* @file refmanager.php
*
*/
require_once('config.inc.php');
require_once('reference.php');
require_once('pubmed.php');
require_once('xslt.php');
require_once('rss10.inc');
/**
* @brief ReferenceManager object
*
* This class encapulates operations on our database of references.
*/
class ReferenceManager {
function ReferenceManager () {}
/**
* @brief Display the add reference form.
*
* Creates an empty XML reference, then uses XSL
* to create a web form.
*
*/
function AddReferenceForm ()
{
$r = new Reference();
$xml = $r->EmptyXML();
//echo $xml;
$xslt_file = "phpbib/xsl/form.xslt";
// Tell XSLT processor that we are inserting a new record
$params = array("operation" => "insert");
$html = XSLT_Buffer ($xml, $xslt_file, '', $params);
return $html;
}
/**
* @brief Display the edit reference form.
*
* Gets the reference from the database as an XML document,
* then uses XSL to create a web form.
*
* @param ref_id Database id of the reference
*/
function EditReferenceForm ($ref_id)
{
$r = new Reference();
$r->Retrieve ($ref_id);
$xml = $r->ToXML();
//echo $xml;
$xslt_file = "phpbib/xsl/form.xslt";
// Tell XSLT processor that we are inserting a new record
$params = array("operation" => "update");
$html = XSLT_Buffer ($xml, $xslt_file, '', $params);
return $html;
}
/**
* @brief Import a PubMed reference
*
* Use's the NCBI Entrez Utilities interface to fetch a PubMed
* record in XML format, then converts it to our XML format
* before displaying it in a form.
*
* @param PMID PubMed identifier
*
*/
function ImportPubMed ($PMID)
{
// Grab PubMed record
$p = new Pubmed($PMID);
$pubmedxml = $p->Get();
// Convert to our XML format
$xslt_file = "phpbib/xsl/pubmed.xslt";
$xml = XSLT_Buffer ($pubmedxml, $xslt_file);
// Populate edit form
$xslt_file = "phpbib/xsl/form.xslt";
// Tell XSLT processor that we are inserting a new record
$params = array("operation" => "update");
$html = XSLT_Buffer ($xml, $xslt_file, '', $params);
return $html;
}
/**
* @brief Convert a reference in EndNote 7 XML to our XML
*
* @param endnoteXML Reference in EndNote XML
*
* @return Reference in our XML format
*/
function EndnoteXML2XML ($endnoteXML)
{
// Remove \" inserted in XML by the web browser
$endnoteXML = str_replace ("\\\"", "\"", $endnoteXML);
$xslt_file = "phpbib/xsl/endnote7.xslt";
$xml = XSLT_Buffer ($endnoteXML, $xslt_file);
return $xml;
}
/**
* @brief Import a reference using the bpp package
*
* @param text Reference
* @param format Format
*
*/
function BP2XML ($text, $format)
{
global $config;
// Ensure it is in Unix format
$text = ereg_replace ("(\r\n|\n|\r)", "\n", $text);
// Write reference to a temporary file
$basefilename = $config['tmp_dir'] . "/" . uniqid ('');
$filename = $basefilename . ".ref";
$xmlfilename = $basefilename . ".xml";
$myfile = @fopen($filename, "w+") or die("could't open file \"$filename\"");
@fwrite($myfile, $text);
fclose($myfile);
// Call external perl script to convert reference into simple XML
$commandline = "perl phpbib/bp2xml.pl -informat=$format:8859-1 $filename > $xmlfilename";
exec ($commandline);
return $xmlfilename;
}
/**
* @brief Import a single reference
*
* Supports EndNote XML, Refer, RIS, ISI, and BibTex formats.
* All except the first are imported using bp.
*
* @param text Reference
* @param format Format
*
*/
function ImportOneReference ($text, $format)
{
$html = "";
// Edit form
$xslt_file = "phpbib/xsl/form.xslt";
// Tell XSLT processor that we are inserting a new record
$params = array("operation" => "update");
if ($format == "endnote_xml")
{
$xml = $this->EndnoteXML2XML ($text);
if ($xml != "")
{
$html = XSLT_Buffer ($xml, $xslt_file, '', $params);
}
}
else
{
$xmlfilename = $this->BP2XML ($text, $format);
//echo $xmlfilename;
$html = XSLT_File ($xmlfilename, $xslt_file, '', $params);
}
return $html;
}
// For each letter in the alphabet count number of papers where the last name
// of the first author starts with that letter
function CountLetters ()
{
global $config;
global $ADODB_FETCH_MODE;
$letter_count = array();
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
// Ensure fields are (only) indexed by column name
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
for ($i = 0; $i < 26; $i++)
{
$letter = chr($i + 65);
$letter_count[$letter] = 0;
$sql = 'SELECT COUNT(last_name), author_order AS n FROM author ';
$sql .= 'INNER JOIN author_reference_joiner ';
$sql .= 'ON author.author_id = author_reference_joiner.author_id ';
$sql .= 'WHERE (last_name LIKE "' . $letter . '%") AND (author_order = "1") ';
$sql .= 'GROUP BY author_order';
//echo $sql;
$result = $this->db->Execute($sql);
if ($result === false) die("failed");
if ($result->RecordCount() > 0)
{
$letter_count[$letter] = $result->fields['n'];
}
}
return $letter_count;
}
function GetReferencesForLetter ($letter)
{
global $config;
global $ADODB_FETCH_MODE;
$reference_ids = array();
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
// Ensure fields are (only) indexed by column name
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$sql = 'SELECT * FROM author ';
$sql .= 'INNER JOIN author_reference_joiner ';
$sql .= 'ON author.author_id = author_reference_joiner.author_id ';
$sql .= 'INNER JOIN reference ';
$sql .= 'ON author_reference_joiner.reference_id = reference.reference_id ';
$sql .= 'WHERE (last_name LIKE "' . $letter . '%") ';
$sql .= 'AND (author_order = "1") ';
$sql .= 'ORDER BY author.last_name, reference.year';
//echo $sql;
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
while (!$result->EOF)
{
array_push ($reference_ids, $result->fields['reference_id']);
$result->MoveNext();
}
// Now, we want to sort these by author name...
return $reference_ids;
}
/**
* @brief Search database
*
* Supports EndNote XML, Refer, RIS, ISI, and BibTex formats.
* All except the first are imported using bp.
*
* @param search_term List of terms to search for. Individual terms are
* separated by spaces.
* @param serach_type A string indicating what fields to search.
* @param count Store the number of hits.
* @param store True (default) if we want to store the result in the database.
*
* @return Id of search results
*/
function Search ($search_term, $search_type, &$count, $store = true)
{
global $config;
global $ADODB_FETCH_MODE;
$search_id = 0;
$count = 0;
$reference_ids = array();
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
// Ensure fields are (only) indexed by column name
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
// If search term is a list we split it here
$term_list = array();
$term_list = split (" ", $search_term);
$num_terms = count($term_list);
$last_name = array();
$first_name = array();
if ($search_type == 'author')
{
for ($i=0; $i<$num_terms; $i++)
{
$parts = explode(",", $term_list[$i]);
$last_name[$i] = trim($parts[0]);
$first_name[$i] = trim($parts[1]);
}
}
$sql = '';
switch ($search_type)
{
case 'doi':
$sql .= 'SELECT * FROM reference ';
$sql .= 'WHERE (' . $search_type . ' = "' . $search_term .'")';
break;
case 'pmid':
$sql .= 'SELECT * FROM reference ';
$sql .= 'WHERE (' . $search_type . ' = "' . $search_term .'")';
break;
case 'title':
$sql .= 'SELECT * FROM reference ';
$sql .= 'WHERE (title LIKE "%' . $term_list[0] . '%")';
for ($i=1; $i<$num_terms; $i++)
{
$sql .= ' AND (title LIKE "%' . $term_list[$i] . '%")';
}
break;
case 'abstract':
$sql .= 'SELECT * FROM reference ';
$sql .= 'WHERE (abstract LIKE "%' . $term_list[0] . '%")';
for ($i=1; $i<$num_terms; $i++)
{
$sql .= ' AND (abstract LIKE "%' . $term_list[$i] . '%")';
}
break;
case 'title_abstract':
$sql .= 'SELECT * FROM reference ';
$sql .= 'WHERE ((abstract LIKE "%' . $term_list[0] . '%")';
$sql .= ' OR (title LIKE "%' . $term_list[0] . '%"))';
for ($i=1; $i<$num_terms; $i++)
{
$sql .= ' AND ((abstract LIKE "%' . $term_list[$i] . '%")';
$sql .= ' OR (title LIKE "%' . $term_list[$i] . '%"))';
}
break;
case 'author':
$sql .= 'SELECT DISTINCT reference.reference_id FROM author ';
$sql .= 'INNER JOIN author_reference_joiner ON author.author_id = author_reference_joiner.author_id ';
$sql .= 'INNER JOIN reference ON reference.reference_id = author_reference_joiner.reference_id ';
$sql .= 'WHERE (author.last_name = "' . $last_name[0] . '")';
for ($i=1; $i<$num_terms; $i++)
{
$sql .= ' OR (author.last_name LIKE "' . $last_name[$i] . '")';
}
break;
}
echo "<p>", $sql, "</p>";
$result = $this->db->Execute($sql);
if ($result == false) die("failed:");
while (!$result->EOF)
{
array_push ($reference_ids, $result->fields['reference_id']);
$result->MoveNext();
}
$count = count($reference_ids);
if ($store)
{
$sql = 'INSERT INTO search (session) VALUES ("' . session_id() . '")';
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
// We now have an id for this search
$search_id = $this->db->Insert_ID();
// Store hits
for ($i=0; $i < sizeof($reference_ids); $i++)
{
$sql = "INSERT INTO search_results (search_id, reference_id) VALUES (\"$search_id\",\"$reference_ids[$i]\");";
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
}
}
return $search_id;
}
function GetNumHits ($search_id)
{
global $config;
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
$sql = 'SELECT reference_id FROM search_results WHERE (search_id = "' . $search_id . '")';
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
return $result->RecordCount();
}
function GetHits ($search_id, $start, $number)
{
global $config;
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
$reference_ids = array();
$sql = 'SELECT reference_id FROM search_results ';
$sql .= 'WHERE (search_id = ' . $search_id . ') ';
$sql .= 'LIMIT ' . $start . ',' . $number;
//echo $sql;
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
// Get array
while (!$result->EOF)
{
array_push ($reference_ids, $result->fields['reference_id']);
$result->MoveNext();
}
return $reference_ids;
}
function GetRSS ()
{
global $config;
global $ADODB_FETCH_MODE;
$reference_ids = array();
$this->db = NewADOConnection('mysql');
$this->db->Connect("localhost",
$config['db_user'], $config['db_passwd'], $config['db_name']);
// Ensure fields are (only) indexed by column name
$ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
$sql = 'SELECT * FROM reference ';
$sql .= 'ORDER BY time_stamp DESC ';
$sql .= 'LIMIT 10';
$result = $this->db->Execute($sql);
if ($result == false) die("failed");
while (!$result->EOF)
{
array_push ($reference_ids, $result->fields['reference_id']);
$result->MoveNext();
}
// Build news feed
$rss=new RSSWriter($config['base_url'], $config['title'],
"Bibliography",
array("dc:publisher" => "Roderic Page.",
"dc:creator" => "Roderic Page <hide@address.com>"));
for ($i=0; $i < sizeof($reference_ids); $i++)
{
$r = new Reference();
$r->Retrieve ($i);
$id = $reference_ids[$i];
$rss->addItem(
$config['base_url'] . "/bib_display_reference.php?format=report&id=". $id,
$r->GetElement('title'),
array(
"description" => $r->GetFormattedReference($id, 'simple'),
"dc:subject" => "Bibliographic item",
"dc:creator" => "Roderic Page <hide@address.com>"
)
);
}
return $rss->serialize();
}
}
?>