/** * Gets an input sentence from the user and a aiml tag and creates an sql like pattern * @param string $sentence * @param string $field * @return string **/ function make_like_pattern($sentence, $field) { runDebug(__FILE__, __FUNCTION__, __LINE__, "Making a like pattern to use in the sql", 4); runDebug(__FILE__, __FUNCTION__, __LINE__, "Transforming {$field}: " . print_r($sentence, true), 4); $sql_like_pattern = "\n"; $i = 0; //if the sentence is contained in an array extract the actual text sentence if (is_array($sentence)) { $sentence = implode_recursive(' ', $sentence, __FILE__, __FUNCTION__, __LINE__); } $words = explode(" ", $sentence); runDebug(__FILE__, __FUNCTION__, __LINE__, "word list:\n" . print_r($words, true), 4); $count_words = count($words) - 1; $first_word = $words[0]; $last_word = $words[$count_words]; $tmpLike = ''; //$sql_like_pattern .= " `$field` like '$first_word % $last_word'";// OR `$field` like '$first_word %' OR `$field` like '% $last_word'"; $sql_like_pattern .= " `{$field}` like '{$first_word} % {$last_word}' OR\n"; $sql_like_pattern .= " `{$field}` like '{$first_word} %' OR\n"; $mid_lp = "`{$field}` like '{$first_word} %'"; foreach ($words as $word) { if ($word == $first_word or $word == $last_word) { continue; } $mid_lp = str_replace(' %', " {$word} %", $mid_lp); $sql_like_pattern .= " {$mid_lp} OR\n"; } runDebug(__FILE__, __FUNCTION__, __LINE__, "mid_lp = {$mid_lp}", 4); /* */ runDebug(__FILE__, __FUNCTION__, __LINE__, "returning like pattern:\n{$sql_like_pattern}", 4); return rtrim($sql_like_pattern) . ' '; }
/** * Gets an input sentence from the user and a aiml tag and creates an sql like pattern * @param string $sentence * @param string $field * @return string **/ function make_like_pattern($sentence, $field) { runDebug(__FILE__, __FUNCTION__, __LINE__, "Making a like pattern to use in the sql", 4); runDebug(__FILE__, __FUNCTION__, __LINE__, "Transforming {$field}: " . print_r($sentence, true), 4); $sql_like_pattern = ''; $i = 0; //if the sentence is contained in an array extract the actual text sentence if (is_array($sentence)) { $sentence = implode_recursive(' ', $sentence, __FILE__, __FUNCTION__, __LINE__); } $words = explode(" ", $sentence); runDebug(__FILE__, __FUNCTION__, __LINE__, "word list:\n" . print_r($words, true), 4); $count_words = count($words) - 1; $first_word = $words[0]; $last_word = $words[$count_words]; $tmpLike = ''; $sql_like_pattern .= " `{$field}` like '{$first_word} %' OR"; foreach ($words as $word) { if ($word == $first_word or $word == $last_word) { continue; } $sql_like_pattern .= " `{$field}` like '% {$word} %' OR"; } $sql_like_pattern .= " `{$field}` like '% {$last_word}%' OR `{$field}` like '{$first_word} % {$last_word}' OR `{$field}` like '{$last_word}'"; runDebug(__FILE__, __FUNCTION__, __LINE__, "returning like pattern:\n{$sql_like_pattern}", 4); return $sql_like_pattern; }
/** * Gets an input sentence from the user and a aiml tag and creates an sql like pattern * @param string $sentence * @param string $field * @return string **/ function make_like_pattern($sentence, $field) { runDebug(__FILE__, __FUNCTION__, __LINE__, "Making a like pattern to use in the sql", 4); runDebug(__FILE__, __FUNCTION__, __LINE__, "Transforming {$field}: " . print_r($sentence, true), 4); $sql_like_pattern = "\n"; $i = 0; //if the sentence is contained in an array extract the actual text sentence if (is_array($sentence)) { $sentence = implode_recursive(' ', $sentence, __FILE__, __FUNCTION__, __LINE__); } $words = explode(" ", $sentence); runDebug(__FILE__, __FUNCTION__, __LINE__, "word list:\n" . print_r($words, true), 4); $count_words = count($words) - 1; $first_word = $words[0]; if ($count_words == 0) { return " `{$field}` like '{$first_word}'\n"; } $last_word = $words[$count_words]; $tmpLike = ''; //$sql_like_pattern .= " `$field` like '$first_word % $last_word'";// OR `$field` like '$first_word %' OR `$field` like '% $last_word'"; $sql_like_pattern .= " `{$field}` like '{$first_word} % {$last_word}' OR\n"; $sql_like_pattern .= " `{$field}` like '{$first_word} %' OR\n"; $wordsArr = explode(" ", $sentence); $totalWordCount = count($wordsArr); $likePatternArr = array(); for ($i = 0; $i < $totalWordCount; $i++) { $twoUp = $i + 2; $oneUp = $i + 1; $oneDown = $i - 1; if (isset($wordsArr[$twoUp])) { $middleWord = $wordsArr[$oneUp]; $likePatternArr[] = "(`{$field}` LIKE '% " . $middleWord . " %')"; } if ($oneDown >= 0) { $likePatternOneArr = $wordsArr; $likePatternOneArr[$i] = '%'; $likePatternOne = implode(' ', $likePatternOneArr); $likePatternArr[] = "(`{$field}` LIKE '" . trim(strstr($likePatternOne, '%', true)) . " %')"; } if ($oneUp < $totalWordCount) { $likePatternOneArr = $wordsArr; $likePatternOneArr[$i] = '%'; $likePatternOne = implode(' ', $likePatternOneArr); $likePatternArr[] = "(`{$field}` LIKE '" . trim(strstr($likePatternOne, '%', false)) . "' )"; } } $newSqlPatterns = implode(' OR ', $likePatternArr) . ' OR '; $sql_like_pattern .= $newSqlPatterns; runDebug(__FILE__, __FUNCTION__, __LINE__, "returning like pattern:\n{$sql_like_pattern}", 4); return rtrim($sql_like_pattern, ' OR ') . ' '; }
/** * Recursively implode an array * * @param string $delim The array item delimiter * @param array $array The array * * @return string The imploded string */ function implode_recursive(array $array, $delim = ' ') { $str = ''; foreach ($array as $data) { if (strlen($str)) { $str .= $delim; } if (is_array($data)) { $str .= implode_recursive($data, $delim); } if (is_string($data)) { $str .= $data; } } return $str; }
/** * function run_srai() * This function controls the SRAI recursion calls * @param array $convoArr - a reference to the existing conversation array * @param string $now_look_for_this - the text to search for * @return string $srai_parsed_template - the result of the search **/ function run_srai(&$convoArr, $now_look_for_this) { global $srai_iterations, $error_response, $dbConn, $dbn; $bot_parent_id = $convoArr['conversation']['bot_parent_id']; $bot_id = $convoArr['conversation']['bot_id']; if ($bot_parent_id != 0 and $bot_parent_id != $bot_id) { $sql_bot_select = " (bot_id = '{$bot_id}' OR bot_id = '{$bot_parent_id}') "; } else { $sql_bot_select = " bot_id = '{$bot_id}' "; } $bot_id = $convoArr['conversation']['bot_id']; runDebug(__FILE__, __FUNCTION__, __LINE__, 'Checking for entries in the srai_lookup table.', 2); runDebug(__FILE__, __FUNCTION__, __LINE__, "google bot_id = {$bot_id}", 2); $lookingfor = $convoArr['aiml']['lookingfor']; //$now_look_for_this = strtoupper($now_look_for_this); $sql = "select `template_id` from `{$dbn}`.`srai_lookup` where `pattern` = '{$now_look_for_this}' and {$sql_bot_select};"; runDebug(__FILE__, __FUNCTION__, __LINE__, "lookup SQL = {$sql}", 2); $sth = $dbConn->prepare($sql); $sth->execute(); $row = $sth->fetchAll(); runDebug(__FILE__, __FUNCTION__, __LINE__, 'Result = ' . print_r($row, true), 2); $num_rows = count($row); if ($num_rows > 0) { runDebug(__FILE__, __FUNCTION__, __LINE__, "Found {$num_rows} rows in lookup table: " . print_r($row, true), 2); $template_id = $row[0]['template_id']; runDebug(__FILE__, __FUNCTION__, __LINE__, "Found a matching entry in the lookup table. Using ID# {$template_id}.", 2); $sql = "select `template` from `{$dbn}`.`aiml` where `id` = '{$template_id}';"; $sth = $dbConn->prepare($sql); $sth->execute(); $row = $sth->fetch(); runDebug(__FILE__, __FUNCTION__, __LINE__, "Row found in AIML for ID {$template_id}: " . print_r($row, true), 2); if (!empty($row)) { $template = add_text_tags($row['template']); try { $sraiTemplate = new SimpleXMLElement($template, LIBXML_NOCDATA); } catch (exception $e) { trigger_error("There was a problem parsing the SRAI template as XML. Template value:\n{$template}", E_USER_WARNING); $sraiTemplate = new SimpleXMLElement("<text>{$error_response}</text>", LIBXML_NOCDATA); } $responseArray = parseTemplateRecursive($convoArr, $sraiTemplate); $response = implode_recursive(' ', $responseArray, __FILE__, __FUNCTION__, __LINE__); runDebug(__FILE__, __FUNCTION__, __LINE__, "Returning results from stored srai lookup.", 2); return $response; } } else { runDebug(__FILE__, __FUNCTION__, __LINE__, 'No match found in lookup table.', 2); } runDebug(__FILE__, __FUNCTION__, __LINE__, "Nothing found in the SRAI lookup table. Looking for a direct pattern match for '{$now_look_for_this}'.", 2); $sql = "SELECT `id`, `bot_id`, `pattern`, `thatpattern`, `topic` FROM `{$dbn}`.`aiml` where `pattern` = :pattern and {$sql_bot_select} order by `id` asc;"; $sth = $dbConn->prepare($sql); $sth->bindValue(':pattern', $now_look_for_this); $sth->execute(); $result = $sth->fetchAll(); $num_rows = count($result); runDebug(__FILE__, __FUNCTION__, __LINE__, "Found {$num_rows} potential responses.", 2); $allrows = array(); $i = 0; if ($result && $num_rows > 0) { $tmp_rows = number_format($num_rows); runDebug(__FILE__, __FUNCTION__, __LINE__, "FOUND: ({$num_rows}) potential AIML matches", 2); //loop through results foreach ($result as $row) { $row['aiml_id'] = $row['id']; $row['score'] = 0; $row['track_score'] = ''; $allrows[] = $row; $mu = memory_get_usage(true); if ($mu >= MEM_TRIGGER) { runDebug(__FILE__, __FUNCTION__, __LINE__, 'Current operation exceeds memory threshold. Aborting data retrieval.', 0); break; } } } else { runDebug(__FILE__, __FUNCTION__, __LINE__, "Error: FOUND NO AIML matches in DB", 1); $allrows[$i]['aiml_id'] = "-1"; $allrows[$i]['bot_id'] = "-1"; $allrows[$i]['pattern'] = "no results"; $allrows[$i]['thatpattern'] = ''; $allrows[$i]['topic'] = ''; } //unset all irrelvant matches $allrows = unset_all_bad_pattern_matches($convoArr, $allrows, $now_look_for_this); //score the relevant matches $allrows = score_matches($convoArr, $allrows, $now_look_for_this); //get the highest $allrows = get_highest_scoring_row($convoArr, $allrows, $lookingfor); if (isset($allrows['aiml_id']) && $allrows['aiml_id'] > 0) { $sql = "select `template` from `{$dbn}`.`aiml` where `id` = :id limit 1;"; $sth = $dbConn->prepare($sql); $aiml_id = $allrows['aiml_id']; $pattern = $allrows['pattern']; $sth->bindValue(':id', $aiml_id); $sth->execute(); $row = $sth->fetch(); $sth->closeCursor(); $template = add_text_tags($row['template']); try { $sraiTemplate = new SimpleXMLElement($template, LIBXML_NOCDATA); } catch (exception $e) { trigger_error("There was a problem parsing the SRAI template as XML. Template value:\n{$template}", E_USER_WARNING); $sraiTemplate = new SimpleXMLElement("<text>{$error_response}</text>", LIBXML_NOCDATA); } $responseArray = parseTemplateRecursive($convoArr, $sraiTemplate); $response = implode_recursive(' ', $responseArray, __FILE__, __FUNCTION__, __LINE__); try { // code to try here $sql = "insert into `{$dbn}`.`srai_lookup` (`id`, `bot_id`, `pattern`, `template_id`) values(null, :bot_id, :pattern, :template_id);"; $sth = $dbConn->prepare($sql); $sth->bindValue(':bot_id', $bot_id); $sth->bindValue(':pattern', $pattern); $sth->bindValue(':template_id', $aiml_id); $sth->execute(); $affectedRows = $sth->rowCount(); if ($affectedRows > 0) { runDebug(__FILE__, __FUNCTION__, __LINE__, "Successfully inserted entry for '{$pattern}'.", 1); } } catch (Exception $e) { //something to handle the problem here, usually involving $e->getMessage() $err = $e->getMessage(); runDebug(__FILE__, __FUNCTION__, __LINE__, "Unable to insert entry for '{$pattern}'! Error = {$err}.", 1); runDebug(__FILE__, __FUNCTION__, __LINE__, "SQL = {$sql}", 1); } // runDebug(__FILE__, __FUNCTION__, __LINE__, "Returning results from stored srai lookup.", 2); return $response; } runDebug(__FILE__, __FUNCTION__, __LINE__, "Running SRAI {$srai_iterations} on {$now_look_for_this}", 3); runDebug(__FILE__, __FUNCTION__, __LINE__, $convoArr['aiml']['html_template'], 4); //number of srai iterations - will stop recursion if it is over 10 $srai_iterations++; runDebug(__FILE__, __FUNCTION__, __LINE__, "Incrementing srai iterations to {$srai_iterations}", 4); if ($srai_iterations > 10) { runDebug(__FILE__, __FUNCTION__, __LINE__, "ERROR - Too much recursion breaking out", 1); $convoArr['aiml']['parsed_template'] = $error_response; return $error_response; } //$tmp_convoArr = array(); $tmp_convoArr = $convoArr; if (!isset($tmp_convoArr['stack'])) { $tmp_convoArr = load_blank_stack($tmp_convoArr); } if (!isset($tmp_convoArr['topic'])) { $tmp_convoArr['topic'] = array(); $tmp_convoArr['topic'][1] = ''; } $tmp_convoArr['aiml'] = array(); $tmp_convoArr['that'][1][1] = ""; //added $tmp_convoArr['aiml']['parsed_template'] = ""; $tmp_convoArr['aiml']['lookingfor'] = $now_look_for_this; $tmp_convoArr['aiml']['pattern'] = $now_look_for_this; $tmp_convoArr['aiml']['thatpattern'] = $convoArr['aiml']['thatpattern']; $tmp_convoArr = get_aiml_to_parse($tmp_convoArr); $tmp_convoArr = parse_matched_aiml($tmp_convoArr, "srai"); $srai_parsed_template = $tmp_convoArr['aiml']['parsed_template']; runDebug(__FILE__, __FUNCTION__, __LINE__, "SRAI Found. Returning '{$srai_parsed_template}'", 2); $convoArr['client_properties'] = $tmp_convoArr['client_properties']; $convoArr['topic'] = $tmp_convoArr['topic']; $convoArr['stack'] = $tmp_convoArr['stack']; $srai_iterations--; runDebug(__FILE__, __FUNCTION__, __LINE__, "Decrementing srai iterations to {$srai_iterations}", 4); return $srai_parsed_template . " "; }
/** * Join array elements with a glue string recursively. * * @param string $glue * @param array $array * @param string $group_prefix * @param string $group_suffix * @return string */ function join_recursive($glue, $array, $group_prefix = '(', $group_suffix = ')') { if (empty($array)) { return ''; } $result = ""; foreach ($array as $item) { $result .= (isset($item) && is_scalar($item) ? $item : $group_prefix . implode_recursive($glue, $item, $group_prefix, $group_suffix) . $group_suffix) . $glue; } return substr($result, 0, -1 * strlen($glue)); }
/** * function load_that(() * A function to load the previous bot responses into the convoArr['that'] array * * @link http://blog.program-o.com/?p=1283 * @param array $convoArr - the current state of the conversation array * @return array $convoArr (updated) */ function load_that($convoArr) { runDebug(__FILE__, __FUNCTION__, __LINE__, 'Loading the THAT array.', 2); global $dbConn, $dbn, $remember_up_to, $bot_id; $remember_up_to = !empty($convoArr['conversation']['remember_up_to']) ? $convoArr['conversation']['remember_up_to'] : $remember_up_to; $user_id = $convoArr['conversation']['user_id']; $bot_id = !empty($convoArr['conversation']['bot_id']) ? $convoArr['conversation']['bot_id'] : $bot_id; $limit = $remember_up_to; $sql = "select `input`, `response` from `{$dbn}`.`conversation_log` where `user_id` = {$user_id} and `bot_id` = {$bot_id} order by `id` desc limit {$limit};"; // desc runDebug(__FILE__, __FUNCTION__, __LINE__, "Getting conversation log entries for the current user. SQL:\n{$sql}", 3); $result = db_fetchAll($sql, null, __FILE__, __FUNCTION__, __LINE__); if ($result) { $tmpThatRows = array(); $tmpInputRows = array(); $tmpThat = array(); $tmpInput = array(); $puncuation = array(',', '?', ';', '!'); foreach ($result as $row) { $tmpThatRows[] = $row['response']; $tmpInputRows[] = $row['input']; } runDebug(__FILE__, __FUNCTION__, __LINE__, 'Inputs returned:' . print_r($tmpInputRows, true), 1); runDebug(__FILE__, __FUNCTION__, __LINE__, 'Loading previous responses into the ~THAT~ array.', 4); runDebug(__FILE__, __FUNCTION__, __LINE__, 'Responses returned:' . print_r($tmpThatRows, true), 1); $tmpThatRows = array_reverse($tmpThatRows); foreach ($tmpThatRows as $row) { $row = str_replace($puncuation, '.', $row); $tmpThat[] = explode('.', $row); } array_unshift($tmpThat, NULL); unset($tmpThat[0]); foreach ($tmpThat as $index => $value) { $value = implode_recursive(' ', $value, __FILE__, __FUNCTION__, __LINE__); $value = clean_that($value, __FILE__, __FUNCTION__, __LINE__); $convoArr = push_on_front_convoArr('that', $value, $convoArr); } runDebug(__FILE__, __FUNCTION__, __LINE__, 'Loading previous user inputs into the ~INPUT~ array.', 4); $tmpInputRows = array_reverse($tmpInputRows); foreach ($tmpInputRows as $row) { $row = str_replace($puncuation, '.', $row); $tmpInput[] = explode('.', $row); } array_unshift($tmpThat, NULL); unset($tmpThat[0]); foreach ($tmpInput as $index => $value) { $value = implode_recursive(' ', $value, __FILE__, __FUNCTION__, __LINE__); $value = clean_that($value, __FILE__, __FUNCTION__, __LINE__); $convoArr = push_on_front_convoArr('input', $value, $convoArr); } } else { runDebug(__FILE__, __FUNCTION__, __LINE__, 'Couldn\'t find any previous inputs or responses.', 4); } return $convoArr; }
/** * Function parse_wiki_tag * * * @param $convoArr * @param $element * @param $parentName * @param $level * @return string */ function parse_wiki_tag($convoArr, $element, $parentName, $level) { global $debugemail; runDebug(__FILE__, __FUNCTION__, __LINE__, 'Parsing custom WIKI tag.', 2); $response = array(); $children = $element->children(); if (!empty($children)) { $response = parseTemplateRecursive($convoArr, $children, $level + 1); } else { $response[] = (string) $element; } $response_string = implode_recursive(' ', $response); // do something here $wikiURL = 'http://en.wikipedia.org/w/api.php?action=opensearch&format=xml&limit=1&search=' . urlencode($response_string); $options = array(CURLOPT_HTTPGET => TRUE, CURLOPT_POST => FALSE, CURLOPT_HEADER => false, CURLOPT_NOBODY => FALSE, CURLOPT_VERBOSE => FALSE, CURLOPT_REFERER => "", CURLOPT_USERAGENT => "Program O version " . VERSION . " - Please contact {$debugemail} regarding any queries or complaints.", CURLOPT_SSL_VERIFYPEER => FALSE, CURLOPT_FOLLOWLOCATION => TRUE, CURLOPT_MAXREDIRS => 4); $wikiText = get_cURL($wikiURL, $options); #save_file(_DEBUG_PATH_ . 'wiki_return.txt', $wikiText); $xml = simplexml_load_string($wikiText, 'SimpleXMLElement', LIBXML_NOCDATA); if ((string) $xml->Section->Item->Description) { $description = (string) $xml->Section->Item->Description; $image = (string) $xml->Section->Item->Image->asXML(); $image = str_replace('<Image source', '<img src', $image); $linkHref = (string) $xml->Section->Item->Url; $linkText = (string) $xml->Section->Item->Text; $link = "<a href=\"{$linkHref}\" target=\"_blank\">{$linkText}</a>"; $output = "{$link}<br/>\n{$image}<br/>\n{$description}"; } else { $output = 'Wikipedia returned no results!'; } //$output = '<![CDATA[' . $output . ']]>'; // Uncomment this line when using the XHTML doctype return $output; }
/** * Converts the contents of the AIML tag to a string. * * @param array $convoArr * @param SimpleXMLElement $element * @param string $parentName * @param int $level * @param string $type * @return string */ function tag_to_string(&$convoArr, $element, $parentName, $level, $type = 'element') { runDebug(__FILE__, __FUNCTION__, __LINE__, "converting the {$parentName} tag into text.", 2); $response = array(); $children = $element->children(); if (!empty($children)) { foreach ($children as $child) { $response[] = parseTemplateRecursive($convoArr, $child, $level + 1); } } else { switch ($type) { case 'element': $response[] = (string) $element; break; default: $response[] = $convoArr['star'][1]; } } $response_string = implode_recursive(' ', $response, __FILE__, __FUNCTION__, __LINE__); // do something here return $response_string; }
public function testRecursiveImplode() { $array = ['test', 'one', 'two', ['fix', 'it'], 'not needed!']; $this->assertEquals('test one two fix it not needed!', implode_recursive($array)); }
/** * Get the value of a log event item, quote if needed. * * @param string $key * @return string */ protected function quoteEventValue($key) { if (is_array($key)) { $key = $key[1]; } // for preg_replace_callback $value = $this->_eventValues[$key]; if (!is_scalar($value)) { $value = $this->arrayImplode['prefix'] . implode_recursive($this->arrayImplode['glue'], $value, $this->arrayImplode['prefix'], $this->arrayImplode['suffix']) . $this->arrayImplode['suffix']; } if (!empty($this->formatValue)) { $value = sprintf($this->formatValue, $this->quote ? addcslashes($key, '"') : $key, $this->quote ? addcslashes($value, '"') : $value); } elseif ($this->quote) { $value = '"' . addcslashes($value, '"') . '"'; } return $value; }