Documentation is available at botloaderfuncs.php
- <?
- /*
- Program E
- Copyright 2002, Paul Rydell
- Portions by Jay Myers
- This file is part of Program E.
- Program E 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.
- Program E 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 Program E; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
- /**
- * AIML loading functions
- *
- * Contains contains the functions for the actual loading of AIML.
- * @author Paul Rydell
- * @copyright 2002
- * @version 0.0.8
- * @package Loader
- */
- /**
- * The general preferences and database details.
- */
- require_once "dbprefs.php";
- global $selectbot, $annesID;
- /**
- * Deletes everything about a bot.
- *
- * Empties the tables, bot, patterns, templates, bots and gmcache
- *
- * @param integer $bot The bot's ID
- *
- * @return void
- */
- function deletebot($bot)
- {
- $q="delete from bot where bot=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from patterns where bot=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from templates where bot=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from bots where id=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from gmcache";
- $e = mysql_query($q);
- if ($e){
- }
- }
- /**
- * Deletes information about a bot in the cache and bot tables.
- *
- * Used by the incremental bot loader program so it doesn't wipe out the whole
- * bot on each aiml file load. Deletes everything in bot, bots and gmcache tables.
- *
- * @param integer $bot The bot's ID.
- *
- * @return void
- */
- //
- //
- function deletejustbot($bot){
- $q="delete from bots where id=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from bot where bot=$bot";
- $e = mysql_query($q);
- if ($e){
- }
- $q="delete from gmcache";
- $e = mysql_query($q);
- if ($e){
- }
- }
- /**
- * Deletes the gmcache table.
- *
- * This needs to be called whenever the patterns or templates table is updated.
- *
- * @return void
- */
- function flushcache()
- {
- $q="delete from gmcache";
- $e = mysql_query($q);
- if ($e){
- }
- }
- /**
- * Makes the keys of an array uppercase.
- *
- * Makes the keys of an array uppercase.
- *
- * @param array $testa The array where the keys need to be changed into uppercase.
- *
- * @return array An array with only uppercase keys.
- */
- function upperkeysarray($testa)
- {
- $newtesta=array();
- $newkeys=array_keys($testa);
- for ($x=0;$x<sizeof($newkeys);$x++){
- $newtesta[strtoupper($newkeys[$x])]=$testa[$newkeys[$x]];
- }
- return $newtesta;
- }
- /**
- * Write the substitution include file
- *
- * Write the substitution arrays back into the subs.inc
- *
- * @global object The opened subs.inc file, ready to write to.
- *
- * @param string $string most likely an array or all arrays turned into a big file.
- *
- * @return void
- */
- function addtosubs($string)
- {
- global $fp;
- fwrite($fp,$string);
- }
- /**
- * Create the object for writing the substitution include file
- *
- * Creates the object, which is then used by addtosubs() to write to
- *
- * @see addtosubs()
- * @see makesubscode()
- * @global object
- *
- * @return void
- */
- function createsubfile()
- {
- global $fp;
- $fp = fopen ("subs.inc", "w+");
- }
- /**
- * Find a word in the patterns table given the word and the parent.
- *
- * The AIML patterns are stored in the MySQL table in a binary tree format.
- * This function retrieves the next word details based upon the previous' word's ID.
- * If this word doesn't exist it returns 0, else it returns it's details.
- *
- * @uses setnotend()
- *
- * @param string $word The word that is to be searched
- * @param integer $parent The ID of the parent word
- *
- * @return integer The ID of the word that was searched
- */
- function findwordid($word,$parent)
- {
- $word=addslashes($word);
- $query="select id,isend from patterns where word='$word' and parent=$parent";
- $selectcode = mysql_query($query);
- if ($selectcode){
- if(!mysql_numrows($selectcode)){
- return 0;
- }
- else{
- while ($q = mysql_fetch_array($selectcode)){
- if ($q[1]==1){
- setnotend($q[0]);
- }
- return $q[0];
- }
- }
- }
- }
- /**
- * Find a wildcard in the patterns table given the word and the parent.
- *
- * Similar as findwordid() but this will retrieve the ID if there is a wildcard that fits.
- *
- * @uses setnotend()
- *
- * @param string $word The word that is to be searched, either _ or *
- * @param integer $parent The ID of the parent word
- *
- * @return integer The ID of the word that was searched
- */
- function findwordidstar($word,$parent)
- {
- if ($word=="*"){
- $val=3;
- }
- elseif ($word=="_"){
- $val=1;
- }
- $query="select id,isend from patterns where parent=$parent and word is null and ordera=$val";
- $selectcode = mysql_query($query);
- if ($selectcode){
- if(!mysql_numrows($selectcode)){
- return 0;
- }
- else{
- while ($q = mysql_fetch_array($selectcode)){
- if ($q[1]==1){
- setnotend($q[0]);
- }
- return $q[0];
- }
- }
- }
- }
- /**
- * Set an entry in the patterns table to not be flagged as the last word in its context.
- *
- * Update a record in the patterns table, change isend column from 1 to 0. Given a particular word ID.
- *
- * @param integer $wordid
- *
- * @return void
- */
- function setnotend($wordid)
- {
- $query="update patterns set isend=0 where id=$wordid";
- $q=mysql_query($query);
- if ($q){
- }
- }
- /**
- * Inserts the pattern into the patterns table.
- *
- * inserts the pattern, that and topic as individual words in binary tree format into the patterns table
- *
- * @uses findwordid()
- * @uses insertwordpattern()
- * @uses findwordidstar()
- *
- * @global string
- * @global integer
- *
- * @param string $mybigsentence Contains the pattern, that and topic in the following format <input>word word<that>word word<topic>word word.
- */
- function insertmysentence($mybigsentence)
- {
- global $selectbot, $annesID;
- $sentencepart="";
- $newstarted=0;
- if($annesID != ""){
- $parent = $annesID;
- } else {
- $parent=-$selectbot;
- }
- //Parse into invidividual words
- //Use split
- $allwords=split(" ",$mybigsentence);
- $qadd="";
- for ($x=0;$x<sizeof($allwords)+1;$x++){
- // Last word in context
- $lwic=0;
- if ($x==sizeof($allwords)){
- $word="";
- }
- else {
- $word=$allwords[$x];
- }
- if (strtoupper($word)=="<INPUT>"){
- $sentencepart="INPUT";
- } elseif (strtoupper($word)=="<THAT>"){
- $sentencepart="THAT";
- } elseif (strtoupper($word)=="<TOPIC>"){
- $sentencepart="TOPIC";
- }
- // Find out if it is the last word in its context
- if ($x==(sizeof($allwords)-1)){
- $lwic=1;
- }
- // Prevent some warnings by checking this first.
- elseif (($x+1) >= (sizeof($allwords))){
- }
- elseif ((strtoupper($allwords[$x+1])=="<THAT>") || (strtoupper($allwords[$x+1])=="<TOPIC>")){
- $lwic=1;
- }
- if (($word!="*")&&($word!="_")){
- if ($newstarted!=1){
- $wordid=findwordid($word,$parent);
- }
- if (($wordid!=0) && ($newstarted!=1)){
- $parent=$wordid;
- }
- else {
- $newstarted=1;
- $sword=addslashes($word);
- $qadd="($selectbot, null,'$sword',2,$parent,$lwic)";
- $parent = insertwordpattern($qadd);
- }
- }
- elseif (($word=="*")||($word=="_")){
- if ($newstarted!=1){
- $wordid=findwordidstar($word,$parent);
- }
- if (($wordid!=0) && ($newstarted!=1)){
- $parent=$wordid;
- }
- else {
- $newstarted=1;
- if ($word=="*"){
- $val=3;
- }
- elseif ($word=="_"){
- $val=1;
- }
- $qadd="($selectbot, null,null,$val,$parent,$lwic)";
- $parent = insertwordpattern($qadd);
- }
- }
- }
- return $parent;
- }
- /**
- * Inserts an entry into the patterns table. Returns the ID of the new row inserted.
- *
- * insert a word into the patterns table, returns the id of the record so it can be
- * used as the parent ID of the next word that's to be inserted.
- *
- * @param string $qadd The word of the pattern to be inserted
- *
- * @return integer The record ID of the inserted word.
- */
- function insertwordpattern($qadd)
- {
- $qcode=mysql_query("insert into patterns(bot,id,word,ordera,parent,isend) values $qadd");
- if ($qcode){
- return mysql_insert_id();
- }
- }
- /**
- * Inserts a template into the template table.
- *
- * Insert the template into the template database. <br/>
- * This version has been adapted to also insert the pattern, that and topic into the additionally added columns
- *
- * @uses templateexists()
- *
- * @global integer
- * @global integer The ID of the record in the patterns table that links to this table
- * @global string The pattern, including variables like _ and *.
- * @global string the topic, including variable like _ and *
- * @global string the that, including variables like _ and *
- *
- * @param integer $idused The ID of the record in the patterns table that links to the template table.
- * @param string $template The contents inbetween <template/> tags.
- *
- * @return void
- */
- function insertmytemplate($idused,$template)
- {
- global $selectbot,$templatesinserted, $pattern, $topic, $that;
- if (!templateexists($idused)){
- $templatesinserted++;
- $template=addslashes($template);
- $query="insert into templates (bot,id,template,pattern,that,topic) values ($selectbot, $idused,'$template','$pattern','$that','$topic')";
- $qcode=mysql_query($query);
- if ($qcode){
- }
- }
- }
- /**
- * Checks if a template exists for a given pattern
- *
- * Does a query on the database to see if an ID is used by a template in the templates table.
- *
- * @param integer $idused The ID number that corresponds to the number in the ID column, if it exists.
- *
- * @return boolean true/false
- */
- function templateexists($idused)
- {
- $query="select id from templates where id=$idused";
- $qcode=mysql_query($query);
- if ($qcode){
- if(!mysql_numrows($qcode)){
- return false;
- }
- }
- return true;
- }
- /**
- * Called by the XML parser that is parsing the startup.xml file.
- *
- * startS and endS are two functions that cooperate. startS looks for the start of an XML tag, endS for the end tag.
- * It fills the global variabls with info to be processed further on. Inserts the bots into the bots table, inserts the bot predicates into its respective table.
- *
- * @todo Find out what Global $areinc does
- *
- * @uses upperkeysarray()
- * @uses botexists()
- * @uses getbotid()
- * @uses deletebot()
- *
- * @global integer
- * @global string
- * @global array
- * @global array contains the splitter characters which are used to split the sentences. For example period, comma, semi-colon, exclamation mark, question mark.
- * @global array contains the input, split into sentences
- * @global array contains the gender words or phrases.
- * @global array contains the person words or phrases
- * @global array contains the person2 words or phrases
- * @global array contains the names of all the bots, or their ID's
- * @global array contains something unknown
- *
- * @param resource $parser SAX XML resource handler
- * @param string $name name of the encountered tag.
- * @param array $attrs contains the additional attribues of a tag, like value, id, find.
- *
- * @return void
- */
- function startS($parser,$name,$attrs)
- {
- global $selectbot, $whaton, $startupwhich, $splitterarray,
- $inputarray, $genderarray, $personarray, $person2array, $allbots, $areinc;
- $attrs=upperkeysarray($attrs);
- if (strtoupper($name)=='LEARN') {
- $whaton = 'LEARN';
- }
- if (strtoupper($name)=="GENDER"){
- $startupwhich="GENDER";
- }
- elseif (strtoupper($name)=="INPUT"){
- $startupwhich="INPUT";
- }
- elseif (strtoupper($name)=="PERSON"){
- $startupwhich="PERSON";
- }
- elseif (strtoupper($name)=="PERSON2"){
- $startupwhich="PERSON2";
- }
- if (strtoupper($name)=="PROPERTY"){
- $q="insert into bot (bot,name,value) values ($selectbot,'" . addslashes($attrs["NAME"]) . "','" . addslashes($attrs["VALUE"]) . "')";
- $qcode=mysql_query($q);
- if ($qcode){
- }
- }
- elseif (strtoupper($name)=="BOT") {
- $bot = $attrs["ID"];
- if (botexists($bot)){
- $existbotid = getbotid($bot);
- if ($areinc==1){
- deletebot($existbotid);
- }
- }
- $asbot=addslashes($bot);
- $q="insert into bots (id,botname) values (null,'$asbot')";
- $qcode=mysql_query($q);
- if ($areinc==1){
- if ($qcode){
- }
- $newbotid=mysql_insert_id();
- }
- else {
- $newbotid=$existbotid;
- }
- $selectbot=$newbotid;
- $allbots[]=$selectbot;
- #print "<font size='3'><b>Loading bot: $bot ($selectbot)<BR></b></font>\n";
- flush();
- }
- elseif (strtoupper($name)=="SPLITTER"){
- $splitterarray[]=$attrs["VALUE"];
- }
- elseif (strtoupper($name)=="SUBSTITUTE"){
- if (trim($attrs["FIND"])!=""){
- if ($startupwhich=="INPUT"){
- $inputarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
- }
- elseif ($startupwhich=="GENDER"){
- $genderarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
- }
- elseif ($startupwhich=="PERSON"){
- $personarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
- }
- elseif ($startupwhich=="PERSON2"){
- $person2array[]=array($attrs["FIND"],$attrs["REPLACE"]);
- }
- }
- }
- }
- /**
- * Called by the XML parser that is parsing the startup.xml file.
- *
- * @global string Which start tag was processed last
- *
- * @param resource $parser SAX XML resource handler
- * @param string $name name of the encountered tag.
- *
- * @return void
- */
- function endS($parser,$name)
- {
- global $whaton;
- if (strtoupper($name)=='LEARN') {
- $whaton = '';
- }
- }
- /**
- * Process contents <learn> tag in startup.xml
- *
- * Called by the XML parser that is parsing the startup.xml file. * -> all files in directory, or single file.
- *
- * @todo When using * it should process AIML in subdirectories too. This is currently only supported by using multiple <learn> tag entries for every folder containing AIML files.
- *
- * @uses learnallfiles()
- *
- * @global string
- * @global array contains the AIML files to learn.
- * @global integer
- *
- * @param resource $parser SAX XML resource handler
- * @param string $data assuming it contains the path to the file.
- */
- function handlemeS($parser, $data)
- {
- global $whaton, $learnfiles, $selectbot;
- if (strtoupper($whaton)=="LEARN"){
- if (trim($data)=="*"){
- learnallfiles($selectbot);
- }
- else {
- $learnfiles[$selectbot][]=trim($data);
- }
- }
- }
- /**
- * Checks if a bot already exists.
- *
- * Does a check to see if a bot with a particular name already exists. The reliance on unique names if crucial for the bot to work.
- *
- * @param string $name the name of the bot that is checked.
- *
- * @return boolean true/false
- */
- function botexists($name){
- // search to get existing id
- $name=addslashes($name);
- $q="select id from bots where botname='$name'";
- $selectcode = mysql_query($q);
- if ($selectcode) {
- while ($q = mysql_fetch_array($selectcode)){
- return true;
- }
- }
- return false;
- }
- /**
- * Gets a bot's property value.
- *
- * Retrieves the value of a particular bot predicate. If the predicate isn't set, then it will return the value 'default'. This has been hardcoded
- *
- *
- * @global integer
- *
- * @param string $name the name of the bot predicate to be retrieved.
- *
- * @return string the value of the bot predicate.
- */
- function getbotvalue($name)
- {
- global $selectbot;
- $q="select value from bot where name=" . addslashes($name) . " and bot=$selectbot";
- $selectcode = mysql_query($q);
- if ($selectcode){
- if(!mysql_numrows($selectcode)){
- return DEFAULTPREDICATEVALUE;
- }
- else{
- while ($q = mysql_fetch_array($selectcode)){
- return $q["value"];
- }
- }
- }
- }
- /**
- * Gets the ID of a bot given its name.
- *
- * Gets the ID of a bot given its name
- *
- * @todo move this function to a common include file shared by both the Loader and the Interpreter.
- *
- * @param string $name The name of the bot
- *
- * @ return integer The bot's ID.
- */
- function getbotid ($name)
- {
- // search to get existing id
- $name=addslashes($name);
- $q="select id from bots where botname='$name'";
- $selectcode = mysql_query($q);
- if ($selectcode) {
- while ($q = mysql_fetch_array($selectcode)){
- return $q["id"];
- }
- }
- }
- /**
- * Used by the AIML XML parser
- *
- * Looks for the start tag used in AIML files for category, template, that, topic.
- *
- * @uses upperkeysarray()
- * @uses getbotvalue()
- *
- * @global string which tag is being processed
- * @global string
- * @global string
- * @global integer to indicate if recursion is allowed
- * @global string the topic at hand in the AIML file
- *
- * @param resource $parser SAX XML resource handler
- * @param string $name name of the encountered tag.
- * @param array $attrs contains the additional attribues of a tag, like value, id, find.
- *
- * @return void
- */
- function startElement($parser, $name, $attrs)
- {
- global $whaton,$template,$pattern,$recursive,$topic;
- if (strtoupper($name)=="CATEGORY"){
- $whaton="CATEGORY";
- }
- elseif (strtoupper($name)=="TEMPLATE"){
- $whaton="TEMPLATE";
- $template="";
- $recursive=0;
- }
- elseif (strtoupper($name)=="PATTERN"){
- $whaton="PATTERN";
- }
- elseif ((strtoupper($name)=="THAT")&&(strtoupper($whaton)!="TEMPLATE")){
- $whaton="THAT";
- }
- elseif (strtoupper($name)=="TOPIC"){
- $whaton="TOPIC";
- }
- if ((strtoupper($whaton)=="PATTERN")&&(strtoupper($name)!="PATTERN")){
- if (strtoupper($name)=="BOT"){
- $attrs = upperkeysarray($attrs);
- $pattern .= getbotvalue($attrs["NAME"]);
- }
- else{
- $pattern .= "<$name";
- while (list ($key, $val) = each ($attrs)) {
- $pattern .= " $key=\"$val\" ";
- }
- $pattern .= ">";
- }
- }
- elseif ((strtoupper($whaton)=="TEMPLATE")&&(strtoupper($name)!="TEMPLATE")){
- $template .="<$name";
- while (list ($key, $val) = each ($attrs)) {
- $template .= " $key=\"$val\" ";
- }
- $template .=">";
- }
- elseif (strtoupper($whaton)=="TOPIC"){
- $attrs = upperkeysarray($attrs);
- $topic=$attrs["NAME"];
- }
- }
- /**
- * Used by the AIML XML parser
- *
- * Looks for the end tags of 'topic' and 'category'.
- *
- * @uses insertmysentence()
- * @uses insertmytemplate()
- *
- * @global string which tag is being processed
- * @global string
- * @global string
- * @global integer to indicate if recursion is allowed
- * @global string the topic at hand in the AIML file
- * @global string the that of the category.
- *
- * @param resource $parser SAX XML resource handler
- * @param string $name name of the encountered tag.
- *
- * @return void
- */
- function endElement($parser, $name)
- {
- global $whaton,$pattern,$template,$recursive,$topic,$that;
- if (strtoupper($name)=="TOPIC"){
- $topic="";
- }
- if (strtoupper($name)=="CATEGORY"){
- $template=trim($template);
- $topic=trim($topic);
- $that=trim($that);
- $pattern=trim($pattern);
- if ($that==""){
- $that="*";
- }
- if ($topic==""){
- $topic="*";
- }
- if ($pattern==""){
- $pattern="*";
- }
- $mybigsentence="<input> $pattern <that> $that <topic> $topic";
- //echo $mybigsentence;
- $idused=insertmysentence($mybigsentence);
- insertmytemplate($idused,$template);
- // IIS doesn't flush properly unless it has a bunch of characters in it. This fills it with spaces.
- print " ";
- flush();
- $pattern="";
- $template="";
- $that="";
- }
- else {
- if ((strtoupper($whaton)=="PATTERN")&&(strtoupper($name)!="PATTERN")){
- if (strtoupper($name)!="BOT"){
- $pattern .="</$name>";
- }
- }
- elseif ((strtoupper($whaton)=="TEMPLATE")&&(strtoupper($name)!="TEMPLATE")){
- $template .="</$name>";
- }
- }
- }
- /**
- * Part of the AIML XML parser.
- *
- * Checks for start tags of pattern, topic, that, template and CDATA
- *
- * @global string
- * @global string
- * @global string
- * @global string
- * @global string
- *
- * @param resource $parser SAX XML resource handler
- * @param string $data containing what needs to be parsed, I guess.
- *
- * @return void
- */
- function handleme($parser, $data)
- {
- global $whaton,$pattern,$template,$topic,$that;
- if (strtoupper($whaton)=="PATTERN"){
- $pattern .= $data;
- }
- elseif (strtoupper($whaton)=="TOPIC"){
- $topic .= $data;
- }
- elseif (strtoupper($whaton)=="THAT"){
- $that .= $data;
- }
- elseif (strtoupper($whaton)=="TEMPLATE"){
- $template .= $data;
- }
- elseif (strtoupper($whaton)=="TEMPLATE"){
- $template .= "<![CDATA[$data]]>";
- }
- }
- /**
- * Parses startup.xml if the bot is loaded incrementally - one file at a time.
- *
- * Parses the startup.xml if the bot id loaded incrementally. One file at a time. This is very hacky and may not work properly.
- *
- * @uses learn()
- *
- * @global string The root directory of the AIML files?
- * @global array This array will hold the files to LEARN
- * @global boolean
- * @global array Contains all the botnames.
- * @global integer contains the selected bot ID.
- *
- * @param integer $fileid the ID of the file to be processed.
- */
- function loadstartupinc($fileid){
- global $rootdir,$learnfiles,$areinc,$allbots,$selectbot;
- $areinc=0;
- if ($fileid==1){
- $areinc=1;
- }
- print "<font size='3'>Loading startup.xml<BR></font>\n";
- $learnfiles = array(); # This array will hold the files to LEARN
- $file = $rootdir . "startup.xml";
- $xml_parser = xml_parser_create();
- xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
- xml_set_element_handler($xml_parser, "startS", "endS");
- xml_set_character_data_handler ($xml_parser, "handlemeS");
- if (!($fp = fopen($file, "r"))) {
- die("could not open XML input");
- }
- while ($data = fread($fp, 4096)) {
- if (!xml_parse($xml_parser, $data, feof($fp))) {
- die(sprintf("XML error: %s at line %d",
- xml_error_string(xml_get_error_code($xml_parser)),
- xml_get_current_line_number($xml_parser)));
- }
- }
- xml_parser_free($xml_parser);
- # For each of the bots learn all of the files
- $totalcounter=1;
- foreach ($allbots as $bot){
- # print "<font size='3'><b>Loading bot: $bot<BR></b></font>\n";
- $single_learnfiles = $learnfiles[$bot];
- $single_learnfiles = array_unique($single_learnfiles);
- foreach ($single_learnfiles as $file) {
- $selectbot=$bot;
- if ($totalcounter==$fileid){
- learn($file);
- return 0;
- }
- $totalcounter++;
- }
- }
- return 1;
- }
- /**
- * Parses startup.xml
- *
- * Loads the startup.xml in the botloading process.
- * XML parses the startup.xml file.
- *
- * @todo Seperate the XML reading from the processing code. Perhaps making a seperate class for this.
- *
- * @see botloader.php
- * @see botloaderinc.php
- * @uses learn()
- * @uses startS()
- * @uses endS()
- * @uses handlemeS()
- *
- * @global string the rootdirectory
- * @global array Files to be learned
- * @global array All the different bots in the startup.xml file
- * @global integer ID of the selected bot
- * @global boolean ????
- *
- * @return void prints HTML
- */
- function loadstartup()
- {
- global $rootdir,$learnfiles,$allbots,$selectbot,$areinc;
- $areinc=1;
- print "<font size='3'>Loading startup.xml<BR></font>\n";
- $learnfiles = array(); // This array will hold the files to LEARN
- $file = $rootdir . "startup.xml";
- $xml_parser = xml_parser_create();
- xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
- xml_set_element_handler($xml_parser, "startS", "endS");
- xml_set_character_data_handler ($xml_parser, "handlemeS");
- if (!($fp = fopen($file, "r"))) {
- die("could not open XML input");
- }
- while ($data = fread($fp, 4096)) {
- if (!xml_parse($xml_parser, $data, feof($fp))) {
- die(sprintf("XML error: %s at line %d",
- xml_error_string(xml_get_error_code($xml_parser)),
- xml_get_current_line_number($xml_parser)));
- }
- }
- xml_parser_free($xml_parser);
- # For each of the bots learn all of the files
- foreach ($allbots as $bot){
- print "<font size='3'><b>Loading bot: $bot<BR></b></font>\n";
- $single_learnfiles = $learnfiles[$bot];
- $single_learnfiles = array_unique($single_learnfiles);
- foreach ($single_learnfiles as $file) {
- $selectbot=$bot;
- learn($file);
- }
- }
- }
- /**
- * Learn all the files in a directory ending with ".aiml"
- *
- * Read all the AIML filenames into the $learnfile Array. This array is then later on used by {@link learn()} in {@link handlemeS()}
- *
- * @global string the rootdirectory
- * @global array contains all the filenames that need to be loaded into the bot.
- *
- * @param integer $curbot ID of the current bot.
- *
- * @return void
- */
- function learnallfiles($curbot)
- {
- global $rootdir,$learnfiles;
- $dir=opendir ($rootdir);
- while ($file = readdir($dir)) {
- if (substr($file,strpos($file,"."))==".aiml"){
- $learnfiles[$curbot][]=$file;
- }
- }
- closedir($dir);
- }
- /**
- * Learn the AIML string.
- *
- * XML parse the AIML string. It seems to have a hardcoded time limit of 600, presume seconds.
- *
- * @uses startElement()
- * @uses endElement()
- * @uses handleme()
- *
- * @param string $xmlstring the AIML category XML string
- *
- * @return void
- */
- function learnstring($xmlstring)
- {
- set_time_limit(600);
- $xml_parser = xml_parser_create();
- xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
- xml_set_element_handler($xml_parser, "startElement", "endElement");
- xml_set_character_data_handler ($xml_parser, "handleme");
- if (!xml_parse($xml_parser, $xmlstring)) {
- die(sprintf("XML error: %s at line %d",
- xml_error_string(xml_get_error_code($xml_parser)),
- xml_get_current_line_number($xml_parser)));
- }
- xml_parser_free($xml_parser);
- }
- /**
- * Learn an AIML file.
- *
- * Learn a single AIML XML file. Again, the hardcoded time limit is set to 600, presumably seconds.
- *
- * @uses startElement()
- * @uses endElement()
- * @uses handleme()
- *
- * @global string The root directory
- *
- * @param string $file The AIML file name.
- */
- function learn($file)
- {
- global $rootdir;
- set_time_limit(600);
- $xml_parser = xml_parser_create();
- xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
- xml_set_element_handler($xml_parser, "startElement", "endElement");
- xml_set_character_data_handler ($xml_parser, "handleme");
- print "<font size='3'>Loading data aiml file: $file<BR></font>\n";
- flush();
- if (strtoupper(substr($file,0,7))=="HTTP://"){
- $file=$file;
- }
- else {
- $file=$rootdir . $file;
- }
- if (!($fp = fopen($file, "r"))) {
- die("could not open XML input");
- }
- while ($data = fread($fp, 4096)) {
- if (!xml_parse($xml_parser, $data, feof($fp))) {
- die(sprintf("XML error: %s at line %d",
- xml_error_string(xml_get_error_code($xml_parser)),
- xml_get_current_line_number($xml_parser)));
- }
- }
- fclose($fp);
- xml_parser_free($xml_parser);
- }
- /**
- * Start a timer
- *
- * Save the start time of the to be timed script
- *
- * @global array ss_timing_start_times contains the start moments of the script
- *
- * @param string $name default value is 'default' Makes it possibe to time more than
- * event in one script.
- *
- * @return void nothing
- */
- function ss_timing_start ($name = 'default') {
- global $ss_timing_start_times;
- $ss_timing_start_times[$name] = explode(' ', microtime());
- }
- /**
- * Stop a timer
- *
- * Save the stop time of the to be timed script
- *
- * @global array ss_timing_stop_times contains the stop moments of a script
- *
- * @param string $name default value is 'default' Makes it possibe to time more than
- * event in one script.
- *
- * @return void nothing
- */
- function ss_timing_stop ($name = 'default') {
- global $ss_timing_stop_times;
- $ss_timing_stop_times[$name] = explode(' ', microtime());
- }
- /**
- * Retrieve timer data
- *
- * Get the running time the timed script
- *
- * @global array ss_timing_start_times contains the start and finish moments of the script
- * @global array ss_timing_stop_times contains the stop moments of a script
- *
- * @param string $name default value is 'default' Makes it possibe to time more than
- * event in one script.
- *
- * @return string the formated running time of the timed stript.
- */
- function ss_timing_current ($name = 'default') {
- global $ss_timing_start_times, $ss_timing_stop_times;
- if (!isset($ss_timing_start_times[$name])) {
- return 0;
- }
- if (!isset($ss_timing_stop_times[$name])) {
- $stop_time = explode(' ', microtime());
- }
- else {
- $stop_time = $ss_timing_stop_times[$name];
- }
- // do the big numbers first so the small ones aren't lost
- $current = $stop_time[1] - $ss_timing_start_times[$name][1];
- $current += $stop_time[0] - $ss_timing_start_times[$name][0];
- return $current;
- }
- /**
- * Creates the PHP array code for subs.inc.
- *
- * Subs.inc contains PHP code written during the bot load process. This function creates the array PHP code and returns the code as a string.
- *
- * @uses cleanforsearch()
- * @uses cleanforreplace()
- *
- * @param array is an array with either gender, person(2), input and splitter details
- * @param string which array is being processed, is also the array namein subs.inc.
- *
- * @return string the array PHP code
- */
- function makesrphp($inarray,$sname)
- {
- $myphp="\$" . $sname . "search=array(\n";
- for ($x=0;$x<sizeof($inarray);$x++){
- $searchvar=cleanforsearch($inarray[$x][0]);
- $beginsearch="";
- $endsearch="";
- if (substr($searchvar,0,1)==" "){
- $beginsearch="\\b";
- }
- if ((substr($searchvar,strlen($searchvar)-1,1))==" "){
- $endsearch="\\b";
- }
- $myphp.="\"/$beginsearch" . trim($searchvar) . "$endsearch/ie\",\n";
- }
- $myphp.=");\n";
- $myphp.="\$" . $sname . "replace=array(\n";
- for ($x=0;$x<sizeof($inarray);$x++){
- $myphp.="\"myfunc('" . cleanforreplace($inarray[$x][1]) . "')\",\n";
- }
- $myphp.=");\n";
- return $myphp;
- }
- /**
- * Load an AIML string. String must be valid XML.
- *
- * This is going to need to take bot as a parameter
- *
- * @uses flushcache()
- * @uses learnstring()
- *
- * @global integer bot ID.
- *
- * @param string $aimlstring The AIML string to be loaded.
- * @param integer $botid The bot's ID.
- *
- * @return void
- */
- function loadaimlstring($aimlstring,$botid)
- {
- global $selectbot;
- $selectbot=$botid;
- flushcache();
- learnstring($aimlstring);
- }
- /**
- * Load an AIML string that is just a category.
- *
- * This is going to need to take bot as a parameter
- *
- * @uses flushcache()
- * @uses learnstring()
- *
- * @global integer bot ID.
- *
- * @param string $aimlstring The AIML string to be loaded.
- * @param integer $botid The bot's ID.
- *
- * @return void
- */
- function loadaimlcategory($aimlstring,$botid)
- {
- global $selectbot;
- $selectbot=$botid;
- $aimlstring="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"" . "?" . "><aiml version=\"1.0\">" . $aimlstring . "</aiml>";
- flushcache();
- learnstring($aimlstring);
- }
- /**
- * Create the array PHP code for the sentence splitters
- *
- * In AIML it is custom to return a reply for every sentence the user inputs.
- * This means the sentence input needs to be split into individual sentences.
- * However, some people find that the semi-colon should also be added, while
- * others think it should. The user will define the sentence splitters in
- * startup.xml and these will then be stored in a PHP file included by the
- * application.
- *
- * @param array $splitterarray containing the sentence splitters found in startup.xml
- *
- * @return string PHP array code for storing the sentence splitters
- */
- function makesplitterphp($splitterarray)
- {
- $splitterphp="\$likeperiodsearch=array(\n";
- for ($x=0;$x<sizeof($splitterarray);$x++){
- $splitterphp.="\"" . $splitterarray[$x] . "\",\n";
- }
- $splitterphp.=");\n";
- $splitterphp.="\$likeperiodreplace=array(\n";
- for ($x=0;$x<sizeof($splitterarray);$x++){
- $splitterphp.="\"" . "." . "\",\n";
- }
- $splitterphp.=");\n";
- return $splitterphp;
- }
- /**
- * Add slashes for replacement purposes
- *
- * Making a string safe to preform a replacement function on.
- *
- * @param string $input string to be cleaned.
- *
- * @return string cleaned string.
- */
- function cleanforreplace($input)
- {
- $input = str_replace("\\", "\\\\", $input);
- $input = str_replace("\"", "\\\"", $input);
- $input = str_replace("'", "\'", $input);
- return trim($input);
- }
- /**
- * Add slashes for database query purpose
- *
- * Making a string safe to put the text in an SQL query.
- *
- * @param string $input string to be cleaned.
- *
- * @return string cleaned string.
- */
- function cleanforsearch($input)
- {
- $input = str_replace("\\", "\\\\\\\\", $input);
- $input = str_replace("\"", "\\\"", $input);
- $input = str_replace("'", "\'", $input);
- $input = str_replace("/", "\/", $input);
- $input = str_replace("(", "\(", $input);
- $input = str_replace(")", "\)", $input);
- $input = str_replace(".", "\.", $input);
- return $input;
- }
- /**
- * Creates the subs.inc file.
- *
- * Creates the subs.inc file and fills it with 5 arrays that correspond to the 4 substitution sections and sentence splitters.
- *
- * @uses makesrphp()
- * @uses makesplitterphp()
- * @uses createsubfile()
- * @uses addtosubs()
- *
- * @global array contains the gender substitutions
- * @global array contains the person substitutions
- * @global array contains the person2 substitutions
- * @global array ?????
- * @global array contains the sentence splitters
- *
- * @return void Writes a file.
- */
- function makesubscode()
- {
- global $genderarray,$personarray,$person2array,$inputarray,$splitterarray;
- $genderphp = makesrphp($genderarray, "gender");
- $personphp = makesrphp($personarray, "firstthird");
- $person2php = makesrphp($person2array, "firstsecond");
- $inputphp = makesrphp($inputarray, "contract");
- $splitterphp = makesplitterphp($splitterarray);
- createsubfile();
- addtosubs("<?\n");
- addtosubs($genderphp);
- addtosubs($personphp);
- addtosubs($person2php);
- addtosubs($inputphp);
- addtosubs($splitterphp);
- addtosubs("\n?>");
- }
- ?>
Documentation generated on Wed, 12 Jan 2005 12:24:44 +0100 by phpDocumentor 1.3.0RC3