#
# Internal function, used to support "+keyword -keyword" syntax in addition
# to "and keyword not keyword" syntax.
#
function bq_handle_shorthand($text) {
$text = preg_replace("/ \+/", " and ", $text);
$text = preg_replace("/ -/", " not ", $text);
return $text;
}
#
# Internal function, used to keep quoted text together when building
# the query. i.e.... [fish and chips and "chipped ham"] syntax
#
# It essentially replaces " " with "~~~~" as long as we aren't within
# a set of quotes, in which case " " is retained. The string is then
# split on "~~~~~" with the surviving spaces intact.
#
function bq_explode_respect_quotes($line) {
$quote_level = 0; #keep track if we are in or out of quote-space
$buffer = "";
for ($a = 0; $a < strlen($line); $a++) {
if ($line[$a] == "\"") {
$quote_level++;
if ($quote_level == 2) { $quote_level = 0; }
}
else {
if ($line[$a] == " " and $quote_level == 0) {
$buffer = $buffer . "~~~~"; #Hackish magic key
}
else {
$buffer = $buffer . $line[$a];
}
}
}
$buffer = str_replace("\\", "", $buffer);
$array = explode("~~~~", $buffer);
return $array;
}
#
# Internal function, used to apply a single keyword against an
# arbitrary number of fields in the database in the same fashion.
#
# Works via replacing whitespace rather than interation
#
function bq_make_subquery($fields, $word, $mode) {
if ($mode == "not") {
$back = " LIKE '%$word%')";
}
else {
$back = " LIKE '%$word%')";
}
if ($mode == "not") {
$front = "(NOT ";
$glue = " LIKE '%$word%' OR ";
}
else {
$front = "(";
$glue = " LIKE '%$word%' OR ";
}
$text = str_replace(" ", $glue, $fields);
$text = $front . $text . $back;
return $text;
}
#
# Generates the "WHERE" portion of a query, iterating over every keyphrase in the
# given search string. Is safe to link (e.g. with AND) with the output of repeated
# calls
#
function bq_make_query($fields, $text) {
#
# We can't trust the user to give us a specific case
#
$fields = strtolower($fields);
$text = strtolower($text);
#
# Support +keyword -keyword
#
$text = bq_handle_shorthand($text);
#
# Split, but respect quotation
#
$wordarray = bq_explode_respect_quotes($text);
$buffer = "";
$output = "";
#
# work through each word (or "quoted phrase") in the text and build the
# outer shell of the query, filling the insides via bq_make_subquery
#
# "or" is assumed if neither "and" nor "not" is specified
#
for ($i = 0; $i 0) {
if ($word == "not") {
#
# $i++ kicks us to the actual keyword that the 'not' is working against, etc
#
$i++;
if ($i == 1) { #invalid sql syntax to prefix the first check with and/or/not
$buffer = bq_make_subquery($fields, $wordarray[$i], "not");
}
else {
$buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "not");
}
}
else {
if ($word == "or") {
$i++;
if ($i == 1) {
$buffer = bq_make_subquery($fields, $wordarray[$i], "");
}
else {
$buffer = " OR " . bq_make_subquery($fields, $wordarray[$i], "");
}
}
else {
if ($word == "and") {
$i++;
if ($i == 1) {
$buffer = bq_make_subquery($fields, $wordarray[$i], "");
}
else {
$buffer = " AND " . bq_make_subquery($fields, $wordarray[$i], "");
}
}
}
}
}
else {
if ($i == 0) { # 0 instead of 1 here because there was no conditional word to skip and no $i++;
$buffer = bq_make_subquery($fields, $wordarray[$i], "");
}
else {
$buffer = " OR " . bq_make_subquery($fields, $wordarray[$i], "");
}
}
$output = $output . $buffer;
}
return $output;
}
#
# Generates a simple boolean query. Use bq_make_query directly if you need to
# add further levels of complexity (the output of bq_make_query can be and/or/etc'd
# with any other output of bq_make_query)
#
#
# $return_fields == " url descripcion";
# "blah1 blah2 blah3" --> "SELECT blah1, blah2, blah3...."
#
# $tables == "quest";
# "t1 t2 t3" --> "FROM t1, t2
#
function bq_simple ($return_fields, $tables, $check_fields, $query_text) {
#
# Convert from space deliniated to comma deliniated for the query
#
$return_fields = str_replace(" ", ", ", $return_fields);
$tables = str_replace(" ", ", ", $tables);
#
# build the query itself
#
$query = "SELECT COUNT(*) $return_fields FROM $tables WHERE ";
$query = $query . bq_make_query($check_fields, $query_text);
$query = $query . " order by visto";
#
# Uncomment to debug
#
#echo $query;
return $query;
}
# Example usage to generate boolean query:
?>