<script language="php">


#######################################################
#    This PHP script is a web-based note taker. It's
#    my replacement for sticky notes. It uses a MySQL
#    database backend to store the notes.
#
#    It's useful for maintaining notes which must be
#    referenced from a number of sites. Or, if you
#    need a very simple way to organize your thoughts.
#
#    Each note/node may contain links to other nodes.
#    The links are categorized as parent, child or jump.
#    Additionally, there's an option to display siblings,
#    that is, children of this node's parents.
#
#    It's different from a hierarchical explorer-like
#    database in that nodes may have any number of parents.
#
#    I personally put this together as proof-of-concept
#    that applications like Natrificial's "The Brain" and
#    Blockstacker's "Everything" could be simplified for
#    single user data entry.
#
#        Contact Info: Stephen Danic. mailto:sdanic@memes.net
#
#        Special thanks to Mike Boone, Steve Hassard and Ben Darnell
#        for their assistance.
#
#
#######################################################
# LICENSE:
#
# 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
#
#######################################################


function displaypage($NodeID,$mode,$passthruText="") {

    global 
$me$mysqlconnection$username$debugmessage$sitename;

    
//str_replace(String to find, replace, in string)
    
$layout getlayout($username);

    
$layout str_replace("%vpins%",displaylinks("pin",$NodeID,"vertical"),$layout);
    
$layout str_replace("%hpins%",displaylinks("pin",$NodeID,"horizontal"),$layout);

    
$layout str_replace("%vrecent%",showRecentlyModified("vertical"),$layout);
    
$layout str_replace("%hrecent%",showRecentlyModified("horizontal"),$layout);

    
//substitute links
    
$layout str_replace("%vjumps%",displaylinks("jump",$NodeID,"vertical"),$layout);
    
$layout str_replace("%hjumps%",displaylinks("jump",$NodeID,"horizontal"),$layout);
    
$layout str_replace("%vparents%",displaylinks("parent",$NodeID,"vertical"),$layout);
    
$layout str_replace("%hparents%",displaylinks("parent",$NodeID,"horizontal"),$layout);
    
$layout str_replace("%vchildren%",displaylinks("child",$NodeID,"vertical"),$layout);
    
$layout str_replace("%hchildren%",displaylinks("child",$NodeID,"horizontal"),$layout);
    
$layout str_replace("%vsiblings%",displaylinks("sibling",$NodeID,"vertical"),$layout);
    
$layout str_replace("%hsiblings%",displaylinks("sibling",$NodeID,"horizontal"),$layout);

    
// substitute icons
    
$layout str_replace("%icons%",displayicons($NodeID,$username),$layout);
    
$layout str_replace("%pinicon%"displaypinicon($NodeID$username),$layout);
    
$layout str_replace("%homeicon%"displayhomeicon($NodeID$username),$layout);
    
$layout str_replace("%editicon%"displayediticon($NodeID$username),$layout);
    
$layout str_replace("%deleteicon%"displaydeleteicon($NodeID$username),$layout);
    
$layout str_replace("%attachmenticon%"displayAttachmentIcon($NodeID),$layout);
    
$layout str_replace("%attachments%"displayAttachments($NodeID),$layout);
    
$layout str_replace("%randomicon%"displayRandomNodeIcon(),$layout);
    
$layout str_replace("%hits%",displayHitCount($NodeID),$layout);

    
// Additions from Rocambole - Dec 24, 2000
    
$layout str_replace("%count%",countnode(),$layout);
    
$layout str_replace("%displayall%",displayall(),$layout);
    
$layout str_replace("%hitOutput%",showHitparade("vertical"),$layout);


    
$layout str_replace("%logo%",displaylogo($username),$layout);
    
$layout str_replace("%license%",displaylicense(),$layout);

    
$layout str_replace("%debugmessages%"$debugmessage,$layout);
// $layout = str_replace("%debugmessage_nohtml%", $striptags($debugmessage,$layout);
    
$layout str_replace("%actions%",displayactions($NodeID),$layout);
    
$layout str_replace("%exportXML%",displayexport(),$layout);
    
$layout str_replace("%nodeid%"$NodeID$layout);
    
$layout str_replace("%me%"$me$layout);
    
$layout str_replace("%nodetitle%",findNodeTitle($NodeID),$layout);
    
$layout str_replace("%sitename%",$sitename,$layout);
    
$layout str_replace("%linkedit%",displaylinkedit($NodeID$username),$layout);

    
$layout str_replace("%layout%",displayLayoutForm($username$NodeID),$layout);
    
$layout str_replace("%timestamp%",displayTimeStamp($username$NodeID),$layout);
    
$layout str_replace("%appendtextbox%",displayAppendNodeTextBox($NodeID), $layout);

    
// Note: %nodetext% has to be the last thing replaced, otherwise the "Layout" node won't show up properly.
    
$layout str_replace("%nodetext%",displaynode($NodeID,$mode,$passthruText),$layout);

    
// Set up a few headers to force dynamic pageloads. No-Cache
//    header ("Expires: Mon, 26 Jul 1997 05:00:00 GMT");              // Date in the past
//    header ("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); // always modified
//    header ("Cache-Control: no-cache, must-revalidate");            // HTTP/1.1
//    header ("Pragma: no-cache");                                    // HTTP/1.0

    
echo $layout;

}


#######################################################
function displaylinks($ReferenceType,$SelectedNode,$direction) {


    
//    ReferenceType = parent, child or jump
    //    SelectedNode is the NodeID (primary key) from the Nodes Table
    //    direction is either vertical or horizontal (display output)

    //    Returns a string with htmlized links
    //        Therefore instead of calling displaylinks(...);
    //        You'll have to call echo displaylinks(...);
    //        Or, if you prefer, you can collect this info in an array
    //            $linktext[$ReferenceType]=displaylinks($ReferenceType,NodeID,vertical
    //


    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function displaylinks</u><ul>";
    
$debugmessage .= "<li>called with: $ReferenceType$SelectedNode$direction";
    
$linkoutput="";


    if (
$direction == "vertical") {
        
$seperator "<br>";
    } elseif (
$direction == "horizontal") {
        
$seperator " | ";
    }


    if (
$ReferenceType == "pin") { // return Pins display
        
$pinQRY "SELECT Pins.NodeID, Nodes.NodeTitle FROM Pins, Nodes
                WHERE Pins.NodeID = Nodes.NodeID
                AND Pins.Username=\"
$username\"
                ORDER BY Nodes.NodeTitle ASC"
;
        
$pinresult mysql_query($pinQRY,$mysqlconnection);
        if (
$pinresult) {
            while ( 
$rowdata mysql_fetch_row($pinresult) ) {
            
$PinNodeID $rowdata[0];
            
$PinNodeTitle$rowdata[1];

            
// Display the resulting link
            
$linkoutput .= "$seperator<a href=\"$me?request=displaypage&NodeID=";
            
$linkoutput .= "$PinNodeID\">$PinNodeTitle</a>\n";
            }
        }

    } elseif (
$ReferenceType == "sibling") { // return siblings display
        
$parents getlinks($SelectedNode,"parent");

        
// I modified getlinks and displaylinks such that NodeTitle gets passed.
        // This saves one select query per link.
        // - sdanic Dec 25, 2000

        
if ($parents) { // check to make sure they exist before walking a nonexistant array
            
while ( list($parentNodeTitle$parentNodeID) = each($parents) ) {
                
$siblings getlinks($parentNodeID,"child"); // Note this will die if getlinks fails.
                
if ( $siblings ) { // check to make sure they exist before you attempt to walk a nonexistant array
                    
while ( list($siblingNodeTitle$siblingNodeID) = each($siblings) ) {
                        if ( 
$siblingNodeID != $SelectedNode ) { // Display the link
                            
$linkoutput .= "$seperator<a href=\"$me?request=displaypage&NodeID=$siblingNodeID\">$siblingNodeTitle</a>";
                        }
                    }
                }
            }
        }

    } else { 
//Reference is either parent,child, or jump
         //Get all the links

        
$links getlinks($SelectedNode,$ReferenceType); // **** There's a problem here. If $links is empty, the program dies
        
if ($links) { // check to make sure they exist before walking a nonexistant array
            
while ( list($linkNodeTitle,$linkNodeID) = each($links) ) {
                
$linkoutput .= "$seperator<a href=\"$me?request=displaypage&NodeID=$linkNodeID\">$linkNodeTitle</a>";
            }
        }
    }

$debugmessage .= "<li>Returned: ".htmlspecialchars($linkoutput);
$debugmessage .= "</ul>";
return 
$linkoutput;
//end of function displaylinks();
}

##############################################################
function displayactions($NodeID) {
    
// Displays a search box
    // Call this with the ID value of the current node
    
global $me$mysqlconnection$debugmessage$username$internationalText$language;

    
$debugmessage .= "<li><u>function displayactions</u><ul>";
    
$debugmessage .= "<li>Called with: $NodeID";

    
$output "<form Method=\"get\" action=\"$me\" name=searchform>
            <input type=\"hidden\" name=\"request\" value=\"findnode\">
            <input type=\"text\" name=\"searchfor\" size=8>\n
            <input type=\"hidden\" name=\"NodeID\" value=
$NodeID>\n
            <input type=\"hidden\" name=\"orderSTR\" value=NodeTitle>\n
            <input type=\"hidden\" name=\"dirSTR\" value=ASC>\n
            <input type=\"hidden\" name=\"reportFormat\" value=brief>\n

            <input type=\"submit\" value=\""
.$internationalText[$language]["search"]."\">
           </form>"
;


$debugmessage .= "<li>Returned: ".htmlspecialchars($output);
$debugmessage .= "</ul>";
return 
$output;

//end of function displayactions($NodeID);
}



##############################################################
function displayexport() {
    global 
$me$mysqlconnection$debugmessage$username;

    
$output .= "Export:<br>";
    
$output .= "<a href=\"$me?request=exporttables&exporttype=csv\">csv</a><br>";

// Took out html export temporarily, until I can make it a more useful feature.
//        <a href=\"$me?request=exporttables&exporttype=html\">html</a>

    
$output .= "<a href=\"$me?request=exportXML\">xml</a><br>";
    
$output .= "<a href=\"$me?request=exportMySQLDump\">MySQLDump</a><br>";
return 
$output;
}

##############################################################
function displaylinkedit($SelectedNode$username) {

    global 
$me$mysqlconnection$debugmessage;

    
$debugmessage .= "<li><u>function displaylinkedit</u><ul>";
    
$debugmessage .= "<li>Called with: $LinkType$LinkTitle$SelectedNode";

    
$linkoutput .= "
        <form Method=\"post\" action=\"
$me\">
            <input type=\"text\" name=\"NodeTitle\" size=8>\n
            <select name=\"ReferenceType\">
                <option value=\"child\">child
                <option value=\"parent\">parent
                <option value=\"jump\">jump
            </select>
            <input type=\"hidden\" name=\"NodeID\"\n
                value=\"
$SelectedNode\">\n
            <input type=\"hidden\" name=\"request\" value=\"modifylinks\">\n
            <input type=\"submit\" size=9 value=\"add/del\">

        </form>"
;
            
// Removed the image submit since it was too obscure
            // <input type=\"image\" value=\"submit\" src=\"graphics/links.jpg\" alt=\"add/remove link\">\n



$debugmessage .= "<li>Returned ".htmlspecialchars($linkoutput);
$debugmessage .= "</ul>";
return 
$linkoutput;

// end of function displaylinkedit($LinkType, $LinkTitle, $SelectedNode);
}

#######################################
function getlayout($username) {
    
// Checks the user cookies to see if a layout is specified
    // Gets the actual layout info from /layout/filename
    // file contains info for how to display the text.
    // Don't bother with a debugmessage on this one. The returned text always gets replaced by displaypage()

    
global $me$mysqlconnection$debugmessage$lucidLayout$defaultLayout;
    
//$debugmessage .= "<li><u>function getlayout called with: $username</u><ul>";

    // Check to see if the user already has a preference set.
    
if ( !isset($lucidLayout) ) { // no cookie found for lucidLayout
        
setcookie("lucidLayout"$defaultLayout); // set a cookie called lucidLayout, value=$defaultLauout, domain=memes.net, secure=1
        
$lucidLayout $defaultLayout// the cookie isn't set until the next pageload
    
}

    
// read in the file that matches the preference/cookie name
    
$openfile fopen("layout/$lucidLayout.layout","r");
    if (
$openfile 0) { // file opened succesfully
        
while (!feof($openfile)) { // do this until reaching the end of file
            
$returnValue .= fgets($openfile4096);
        }
        
fclose($openfile);
    } else { 
// screwed up cookie value for lucidLayout - or file got deleted
        
setcookie("lucidLayout",$defaultLayout); // set a cookie called lucidLayout
        
$lucidLayout $defaultLayout// the cookie isn't set until the next pageload
        
$returnValue .= "Something went wrong with your layout setting.";
        
$returnValue .= "<a href=\"$me\">Try Again</a>";

        
$lowestNode findlowestnode();
        
$returnValue .= displayLayoutForm($username,$lowestNode);
    }



// This code was useful when I was pulling the layout from one of the nodes.
// I may add it back in as a custom layout node. search for node titled $username layout
//    $layoutQRY="SELECT NodeText FROM Nodes
//                WHERE NodeTitle = \"Layout\"";
//    $layoutresult=mysql_query($layoutQRY, $mysqlconnection);
//    $rowdata=mysql_fetch_row($layoutresult);


// $debugmessage .= "<li>Returned: ".htmlentities($rowdata[0]);
// $debugmessage .= "</ul>";
//return $rowdata[0];

return $returnValue;

}


#######################################
function displayRandomNodeIcon() {
    global 
$me$mysqlconnection$debugmessage;

    
$randomNodeID findrandomnode();
    
$randomNodeTitle findNodeTitle($randomNodeID);
    
$outputSTR "<a href=\"$me?request=displaypage&NodeID=$randomNodeID\">";
    
$outputSTR .= "<img src=\"graphics/random.jpg\" border=0 alt=\"$randomNodeTitle\">";
    
$outputSTR .= "</a>";

return 
$outputSTR;

}

#######################################
function displayLayoutForm($username$nodeID) {

    global 
$me,$mysqlconnection,$debugmessage,$lucidLayout,$layoutsList,$internationalText,$language;

    
$layoutoptions explode(",",$layoutsList);

    
$output "";
    
$output .= "\n<form method=\"post\" action=\"$me?request=setlayout\">";
    
$output .= "\n\t<select name=\"layouttype\">";

    while ( list(
$key$value) = each($layoutoptions) ) {
        
$output .= "\n\t\t<option value=\"$value\"";
        if ( 
$value == $lucidLayout ) { // This is their chosen layout
            
$output .= " selected ";
        }
        
$output .= ">$value</option>";

    }

    
$output .= "\n\t</select>";
    
$output .= "\n\t<input type=hidden name=\"nodeID\" value=\"$nodeID\">";
    
$output .= "\n\t<input type=submit value=\"".$internationalText[$language]["changelayout"]."\">";
    
$output .= "\n</form>";

return 
$output;
}
#######################################

function layout_file_exists($strFileName$strPath) {

    
$handle opendir($strPath);

    
$success 0;
        while (
$file readdir($handle)) {
        if ( 
$file == $strFileName ) { //found the file
            
$success 1;
        }
        }
        
closedir($handle);

return 
$success;

}
#######################################


function processLayoutForm($layouttype$nodeID) {
    global 
$me,$mysqlconnection,$debugmessage,$lucidLayout;

    
// Note, when messing around with cookies, the cookie variable isn't available
    // within local functions unless you declare it global.

    // Make sure the layout type is in the list of layout files.
    
if ( file_exists("layout/$layouttype.layout") > ) { // Layout File exists in path


        // set a cookie called lucidLayout, value=$defaultlayout, domain=memes.net, secure=1
        
header("Location: $me?request=displaypage&NodeID=$nodeID");
        
setcookie("lucidLayout",$layouttype,time()+200000000);
        
$lucidLayout $layouttype// Cookies aren't set until next time you load the page
        
$outputValue "Your default layout has now been set to: $lucidLayout";

    } else { 
// Something's wrong with the layout type. File doesn't exist.
        
$outputValue "<br>I think you submitted a bad layout type.";
        
$outputValue .= "<br>Either that, or the file was removed from the layout directory";

    }
    
$outputValue .= "<p><a href=\"$me?request=displaypage&NodeID=$nodeID\">Return to memes.net</a>";
    

return 
$outputValue;


}


#######################################
function displaylogo($username) {
    
// Just returns a bitmap. Not a very exciting function.

    
global $me,$mysqlconnection,$debugmessage;
    
$debugmessage .= "<li><u>function displaylogo called with $username</u><ul>";

    
$output "";
    
$output .= "<img src=\"graphics/logo.jpg\">";

$debugmessage .= "<li>Returned: ".htmlspecialchars($output);
$debugmessage .= "</ul>";
return 
$output;
}

#######################################
function displaylicense() {
    
// Simple function which returns a license statement.

    
global $me,$mysqlconnection,$debugmessage,$shortlicense;

    
$output "";
    
$output .= "<font size=1>";
    
$output .= "All programming for memes.net is released under the <a href=\"http://www.fsf.org/copyleft/gpl.html\">GNU General Public License</a><br>";
    
$output .= $shortlicense;
    
$output .= "</font>";

return 
$output;

}


#######################################
function displaypinicon($NodeID$username) {
    global 
$me,$mysqlconnection,$debugmessage;
    
$debugmessage .= "<li><u>function displaypinicon</u><ul>";
    
$debugmessage .= "<li>Called with $NodeID$username";

    
//Check to see if the node is already pinned to the favorites list

    
$pinQRY="SELECT * FROM Pins
        WHERE NodeID = 
$NodeID
        AND Username = \"
$username\"";

    
$pinQRYresult=mysql_query($pinQRY$mysqlconnection);
    if (
$pinQRYresult 0) { // Query Succeeded

        
if (mysql_num_rows($pinQRYresult) > 0) { // this node is pinned already
            
$buttonoutput .= "<form method=\"POST\" action=\"$me\">";
            
$buttonoutput .= "<input name=\"request\" type=\"hidden\" value=removepin>";
            
$buttonoutput .= "<input name=\"NodeID\" type=\"hidden\" value=$NodeID>";

            
// **** Removed align=\'right\' from following line. -sdanic Sept 19, 2000
            
$buttonoutput .= "<input name=\"submit\" type=\"image\" src=\"graphics/no-pin-left.png\" border=\"0\" align=\"right\">";
            
$buttonoutput .= "</form>";
                
            } else { 
//This node is not pinned
            
$buttonoutput .= "<form method=\"POST\" action=\"$me\">";
            
$buttonoutput .= "<input name=\"request\" type=\"hidden\" value=addpin>";
            
$buttonoutput .= "<input name=\"NodeID\" type=\"hidden\" value=$NodeID>";
                
            
$buttonoutput .= "<input name=\"submit\" type=\"image\" src=\"graphics/pin-left.png\" border=\"0\" align=\"right\">";
            
$buttonoutput .= "</form>";
        }

    } else { 
// pinstatus Query Failed
        
$debugmessage .= "<li>Unable to determine Pin status - Query Failed:<br>$pinQRY";
    }

return 
$buttonoutput;

}

#######################################
function displayhomeicon($NodeID$username) {
    global 
$me,$mysqlconnection,$debugmessage,$internationalText,$language;
    
$debugmessage .= "<li><u>function displayhomeicon</u><ul>";
    
$debugmessage .= "<li>Called with $NodeID$username";

    
$buttonoutput .= "<!-- Home Button -->";
    
$buttonoutput .= "<a href=\"$me?request=displaypage&NodeID=".findlowestnode()."\">";
    
$buttonoutput .= "<img src=\"graphics/home.png\" border=0 alt=\"".$internationalText[$language]["home"]."\"></a>\n";

return 
$buttonoutput;

}

#######################################
function displayediticon($NodeID$username) {
    global 
$me,$mysqlconnection,$debugmessage,$internationalText,$language;
    
$debugmessage .= "<li><u>function displayediticon</u><ul>";
    
$debugmessage .= "<li>Called with $NodeID$username";

    
$buttonoutput .= "<!-- Edit Button -->";
    
$buttonoutput .= "<a href=\"$me?request=editnode&NodeID=$NodeID\">";
    
$buttonoutput .= "<img src=\"graphics/pencil.png\" border=0 alt=\"".$internationalText[$language]["edittext"]."\"></a>\n";

return 
$buttonoutput;

}

#######################################
function displaydeleteicon($NodeID$username) {
    global 
$me,$mysqlconnection,$debugmessage,$internationalText,$language;
    
$debugmessage .= "<li><u>function displaydeleteicon</u><ul>";
    
$debugmessage .= "<li>Called with $NodeID$username";

    
$buttonoutput .= "<!-- Delete Button -->";
    
$buttonoutput .= "<a href=\"$me?request=deletenode&NodeID=$NodeID&confirmation=0\">";
    
$buttonoutput .= "<img src=\"graphics/delete.png\" border=0 alt=\"".$internationalText[$language]["deletenode"]."\"></a>\n";

return 
$buttonoutput;

}


#######################################
function displayicons($NodeID,$username) {
    
//Returns string: icons for editing, deleting, pinning nodes

    
global $me,$mysqlconnection,$debugmessage,$internationalText,$language;
    
$debugmessage .= "<li><u>function displayicons</u><ul>";
    
$debugmessage .= "<li>Called with $NodeID$username";

    
$iconsnoutput displayhomeicon($NodeID$username);
    
$iconsnoutput .= displaypinicon($NodeID$username);
    
$iconsnoutput .= displayediticon($NodeID$username);
    
$iconsnoutput .= displaydeleteicon($NodeID$username);
    

$debugmessage .= "<li>Returned: <pre>".htmlspecialchars($iconsnoutput)."</pre>";
$debugmessage .= "</ul>";
return 
$iconsnoutput;
// end of function displayicons($NodeID, $username);
}


#######################################

function makeDatePretty($strDate$dateFormat "short") {
    
// Takes a MySQL timestamp and returns a readable date.

    
global $internationalText$language;

    
ereg("([0-9]{4})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})([0-9]{2})",$strDate$regs); 
        
$msgtime=mktime($regs[4],$regs[5],$regs[6], 
        
$regs[2],$regs[3],$regs[1]); 

    if ( 
$dateFormat == "long" ) {
            
$strTimeStamp=date($internationalText[$language]["longdateformat"],$msgtime);
    } elseif ( 
$dateFormat == "short" ) {
            
$strTimeStamp=date($internationalText[$language]["shortdateformat"],$msgtime);
    }

return 
$strTimeStamp;

}


#######################################

function displayTimeStamp($userName,$NodeID,$dateFormat "long") { 
                    global 
$me,$mysqlconnection,$username,$debugmessage

                    
// Get the timestamp of the node from the MySQL database 
                    
$strQRY "SELECT lastModified FROM Nodes WHERE NodeID = $NodeID"
                    
$qryresult mysql_query($strQRY,$mysqlconnection); 

                    
$strTimeStamp="Error...could not get timestamp."

                    if ( 
$qryresult ) { // Query succeeded 
                        
$RowData mysql_fetch_row($qryresult); 

            
$strTimeStamp makeDatePretty($RowData[0],$dateFormat);

                    } 

    return 
$strTimeStamp



#######################################
function displaynode($NodeID,$mode="view",$passthruText="") {
    
//Returns a string: contents of NodeText
    // Modes: edit, view and passthru
    // Edit will show a textbox
    // view will show a normal Node
    // passthru will show any given text, results of searches, etc.

    
global $me,$mysqlconnection,$username,$debugmessage,$language,$internationalText;

    
$debugmessage .= "<li><u>function displaynode called with $NodeID$mode</u><ul>";
    
$nodeoutput="";

    
// Get the title and text of the node from the MySQL database
    
$strQRY="SELECT * FROM Nodes WHERE NodeID = $NodeID";
    
$qryresult=mysql_query($strQRY,$mysqlconnection);

    if ( 
$qryresult ) { // Query succeeded

    
$RowData=mysql_fetch_row($qryresult);
    
$NodeTitle=$RowData[1];
    
$NodeText=$RowData[2];

        if (
$mode == "view") { // show the html formatted text of the node
            
if (strstr($NodeTitle,"[showtags]")) { // If the title of the node contains the term [showtags], then show the html code.
                
$nodeoutput .= "<pre>".stripslashes(htmlspecialchars($NodeText))."</pre>";
            } else { 
// Normal Node. No need to add htmlspecialchars
                
$nodeoutput .= "<br>".stripslashes($NodeText);
            }
            
// Raise the hitcount and change the lastViewed field
            
changeHitCount($NodeID);        
        } elseif (
$mode == "edit") { // Show a textarea box that the user can edit.
    
            
$nodeoutput .= displayChangeNodeTextBox($NodeIDstripslashes($NodeText), 1640"replace"$internationalText[$language]["changetext"]);
            
$nodeoutput .= "<a href=\"$me?request=displaypage&NodeID=$NodeID\">Cancel, Return to View";
    
        } elseif (
$mode == "passthru") { // display $passthruText only
            // This is for presenting search results, etc.
            
$nodeoutput .= $passthruText;
        }

    } else { 
// Query failed
        
$debugmessage .= "<li>Query failed: $strQRY";
    }
$debugmessage .= "<li>Returned: <pre>".strip_tags($nodeoutput)."</pre>";
$debugmessage .= "</ul>";
return 
$nodeoutput;

//end of function displaynode($NodeID.$mode);
}

###########################################
function changeHitCount($nodeID) {
    
// Adds 1 to the field NodeHits
    // Changes the lastViewed date to the current timestamp

    
global $me$mysqlconnection;

    
// Get the previous count from the table
    
$strQRY "SELECT HitCount FROM Nodes WHERE NodeID=$nodeID";
    
$qryResult mysql_query($strQRY,$mysqlconnection);
    if (
$qryResult 0) { // Success

        
$rowData mysql_fetch_row($qryResult);
        
$oldCount $rowData[0];
        
$newCount $oldCount 1;

        
// increment the count. Update the table
        
$updateQRY "UPDATE Nodes Set
                HitCount='
$newCount',
                lastViewed='"
.date("YmdHis",time())."'
                 WHERE NodeID=
$nodeID";
        
$updateResult mysql_query($updateQRY,$mysqlconnection) or DIE("update query: $updateQRY failed in changeNodeCount");
        if ( 
$updateResult ) { // success
            
return 1;
        }
    } else { 
// Failure
        
DIE("Query: $strQRY failed in changeNodeCount");
    }


}

###########################################
function displayHitCount($nodeID) {

    global 
$me$mysqlconnection;

    
$strQRY "SELECT HitCount FROM Nodes WHERE NodeID=$nodeID";
    
$qryResult mysql_query($strQRY,$mysqlconnection);
    if (
$qryResult 0) { // Success

        
$rowData mysql_fetch_row($qryResult);
        
$Count $rowData[0];
    } else { 
// failure
        
DIE('function displayHitCount failed');
    }

return 
$Count;

}

###########################################
function displayLastViewed($nodeID) {

    global 
$me$mysqlconnection;

    
$strQRY "SELECT lastViewed FROM Nodes WHERE NodeID=$nodeID";
    
$qryResult mysql_query($strQRY,$mysqlconnection);
    if (
$qryResult 0) { // Success

        
$rowData mysql_fetch_row($qryResult);
        
$lastViewed $rowData[0];
    } else { 
// failure
        
DIE('function displayLastViewed failed');
    }

return 
$lastViewed;

}



###########################################
#function strip_tags($userMessage) {
#    // for older versions of php which don't support the strip_tags function
#
#    $userMessage = ereg_replace('<([^>]|\n)*>', '', $userMessage);
#
#return $userMessage;
#}
#

###########################################
function changenodetext($NodeID,$NodeText$mode "replace") {
    
// update table - change nodetext where nodeid = $NodeID
    // two uses determined by $mode: "replace" text outright, or "append" to text. 
    // returns 1 on success

    
global $me,$mysqlconnection,$username,$debugmessage;
    
$debugmessage .= "<li><u>function changenodetext</u><ul>";
    
$debugmessage .= "<li>".strip_tags("Called with: $NodeID$NodeText");

    
$existingTextQuery "SELECT NodeText FROM Nodes WHERE NodeID = $NodeID";
    
$existingTextQueryResult mysql_query($existingTextQuery$mysqlconnection ) OR DIE("query failed: $existingTextQuery");
    
$existingTextRowData mysql_fetch_row($existingTextQueryResult);
    
$existingText $existingTextRowData[0];

    if ( 
$mode == "replace" ) { // don't worry about existing text, just replace NodeText outright
        
$newNodeText addslashes($NodeText);
    } elseif ( 
$mode == "append" ) { // add the new text to the existing text
        
if ( strstr(findNodeTitle($NodeID),"[showtags]")) { // this node has the showtags flag set. don't use html formatting.
            
$newNodeText addslashes($existingText)."\n--------------------------\n";
            
$newNodeText .= chunk_split($NodeText)." - (".date("h:i M d, Y",time()).")\n";

        } else { 
// showtags is not set. Use HTML formatting
            
$newNodeText addslashes($existingText)."<hr><p>";
            
$newNodeText .= addslashes($NodeText);
            
$newNodeText .= " <font size=1>( ";
            
$newNodeText .= date("h:i M d, Y",time());
            
$newNodeText .= " )</font>\n\n";
        }
    }

    
$updatequery "UPDATE Nodes SET
                NodeText='
$newNodeText',
                lastModified='"
.date("YmdHis",time())."'
            WHERE NodeID='
$NodeID'";

    
$updateqryresult mysql_query($updatequery,$mysqlconnection) or DIE('update query failed in changeNodeText');
    
    
$result 0;
    if (
$updateqryresult 0) { //UPDATE Succeeded

        
$debugmessage .= "<li>Returned 1";
        
$result 1;
    } else { 
//UPDATE failed
        
$debugmessage .= "<li>UPDATE Failed: $updatequery";
        
$result 0;
    }

$debugmessage .= "<li>Returned: $result";
$debugmessage .= "</ul>";
return 
$result;

//end of function changenodetext
}

###########################################
function showRecentlyModified($layout$showtime "true"$numNodesShown 10) {

    
// Shows a list of the five most recently modified nodes

    
global $me,$mysqlconnection,$username,$debugmessage;


    if ( 
$layout == "vertical" ) {
        
$seperator "<br>";
    } elseif ( 
$layout == "horizontal" ) {
        
$seperator " | ";
    }

    
$modifiedQuery "SELECT NodeID, NodeTitle, lastModified FROM Nodes ORDER BY lastModified DESC";
    
$modifiedResult mysql_query($modifiedQuery,$mysqlconnection); 

    if ( 
$modifiedResult ) { // Query succeeded
    
        
$modifiedOutput ""// initialize return string
        
for ( $i=0$i $numNodesShown$i++ ) { // Only show the five most recent
            
$rowData mysql_fetch_row($modifiedResult);
            if (
$rowData) {
                
$recentNodeID $rowData[0];
                
$recentNodeTitle $rowData[1];
                
$recentDateModified $rowData[2];
                
$modifiedOutput .= "<a href=\"$me?request=displaypage&NodeID=".$recentNodeID."\">";
                
$modifiedOutput .= $recentNodeTitle;
                
$modifiedOutput .= "</a>";
                if ( 
$showtime ) {
                    
$modifiedOutput .= " <font size=\"1\">(".makedatepretty($recentDateModified,"short").")</font>";
                }
                
$modifiedOutput .= $seperator;
            }
        }
    }
        
return 
$modifiedOutput;
}


###########################################
function searchNodes($searchfor$NodeID$orderSTR "NodeTitle"$dirSTR="ASC"$reportFormat="brief") {
    
// Searches for $nodeText in the titles and text of all nodes.
    // Returns a hyperlinked list of nodes
    // Must pass the ID number of the previous node.
    
    
global $me,$mysqlconnection,$username,$debugmessage;

    if ( !
$searchfor OR $searchfor == "" ) { // searchfor is empty
        
return displayall();
    }

    
$resultStringHeader "";
    
$resultStringFooter "";
    
$shortList "";
    
$longList "";

    
$debugmessage .= "<li><u>function searchNodes</u><ul>";
    
$debugmessage .= "<li>Called with: $searchfor";

    
$originatingNodeTitle findnodetitle($NodeID);
    if ( 
$reportFormat == "verbose" ) {
        if ( 
$searchfor ) { // User is searching for something
            
$searchQRY "SELECT NodeID,NodeTitle,left(NodeText,255),right(NodeText,255),lastModified,lastViewed,HitCount FROM Nodes 
                WHERE NodeTitle Like \"%
$searchfor%\"
                OR NodeText Like \"%
$searchfor%\"
                ORDER BY 
$orderSTR $dirSTR";
        } else { 
// User just wants all fields
            
$searchQRY "SELECT NodeID,NodeTitle,left(NodeText,255),right(NodeText,255),lastModified,lastViewed,HitCount FROM Nodes ORDER BY $orderSTR $dirSTR";
        }    
    } else { 
// brief format
        
if ( $searchfor ) { // User is searching for something
            
$searchQRY "SELECT NodeID,NodeTitle,\"null\",\"null\",lastModified,lastViewed,HitCount FROM Nodes 
                WHERE NodeTitle Like \"%
$searchfor%\"
                OR NodeText Like \"%
$searchfor%\"
                ORDER BY 
$orderSTR $dirSTR";
        } else { 
// User just wants all fields
            
$searchQRY "SELECT NodeID,NodeTitle,\"null\",\"null\",lastModified,lastViewed,HitCount FROM Nodes ORDER BY $orderSTR $dirSTR";
        }    
    }


    
$searchResult mysql_query($searchQRY$mysqlconnection) OR die($mysql_error);
        
    if ( 
$searchResult ) { // Succcess
        
if ( mysql_num_rows($searchResult) > ) {
            
$debugmessage .= "<li>function searchnodes: $searchQRY";
            
$resultStringHeader .= "<p>These are the results of your search for \"$searchfor\" from \"$originatingNodeTitle\":";


            
// Display Order BY options
            
$resultStringHeader .= "<table cellpadding=5 cellspacing=0 border=1><tr>";
            
$resultStringHeader .= "<td>Order By:</td>";
            
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=NodeTitle&dirSTR=ASC&reportFormat=$reportFormat>Node Title</a></td>";
            
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=lastModified&dirSTR=DESC&reportFormat=$reportFormat>Last Modified</a></td>";
            
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=lastViewed&dirSTR=DESC&reportFormat=$reportFormat>Last Viewed</a></td>";
            
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=HitCount&dirSTR=DESC&reportFormat=$reportFormat>Page Views</a></td>";
            if ( 
$reportFormat == "brief" ) {
                
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=$orderSTR&dirSTR=$dirSTR&reportFormat=verbose>Verbose</a></td>";
            } elseif ( 
$reportFormat == "verbose" ) {
                
$resultStringHeader .= "<td><a href=$me?request=findnode&searchfor=$searchfor&NodeID=$NodeID&orderSTR=$orderSTR&dirSTR=$dirSTR&reportFormat=brief>Brief</a></td>";
            }

            
$resultStringHeader .= "</tr></table>";

            
$longList .= "<dl>";

            while ( 
$rowData mysql_fetch_row($searchResult) ) { // Do this for each returned Node
                
$ResultNodeID $rowData[0];
                
$NodeTitle $rowData[1];
                
$NodeText strip_tags($rowData[2])."<br>...<br>".strip_tags($rowData[3]);
                
$lastModified $rowData[4];
                
$lastViewed $rowData[5];
                
$HitCount $rowData[6];

                
$dateLastModified makeDatePretty($lastModified,"short");
                
$dateLastViewed makeDatePretty($lastViewed,"short");

                
$shortList .= "<br>\"<a href=\"$me?request=displaypage&NodeID=$ResultNodeID\">$NodeTitle</a>\"";
                
$shortList .= " - <font size=1>Modified: $dateLastModified - Hits: $HitCount</font>";


                
$longList .= "<dt><b>Title:</b> <a href=\"$me?request=displaypage&NodeID=$ResultNodeID\">$NodeTitle</a>";
                
$longList .= "<dt><b>Sample Text:</b> $NodeText";
                
$longList .= "<dd><b>Last Modified:</b> $dateLastModified";

                
$longList .= "<dd><b>Link to $originatingNodeTitle as:</b> ";
                
// Insert options to link search result to previous node
                
$linktypes = array(    "parent" => "P",
                            
"child" => "C",
                            
"jump" => "J");
                while ( list(
$linktype,$linkname) = each($linktypes) ) {
                    
$longList .= "[";
                    
$longList .= "<a href=\"$me?request=modifylinks&NodeID=".$NodeID."&NodeTitle=".urlencode($NodeTitle)."&ReferenceType=$linktype\">$linkname</a>";
                    
$longList .= "]";
                }
                
$longList .= "<dd><b>Date Last Viewed:</b> $dateLastViewed";
                
$longList .= "<dd><b>Number of Hits:</b> $HitCount";
                
$longList .= "<dt><hr>";
            }    
            
$longList .= "</dl>";
        } else { 
// No Results found in Lucid. Go to Google automatically:
            // header(Location: 
            
$remoteResult fopen("http://search.dmoz.org/cgi-bin/search?search=".urlencode($searchfor),'r');
            if (
$remoteResult 0) { // file opened succesfully
                
$sitename "http://www.dmoz.org";
                
$resultStringHeader .= "<h2>Lucid didn't find anything. Here are some results from the web</h2>";
                while (!
feof($remoteResult)) { // do this until reaching the end of file
                    
$urlpacket fgets($remoteResult4096);
                    
$urlpacket str_replace("www.memes.net","www.dmoz.org",$urlpacket);
                    
$urlpacket str_replace("A HREF=/","A HREF=$sitename/",$urlpacket);
                    
$urlpacket str_replace("a href=/","A HREF=$sitename/",$urlpacket);
                    
$urlpacket str_replace("src=/","src=$sitename/",$urlpacket);
                    
$urlpacket str_replace("SRC=/","src=$sitename/",$urlpacket);
                    
$urlpacket str_replace("SRC=\"/","src=\"$sitename/",$urlpacket);
                    
$urlpacket str_replace("ACTION=\"","action=\"$sitename",$urlpacket);
                    
$urlpacket str_replace("action=\"","action=\"$sitename",$urlpacket);
                    
$longList .= $urlpacket;
                    
$shortList .= $urlpacket;
                }
                
fclose($remoteResult);
            }
        }
    }



    
$resultStringFooter .= "<hr><h3>You may want to refine your search or search Google for further information</h3>";

    
// Offer the user the opportunity to search Lucid again.
    
$resultStringFooter .= "<form Method=\"post\" action=\"$me\">
                <input type=\"hidden\" name=\"request\" value=\"findnode\">
                <input type=\"text\" name=\"searchfor\" size=18 value=\"
$searchfor\">\n
                <input type=\"hidden\" name=\"NodeID\" value=
$NodeID>\n
                <input type=\"hidden\" name=\"orderSTR\" value=
$orderSTR>\n
                <input type=\"hidden\" name=\"dirSTR\" value=
$dirSTR>\n
                <input type=\"submit\" value=\"Search Lucid again\">
               </form>"
;
/*
    $resultStringFooter .= "<FORM method=GET action=http://www.google.com/custom>
                <INPUT TYPE=text name=q size=18 maxlength=255 value=\"$searchfor\">
                <INPUT type=submit name=sa VALUE=\"Google Search\">
                <INPUT type=hidden name=cof VALUE=\"T:00cc00;LW:300;ALC:00aaaa;L:http://www.memes.net/graphics/logo.jpg;LC:cc0000;LH:100;BGC:black;AH:left;VLC:00aaaa;GL:2;AWFID:b5006d6be0721803;\">
                <A HREF=http://www.google.com/custom>
                <IMG height=38 width=88 SRC=http://www.google.com/images/Logo_60blk.gif border=0 ALT=Google align=middle></A>
            </FORM>";
*/

    // Offer user the opportunity to search Google.

    
$resultStringFooter .= "
                <!-- Search Google -->
                    <IMG SRC=\"http://service.bfast.com/bfast/serve?bfmid=27253343&siteid=28247140&bfpage=horizontal\" BORDER=\"0\" WIDTH=\"1\" HEIGHT=\"1\" NOSAVE >
                    <FORM ACTION=\"http://service.bfast.com/bfast/click\" >
                    <INPUT TYPE=\"hidden\" NAME=\"siteid\" VALUE=\"28247140\" >
                    <INPUT TYPE=\"hidden\" NAME=\"bfpage\" VALUE=\"horizontal\">
                    <INPUT TYPE=\"hidden\" NAME=\"bfmid\" VALUE=\"27253343\" >
                    <IMG SRC=\"http://www.google.com/images/cleardot.gif\" height=1 border=\"0\" ALT=\"Google\">
                    <INPUT TYPE=text name=q size=18 maxlength=255 value=\"
$searchfor\">
                    <INPUT type=submit name=sa VALUE=\"Go\">
                    <IMG SRC=\"http://www.google.com/affiliates/affiliate_logo.gif\" border=\"0\" ALT=\"Google\" align=\"center\">
                    <IMG SRC=\"http://www.google.com/images/cleardot.gif\" height=1 border=\"0\" ALT=\"Google\"></td></tr>
                    </FORM>
                <!-- Search Google -->
                "
;




    if ( 
$reportFormat == "verbose" ) {
        
$fullResultSTR $resultStringHeader.$longList.$resultStringFooter;
    } elseif ( 
$reportFormat == "brief" ) {
        
$fullResultSTR $resultStringHeader.$shortList.$resultStringFooter;
    } 

return 
$fullResultSTR;
}


###########################################
function findnodeID($NodeTitle) {
    
// Returns the NodeID number of $NodeTitle if found, otherwise returns 0

    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function findnodeID</u><ul>";
    
$debugmessage .= "<li>Called with: $NodeTitle";

    
$searchQRY="SELECT NodeID FROM Nodes
            WHERE NodeTitle=\"
$NodeTitle\"";
    
$searchresult=mysql_query($searchQRY,$mysqlconnection);

    
$result=0;
    if (
$searchresult 0) { // Query succeeded
        
if (mysql_num_rows($searchresult) > 0) { // NodeTitle already exists
            //Get the NodeID
            
$rowdata=mysql_fetch_row($searchresult);
            
$foundNodeID=$rowdata[0];
            
$result $foundNodeID;
        } else {
            
$debugmessage .= "<li>node not found";
            
$result 0;
        }
    } else { 
// Query Failed
        
$debugmessage .= "<li>Query failed<br>: $searchQRY";
        
$result 0;
    }

$debugmessage .= "<li>Returned $result";
$debugmessage .= "</ul>";
return 
$result;

// end of function findnodeID($NodeTitle);
}
###########################################
function findNodeTitle($NodeID) {
    
//returns the title of a node given NodeID
    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function findNodeTitle</u><ul>";
    
$debugmessage .= "<li>Called with: $NodeID";

    
$searchQRY="SELECT NodeTitle FROM Nodes
            WHERE NodeID=\"
$NodeID\"";
    
$searchresult=mysql_query($searchQRY,$mysqlconnection);

    
$result 0// Value to return at end of function.
    
if ($searchresult 0) { // Query succeeded
        
if (mysql_num_rows($searchresult) > 0) { // Node exists
            //Get the NodeTitle
            
$rowdata=mysql_fetch_row($searchresult);
            
$foundNodeTitle=$rowdata[0];
            
$result $foundNodeTitle;
        } else {
            
$debugmessage .= "<li>Node Doesn't exist";
            
$result 0;
        }
    } else { 
// Query Failed
        
$debugmessage .= "<li>Query Failed:$searchQRY";
        
$result 0;
    }

$debugmessage .= "<li>Returned: $result";
$debugmessage .= "</ul>";
return 
$result;
// end of function findNodeTitle($NodeID);
}

###########################################
function addnode($NodeTitle) {

    global 
$me,$mysqlconnection,$username,$debugmessage;

    
    
//    Search to see if node title already exists
    //    If it doesn't exist, add it and return the new NodeID
    


    
$debugmessage .= "<li><u>function addnode</u><ul>";
    
$debugmessage .= "<li>Called with: $NodeTitle";

    
$result 0// Value to return at end of function.

    //Search for the node
    
$foundNodeID=findnodeID($NodeTitle);
    if (
$foundNodeID == 0) { //NodeTitle does not exist already

        //Add a new node
        
$strQRY="INSERT INTO Nodes (NodeTitle) VALUES (\"$NodeTitle\")";
        
$qryresult=mysql_query($strQRY,$mysqlconnection);

        if (
$qryresult 0) { //Node added successfully
            
$debugmessage .= "Node added succesfully";

            
//find the id number of the unique node title
            
$NewNodeID=findNodeID($NodeTitle);
            
$result $NewNodeID;
        } else { 
//Failure creating new node
            
$debugmessage .= "Failed to create new node";
            
$result 0;
        }
    } else { 
//Node Title already exists. Just return 0
        
$debugmessage .= "Node Title already exists";
        
$result 0;
    }


$debugmessage .= "<li>Returned $result";
$debugmessage .= "</ul>";
return 
$result;
//end of function addnode($ReferenceType,$SelectedNodeID,$NodeTitle);
}

################################
function in_my_array($value$arrayname) {
    
//Will determine if value exists in array
    //The function in_array is included in php4 so you can remove this one then.
    //Only works for a 1 dimensional array

    // Be careful of variable types. It seems that a string compared against a number will evaluate to true?


    
global $debugmessage;

    
$debugmessage .= "<li><u>function in_my_array</u><ul>";
    
$debugmessage .= "<li>called with $value$arrayname";


    
$debugmessage .= "<li>Array consists of these values<ul>"// set up layout for debugmessage arrayresult
    
    
$result 0// initialize the return value. false until proven true

    
if (count($arrayname) > 0) { // There's at least 1 element in $arrayname
        
while (list($arraykey$elementvalue) = each($arrayname) ) {
            
$debugmessage .= "<li>$arraykey =%gt; $elementvalue";
            if (
$value == $elementvalue) { // found the value in the array
                
$result 1;
            }
        }
    }

    
$debugmessage .= "</ul>";
    
$debugmessage .= "<li>returned: $result";
$debugmessage .= "</ul>";
return 
$result;

}



################################
function modifylinks($SelectedNodeID,$ReferenceType,$ReferenceTitle) {

    
    
// Add or Remove a link from the list depending on whether it already exists.
    // Returns 0 for failue, -NodeID for succesful link removal
    // and +NodeID of any new link it adds.
    

    
global $me$mysqlconnection$username$debugmessage;

    
$debugmessage .= "<li><u>function modifylinks</u><ul>";
    
$debugmessage .= "<li>Called with: $SelectedNodeID$ReferenceType$ReferenceTitle";

    if (isset(
$ReferenceTitle) && ($ReferenceTitle != "") ) { // Prevent empty titles

        
$RecipientNodeID findNodeID($ReferenceTitle); // get the Node ID from the Node Title
        
if ( $RecipientNodeID ) { //Node exists

            // Determine if $Recipient NodeID is in the array of existing links
            
$links getlinks($SelectedNodeID,$ReferenceType);
            if ( 
in_my_array($RecipientNodeID$links) ) { //link found

                
$removalstatus removereference($SelectedNodeID$ReferenceType$ReferenceTitle);
                if (
$removalstatus 0) { // Successfully removed link

                    
$debugmessage .= "<li>Link removed ok. $RecipientNodeID is no longer a $ReferenceType of $SelectedNodeID";
                    
$result $RecipientNodeID*(-1);
                
// **** This is suspect. What's the proper way to reference negative values?
                    // Return a negative number to indicate that NodeID has been removed from the list of links

                
} else { //link couldn't be removed
                    
$debugmessage .= "<li>Link couldn't be removed";
                    
$result 0;
                }

            } else { 
//Node exists, but isn't in links list, add it.
                
$linkstatus makelink($SelectedNodeID$ReferenceType$RecipientNodeID);
                if (
$linkstatus 0) { // link added ok
                
$debugmessage .= "<li>Link added ok: $RecipientNodeID is a new $ReferenceType of $SelectedNodeID";
                    
$result $RecipientNodeID;
                } else { 
// link couldn't be added
                    
$debugmessage .= "<li>Link couldn't be added";
                    
$result 0;
                }
            }
        } else { 
// Node does not exist. Add it, then create the link
            
$debugmessage .= "Node does not exist. Attempting to add a new node.";
            
$RecipientNodeID addnode($ReferenceTitle);
            if ( 
$RecipientNodeID ) { // Created Node succesfully
                
$debugmessage .= "Created node $RecipientNodeID successfully";
                
$linkstatus makelink($SelectedNodeID,$ReferenceType,$RecipientNodeID);
                if ( 
$linkstatus ) { // Created Link succesfully
                    
$debugmessage .= "<li>Created link $SelectedNodeID$ReferenceType$RecipientNodeID successfully";
                    
$result $RecipientNodeID// Set the return value to the new NodeID
                
} else { // Failed to create Link
                    
$debugmessage .= "<li>Failed to create link: makelink($SelectedNodeID,$ReferenceType,$RecipientNodeID)";
                    
$debugmessage .= "<li>".mysql_error();
                    
$result 0;
                }
            } else { 
// Failed to create new node
                
$debugmessage .= "<li>Failure to create Node";
                
$result 0;
            }
        }

    } else { 
// User clicked submit but the title was empty.
        
$debugmessage .= "<li>You have to enter the name of a node to add or remove";
        
$result 0;
    }


$debugmessage .= "<li>returned $result";
$debugmessage .= "</ul>";
return 
$result;

// end of function modifylinks
}

################################
function getlinks($ReferringNodeID,$ReferenceType) {
    
//returns an array of NodeIDs

    
global $me,$mysqlconnection,$debugmessage;
    
$debugmessage .= "<li><u>function getlinks</u><ul>";
    
$debugmessage .= "<li>Called with: $ReferringNodeID$ReferenceType";

    
$result = array();
    
$strQRY "SELECT NodeReferences.RecipientNodeID,Nodes.NodeTitle FROM NodeReferences,Nodes
            WHERE NodeReferences.RecipientNodeID = Nodes.NodeID
            AND NodeReferences.ReferringNodeID = 
$ReferringNodeID
            AND NodeReferences.ReferenceType = \"
$ReferenceType\"
            ORDER BY Nodes.lastModified DESC"
;

    
$queryresult mysql_query($strQRY,$mysqlconnection);
    if (
$queryresult 0) { //Query succesful

        
$debugmessage .= "<li>Now returning the array of links";
        
$debugmessage .= "<ul>"// set up the format for the debugging display

        
while ( $rowdata mysql_fetch_row($queryresult) ) { 
            
$RecipientNodeID $rowdata[0];
            
$NodeTitle $rowdata[1];
            
$debugmessage .= "<li>linkNodeID[$NodeTitle]=$RecipientNodeID";
            
$linkNodeID[$NodeTitle] = $RecipientNodeID;
        }

        
$debugmessage .= "</ul>";

        
$result $linkNodeID//Array of NodeID's
    
} else { //query failed
        
$debugmessage .= "Query failed: $strQRY";
        
$result 0;
    }

$debugmessage .= "</ul>";
return 
$result;

//end of function getlinks($ReferringNodeID,$ReferenceType);
}

################################################################
function deletenode($NodeID,$confirmation) {
    
// return 1 on success, 0 on failure

    
    //    Delete the current node as well as all links to or from this node and all pins.
    //    DANGEROUS since it could easily leave orphans.
    //    I don't plan to write any code to traverse the links and remove blocks of nodes.

    //    This should be called first with $confirmation=no then with $confirmation=yes

    //    **** Should modify this function so it just echos the confirmation form directly rather
    //    than relying on the function that called it to display the $debugmessage.
    

    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function deletenode</u><ul>";
    
$debugmessage .= "<li>Called with: $NodeID$confirmation";

    
$result 0// Initialize return value. False until proven true

    
$deleteQRY = array(
        
"nodes"    =>    "DELETE FROM Nodes WHERE NodeID=\"$NodeID\"",
        
"links"    =>    "DELETE FROM NodeReferences WHERE ReferringNodeID=\"$NodeID\"
                 OR RecipientNodeID=\"
$NodeID\"",
        
"pins"    =>    "DELETE FROM Pins WHERE NodeID=\"$NodeID\""
    
);

    if ( 
$confirmation == "yes" ) { // send the SQL DELETE commands
        
if ( $NodeID == findlowestnode() ) { // They're trying to delete the home node.
            
DIE('Can\'t delete the home node.');
        } else {

            
reset($deleteQRY);
            while ( list(
$linktype,$strQRY) = each($deleteQRY) ) {
                
$deleteresult=mysql_query($strQRY,$mysqlconnection);
                if ( 
$deleteresult ) { // Query succeeded
                    
$debugmessage "<li>Delete successful: $strQRY";
                    
$result 1;
                } else {
                    
$debugmessage "<li>Query Failed: $strQRY";
                }
            }
        }
        
$debugmessage .= "</ul>";

    } else { 
// Tell them what they're going to do and give them an option to cancel
        
reset($deleteQRY);
        
$debugmessage ""// Reset the message so just the following text shows up.
        
$debugmessage .= "<h3>Are you damn sure you want to do this? It's probably a bad idea.</h3>";
        
$debugmessage .= "<p>Recklessly deleted nodes and links can cause orphans in your Lucid Fried Eggs database.";

        
$debugmessage .= "<p>Here's what's going to happen.<ul>";

        while (list(
$linktype,$strQRY) = each($deleteQRY)) {
            
$debugmessage .= "<li>$linktype<ul><li>$strQRY</ul>";
        }
        
$debugmessage .= "</ul>";

        
$debugmessage .= "<h3>Choose Wisely</h3>
            <table><tr><td>
            <form method=\"POST\" action=\"
$me\">
                <input type=hidden name=\"request\" value=\"deletenode\">
                <input type=hidden name=\"NodeID\" value=\"
$NodeID\">
                <input type=hidden name=\"confirmation\" value=\"yes\">
                <input type=submit value=\"I really want to delete this node (bad idea)\">
            </form>
            </td><td>
            <form method=\"POST\" action=\"
$me\">
                <input type=hidden name=\"request\" value=\"displaypage\">
                <input type=hidden name=\"NodeID\" value=
$NodeID>
                <input type=submit value=\"I decided not to delete this node (good idea)\">
            </form>
            </table>"
;

        
$result 0// **** I'm not sure about this. If this function is called, and returns a value
                 //      of zero, the initial call may assume that the delete failed, when in fact
                 //      it was passed on for confirmation

    
}

return 
$result;

// end of function deletenode($NodeID,$confirmation);
}




#################################
function removereference($SelectedNode,$ReferenceType,$ReferenceTitle) {
    
// Find and remove the reference given a NodeID, a type of reference(parent, child, jump) and a name.
    // Returns 1 on success and 0 on failure

    
global $me$mysqlconnection$username,$debugmessage;

    
$debugmessage .= "<li><u>function removereference</u><ul>";
    
$debugmessage .= "<li>Called with: $SelectedNode$ReferenceType$ReferenceTitle";

    
$result 0// Unsuccessful until proven Successful

    // Find the NodeID for the ReferenceTitle given
    
$RecipientID=findNodeID($ReferenceTitle);
    if (
$RecipientID 0) { // Recipient NodeID found
        
        //Delete forward reference
        
$delQRY="DELETE FROM NodeReferences
                WHERE ReferringNodeID = 
$SelectedNode
                AND RecipientNodeID = 
$RecipientID
                AND ReferenceType = \"
$ReferenceType\"";
        
$qryresult=mysql_query($delQRY,$mysqlconnection);
        if ( 
$qryresult ) { // Successful query
            
$debugmessage .= "<li>Deleted ".mysql_affected_rows($qryresult)." links with this command: $delQRY";


            
//Delete reverse reference
            //find the inverse of the link type parent/child jump/jump
            
$reversetype getreversereferencetype($ReferenceType);
        
            
$delQRY="DELETE FROM NodeReferences
                    WHERE ReferringNodeID = 
$RecipientID
                    AND RecipientNodeID = 
$SelectedNode
                    AND ReferenceType = \"
$reversetype\"";
            
$qryresult=mysql_query($delQRY,$mysqlconnection);

            if ( 
$qryresult ) { // Successfully deleted reverse reference
                
$debugmessage .= "<li>Deleted ".mysql_affected_rows($qryresult)." links with this command: $delQRY";
                
$result 1// This is the only time Result will equal 1 (success)

            
} else { // Delete Reverse Reference Query failed
                
$debugmessage .= "Delete Failed: $delQRY";
            }


        } else { 
// Delete Forward Reference Query failed
            
$debugmessage .= "Delete Failed: $delQRY";
        }



    } else { 
// Recipient NodeTitle not found
        
$debugmessage .= "No Node exists by this name: $ReferenceTitle";
    }


$debugmessage .= "<li>Returned $result";
$debugmessage .= "</ul>";
return 
$result;

// end of function removereference($SelectedNod, $ReferenceType, $ReferenceTitle);
}


#################################
function findrandomnode() {
    global 
$me$mysqlconnection$username$debugmessage;
    
// generates and returns a random nodeID

    
$strQRY "SELECT NodeID FROM Nodes";
    
$queryresult mysql_query($strQRY$mysqlconnection) or DIE("query: $strQRY failed in findrandomnode");
    
$numrows mysql_num_rows($queryresult);
    if (
$numrows 0) {
        
mt_srand((double)microtime()*1000000);
        
$randomRow mt_rand(0,$numrows-1);
        
$movePointer mysql_data_seek($queryresult$randomRow);
        
$rowData mysql_fetch_row($queryresult);
        
$randomNode $rowData[0];
    } else {
        return 
0;
    }

return 
$randomNode;
}

#################################
function findlowestnode() {
    
// Function to find the node with the lowest NodeID
    // Returns the NodeID
    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function findlowestnode</u><ul>";
    
$debugmessage .= "<li>Called with: ()";

    
$idQRY "SELECT Min(NodeID) FROM Nodes";
    
$idresult mysql_query($idQRY,$mysqlconnection);
    
$rowdata mysql_fetch_row($idresult);
    
$lowestnodeID $rowdata[0];

$debugmessage .= "<li>Returned $lowestnodeID";
$debugmessage .= "</ul>";
return 
$lowestnodeID;

// end function findlowestnode();
}
#################################
function makelink($ReferringNodeID,$ReferenceType,$RecipientNodeID) {
    
// Creates a link from $ReferringNodeID to $RecipientNodeID using $ReferenceType
    // This is simply a row in the NodeReferences Table.
    // Then creates the reverse link parent/child child/parent jump/jump
    // returns a positive value on succesful completion

    
global $me,$mysqlconnection,$username,$debugmessage;

    
$debugmessage .= "<li><u>function makelink</u><ul>";
    
$debugmessage .= "<li>Called with: $ReferringNodeID$ReferenceType$RecipientNodeID";

    
//Initialize the function return value
    
$makelinkstatus 0// False until proven true

    // Insert the forward reference
    
$forwardreference="INSERT INTO NodeReferences
               (ReferringNodeID, ReferenceType, RecipientNodeID)
               VALUES (
$ReferringNodeID,\"$ReferenceType\",$RecipientNodeID)";
    
$forwardreferenceresult=mysql_query($forwardreference,$mysqlconnection);
    if (
$forwardreferenceresult 0) { // Created forward reference
        
$debugmessage .= "<li>Created forward link";
        
        
// Determine the inverse reference type parent/child, jump/jump
        
$reverselink getreversereferencetype($ReferenceType);
    
        
// Insert the reverse reference
        
$reversereference "INSERT INTO NodeReferences
                   (ReferringNodeID, ReferenceType, RecipientNodeID)
                   VALUES (
$RecipientNodeID,\"$reverselink\",$ReferringNodeID)";
        
$reversereferenceresult mysql_query($reversereference,$mysqlconnection);
        
        if (
$reversereferenceresult 0) { // Created the Reverse reference
            
$debugmessage .= "<li>Created reverse link";
            
$makelinkstatus 1// This is the only time this will be true
                        // Both forward and reverse references have been created.
        
} else { // Failed to create Reverse Reference
            
$debugmessage .= "<li>Failed to Create Reverse Reference: $reversereference";
            
$debugmessage .= "<li>".mysql_error();
        }
    } else { 
// Failed to create forward reference
        
$debugmessage .= "<li>Failed to Create Forward Reference: $forwardreference";
        
$debugmessage .= "<li>".mysql_error();
    }

$debugmessage .= "<li>Returned $makelinkstatus";
$debugmessage .= "</ul>";
return 
$makelinkstatus;
//end of function makelink($ReferringNodeID,$Referencetype,$RecipientNodeID);
}

###################################################################
function getreversereferencetype($ReferenceType) {
    
//Returns a string indicating the type of reference which is exactly opposite to this one

    
global $me$mysqlconnection$debugmessage$username;

    
$debugmessage .= "<li><u>function getreversereferencetype called</u><ul>";
    
$debugmessage .= "<li>Initial Reference type = $ReferenceType";
    
    
$lookup = array(
            
"parent"    =>    "child",
            
"child"        =>    "parent",
            
"jump"        =>    "jump"
            
);

    
$result $lookup[$ReferenceType];

$debugmessage .= "<li>Reverse Reference Type = $result";
$debugmessage .= "</ul>";
return 
$result;

// end of function getreversereferencetype($ReferenceType);
}
###################################################################
function modifypins($action,$NodeID,$username) {
    
//returns 1 for success, and 0 for failure

    // This function requires a pins table
    //    table: Pins Fields: PinID, NodeID, Username
    

    
global $me,$mysqlconnection,$debugmessage;
    
$debugmessage .= "<li><u>function modifypins</u><ul>";
    
$debugmessage .= "<li>Called with: $action$NodeID$username";

    
$result 0// False until proven true
    
    // Define Query
    
if ( ($action == "add") || ($action == "remove") ) { // Requested action matches expected input
        
if ($action == "add") {
            
$strQRY="INSERT INTO Pins (NodeID, Username)
                 VALUES (\"
$NodeID\",\"$username\")";
        } elseif (
$action == "remove") {
            
$strQRY="DELETE FROM Pins
                WHERE NodeID=\"
$NodeID\"
                AND Username=\"
$username\"";
        }
        
// Execute Query
        
$qryresult=mysql_query($strQRY,$mysqlconnection);
        if (
$qryresult 0) { //Success
            
$result 1// This will be the only time result can equal 1. 
        
} else { //Failure
            
$debugmessage .= "<li>Unable to complete request. Problem executing $strQRY";
        }
    } else { 
//$action doesn't match expected input
        
$debugmessage .= "<li>Unable to complete request. No action specified by $me";
    }


$debugmessage .= "<li>returned: $result";
$debugmessage .= "</ul>";
return 
$result;

//end of function modifypins();
}

##########################################################
function exporttables($exporttype) {
    
// Displays the output right away. Not returned string

    
global $me,$mysqlconnection,$username,$debugmessage;
    
$debugmessage .= "<hr><h3>function exporttables</h3>\n";
    
$debugmessage .= "Called with: $exporttype";

//Removed Pins from the export list. Didn't feel they were necessary.
//    $strQRY[pins]="SELECT * FROM Pins";

    
$strQRY[nodes]="SELECT * FROM Nodes";
    
$strQRY[links]="SELECT * FROM NodeReferences";

    
$delimiter = array( // $delimiter[$exporttype][$location]
        
"html" => array(
            
"tablestart"    =>    "<table border=1>",
            
"tableend"    =>    "</table>",
            
"rowstart"    =>    "<tr>",
            
"rowend"    =>    "</tr>",
            
"cellstart"    =>    "<td align=left valign=top>",
            
"cellend"    =>    "</td>"
            
),
        
"csv" => array(
            
"tablestart"    =>    "",
            
"tableend"    =>    "",
            
"rowstart"    =>    "",
            
"rowend"    =>    "\n<br>",
            
"cellstart"    =>    "\"",
            
"cellend"    =>    "\","
            
)
        );

    if (
$exporttype=="csv") {
        
$striptags=1;
    } else {
        
$striptags=0;
    }


    
reset($strQRY);
    while (list(
$Table,$query) = each($strQRY)) { // submit each strQRY
        
$result mysql_query($query,$mysqlconnection);
        echo 
$delimiter[$exporttype]["tablestart"];
        while (
$rowdata mysql_fetch_row($result)) { // get each Row
            
echo $delimiter[$exporttype]["rowstart"];
            while (list(
$field,$celldata) = each($rowdata)) { // get each cell value
                
echo $delimiter[$exporttype]["cellstart"];
                if (
$striptags) { // Don't want nasty html characters
                    
echo strip_tags($celldata);
                } else { 
//html ok
                    
echo ($celldata);
                }
                echo 
$delimiter[$exporttype]["cellend"];
            }
            echo 
$delimiter[$exporttype]["rowend"];
        }
        echo 
$delimiter[$exporttype]["tableend"];
    }

// end of function exporttables($exporttype);
}

###################################################################################
function exportXML() {

    global 
$me,$mysqlconnection,$username,$debugmessage;
    
header("Content-type: text/plain"); // Make sure the browser doesn't render this as html

    
$debugmessage .= "<hr><h3>function exportXML</h3>\n";
    
$debugmessage .= "Called with: nothing... the function has no arguments";


    
$returnSTR "";
    
    
$returnSTR .= "<mind default_idea=\"".findlowestnode()."\">";
    
$returnSTR .= "\n<head></head>";
    
$returnSTR .= "\n<body>";
    
// grab NodeID, NodeTitle, NodeText, lastModified from Nodes
    // grab RecipientNodeID, ReferenceType from NodeReferences WHERE ReferringNodeID = (from above) Nodes.nodeID

    
$nodeQRY "SELECT NodeID, NodeTitle, NodeText, lastModified from Nodes";

    
$nodeResult mysql_query($nodeQRY$mysqlconnection);
    while (
$nodeRowData mysql_fetch_row($nodeResult) ) { // Get each node
        
$returnSTR .= "\n";
        
$returnSTR .= "<idea id=\"".$nodeRowData[0]."\" timestamp=\"".$nodeRowData[3]."\"";
        
$returnSTR .= " xlink:title=\"".htmlspecialchars($nodeRowData[1])."\">";
        
$referenceQRY "SELECT RecipientNodeID, ReferenceType FROM NodeReferences WHERE ReferringNodeID = ".$nodeRowData[0]." ORDER BY ReferenceType";
        
$referenceResult mysql_query($referenceQRY$mysqlconnection) OR Die("failed ".$referenceQRY);
        if ( 
mysql_num_rows($referenceResult) > ) { // more than zero links found, display them.
            
$returnSTR .= "\n";
            while (
$referenceRowData mysql_fetch_row($referenceResult) ) { // do this for each reference
                // **** This is important. Jumps are arbitrarily changed to "peers". I should change the entire database, not just this line
                
if ( $referenceRowData[1] == "jump" ) { // Change jumps to peers for exporting to ThoughtStream
                    
$referenceRowData[1] = "peer";
                }
                
$returnSTR .= "\n\t<assoc xlink:role=\"".$referenceRowData[1];
                
$returnSTR .= "\" xlink:href=\"#".$referenceRowData[0]."\"/>";
            }
            
$returnSTR .= "\n";
        }
        
$returnSTR .= "\n\t";
        
$returnSTR .= "<content type=\"text/plain\">";

        
// Display the Node Content - newline every 76 chars, no html
        
$returnSTR .= "\r\n".substr(strip_tags($nodeRowData[2]),0,1023);
        
$returnSTR .= "\n\t";
        
$returnSTR .= "</content>";
        
$returnSTR .= "\n</idea>";
    }
    
$returnSTR .= "\n</body>\n</mind>";


return 
$returnSTR;
//end of function exportXML
}


##################################################
function exportMySQLDump() {

    global 
$me,$mysqlconnection,$username,$password,$dbname,$debugmessage,$mysqldumploc;
    
header("Content-type: text/plain"); // Make sure the browser doesn't render this as html

    // First, passthru the dump of all tables except for binaryData.
    // Include row data
    
passthru("$mysqldumploc \
            --user=
$username \
            --password=
$password \
            
$dbname \
            NodeReferences \
            Nodes \
            Pins
        "
);

    
// Next, dump binaryData
    // Leave out row data
    
passthru("$mysqldumploc \
            --user=
$username \
            --password=
$password \
            
$dbname \
            --no-data \
            binary_data
        "
);


//end of function exportMySQLDump
}
################################################
function countnode() {

    global 
$me,$mysqlconnection,$debugmessage;
    
$countQRY="SELECT count(*) FROM Nodes ";
    
$countresult=mysql_query($countQRY$mysqlconnection);

    
$lecompte=mysql_fetch_row($countresult) ;
    
$compte=$lecompte[0];
return 
$compte;
//fin de la fonction countnode
}

################################################
function displayall() {

    global 
$me,$mysqlconnection,$debugmessage;
    


$strQRY="SELECT * FROM Nodes ORDER BY NodeID";

    
$qryresult=mysql_query($strQRY,$mysqlconnection);

    
    


while ( 
$rowData mysql_fetch_row($qryresult) )
{

$resultat .= "<a href=\"$me?request=displaypage&NodeID=".$rowData[0]."\">";
                
$resultat .= $rowData[1]."</a> ";


$resultat .= ".|.";
}


return 
$resultat;
//fin de la fonction displayall
}


###########################################
function showHitparade($layout "vertical"$showtime "true"$numNodesShown 10) {

    
// Montre les  pages les plus lues
    // List The Most Popular Nodes

    
global $me,$mysqlconnection,$username,$debugmessage;


    if ( 
$layout == "vertical" ) {
        
$seperator "<br>";
    } elseif ( 
$layout == "horizontal" ) {
        
$seperator " | ";
    }

    
$modifiedQuery "SELECT NodeID, HitCount FROM Nodes ORDER BY HitCount DESC";
    
$modifiedResult mysql_query($modifiedQuery,$mysqlconnection); 

    if ( 
$modifiedResult ) { // Query succeeded
    
        
$hitOutput ""// initialize return string
        
for ( $i=0$i $numNodesShown$i++ ) { // Only show the  most popular
            
$rowData mysql_fetch_row($modifiedResult);
            if (
$rowData) {
                
$nodeID $rowData[0];
                
$hitOutput .= "<a href=\"$me?request=displaypage&NodeID=".$rowData[0]."\">";
                
$hitOutput .= findNodeTitle($nodeID);
                
$hitOutput .= "</a>";
                if ( 
$showtime ) {
                    
$hitOutput .= " <font size=\"1\">(".displayHitCount($nodeID).")</font>";
                }
                
$hitOutput .= $seperator;
            }
        }
    }
        
return 
$hitOutput;
}


</script>