Source for file util.php

Documentation is available at util.php

  1. <?php
  2.  
  3. /*
  4. Program E
  5. Copyright 2002, Paul Rydell
  6. This file is part of Program E.
  7. Program E is free software; you can redistribute it and/or modify
  8. it under the terms of the GNU General Public License as published by
  9. the Free Software Foundation; either version 2 of the License, or
  10. (at your option) any later version.
  11.  
  12. Program E is distributed in the hope that it will be useful,
  13. but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. GNU General Public License for more details.
  16.  
  17. You should have received a copy of the GNU General Public License
  18. along with Program E; if not, write to the Free Software
  19. Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. */
  21.  
  22. /**
  23. * Util.php, Utility functions
  24. *
  25. * Contains reusable functions for Program E
  26. * @author Paul Rydell
  27. * @copyright 2002
  28. * @version 0.0.8
  29. * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  30. * @package Interpreter
  31. */
  32.  
  33.  
  34.  
  35. /**
  36. * Class to hold the reponse
  37. *
  38. * Container class to hold response, input error and a bunch of other
  39. * bits of information that is used in other functions
  40. * @author Paul Rydell
  41. * @copyright 2002
  42. * @version 0.0.8
  43. * @package Interpreter
  44. */
  45. class Response
  46. {
  47. var $response;
  48. var $patternsmatched;
  49. var $inputs;
  50. var $errors;
  51. var $timer;
  52. }
  53.  
  54. /**
  55. * subs.inc has all of the substitution values and sentence splitter values
  56. */
  57. require_once "admin/subs.inc";
  58.  
  59. // Initialize information for search replace routines
  60. $replacecounter=1;
  61. $aftersearch=array();
  62. $afterreplace=array();
  63.  
  64.  
  65. /**
  66. * Create a random number based upon the present time.
  67. *
  68. * @return float A fully random generated floating point number.
  69. */
  70. function make_seed() {
  71. list($usec, $sec) = explode(' ', microtime());
  72. return (float) $sec + ((float) $usec * 100000);
  73. }
  74.  
  75. /**
  76. * This function will clean up old data in the database that is not
  77. * needed according to user defined settings.
  78. *
  79. * Deletes entries in the database tables dstore, thatstack, thatstackindex
  80. * and if set also conversationlog.
  81. *
  82. * @uses make_seed()
  83. *
  84. * @return void nothing, deletes database entires
  85. */
  86. function cleanup(){
  87.  
  88. if ((RANDOMCHANCECLEAN == -1) || (MINUTESTOKEEPDATA == -1)){
  89. return;
  90. }
  91.  
  92. mt_srand(make_seed());
  93. $randval = mt_rand(1,RANDOMCHANCECLEAN);
  94.  
  95. if ($randval==RANDOMCHANCECLEAN){
  96.  
  97. if (MINUTESTOKEEPDATA != -1){
  98. $clean_dstore="delete from dstore where enteredtime < date_add(now(), interval - " . MINUTESTOKEEPDATA . " minute)";
  99. $clean_thatstack="delete from thatstack where enteredtime < date_add(now(), interval - " . MINUTESTOKEEPDATA . " minute)";
  100. $clean_thatindex="delete from thatindex where enteredtime < date_add(now(), interval - " . MINUTESTOKEEPDATA . " minute)";
  101.  
  102. $selectcode = mysql_query($clean_dstore);
  103. if ($selectcode){
  104. }
  105. $selectcode = mysql_query($clean_thatstack);
  106. if ($selectcode){
  107. }
  108. $selectcode = mysql_query($clean_thatindex);
  109. if ($selectcode){
  110. }
  111.  
  112. }
  113. if (MINUTESTOKEEPCHATLOG != -1){
  114. $clean_convlog="delete from conversationlog where enteredtime < date_add(now(), interval - " . MINUTESTOKEEPCHATLOG . " minute) and " . whichbots();
  115.  
  116. $selectcode = mysql_query($clean_convlog);
  117. if ($selectcode){
  118. }
  119.  
  120. }
  121.  
  122. }
  123.  
  124. }
  125.  
  126. /**
  127. * Check if a tag is an old style AIML tag.
  128. *
  129. * If it is then return its new name and the fact that it is deprecated. This
  130. * information is not send back through the return value, but by using call-by-reference
  131. * variable &$ttag.
  132. *
  133. * @param string $tag the tag name that needs to be checked
  134. * @param string &$ttag depreciated AIML tag name. Note, call-by-reference variable.
  135. *
  136. * @return boolean true/false; either it is a depreciated AIML tag or it is not.
  137. */
  138. function isdeprecated($tag,&$ttag){
  139.  
  140. if ($tag=="FOR_FUN"){
  141. $tag="FORFUN";
  142. }
  143. if ($tag=="BOTMASTER"){
  144. $tag="MASTER";
  145. }
  146. if ($tag=="KIND_MUSIC"){
  147. $tag="KINDMUSIC";
  148. }
  149. if ($tag=="LOOK_LIKE"){
  150. $tag="LOOKLIKE";
  151. }
  152.  
  153. if ($tag=="TALK_ABOUT"){
  154. $tag="TALKABOUT";
  155. }
  156. $deptags=array("NAME","BIRTHDAY","BIRTHPLACE","BOYFRIEND","FAVORITEBAND","FAVORITEBOOK","FAVORITECOLOR","FAVORITEFOOD","FAVORITESONG","FAVORITEMOVIE","FORFUN","FRIENDS","GIRLFRIEND","KINDMUSIC","LOCATION","LOOKLIKE","MASTER","QUESTION","SIGN","TALKABOUT","WEAR");
  157.  
  158. if (in_array($tag,$deptags)){
  159. $ttag=$tag;
  160. return true;
  161. }
  162. else {
  163. return false;
  164. }
  165.  
  166. }
  167.  
  168. /**
  169. * Substitution routine
  170. *
  171. * Is used in combination with for example {@link firstthird()} {@link gender()}. The myfunc() is called from these functions from the arrays generated in {@link subs.inc} by {@link makesrphp()}.
  172. *
  173. * When doing substitution myfunc replaces the words to be substituted with ~~x~~
  174. * where x is an incremented integer instead of what should eventually be substituted.
  175. * Then when all substitution is done another function will go through and replace the
  176. * ~~x~~ with the real value.
  177. *
  178. * @todo Analyse if a straight replace will be more effective and efficient. Hard to see why this two-stage replace has any advantages. If not, then rename the function.
  179. *
  180. * @global integer replacecounter The incremented integer number for substitution.
  181. * @global array aftersearch Contains ~~replacecounter number~~
  182. * @global array afterreplace Countains the input. (Anne:Have no idea how this works, yet.)
  183. *
  184. * @param string $input The new word replacing the old word.
  185. *
  186. * @return string The user's input, with ~~number~~ where the words in the substitution list
  187. * should be.
  188. */
  189. function myfunc($input){
  190. global $replacecounter,$aftersearch,$afterreplace;
  191.  
  192. $aftersearch[]="~~" . $replacecounter . "~~";
  193. $afterreplace[]=$input;
  194.  
  195. return "~~" . $replacecounter++ . "~~";
  196.  
  197. }
  198.  
  199. /**
  200. * Get the ID, or IP of the user
  201. *
  202. * Uses the server global REMOTE_ADDR.
  203. *
  204. * @global REMOTE_ADDR The user's remote address, i.e. LAN address.
  205. *
  206. * @return string IP number
  207. */
  208. function getid(){
  209.  
  210. return getenv("REMOTE_ADDR");
  211.  
  212. }
  213.  
  214. /**
  215. * get the current date formatted.
  216. *
  217. * Should look like: Wed Nov 14 18:09:55 CST 2002
  218. *
  219. * @return string formated date string, Day name, Month name, day number month, time, time zone and year.
  220. *
  221. */
  222. function getfdate(){
  223.  
  224. return date("D M j G:i:s T Y");
  225.  
  226. }
  227.  
  228. /**
  229. * Gets the numer of AIML categories stored in the database
  230. *
  231. * The size of the AIML knowledgebase is counted in categories. This function
  232. * will count the number of categories based upon the number of records in the
  233. * templates table.
  234. *
  235. * @uses whichbots()
  236. *
  237. * @return integer the number of templates in the template database.
  238. */
  239. function getsize(){
  240.  
  241. $query="select count(*) from templates where " . whichbots();
  242.  
  243. $selectcode = mysql_query($query);
  244. if ($selectcode){
  245. if(!mysql_numrows($selectcode)){
  246. return 0;
  247. }
  248. else{
  249. while ($q = mysql_fetch_array($selectcode)){
  250. return $q[0];
  251. }
  252. }
  253. }
  254. return "";
  255.  
  256. }
  257.  
  258. /**
  259. * Get information about the bot that was entered in the startup.xml
  260. *
  261. * In startup.xml there are a number of bot-varables called in AIML as <bot name="foo"/>
  262. * These are stored in the table 'bot' and this function retrieves (ex.) the value of
  263. * bot-variable "foo".
  264. *
  265. * @global integer uid is created in talk.php as $myuniqueid then transformed
  266. * in respond.php into $uid by reply()
  267. * @global integer selectbot is created in respond.php:replybotname() as $botid
  268. * which in return calls reply() that turns it into $selectbot
  269. *
  270. * @see talk.php
  271. * @see reply()
  272. * @see replybotname()
  273. *
  274. * @param string $name The name of the bot-variable of which the value is requested.
  275. *
  276. * @return string The value of requested bot variable.
  277. */
  278. function botget($name){
  279.  
  280. global $uid, $selectbot;
  281.  
  282. $name=addslashes($name);
  283.  
  284. $query="select value from bot where name='$name' and bot = $selectbot";
  285.  
  286. $selectcode = mysql_query($query);
  287. if ($selectcode){
  288. if(!mysql_numrows($selectcode)){
  289. return "";
  290. }
  291. else{
  292. while ($q = mysql_fetch_array($selectcode)){
  293. return $q[0];
  294. }
  295. }
  296. }
  297. return "";
  298.  
  299. }
  300.  
  301. /**
  302. * Get a value for some variable set by the user in AIML.
  303. *
  304. * In the template (<template> ... </template>) variables can be set and used during matching.
  305. * after matching these variables are stored in the table dstore. This function retrieves the
  306. * value of a stored variable. This type of variable is also called a 'predicate'.
  307. *
  308. * @global integer
  309. *
  310. * @return string Either the value of the stored predicate, or the constand default
  311. * value of a predicate
  312. */
  313. function bget($name){
  314.  
  315. global $uid;
  316.  
  317. $name=addslashes($name);
  318.  
  319. $query="select value from dstore where name='$name' and uid='$uid' order by id desc limit 1";
  320.  
  321. $selectcode = mysql_query($query);
  322. if ($selectcode){
  323. if(!mysql_numrows($selectcode)){
  324. return DEFAULTPREDICATEVALUE;
  325. }
  326. else{
  327. while ($q = mysql_fetch_array($selectcode)){
  328. return $q[0];
  329. }
  330. }
  331. }
  332. return DEFAULTPREDICATEVALUE;
  333.  
  334. }
  335.  
  336. /**
  337. * Set the value for an AIML variable
  338. *
  339. * Function to store the variable name and it's contents into the dstore table. It doens't
  340. * update the table, just the first insert.
  341. *
  342. * @global integer
  343. *
  344. * @param string $name The name in which the value should be stored
  345. * @param string $value The contents of the variable.
  346. *
  347. * @return void doesn't return anything
  348. */
  349. function bset($name,$value){
  350.  
  351. global $uid;
  352.  
  353. $value=trim($value);
  354. $name=addslashes($name);
  355. $value=addslashes($value);
  356.  
  357. $query="insert into dstore (uid,name,value) values ('$uid','$name','$value')";
  358. $selectcode = mysql_query($query);
  359. if ($selectcode){
  360. }
  361.  
  362. }
  363.  
  364. /**
  365. * Store the clients inputs into the database.
  366. *
  367. * This is an array because it separates on .'s and other sentence splitters. Stores these in the
  368. * dstore table of the database.
  369. *
  370. * @global integer
  371. *
  372. * @param array $inputsarray Contains multiple inputs (i.e. sentences) of a user
  373. *
  374. * @return void nothing
  375. */
  376. function addinputs($inputsarray){
  377.  
  378. global $uid;
  379.  
  380. $query="insert into dstore (uid,name,value) values ";
  381.  
  382. for ($x=0;$x<sizeof($inputsarray);$x++){
  383.  
  384. $value=addslashes(trim($inputsarray[$x]));
  385.  
  386. $query.="('$uid','input','$value'),";
  387.  
  388. }
  389.  
  390. $query=substr($query,0,(strlen($query)-1));
  391. $selectcode = mysql_query($query);
  392. if ($selectcode){
  393. }
  394.  
  395. }
  396.  
  397. /**
  398. * Store the bots responses into the database
  399. *
  400. * This is an array because it separates on .'s and other sentence splitters. Stores these in the
  401. * thatindex table of the database.
  402. *
  403. * @global integer
  404. *
  405. * @param array $inputsarray Contains multiple inputs (sentences) of the bot
  406. *
  407. * @return void nothing
  408. */
  409. function addthats($inputsarray){
  410.  
  411. global $uid;
  412.  
  413.  
  414. $query="insert into thatindex (uid) values ('$uid')";
  415.  
  416. $selectcode = mysql_query($query);
  417. if ($selectcode){
  418. }
  419. $thatidx=mysql_insert_id();
  420.  
  421. $query="insert into thatstack (thatid,value) values ";
  422.  
  423. for ($x=0;$x<sizeof($inputsarray);$x++){
  424.  
  425. $value=trim($inputsarray[$x]);
  426. $value=strip_tags($value);
  427. $value=addslashes($value);
  428.  
  429. $query.="($thatidx,'$value'),";
  430. }
  431.  
  432. $query=substr($query,0,(strlen($query)-1));
  433.  
  434. $selectcode = mysql_query($query);
  435. if ($selectcode){
  436. }
  437.  
  438. }
  439.  
  440. /**
  441. * Logs the whole input and response
  442. *
  443. * Saves the input and response into the conversationlog table of the database.
  444. *
  445. * @param string $input The user's input.
  446. * @param string $reponse The bot's response to the user's input.
  447. *
  448. * @global integer
  449. * @global integer
  450. * @return void nothing
  451. */
  452. function logconversation($input,$response){
  453.  
  454. global $uid, $selectbot;
  455.  
  456. $input=addslashes($input);
  457. $response=addslashes($response);
  458.  
  459. $query="insert into conversationlog (uid,input,response,bot) values ('$uid','$input','$response',$selectbot)";
  460. $selectcode = mysql_query($query);
  461. if ($selectcode){
  462. }
  463.  
  464. }
  465.  
  466. /**
  467. * Get the previous thing the bot said
  468. *
  469. * Retrieve from the thatindex table the previous output, per sentence, of what the bot said from the thatindex en thatstack table.
  470. *
  471. * @global integer
  472. *
  473. * @param integer $index Number between 1-5, 1 representing the previous bot output and 5 the 5th last bot output.
  474. * @param integer $offset Bot output is saved per sentence. So 1 would be last sentence, 3 would be third last sentence of that bot output.
  475. *
  476. * @return string The requested sentence of the bot's output
  477. */
  478. function getthat($index,$offset){
  479.  
  480. global $uid;
  481.  
  482. $index=$index-1;
  483. $offset=$offset-1;
  484.  
  485. $query="select id from thatindex where uid='$uid' order by id desc limit $index,1";
  486. $selectcode = mysql_query($query);
  487. if ($selectcode){
  488. if(!mysql_numrows($selectcode)){
  489. return "";
  490. }
  491. else{
  492. while ($q = mysql_fetch_array($selectcode)){
  493. $thatid=$q[0];
  494. }
  495. }
  496. }
  497.  
  498. $query="select value from thatstack where thatid=$thatid order by id desc limit $offset,1";
  499.  
  500.  
  501. $selectcode = mysql_query($query);
  502. if ($selectcode){
  503. if(!mysql_numrows($selectcode)){
  504. return "";
  505. }
  506. else{
  507. while ($q = mysql_fetch_array($selectcode)){
  508. return $q[0];
  509. }
  510. }
  511. }
  512. return "";
  513.  
  514. }
  515.  
  516. /**
  517. * Get the previous thing the client said
  518. *
  519. * Retrieve the entire previous input of the user from the dstore table.
  520. *
  521. * @global integer
  522. *
  523. * @return string The previous input of the user.
  524. */
  525. function getinput($index){
  526.  
  527. global $uid;
  528.  
  529. $offset=1;
  530.  
  531. $query="select value from dstore where uid='$uid' and name='input' order by id desc limit $index,$offset";
  532.  
  533. $selectcode = mysql_query($query);
  534. if ($selectcode){
  535. if(!mysql_numrows($selectcode)){
  536. return "";
  537. }
  538. else{
  539. while ($q = mysql_fetch_array($selectcode)){
  540. return $q[0];
  541. }
  542. }
  543. }
  544. return "";
  545.  
  546. }
  547.  
  548. /**
  549. * Take the user input and do all substitutions and split it into sentences
  550. *
  551. * The matching process searches a match for every sentence and in the end combines all
  552. * those individual matches into one reply. This funtion splits the sentences of the user's
  553. * input, replaces the words that need to be subtituted (found in startup.xml).
  554. *
  555. *
  556. * @global array contractsearch
  557. * @global array contractreplace
  558. * @global mixed abbrevsearch not used in this function
  559. * @global mixed removepunct used in this function, but code is commented out.
  560. * @global array likeperiodsearch
  561. * @global array likeperiodreplace
  562. * @global array aftersearch
  563. * @global array afterreplace
  564. * @global integer replacecounter
  565. *
  566. * @param string $input The unchanged user input.
  567. *
  568. * @return array each individual sentence, ready for matching.
  569. */
  570. function normalsentences($input){
  571.  
  572. global $contractsearch,$contractreplace,$abbrevsearch,$abbrevreplace,$removepunct,$likeperiodsearch,$likeperiodreplace,$aftersearch,$afterreplace,$replacecounter;
  573.  
  574. $cfull=$input;
  575.  
  576. $cfull=preg_replace($contractsearch,$contractreplace,$cfull);
  577. $cfull=str_replace($aftersearch,$afterreplace,$cfull);
  578.  
  579. $replacecounter=1;
  580. $aftersearch=array();
  581. $afterreplace=array();
  582.  
  583. //$cfull=str_replace($removepunct,"",$cfull);
  584. $cfull=str_replace($likeperiodsearch,$likeperiodreplace,$cfull);
  585.  
  586. $newsentences=array();
  587.  
  588. // Now split based on .'s
  589. $cfulls=split("\.",$cfull);
  590.  
  591. for ($x=0;$x<sizeof($cfulls);$x++){
  592. if (trim($cfulls[$x])==""){
  593.  
  594. }
  595. else {
  596. $newsentences[]=$cfulls[$x];
  597. }
  598. }
  599.  
  600. return $newsentences;
  601. }
  602.  
  603.  
  604. /**
  605. * Reverse the gender of a phrase
  606. *
  607. * Replaces, for example, 'he' in the string to 'she'. The gender related words and phrases that are used
  608. * can be found in subs.inc and originally in the startup.xml
  609. *
  610. * @global array gendersearch
  611. * @global array genderreplace
  612. * @global array
  613. * @global array
  614. * @global integer
  615. *
  616. * @param string $input The string where the gender related words/phrases need to be replaced
  617. *
  618. * @return string The string containing where the gender related words have been replaced.
  619. */
  620. function gender($input){
  621.  
  622. global $gendersearch,$genderreplace,$aftersearch,$afterreplace,$replacecounter;
  623.  
  624. $newinput=preg_replace($gendersearch,$genderreplace,$input);
  625.  
  626. $newinput=str_replace($aftersearch,$afterreplace,$newinput);
  627. $replacecounter=1;
  628. $aftersearch=array();
  629. $afterreplace=array();
  630.  
  631. return $newinput;
  632.  
  633. }
  634.  
  635. /**
  636. * Do a first to third person replacement
  637. *
  638. * Replaces, for example, "I was" to "he or she was". he gender related words and phrases that are used
  639. * can be found in subs.inc and originally in the startup.xml
  640. *
  641. * @global array firstthirdsearch
  642. * @global array firstthirdreplace
  643. * @global array
  644. * @global array
  645. * @global array
  646. * @global array
  647. * @global integer
  648. *
  649. * @param string $input The string where the first->third related words/phrases need to be replaced
  650. *
  651. * @return string The string containing where the first->third related words have been replaced.
  652. */
  653. function firstthird($input){
  654.  
  655. global $firstthirdsearch,$firstthirdreplace,$aftersearch,$afterreplace,$contractsearch,$contractreplace,$replacecounter;
  656.  
  657. $newinput=preg_replace($firstthirdsearch,$firstthirdreplace,$input);
  658.  
  659. $newinput=str_replace($aftersearch,$afterreplace,$newinput);
  660. $replacecounter=1;
  661. $aftersearch=array();
  662. $afterreplace=array();
  663.  
  664. return $newinput;
  665.  
  666. }
  667.  
  668. /**
  669. * Do a first to second person replacement
  670. *
  671. * Replaces, for example, "with you" to "with me". he gender related words and phrases that are used
  672. * can be found in subs.inc and originally in the startup.xml
  673. *
  674. * @global array
  675. * @global array
  676. * @global array
  677. * @global array
  678. * @global integer
  679. *
  680. * @param string $input The string where the first->second related words/phrases need to be replaced
  681. *
  682. * @return string The string containing where the first->second related words have been replaced.
  683. */
  684. function firstsecond($input){
  685.  
  686. global $firstsecondsearch,$firstsecondreplace,$aftersearch,$afterreplace,$replacecounter;
  687.  
  688. $newinput=preg_replace($firstsecondsearch,$firstsecondreplace,$input);
  689.  
  690. $newinput=str_replace($aftersearch,$afterreplace,$newinput);
  691. $replacecounter=1;
  692. $aftersearch=array();
  693. $afterreplace=array();
  694.  
  695. return $newinput;
  696.  
  697. }
  698.  
  699. /**
  700. * Insert gossip into the database
  701. *
  702. * Gossip is an AIML tag where the user can store bits of information from one user and then
  703. * reuse is in the conversation of another user. It is the only tag that behaves this way. Stores
  704. * value into the gossip table of the database.
  705. *
  706. * @param string $gossip The string that needs to be saved.
  707. *
  708. * @return void Nothing.
  709. */
  710. function insertgossip($gossip){
  711.  
  712. global $selectbot;
  713.  
  714. $gossip=addslashes($gossip);
  715.  
  716. $query="insert into gossip (gossip,bot) values ('$gossip'," . $selectbot . ")";
  717. $selectcode = mysql_query($query);
  718. if ($selectcode){
  719. }
  720.  
  721. }
  722.  
  723. /**
  724. * Get the child nodes of the XML tree
  725. *
  726. * Retrieve the child nodes of the XML tree. This is a recursive function.
  727. *
  728. * @uses GetChildren()
  729. *
  730. * @param array $vals
  731. * @param integer &$i call-by-reference variable for, most likely, GetXMLTree()
  732. *
  733. * @return array The child nodes in an array.
  734. */
  735. function GetChildren($vals, &$i) {
  736.  
  737. $children = array();
  738. if (isset($vals[$i]['value']))
  739. array_push($children, $vals[$i]['value']);
  740.  
  741. while (++$i < count($vals)) {
  742. if (!isset($vals[$i]['attributes'])){
  743. $vals[$i]['attributes']="";
  744. }
  745. if (!isset($vals[$i]['value'])){
  746. $vals[$i]['value']="";
  747. }
  748. switch ($vals[$i]['type']) {
  749. case 'cdata':
  750. array_push($children, $vals[$i]['value']);
  751. break;
  752. case 'complete':
  753. array_push($children, array('tag' => $vals[$i]['tag'], 'attributes' => $vals[$i]['attributes'], 'value' => $vals[$i]['value']));
  754. break;
  755. case 'open':
  756. array_push($children, array('tag' => $vals[$i]['tag'],'attributes' => $vals[$i]['attributes'], 'children' => GetChildren($vals,$i)));
  757. break;
  758.  
  759. case 'close':
  760. return $children;
  761. }
  762. }
  763. }
  764.  
  765. /**
  766. * Get an XML tree
  767. *
  768. * Create an XML tree in array form from a large string.
  769. *
  770. * @uses GetChildren()
  771. *
  772. * @param string $data Large string that needs to be turned into XML data.
  773. *
  774. * @return array Multi dimensional array in an XML way containing XML data.
  775. */
  776. function GetXMLTree($data) {
  777.  
  778. $p = xml_parser_create();
  779. xml_parser_set_option($p,XML_OPTION_CASE_FOLDING,0);
  780. xml_parse_into_struct($p, $data, $vals, $index);
  781. xml_parser_free($p);
  782.  
  783. $tree = array();
  784. $i = 0;
  785.  
  786. if (!isset($vals[$i]['attributes'])){
  787. $vals[$i]['attributes']="";
  788. }
  789.  
  790. array_push($tree, array('tag' => $vals[$i]['tag'], 'attributes' => $vals[$i]['attributes'], 'children' => GetChildren($vals, $i)));
  791. return $tree;
  792.  
  793. }
  794.  
  795. /**
  796. * Start a timer
  797. *
  798. * Save the start time of the to be timed script
  799. *
  800. * @global array ss_timing_start_times contains the start moments of the script
  801. *
  802. * @param string $name default value is 'default' Makes it possibe to time more than
  803. * event in one script.
  804. *
  805. * @return void nothing
  806. */
  807. function ss_timing_start ($name = 'default') {
  808. global $ss_timing_start_times;
  809. $ss_timing_start_times[$name] = explode(' ', microtime());
  810. }
  811.  
  812. /**
  813. * Stop a timer
  814. *
  815. * Save the stop time of the to be timed script
  816. *
  817. * @global array ss_timing_stop_times contains the stop moments of a script
  818. *
  819. * @param string $name default value is 'default' Makes it possibe to time more than
  820. * event in one script.
  821. *
  822. * @return void nothing
  823. */
  824. function ss_timing_stop ($name = 'default') {
  825. global $ss_timing_stop_times;
  826. $ss_timing_stop_times[$name] = explode(' ', microtime());
  827. }
  828.  
  829. /**
  830. * Retrieve timer data
  831. *
  832. * Get the running time the timed script
  833. *
  834. * @global array ss_timing_start_times contains the start and finish moments of the script
  835. * @global array ss_timing_stop_times contains the stop moments of a script
  836. *
  837. * @param string $name default value is 'default' Makes it possibe to time more than
  838. * event in one script.
  839. *
  840. * @return string the formated running time of the timed stript.
  841. */
  842. function ss_timing_current ($name = 'default') {
  843. global $ss_timing_start_times, $ss_timing_stop_times;
  844. if (!isset($ss_timing_start_times[$name])) {
  845. return 0;
  846. }
  847. if (!isset($ss_timing_stop_times[$name])) {
  848. $stop_time = explode(' ', microtime());
  849. }
  850. else {
  851. $stop_time = $ss_timing_stop_times[$name];
  852. }
  853. // do the big numbers first so the small ones aren't lost
  854. $current = $stop_time[1] - $ss_timing_start_times[$name][1];
  855. $current += $stop_time[0] - $ss_timing_start_times[$name][0];
  856. return $current;
  857. }
  858.  
  859. /**
  860. * Change the case of the keys of an array to all uppercase
  861. *
  862. * Array keys can be number or strings. If strings then it's a good habit to use only uppercase.
  863. * This is sadly not always the case. This function makes sure that they are.
  864. *
  865. * @param array Array suspected of having mixed case array keys.
  866. *
  867. * @return array Array containing only uppercase array keys.
  868. */
  869. function upperkeysarray($testa){
  870. $newtesta=$testa;
  871. if (is_array($testa)){
  872. $newtesta=array();
  873. $newkeys=array_keys($testa);
  874. for ($x=0;$x<sizeof($newkeys);$x++){
  875. $newtesta[strtoupper($newkeys[$x])]=$testa[$newkeys[$x]];
  876. }
  877. }
  878. return $newtesta;
  879.  
  880. }
  881.  
  882. /**
  883. * Check to see if a tag is a custom tag.
  884. *
  885. * Program E supports additional, non AIML 1.0x specified, custom tags. This function checks to see if
  886. * the encountered XML tag is indeed a custom AIML tag. If it is a custom tag, it will then the
  887. * appropriate function to use in &$functicall.
  888. *
  889. * @global array cttags contains all the custom tags. Array is created by loadcustomtags()
  890. *
  891. * @see loadcustomtags()
  892. *
  893. * @param string $tagname name of the tag to be checked
  894. * @param &$functocall call-by-reference variable used to send back the function name that
  895. * needs to be called to process the tag's contents.
  896. *
  897. * @return boolean true/false
  898. */
  899. function iscustomtag($tagname,&$functocall){
  900.  
  901. global $cttags;
  902.  
  903. if (in_array(strtoupper($tagname),$cttags)){
  904. $functocall="ct_" . $tagname;
  905. return true;
  906. }
  907. else {
  908. return false;
  909. }
  910.  
  911. }
  912.  
  913. /**
  914. * Load all custom tags
  915. *
  916. * Create a global accessible array with all custom tags, based upon the custom tag functions (ct_FunctionName()).
  917. *
  918. * @see customtags.php
  919. *
  920. * @return void
  921. */
  922. function loadcustomtags(){
  923.  
  924. global $cttags;
  925. $cttags=array();
  926.  
  927. $definedfuncs = get_defined_functions();
  928. $definedfuncs=$definedfuncs["user"];
  929.  
  930. // find all funcs in ["user"] funcs that match ct_??? and register each function and tag name
  931. foreach($definedfuncs as $x){
  932. if (substr($x,0,3)=="ct_"){
  933. $cttags[]=strtoupper(substr($x,3,strlen($x)));
  934. }
  935. }
  936.  
  937. }
  938.  
  939. /**
  940. * Look up the bot's ID number
  941. *
  942. * From the bot's name, retrieve it's bot ID number from the bots table in the database. This
  943. * funtion requires that each bot has a uniqe name to function.
  944. *
  945. * @param string $botname The bot's name.
  946. *
  947. * @return integer The bot ID that belongs to the unique botname.
  948. */
  949. function lookupbotid($botname){
  950.  
  951. $name=addslashes($botname);
  952. $q="select id from bots where botname='$name'";
  953. $selectcode = mysql_query($q);
  954. if ($selectcode) {
  955. while ($q = mysql_fetch_array($selectcode)){
  956. return $q["id"];
  957. }
  958. }
  959. return -1;
  960.  
  961. }
  962.  
  963.  
  964. /**
  965. * Which bot is selected
  966. *
  967. * Returns the bit of SQL query that limits the results to the selected bot.
  968. *
  969. * @global string selectbot The currently selected bot. The bot the user is chatting to.
  970. *
  971. * @return string The bit of SQL query that limits the results to the selected bot.
  972. */
  973. function whichbots()
  974. {
  975. global $selectbot;
  976.  
  977. return "bot=$selectbot";
  978. }
  979.  
  980. ?>

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