Source for file botloaderfuncs.php

Documentation is available at botloaderfuncs.php

  1. <?
  2.  
  3. /*
  4. Program E
  5. Copyright 2002, Paul Rydell
  6. Portions by Jay Myers
  7. This file is part of Program E.
  8. Program E is free software; you can redistribute it and/or modify
  9. it under the terms of the GNU General Public License as published by
  10. the Free Software Foundation; either version 2 of the License, or
  11. (at your option) any later version.
  12.  
  13. Program E is distributed in the hope that it will be useful,
  14. but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. GNU General Public License for more details.
  17.  
  18. You should have received a copy of the GNU General Public License
  19. along with Program E; if not, write to the Free Software
  20. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  21. */
  22.  
  23. /**
  24. * AIML loading functions
  25. *
  26. * Contains contains the functions for the actual loading of AIML.
  27. * @author Paul Rydell
  28. * @copyright 2002
  29. * @version 0.0.8
  30. * @package Loader
  31. */
  32.  
  33.  
  34. /**
  35. * The general preferences and database details.
  36. */
  37. require_once "dbprefs.php";
  38.  
  39. global $selectbot, $annesID;
  40.  
  41.  
  42. /**
  43. * Deletes everything about a bot.
  44. *
  45. * Empties the tables, bot, patterns, templates, bots and gmcache
  46. *
  47. * @param integer $bot The bot's ID
  48. *
  49. * @return void
  50. */
  51. function deletebot($bot)
  52. {
  53. $q="delete from bot where bot=$bot";
  54. $e = mysql_query($q);
  55. if ($e){
  56. }
  57. $q="delete from patterns where bot=$bot";
  58. $e = mysql_query($q);
  59. if ($e){
  60. }
  61. $q="delete from templates where bot=$bot";
  62. $e = mysql_query($q);
  63. if ($e){
  64. }
  65. $q="delete from bots where id=$bot";
  66. $e = mysql_query($q);
  67. if ($e){
  68. }
  69. $q="delete from gmcache";
  70. $e = mysql_query($q);
  71. if ($e){
  72. }
  73.  
  74.  
  75. }
  76.  
  77. /**
  78. * Deletes information about a bot in the cache and bot tables.
  79. *
  80. * Used by the incremental bot loader program so it doesn't wipe out the whole
  81. * bot on each aiml file load. Deletes everything in bot, bots and gmcache tables.
  82. *
  83. * @param integer $bot The bot's ID.
  84. *
  85. * @return void
  86. */
  87.  
  88. //
  89. //
  90.  
  91. function deletejustbot($bot){
  92.  
  93. $q="delete from bots where id=$bot";
  94. $e = mysql_query($q);
  95. if ($e){
  96. }
  97. $q="delete from bot where bot=$bot";
  98. $e = mysql_query($q);
  99. if ($e){
  100. }
  101. $q="delete from gmcache";
  102. $e = mysql_query($q);
  103. if ($e){
  104. }
  105.  
  106. }
  107.  
  108. /**
  109. * Deletes the gmcache table.
  110. *
  111. * This needs to be called whenever the patterns or templates table is updated.
  112. *
  113. * @return void
  114. */
  115. function flushcache()
  116. {
  117. $q="delete from gmcache";
  118. $e = mysql_query($q);
  119. if ($e){
  120. }
  121. }
  122.  
  123. /**
  124. * Makes the keys of an array uppercase.
  125. *
  126. * Makes the keys of an array uppercase.
  127. *
  128. * @param array $testa The array where the keys need to be changed into uppercase.
  129. *
  130. * @return array An array with only uppercase keys.
  131. */
  132. function upperkeysarray($testa)
  133. {
  134. $newtesta=array();
  135. $newkeys=array_keys($testa);
  136. for ($x=0;$x<sizeof($newkeys);$x++){
  137. $newtesta[strtoupper($newkeys[$x])]=$testa[$newkeys[$x]];
  138. }
  139. return $newtesta;
  140. }
  141.  
  142. /**
  143. * Write the substitution include file
  144. *
  145. * Write the substitution arrays back into the subs.inc
  146. *
  147. * @global object The opened subs.inc file, ready to write to.
  148. *
  149. * @param string $string most likely an array or all arrays turned into a big file.
  150. *
  151. * @return void
  152. */
  153. function addtosubs($string)
  154. {
  155.  
  156. global $fp;
  157.  
  158. fwrite($fp,$string);
  159.  
  160. }
  161.  
  162. /**
  163. * Create the object for writing the substitution include file
  164. *
  165. * Creates the object, which is then used by addtosubs() to write to
  166. *
  167. * @see addtosubs()
  168. * @see makesubscode()
  169. * @global object
  170. *
  171. * @return void
  172. */
  173. function createsubfile()
  174. {
  175.  
  176. global $fp;
  177.  
  178. $fp = fopen ("subs.inc", "w+");
  179.  
  180. }
  181.  
  182. /**
  183. * Find a word in the patterns table given the word and the parent.
  184. *
  185. * The AIML patterns are stored in the MySQL table in a binary tree format.
  186. * This function retrieves the next word details based upon the previous' word's ID.
  187. * If this word doesn't exist it returns 0, else it returns it's details.
  188. *
  189. * @uses setnotend()
  190. *
  191. * @param string $word The word that is to be searched
  192. * @param integer $parent The ID of the parent word
  193. *
  194. * @return integer The ID of the word that was searched
  195. */
  196. function findwordid($word,$parent)
  197. {
  198.  
  199. $word=addslashes($word);
  200. $query="select id,isend from patterns where word='$word' and parent=$parent";
  201.  
  202. $selectcode = mysql_query($query);
  203. if ($selectcode){
  204. if(!mysql_numrows($selectcode)){
  205. return 0;
  206. }
  207. else{
  208. while ($q = mysql_fetch_array($selectcode)){
  209. if ($q[1]==1){
  210. setnotend($q[0]);
  211. }
  212.  
  213. return $q[0];
  214. }
  215. }
  216. }
  217. }
  218.  
  219. /**
  220. * Find a wildcard in the patterns table given the word and the parent.
  221. *
  222. * Similar as findwordid() but this will retrieve the ID if there is a wildcard that fits.
  223. *
  224. * @uses setnotend()
  225. *
  226. * @param string $word The word that is to be searched, either _ or *
  227. * @param integer $parent The ID of the parent word
  228. *
  229. * @return integer The ID of the word that was searched
  230. */
  231. function findwordidstar($word,$parent)
  232. {
  233.  
  234. if ($word=="*"){
  235. $val=3;
  236. }
  237. elseif ($word=="_"){
  238. $val=1;
  239. }
  240. $query="select id,isend from patterns where parent=$parent and word is null and ordera=$val";
  241. $selectcode = mysql_query($query);
  242. if ($selectcode){
  243. if(!mysql_numrows($selectcode)){
  244. return 0;
  245. }
  246. else{
  247. while ($q = mysql_fetch_array($selectcode)){
  248. if ($q[1]==1){
  249. setnotend($q[0]);
  250. }
  251. return $q[0];
  252. }
  253. }
  254. }
  255. }
  256.  
  257.  
  258. /**
  259. * Set an entry in the patterns table to not be flagged as the last word in its context.
  260. *
  261. * Update a record in the patterns table, change isend column from 1 to 0. Given a particular word ID.
  262. *
  263. * @param integer $wordid
  264. *
  265. * @return void
  266. */
  267. function setnotend($wordid)
  268. {
  269.  
  270. $query="update patterns set isend=0 where id=$wordid";
  271. $q=mysql_query($query);
  272. if ($q){
  273.  
  274. }
  275.  
  276. }
  277.  
  278. /**
  279. * Inserts the pattern into the patterns table.
  280. *
  281. * inserts the pattern, that and topic as individual words in binary tree format into the patterns table
  282. *
  283. * @uses findwordid()
  284. * @uses insertwordpattern()
  285. * @uses findwordidstar()
  286. *
  287. * @global string
  288. * @global integer
  289. *
  290. * @param string $mybigsentence Contains the pattern, that and topic in the following format <input>word word<that>word word<topic>word word.
  291. */
  292. function insertmysentence($mybigsentence)
  293. {
  294. global $selectbot, $annesID;
  295.  
  296. $sentencepart="";
  297.  
  298. $newstarted=0;
  299. if($annesID != ""){
  300. $parent = $annesID;
  301. } else {
  302. $parent=-$selectbot;
  303. }
  304.  
  305. //Parse into invidividual words
  306. //Use split
  307. $allwords=split(" ",$mybigsentence);
  308. $qadd="";
  309. for ($x=0;$x<sizeof($allwords)+1;$x++){
  310.  
  311. // Last word in context
  312. $lwic=0;
  313.  
  314. if ($x==sizeof($allwords)){
  315. $word="";
  316. }
  317. else {
  318. $word=$allwords[$x];
  319. }
  320. if (strtoupper($word)=="<INPUT>"){
  321. $sentencepart="INPUT";
  322. } elseif (strtoupper($word)=="<THAT>"){
  323. $sentencepart="THAT";
  324. } elseif (strtoupper($word)=="<TOPIC>"){
  325. $sentencepart="TOPIC";
  326. }
  327. // Find out if it is the last word in its context
  328. if ($x==(sizeof($allwords)-1)){
  329. $lwic=1;
  330. }
  331. // Prevent some warnings by checking this first.
  332. elseif (($x+1) >= (sizeof($allwords))){
  333. }
  334. elseif ((strtoupper($allwords[$x+1])=="<THAT>") || (strtoupper($allwords[$x+1])=="<TOPIC>")){
  335. $lwic=1;
  336. }
  337. if (($word!="*")&&($word!="_")){
  338.  
  339. if ($newstarted!=1){
  340. $wordid=findwordid($word,$parent);
  341. }
  342. if (($wordid!=0) && ($newstarted!=1)){
  343. $parent=$wordid;
  344. }
  345. else {
  346. $newstarted=1;
  347.  
  348. $sword=addslashes($word);
  349. $qadd="($selectbot, null,'$sword',2,$parent,$lwic)";
  350.  
  351. $parent = insertwordpattern($qadd);
  352.  
  353.  
  354. }
  355. }
  356. elseif (($word=="*")||($word=="_")){
  357.  
  358. if ($newstarted!=1){
  359. $wordid=findwordidstar($word,$parent);
  360. }
  361. if (($wordid!=0) && ($newstarted!=1)){
  362. $parent=$wordid;
  363. }
  364. else {
  365. $newstarted=1;
  366.  
  367. if ($word=="*"){
  368. $val=3;
  369. }
  370. elseif ($word=="_"){
  371. $val=1;
  372. }
  373.  
  374. $qadd="($selectbot, null,null,$val,$parent,$lwic)";
  375.  
  376. $parent = insertwordpattern($qadd);
  377.  
  378.  
  379. }
  380. }
  381. }
  382.  
  383. return $parent;
  384.  
  385. }
  386.  
  387. /**
  388. * Inserts an entry into the patterns table. Returns the ID of the new row inserted.
  389. *
  390. * insert a word into the patterns table, returns the id of the record so it can be
  391. * used as the parent ID of the next word that's to be inserted.
  392. *
  393. * @param string $qadd The word of the pattern to be inserted
  394. *
  395. * @return integer The record ID of the inserted word.
  396. */
  397. function insertwordpattern($qadd)
  398. {
  399.  
  400. $qcode=mysql_query("insert into patterns(bot,id,word,ordera,parent,isend) values $qadd");
  401.  
  402. if ($qcode){
  403.  
  404. return mysql_insert_id();
  405. }
  406. }
  407.  
  408. /**
  409. * Inserts a template into the template table.
  410. *
  411. * Insert the template into the template database. <br/>
  412. * This version has been adapted to also insert the pattern, that and topic into the additionally added columns
  413. *
  414. * @uses templateexists()
  415. *
  416. * @global integer
  417. * @global integer The ID of the record in the patterns table that links to this table
  418. * @global string The pattern, including variables like _ and *.
  419. * @global string the topic, including variable like _ and *
  420. * @global string the that, including variables like _ and *
  421. *
  422. * @param integer $idused The ID of the record in the patterns table that links to the template table.
  423. * @param string $template The contents inbetween <template/> tags.
  424. *
  425. * @return void
  426. */
  427. function insertmytemplate($idused,$template)
  428. {
  429. global $selectbot,$templatesinserted, $pattern, $topic, $that;
  430. if (!templateexists($idused)){
  431. $templatesinserted++;
  432.  
  433. $template=addslashes($template);
  434. $query="insert into templates (bot,id,template,pattern,that,topic) values ($selectbot, $idused,'$template','$pattern','$that','$topic')";
  435.  
  436. $qcode=mysql_query($query);
  437. if ($qcode){
  438. }
  439. }
  440.  
  441. }
  442.  
  443. /**
  444. * Checks if a template exists for a given pattern
  445. *
  446. * Does a query on the database to see if an ID is used by a template in the templates table.
  447. *
  448. * @param integer $idused The ID number that corresponds to the number in the ID column, if it exists.
  449. *
  450. * @return boolean true/false
  451. */
  452. function templateexists($idused)
  453. {
  454. $query="select id from templates where id=$idused";
  455.  
  456. $qcode=mysql_query($query);
  457.  
  458. if ($qcode){
  459. if(!mysql_numrows($qcode)){
  460. return false;
  461. }
  462. }
  463.  
  464. return true;
  465.  
  466. }
  467.  
  468. /**
  469. * Called by the XML parser that is parsing the startup.xml file.
  470. *
  471. * startS and endS are two functions that cooperate. startS looks for the start of an XML tag, endS for the end tag.
  472. * 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.
  473. *
  474. * @todo Find out what Global $areinc does
  475. *
  476. * @uses upperkeysarray()
  477. * @uses botexists()
  478. * @uses getbotid()
  479. * @uses deletebot()
  480. *
  481. * @global integer
  482. * @global string
  483. * @global array
  484. * @global array contains the splitter characters which are used to split the sentences. For example period, comma, semi-colon, exclamation mark, question mark.
  485. * @global array contains the input, split into sentences
  486. * @global array contains the gender words or phrases.
  487. * @global array contains the person words or phrases
  488. * @global array contains the person2 words or phrases
  489. * @global array contains the names of all the bots, or their ID's
  490. * @global array contains something unknown
  491. *
  492. * @param resource $parser SAX XML resource handler
  493. * @param string $name name of the encountered tag.
  494. * @param array $attrs contains the additional attribues of a tag, like value, id, find.
  495. *
  496. * @return void
  497. */
  498. function startS($parser,$name,$attrs)
  499. {
  500.  
  501. global $selectbot, $whaton, $startupwhich, $splitterarray,
  502. $inputarray, $genderarray, $personarray, $person2array, $allbots, $areinc;
  503. $attrs=upperkeysarray($attrs);
  504.  
  505. if (strtoupper($name)=='LEARN') {
  506. $whaton = 'LEARN';
  507. }
  508. if (strtoupper($name)=="GENDER"){
  509. $startupwhich="GENDER";
  510. }
  511. elseif (strtoupper($name)=="INPUT"){
  512. $startupwhich="INPUT";
  513. }
  514. elseif (strtoupper($name)=="PERSON"){
  515. $startupwhich="PERSON";
  516. }
  517. elseif (strtoupper($name)=="PERSON2"){
  518. $startupwhich="PERSON2";
  519. }
  520.  
  521. if (strtoupper($name)=="PROPERTY"){
  522. $q="insert into bot (bot,name,value) values ($selectbot,'" . addslashes($attrs["NAME"]) . "','" . addslashes($attrs["VALUE"]) . "')";
  523.  
  524. $qcode=mysql_query($q);
  525. if ($qcode){
  526. }
  527.  
  528. }
  529. elseif (strtoupper($name)=="BOT") {
  530. $bot = $attrs["ID"];
  531. if (botexists($bot)){
  532. $existbotid = getbotid($bot);
  533. if ($areinc==1){
  534. deletebot($existbotid);
  535. }
  536. }
  537.  
  538. $asbot=addslashes($bot);
  539. $q="insert into bots (id,botname) values (null,'$asbot')";
  540. $qcode=mysql_query($q);
  541. if ($areinc==1){
  542. if ($qcode){
  543. }
  544. $newbotid=mysql_insert_id();
  545. }
  546. else {
  547. $newbotid=$existbotid;
  548. }
  549.  
  550. $selectbot=$newbotid;
  551. $allbots[]=$selectbot;
  552.  
  553. #print "<font size='3'><b>Loading bot: $bot ($selectbot)<BR></b></font>\n";
  554. flush();
  555. }
  556. elseif (strtoupper($name)=="SPLITTER"){
  557. $splitterarray[]=$attrs["VALUE"];
  558. }
  559. elseif (strtoupper($name)=="SUBSTITUTE"){
  560. if (trim($attrs["FIND"])!=""){
  561. if ($startupwhich=="INPUT"){
  562. $inputarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
  563. }
  564. elseif ($startupwhich=="GENDER"){
  565. $genderarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
  566. }
  567. elseif ($startupwhich=="PERSON"){
  568. $personarray[]=array($attrs["FIND"],$attrs["REPLACE"]);
  569. }
  570. elseif ($startupwhich=="PERSON2"){
  571. $person2array[]=array($attrs["FIND"],$attrs["REPLACE"]);
  572. }
  573. }
  574. }
  575. }
  576.  
  577. /**
  578. * Called by the XML parser that is parsing the startup.xml file.
  579. *
  580. * @global string Which start tag was processed last
  581. *
  582. * @param resource $parser SAX XML resource handler
  583. * @param string $name name of the encountered tag.
  584. *
  585. * @return void
  586. */
  587. function endS($parser,$name)
  588. {
  589. global $whaton;
  590. if (strtoupper($name)=='LEARN') {
  591. $whaton = '';
  592. }
  593. }
  594.  
  595. /**
  596. * Process contents <learn> tag in startup.xml
  597. *
  598. * Called by the XML parser that is parsing the startup.xml file. * -> all files in directory, or single file.
  599. *
  600. * @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.
  601. *
  602. * @uses learnallfiles()
  603. *
  604. * @global string
  605. * @global array contains the AIML files to learn.
  606. * @global integer
  607. *
  608. * @param resource $parser SAX XML resource handler
  609. * @param string $data assuming it contains the path to the file.
  610. */
  611. function handlemeS($parser, $data)
  612. {
  613. global $whaton, $learnfiles, $selectbot;
  614. if (strtoupper($whaton)=="LEARN"){
  615. if (trim($data)=="*"){
  616. learnallfiles($selectbot);
  617. }
  618. else {
  619. $learnfiles[$selectbot][]=trim($data);
  620. }
  621. }
  622. }
  623.  
  624. /**
  625. * Checks if a bot already exists.
  626. *
  627. * 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.
  628. *
  629. * @param string $name the name of the bot that is checked.
  630. *
  631. * @return boolean true/false
  632. */
  633. function botexists($name){
  634.  
  635. // search to get existing id
  636. $name=addslashes($name);
  637. $q="select id from bots where botname='$name'";
  638. $selectcode = mysql_query($q);
  639. if ($selectcode) {
  640. while ($q = mysql_fetch_array($selectcode)){
  641. return true;
  642. }
  643. }
  644.  
  645. return false;
  646.  
  647. }
  648.  
  649. /**
  650. * Gets a bot's property value.
  651. *
  652. * 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
  653. *
  654. *
  655. * @global integer
  656. *
  657. * @param string $name the name of the bot predicate to be retrieved.
  658. *
  659. * @return string the value of the bot predicate.
  660. */
  661. function getbotvalue($name)
  662. {
  663. global $selectbot;
  664.  
  665. $q="select value from bot where name=" . addslashes($name) . " and bot=$selectbot";
  666.  
  667. $selectcode = mysql_query($q);
  668. if ($selectcode){
  669. if(!mysql_numrows($selectcode)){
  670. return DEFAULTPREDICATEVALUE;
  671. }
  672. else{
  673. while ($q = mysql_fetch_array($selectcode)){
  674. return $q["value"];
  675. }
  676. }
  677. }
  678. }
  679.  
  680. /**
  681. * Gets the ID of a bot given its name.
  682. *
  683. * Gets the ID of a bot given its name
  684. *
  685. * @todo move this function to a common include file shared by both the Loader and the Interpreter.
  686. *
  687. * @param string $name The name of the bot
  688. *
  689. * @ return integer The bot's ID.
  690. */
  691. function getbotid ($name)
  692. {
  693. // search to get existing id
  694. $name=addslashes($name);
  695. $q="select id from bots where botname='$name'";
  696. $selectcode = mysql_query($q);
  697. if ($selectcode) {
  698. while ($q = mysql_fetch_array($selectcode)){
  699. return $q["id"];
  700. }
  701. }
  702.  
  703. }
  704.  
  705. /**
  706. * Used by the AIML XML parser
  707. *
  708. * Looks for the start tag used in AIML files for category, template, that, topic.
  709. *
  710. * @uses upperkeysarray()
  711. * @uses getbotvalue()
  712. *
  713. * @global string which tag is being processed
  714. * @global string
  715. * @global string
  716. * @global integer to indicate if recursion is allowed
  717. * @global string the topic at hand in the AIML file
  718. *
  719. * @param resource $parser SAX XML resource handler
  720. * @param string $name name of the encountered tag.
  721. * @param array $attrs contains the additional attribues of a tag, like value, id, find.
  722. *
  723. * @return void
  724. */
  725. function startElement($parser, $name, $attrs)
  726. {
  727. global $whaton,$template,$pattern,$recursive,$topic;
  728.  
  729. if (strtoupper($name)=="CATEGORY"){
  730. $whaton="CATEGORY";
  731. }
  732. elseif (strtoupper($name)=="TEMPLATE"){
  733. $whaton="TEMPLATE";
  734. $template="";
  735. $recursive=0;
  736. }
  737. elseif (strtoupper($name)=="PATTERN"){
  738. $whaton="PATTERN";
  739. }
  740. elseif ((strtoupper($name)=="THAT")&&(strtoupper($whaton)!="TEMPLATE")){
  741. $whaton="THAT";
  742. }
  743. elseif (strtoupper($name)=="TOPIC"){
  744. $whaton="TOPIC";
  745. }
  746.  
  747. if ((strtoupper($whaton)=="PATTERN")&&(strtoupper($name)!="PATTERN")){
  748.  
  749.  
  750. if (strtoupper($name)=="BOT"){
  751.  
  752. $attrs = upperkeysarray($attrs);
  753. $pattern .= getbotvalue($attrs["NAME"]);
  754.  
  755. }
  756. else{
  757. $pattern .= "<$name";
  758.  
  759. while (list ($key, $val) = each ($attrs)) {
  760. $pattern .= " $key=\"$val\" ";
  761. }
  762.  
  763. $pattern .= ">";
  764. }
  765.  
  766. }
  767. elseif ((strtoupper($whaton)=="TEMPLATE")&&(strtoupper($name)!="TEMPLATE")){
  768. $template .="<$name";
  769.  
  770. while (list ($key, $val) = each ($attrs)) {
  771. $template .= " $key=\"$val\" ";
  772. }
  773.  
  774. $template .=">";
  775. }
  776. elseif (strtoupper($whaton)=="TOPIC"){
  777.  
  778. $attrs = upperkeysarray($attrs);
  779. $topic=$attrs["NAME"];
  780.  
  781. }
  782. }
  783.  
  784. /**
  785. * Used by the AIML XML parser
  786. *
  787. * Looks for the end tags of 'topic' and 'category'.
  788. *
  789. * @uses insertmysentence()
  790. * @uses insertmytemplate()
  791. *
  792. * @global string which tag is being processed
  793. * @global string
  794. * @global string
  795. * @global integer to indicate if recursion is allowed
  796. * @global string the topic at hand in the AIML file
  797. * @global string the that of the category.
  798. *
  799. * @param resource $parser SAX XML resource handler
  800. * @param string $name name of the encountered tag.
  801. *
  802. * @return void
  803. */
  804. function endElement($parser, $name)
  805. {
  806.  
  807. global $whaton,$pattern,$template,$recursive,$topic,$that;
  808. if (strtoupper($name)=="TOPIC"){
  809. $topic="";
  810. }
  811.  
  812. if (strtoupper($name)=="CATEGORY"){
  813. $template=trim($template);
  814. $topic=trim($topic);
  815. $that=trim($that);
  816. $pattern=trim($pattern);
  817.  
  818. if ($that==""){
  819. $that="*";
  820. }
  821. if ($topic==""){
  822. $topic="*";
  823. }
  824. if ($pattern==""){
  825. $pattern="*";
  826. }
  827.  
  828. $mybigsentence="<input> $pattern <that> $that <topic> $topic";
  829.  
  830. //echo $mybigsentence;
  831. $idused=insertmysentence($mybigsentence);
  832. insertmytemplate($idused,$template);
  833.  
  834. // IIS doesn't flush properly unless it has a bunch of characters in it. This fills it with spaces.
  835. print " ";
  836. flush();
  837.  
  838. $pattern="";
  839. $template="";
  840. $that="";
  841.  
  842. }
  843. else {
  844. if ((strtoupper($whaton)=="PATTERN")&&(strtoupper($name)!="PATTERN")){
  845. if (strtoupper($name)!="BOT"){
  846. $pattern .="</$name>";
  847. }
  848. }
  849. elseif ((strtoupper($whaton)=="TEMPLATE")&&(strtoupper($name)!="TEMPLATE")){
  850. $template .="</$name>";
  851. }
  852. }
  853.  
  854. }
  855.  
  856.  
  857. /**
  858. * Part of the AIML XML parser.
  859. *
  860. * Checks for start tags of pattern, topic, that, template and CDATA
  861. *
  862. * @global string
  863. * @global string
  864. * @global string
  865. * @global string
  866. * @global string
  867. *
  868. * @param resource $parser SAX XML resource handler
  869. * @param string $data containing what needs to be parsed, I guess.
  870. *
  871. * @return void
  872. */
  873. function handleme($parser, $data)
  874. {
  875. global $whaton,$pattern,$template,$topic,$that;
  876. if (strtoupper($whaton)=="PATTERN"){
  877. $pattern .= $data;
  878. }
  879. elseif (strtoupper($whaton)=="TOPIC"){
  880. $topic .= $data;
  881. }
  882. elseif (strtoupper($whaton)=="THAT"){
  883. $that .= $data;
  884. }
  885. elseif (strtoupper($whaton)=="TEMPLATE"){
  886. $template .= $data;
  887. }
  888. elseif (strtoupper($whaton)=="TEMPLATE"){
  889. $template .= "<![CDATA[$data]]>";
  890. }
  891. }
  892.  
  893.  
  894. /**
  895. * Parses startup.xml if the bot is loaded incrementally - one file at a time.
  896. *
  897. * Parses the startup.xml if the bot id loaded incrementally. One file at a time. This is very hacky and may not work properly.
  898. *
  899. * @uses learn()
  900. *
  901. * @global string The root directory of the AIML files?
  902. * @global array This array will hold the files to LEARN
  903. * @global boolean
  904. * @global array Contains all the botnames.
  905. * @global integer contains the selected bot ID.
  906. *
  907. * @param integer $fileid the ID of the file to be processed.
  908. */
  909. function loadstartupinc($fileid){
  910.  
  911. global $rootdir,$learnfiles,$areinc,$allbots,$selectbot;
  912. $areinc=0;
  913.  
  914. if ($fileid==1){
  915. $areinc=1;
  916. }
  917.  
  918. print "<font size='3'>Loading startup.xml<BR></font>\n";
  919. $learnfiles = array(); # This array will hold the files to LEARN
  920.  
  921. $file = $rootdir . "startup.xml";
  922. $xml_parser = xml_parser_create();
  923. xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
  924. xml_set_element_handler($xml_parser, "startS", "endS");
  925. xml_set_character_data_handler ($xml_parser, "handlemeS");
  926. if (!($fp = fopen($file, "r"))) {
  927. die("could not open XML input");
  928. }
  929. while ($data = fread($fp, 4096)) {
  930. if (!xml_parse($xml_parser, $data, feof($fp))) {
  931. die(sprintf("XML error: %s at line %d",
  932. xml_error_string(xml_get_error_code($xml_parser)),
  933. xml_get_current_line_number($xml_parser)));
  934. }
  935. }
  936. xml_parser_free($xml_parser);
  937.  
  938. # For each of the bots learn all of the files
  939.  
  940. $totalcounter=1;
  941.  
  942. foreach ($allbots as $bot){
  943.  
  944. # print "<font size='3'><b>Loading bot: $bot<BR></b></font>\n";
  945.  
  946. $single_learnfiles = $learnfiles[$bot];
  947. $single_learnfiles = array_unique($single_learnfiles);
  948.  
  949. foreach ($single_learnfiles as $file) {
  950. $selectbot=$bot;
  951. if ($totalcounter==$fileid){
  952. learn($file);
  953. return 0;
  954. }
  955.  
  956. $totalcounter++;
  957.  
  958. }
  959. }
  960.  
  961. return 1;
  962.  
  963.  
  964. }
  965.  
  966. /**
  967. * Parses startup.xml
  968. *
  969. * Loads the startup.xml in the botloading process.
  970. * XML parses the startup.xml file.
  971. *
  972. * @todo Seperate the XML reading from the processing code. Perhaps making a seperate class for this.
  973. *
  974. * @see botloader.php
  975. * @see botloaderinc.php
  976. * @uses learn()
  977. * @uses startS()
  978. * @uses endS()
  979. * @uses handlemeS()
  980. *
  981. * @global string the rootdirectory
  982. * @global array Files to be learned
  983. * @global array All the different bots in the startup.xml file
  984. * @global integer ID of the selected bot
  985. * @global boolean ????
  986. *
  987. * @return void prints HTML
  988. */
  989. function loadstartup()
  990. {
  991.  
  992. global $rootdir,$learnfiles,$allbots,$selectbot,$areinc;
  993. $areinc=1;
  994.  
  995. print "<font size='3'>Loading startup.xml<BR></font>\n";
  996. $learnfiles = array(); // This array will hold the files to LEARN
  997.  
  998.  
  999. $file = $rootdir . "startup.xml";
  1000. $xml_parser = xml_parser_create();
  1001. xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
  1002. xml_set_element_handler($xml_parser, "startS", "endS");
  1003. xml_set_character_data_handler ($xml_parser, "handlemeS");
  1004. if (!($fp = fopen($file, "r"))) {
  1005. die("could not open XML input");
  1006. }
  1007. while ($data = fread($fp, 4096)) {
  1008. if (!xml_parse($xml_parser, $data, feof($fp))) {
  1009. die(sprintf("XML error: %s at line %d",
  1010. xml_error_string(xml_get_error_code($xml_parser)),
  1011. xml_get_current_line_number($xml_parser)));
  1012. }
  1013. }
  1014. xml_parser_free($xml_parser);
  1015.  
  1016. # For each of the bots learn all of the files
  1017. foreach ($allbots as $bot){
  1018. print "<font size='3'><b>Loading bot: $bot<BR></b></font>\n";
  1019. $single_learnfiles = $learnfiles[$bot];
  1020. $single_learnfiles = array_unique($single_learnfiles);
  1021. foreach ($single_learnfiles as $file) {
  1022. $selectbot=$bot;
  1023. learn($file);
  1024. }
  1025. }
  1026.  
  1027. }
  1028.  
  1029. /**
  1030. * Learn all the files in a directory ending with ".aiml"
  1031. *
  1032. * Read all the AIML filenames into the $learnfile Array. This array is then later on used by {@link learn()} in {@link handlemeS()}
  1033. *
  1034. * @global string the rootdirectory
  1035. * @global array contains all the filenames that need to be loaded into the bot.
  1036. *
  1037. * @param integer $curbot ID of the current bot.
  1038. *
  1039. * @return void
  1040. */
  1041. function learnallfiles($curbot)
  1042. {
  1043. global $rootdir,$learnfiles;
  1044.  
  1045. $dir=opendir ($rootdir);
  1046. while ($file = readdir($dir)) {
  1047. if (substr($file,strpos($file,"."))==".aiml"){
  1048.  
  1049. $learnfiles[$curbot][]=$file;
  1050. }
  1051. }
  1052.  
  1053. closedir($dir);
  1054. }
  1055.  
  1056.  
  1057. /**
  1058. * Learn the AIML string.
  1059. *
  1060. * XML parse the AIML string. It seems to have a hardcoded time limit of 600, presume seconds.
  1061. *
  1062. * @uses startElement()
  1063. * @uses endElement()
  1064. * @uses handleme()
  1065. *
  1066. * @param string $xmlstring the AIML category XML string
  1067. *
  1068. * @return void
  1069. */
  1070. function learnstring($xmlstring)
  1071. {
  1072.  
  1073. set_time_limit(600);
  1074. $xml_parser = xml_parser_create();
  1075. xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
  1076. xml_set_element_handler($xml_parser, "startElement", "endElement");
  1077. xml_set_character_data_handler ($xml_parser, "handleme");
  1078.  
  1079. if (!xml_parse($xml_parser, $xmlstring)) {
  1080. die(sprintf("XML error: %s at line %d",
  1081. xml_error_string(xml_get_error_code($xml_parser)),
  1082. xml_get_current_line_number($xml_parser)));
  1083. }
  1084.  
  1085. xml_parser_free($xml_parser);
  1086. }
  1087.  
  1088.  
  1089. /**
  1090. * Learn an AIML file.
  1091. *
  1092. * Learn a single AIML XML file. Again, the hardcoded time limit is set to 600, presumably seconds.
  1093. *
  1094. * @uses startElement()
  1095. * @uses endElement()
  1096. * @uses handleme()
  1097. *
  1098. * @global string The root directory
  1099. *
  1100. * @param string $file The AIML file name.
  1101. */
  1102. function learn($file)
  1103. {
  1104.  
  1105. global $rootdir;
  1106. set_time_limit(600);
  1107. $xml_parser = xml_parser_create();
  1108. xml_parser_set_option($xml_parser,XML_OPTION_CASE_FOLDING,0);
  1109. xml_set_element_handler($xml_parser, "startElement", "endElement");
  1110. xml_set_character_data_handler ($xml_parser, "handleme");
  1111. print "<font size='3'>Loading data aiml file: $file<BR></font>\n";
  1112. flush();
  1113.  
  1114. if (strtoupper(substr($file,0,7))=="HTTP://"){
  1115. $file=$file;
  1116. }
  1117. else {
  1118. $file=$rootdir . $file;
  1119. }
  1120. if (!($fp = fopen($file, "r"))) {
  1121. die("could not open XML input");
  1122. }
  1123.  
  1124. while ($data = fread($fp, 4096)) {
  1125. if (!xml_parse($xml_parser, $data, feof($fp))) {
  1126. die(sprintf("XML error: %s at line %d",
  1127. xml_error_string(xml_get_error_code($xml_parser)),
  1128. xml_get_current_line_number($xml_parser)));
  1129. }
  1130. }
  1131. fclose($fp);
  1132. xml_parser_free($xml_parser);
  1133. }
  1134.  
  1135. /**
  1136. * Start a timer
  1137. *
  1138. * Save the start time of the to be timed script
  1139. *
  1140. * @global array ss_timing_start_times contains the start moments of the script
  1141. *
  1142. * @param string $name default value is 'default' Makes it possibe to time more than
  1143. * event in one script.
  1144. *
  1145. * @return void nothing
  1146. */
  1147. function ss_timing_start ($name = 'default') {
  1148. global $ss_timing_start_times;
  1149. $ss_timing_start_times[$name] = explode(' ', microtime());
  1150. }
  1151.  
  1152. /**
  1153. * Stop a timer
  1154. *
  1155. * Save the stop time of the to be timed script
  1156. *
  1157. * @global array ss_timing_stop_times contains the stop moments of a script
  1158. *
  1159. * @param string $name default value is 'default' Makes it possibe to time more than
  1160. * event in one script.
  1161. *
  1162. * @return void nothing
  1163. */
  1164. function ss_timing_stop ($name = 'default') {
  1165. global $ss_timing_stop_times;
  1166. $ss_timing_stop_times[$name] = explode(' ', microtime());
  1167. }
  1168.  
  1169. /**
  1170. * Retrieve timer data
  1171. *
  1172. * Get the running time the timed script
  1173. *
  1174. * @global array ss_timing_start_times contains the start and finish moments of the script
  1175. * @global array ss_timing_stop_times contains the stop moments of a script
  1176. *
  1177. * @param string $name default value is 'default' Makes it possibe to time more than
  1178. * event in one script.
  1179. *
  1180. * @return string the formated running time of the timed stript.
  1181. */
  1182. function ss_timing_current ($name = 'default') {
  1183. global $ss_timing_start_times, $ss_timing_stop_times;
  1184. if (!isset($ss_timing_start_times[$name])) {
  1185. return 0;
  1186. }
  1187. if (!isset($ss_timing_stop_times[$name])) {
  1188. $stop_time = explode(' ', microtime());
  1189. }
  1190. else {
  1191. $stop_time = $ss_timing_stop_times[$name];
  1192. }
  1193. // do the big numbers first so the small ones aren't lost
  1194. $current = $stop_time[1] - $ss_timing_start_times[$name][1];
  1195. $current += $stop_time[0] - $ss_timing_start_times[$name][0];
  1196. return $current;
  1197. }
  1198.  
  1199.  
  1200. /**
  1201. * Creates the PHP array code for subs.inc.
  1202. *
  1203. * 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.
  1204. *
  1205. * @uses cleanforsearch()
  1206. * @uses cleanforreplace()
  1207. *
  1208. * @param array is an array with either gender, person(2), input and splitter details
  1209. * @param string which array is being processed, is also the array namein subs.inc.
  1210. *
  1211. * @return string the array PHP code
  1212. */
  1213. function makesrphp($inarray,$sname)
  1214. {
  1215.  
  1216. $myphp="\$" . $sname . "search=array(\n";
  1217.  
  1218. for ($x=0;$x<sizeof($inarray);$x++){
  1219.  
  1220. $searchvar=cleanforsearch($inarray[$x][0]);
  1221.  
  1222. $beginsearch="";
  1223. $endsearch="";
  1224.  
  1225. if (substr($searchvar,0,1)==" "){
  1226. $beginsearch="\\b";
  1227. }
  1228. if ((substr($searchvar,strlen($searchvar)-1,1))==" "){
  1229. $endsearch="\\b";
  1230. }
  1231. $myphp.="\"/$beginsearch" . trim($searchvar) . "$endsearch/ie\",\n";
  1232.  
  1233. }
  1234.  
  1235. $myphp.=");\n";
  1236.  
  1237. $myphp.="\$" . $sname . "replace=array(\n";
  1238.  
  1239. for ($x=0;$x<sizeof($inarray);$x++){
  1240. $myphp.="\"myfunc('" . cleanforreplace($inarray[$x][1]) . "')\",\n";
  1241. }
  1242.  
  1243. $myphp.=");\n";
  1244. return $myphp;
  1245.  
  1246. }
  1247.  
  1248.  
  1249. /**
  1250. * Load an AIML string. String must be valid XML.
  1251. *
  1252. * This is going to need to take bot as a parameter
  1253. *
  1254. * @uses flushcache()
  1255. * @uses learnstring()
  1256. *
  1257. * @global integer bot ID.
  1258. *
  1259. * @param string $aimlstring The AIML string to be loaded.
  1260. * @param integer $botid The bot's ID.
  1261. *
  1262. * @return void
  1263. */
  1264. function loadaimlstring($aimlstring,$botid)
  1265. {
  1266.  
  1267. global $selectbot;
  1268.  
  1269. $selectbot=$botid;
  1270.  
  1271. flushcache();
  1272. learnstring($aimlstring);
  1273.  
  1274. }
  1275.  
  1276.  
  1277. /**
  1278. * Load an AIML string that is just a category.
  1279. *
  1280. * This is going to need to take bot as a parameter
  1281. *
  1282. * @uses flushcache()
  1283. * @uses learnstring()
  1284. *
  1285. * @global integer bot ID.
  1286. *
  1287. * @param string $aimlstring The AIML string to be loaded.
  1288. * @param integer $botid The bot's ID.
  1289. *
  1290. * @return void
  1291. */
  1292. function loadaimlcategory($aimlstring,$botid)
  1293. {
  1294.  
  1295. global $selectbot;
  1296.  
  1297. $selectbot=$botid;
  1298. $aimlstring="<?xml version=\"1.0\" encoding=\"ISO-8859-1\"" . "?" . "><aiml version=\"1.0\">" . $aimlstring . "</aiml>";
  1299.  
  1300.  
  1301. flushcache();
  1302.  
  1303. learnstring($aimlstring);
  1304.  
  1305. }
  1306.  
  1307.  
  1308. /**
  1309. * Create the array PHP code for the sentence splitters
  1310. *
  1311. * In AIML it is custom to return a reply for every sentence the user inputs.
  1312. * This means the sentence input needs to be split into individual sentences.
  1313. * However, some people find that the semi-colon should also be added, while
  1314. * others think it should. The user will define the sentence splitters in
  1315. * startup.xml and these will then be stored in a PHP file included by the
  1316. * application.
  1317. *
  1318. * @param array $splitterarray containing the sentence splitters found in startup.xml
  1319. *
  1320. * @return string PHP array code for storing the sentence splitters
  1321. */
  1322. function makesplitterphp($splitterarray)
  1323. {
  1324. $splitterphp="\$likeperiodsearch=array(\n";
  1325. for ($x=0;$x<sizeof($splitterarray);$x++){
  1326. $splitterphp.="\"" . $splitterarray[$x] . "\",\n";
  1327.  
  1328. }
  1329. $splitterphp.=");\n";
  1330.  
  1331. $splitterphp.="\$likeperiodreplace=array(\n";
  1332. for ($x=0;$x<sizeof($splitterarray);$x++){
  1333. $splitterphp.="\"" . "." . "\",\n";
  1334.  
  1335. }
  1336. $splitterphp.=");\n";
  1337. return $splitterphp;
  1338. }
  1339.  
  1340.  
  1341.  
  1342. /**
  1343. * Add slashes for replacement purposes
  1344. *
  1345. * Making a string safe to preform a replacement function on.
  1346. *
  1347. * @param string $input string to be cleaned.
  1348. *
  1349. * @return string cleaned string.
  1350. */
  1351. function cleanforreplace($input)
  1352. {
  1353. $input = str_replace("\\", "\\\\", $input);
  1354. $input = str_replace("\"", "\\\"", $input);
  1355. $input = str_replace("'", "\'", $input);
  1356. return trim($input);
  1357. }
  1358.  
  1359.  
  1360.  
  1361. /**
  1362. * Add slashes for database query purpose
  1363. *
  1364. * Making a string safe to put the text in an SQL query.
  1365. *
  1366. * @param string $input string to be cleaned.
  1367. *
  1368. * @return string cleaned string.
  1369. */
  1370. function cleanforsearch($input)
  1371. {
  1372. $input = str_replace("\\", "\\\\\\\\", $input);
  1373. $input = str_replace("\"", "\\\"", $input);
  1374. $input = str_replace("'", "\'", $input);
  1375. $input = str_replace("/", "\/", $input);
  1376. $input = str_replace("(", "\(", $input);
  1377. $input = str_replace(")", "\)", $input);
  1378. $input = str_replace(".", "\.", $input);
  1379. return $input;
  1380. }
  1381.  
  1382.  
  1383. /**
  1384. * Creates the subs.inc file.
  1385. *
  1386. * Creates the subs.inc file and fills it with 5 arrays that correspond to the 4 substitution sections and sentence splitters.
  1387. *
  1388. * @uses makesrphp()
  1389. * @uses makesplitterphp()
  1390. * @uses createsubfile()
  1391. * @uses addtosubs()
  1392. *
  1393. * @global array contains the gender substitutions
  1394. * @global array contains the person substitutions
  1395. * @global array contains the person2 substitutions
  1396. * @global array ?????
  1397. * @global array contains the sentence splitters
  1398. *
  1399. * @return void Writes a file.
  1400. */
  1401.  
  1402. function makesubscode()
  1403. {
  1404.  
  1405. global $genderarray,$personarray,$person2array,$inputarray,$splitterarray;
  1406.  
  1407. $genderphp = makesrphp($genderarray, "gender");
  1408. $personphp = makesrphp($personarray, "firstthird");
  1409. $person2php = makesrphp($person2array, "firstsecond");
  1410. $inputphp = makesrphp($inputarray, "contract");
  1411. $splitterphp = makesplitterphp($splitterarray);
  1412.  
  1413. createsubfile();
  1414. addtosubs("<?\n");
  1415. addtosubs($genderphp);
  1416. addtosubs($personphp);
  1417. addtosubs($person2php);
  1418. addtosubs($inputphp);
  1419. addtosubs($splitterphp);
  1420. addtosubs("\n?>");
  1421.  
  1422. }
  1423.  
  1424. ?>

Documentation generated on Wed, 12 Jan 2005 12:24:44 +0100 by phpDocumentor 1.3.0RC3