if (isset($_SESSION['errors'])) { $errors = $_SESSION['errors']; // read session variable (only necessary if register globals is OFF!) // Note: though we clear the session variable, the current error message is still available to this script via '$errors': deleteSessionVariable("errors"); // function 'deleteSessionVariable()' is defined in 'include.inc.php' } else { $errors = array(); } // initialize the '$errors' variable in order to prevent 'Undefined variable...' messages if (isset($_SESSION['formVars'])) { $formVars = $_SESSION['formVars']; // read session variable (only necessary if register globals is OFF!) // Remove slashes from parameter values if 'magic_quotes_gpc = On': foreach ($formVars as $varname => $value) { $formVars[$varname] = stripSlashesIfMagicQuotes($value); } // function 'stripSlashesIfMagicQuotes()' is defined in 'include.inc.php' // Note: though we clear the session variable, the current form variables are still available to this script via '$formVars': deleteSessionVariable("formVars"); // function 'deleteSessionVariable()' is defined in 'include.inc.php' } else { $formVars = array(); } // -------------------------------------------------------------------- // Initialize preferred display language: // (note that 'locales.inc.php' has to be included *after* the call to the 'start_session()' function) include 'includes/locales.inc.php'; // include the locales // -------------------------------------------------------------------- // If there's no stored message available:
function findDuplicates($sqlQuery, $originalDisplayType) { global $tableRefs, $tableUserData; // defined in 'db.inc.php' global $alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, $print, $punct, $space, $upper, $word, $patternModifiers; // defined in 'transtab_unicode_charset.inc.php' and 'transtab_latin1_charset.inc.php' // re-assign the correct display type (i.e. the view that was active when the user clicked the 'dups' link in the header): if (!empty($originalDisplayType)) { $displayType = $originalDisplayType; } // Extract form variables provided by the 'duplicateSearch' form in 'duplicate_search.php': if (isset($_REQUEST['matchFieldsSelector'])) { if (is_string($_REQUEST['matchFieldsSelector'])) { // we accept a string containing a (e.g. comma delimited) list of field names $selectedFieldsArray = preg_split("/[^a-z_]+/", $_REQUEST['matchFieldsSelector'], -1, PREG_SPLIT_NO_EMPTY); } else { // the field list is already provided as array: $selectedFieldsArray = $_REQUEST['matchFieldsSelector']; } } else { $selectedFieldsArray = array(); } if (isset($_REQUEST['ignoreWhitespace']) and $_REQUEST['ignoreWhitespace'] == "1") { $ignoreWhitespace = "1"; } else { $ignoreWhitespace = "0"; } if (isset($_REQUEST['ignorePunctuation']) and $_REQUEST['ignorePunctuation'] == "1") { $ignorePunctuation = "1"; } else { $ignorePunctuation = "0"; } if (isset($_REQUEST['ignoreCharacterCase']) and $_REQUEST['ignoreCharacterCase'] == "1") { $ignoreCharacterCase = "1"; } else { $ignoreCharacterCase = "0"; } if (isset($_REQUEST['ignoreAuthorInitials']) and $_REQUEST['ignoreAuthorInitials'] == "1") { $ignoreAuthorInitials = "1"; } else { $ignoreAuthorInitials = "0"; } if (isset($_REQUEST['nonASCIIChars'])) { $nonASCIIChars = $_REQUEST['nonASCIIChars']; } else { $nonASCIIChars = "keep"; } // VALIDATE FORM DATA: $errors = array(); // Validate the field selector: if (empty($selectedFieldsArray)) { $errors["matchFieldsSelector"] = "You must select at least one field:"; } // Validate the 'SQL Query' field: if (empty($sqlQuery)) { $errors["sqlQuery"] = "You must specify a query string:"; } elseif (!preg_match("/^SELECT/i", $sqlQuery)) { $errors["sqlQuery"] = "You can only execute SELECT queries:"; } // Check if there were any errors: if (count($errors) > 0) { // In case of an error, we write all form variables back to the '$formVars' array // (which 'duplicate_search.php' requires to reload form values): foreach ($_REQUEST as $varname => $value) { $formVars[$varname] = $value; } // Since checkbox form fields do only get included in the '$_REQUEST' array if they were marked, // we have to add appropriate array elements for all checkboxes that weren't set: if (!isset($formVars["ignoreWhitespace"])) { $formVars["ignoreWhitespace"] = "0"; } if (!isset($formVars["ignorePunctuation"])) { $formVars["ignorePunctuation"] = "0"; } if (!isset($formVars["ignoreCharacterCase"])) { $formVars["ignoreCharacterCase"] = "0"; } if (!isset($formVars["ignoreAuthorInitials"])) { $formVars["ignoreAuthorInitials"] = "0"; } if (!isset($formVars["showLinks"])) { $formVars["showLinks"] = "0"; } // Write back session variables: saveSessionVariable("errors", $errors); // function 'saveSessionVariable()' is defined in 'include.inc.php' saveSessionVariable("formVars", $formVars); // There are errors. Relocate back to 'duplicate_search.php': header("Location: duplicate_search.php"); exit; // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> !EXIT! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< } // CONSTRUCT SQL QUERY (1. DUPLICATE SEARCH): // To identify any duplicates within the results of the original query, we build a new query based on the original SQL query: $query = $sqlQuery; // Replace SELECT list of columns with those from '$selectedFieldsArray' (plus the 'serial' column): $selectedFieldsString = implode(", ", $selectedFieldsArray); $query = newSELECTclause("SELECT " . $selectedFieldsString . ", serial", $query, false); // function 'newSELECTclause()' is defined in 'include.inc.php' // Replace any existing ORDER BY clause with the list of columns given in '$selectedFieldsArray': $query = newORDERclause("ORDER BY " . $selectedFieldsString, $query, false); // function 'newORDERclause()' is defined in 'include.inc.php' // Fix escape sequences within the SQL query: $query = stripSlashesIfMagicQuotes($query); // RUN the query on the database through the connection: $result = queryMySQLDatabase($query); // function 'queryMySQLDatabase()' is defined in 'include.inc.php' // PROCESS RESULTS: $recordSerialsArray = array(); $duplicateRecordSerialsArray = array(); $rowsFound = @mysql_num_rows($result); // Identify any records with matching field data: if ($rowsFound > 0) { // Count the number of fields: $fieldsFound = mysql_num_fields($result); // Loop over each row in the result set: for ($rowCounter = 0; $row = @mysql_fetch_array($result); $rowCounter++) { $recordIdentifier = ""; // make sure our buffer variable is empty // For each row, loop over each field (except for the last one which is the 'serial' field): for ($i = 0; $i < $fieldsFound - 1; $i++) { // fetch the current attribute name: $fieldName = getMySQLFieldInfo($result, $i, "name"); // function 'getMySQLFieldInfo()' is defined in 'include.inc.php' // normalize author names: if ($fieldName == "author" and $ignoreAuthorInitials == "1") { // this is a stupid hack that maps the names of the '$row' array keys to those used // by the '$formVars' array (which is required by function 'parsePlaceholderString()') // (eventually, the '$formVars' array should use the MySQL field names as names for its array keys) $formVars = buildFormVarsArray($row); // function 'buildFormVarsArray()' is defined in 'include.inc.php' // ignore initials in author names: $row[$i] = parsePlaceholderString($formVars, "<:authors[0||]:>", ""); // function 'parsePlaceholderString()' is defined in 'include.inc.php' } $recordIdentifier .= $row[$i]; // merge all field values to form a unique record identifier string } // Normalize record identifier string: if ($ignoreWhitespace == "1") { // ignore whitespace $recordIdentifier = preg_replace("/\\s+/", "", $recordIdentifier); } if ($ignorePunctuation == "1") { // ignore punctuation $recordIdentifier = preg_replace("/[{$punct}]+/{$patternModifiers}", "", $recordIdentifier); } if ($ignoreCharacterCase == "1") { // ignore character case $recordIdentifier = strtolower($recordIdentifier); } if ($nonASCIIChars == "strip") { // strip non-ASCII characters $recordIdentifier = handleNonASCIIAndUnwantedCharacters($recordIdentifier, "\\S\\s", "strip"); } elseif ($nonASCIIChars == "transliterate") { // transliterate non-ASCII characters $recordIdentifier = handleNonASCIIAndUnwantedCharacters($recordIdentifier, "\\S\\s", "transliterate"); } // Check whether the record identifier string has occurred already: if (isset($recordSerialsArray[$recordIdentifier])) { // this record identifier string has already been seen $recordSerialsArray[$recordIdentifier][] = $row["serial"]; } else { // new record identifier string $recordSerialsArray[$recordIdentifier] = array($row["serial"]); } // add a new array element for this record's identifier string (and store its serial number as value within a sub-array) } // Collect all array elements from '$recordSerialsArray' where their sub-array contains more than one serial number: foreach ($recordSerialsArray as $recordSerials) { if (count($recordSerials) > 1) { foreach ($recordSerials as $recordSerial) { $duplicateRecordSerialsArray[] = $recordSerial; } } // add this record's serial number to the array of duplicate record serials } } else { // TODO! } if (empty($duplicateRecordSerialsArray)) { $duplicateRecordSerialsArray[] = "0"; } // if no duplicate records were found, the non-existing serial number '0' will result in a "nothing found" feedback // CONSTRUCT SQL QUERY (2. DUPLICATES DISPLAY): // To display any duplicates that were found within the results of the original query, we build again a new query based on the original SQL query: $query = $sqlQuery; // Replace WHERE clause: // TODO: maybe make this into a generic function? (compare with function 'extractWHEREclause()' in 'include.inc.php') $duplicateRecordSerialsString = implode("|", $duplicateRecordSerialsArray); $query = preg_replace("/(?<=WHERE )(.+?)(?= ORDER BY| LIMIT| GROUP BY| HAVING| PROCEDURE| FOR UPDATE| LOCK IN|[ ;]+(SELECT|INSERT|UPDATE|DELETE|CREATE|ALTER|DROP|FILE)\\b|\$)/i", "serial RLIKE \"^(" . $duplicateRecordSerialsString . ")\$\"", $query); // Replace any existing ORDER BY clause with the list of columns given in '$selectedFieldsArray': $query = newORDERclause("ORDER BY " . $selectedFieldsString, $query, false); return array($query, $displayType); }
$showRows = $formVars['showRows']; if (isset($formVars['citeStyle'])) { $citeStyle = $formVars['citeStyle']; } else { $citeStyle = ""; } if (preg_match("/%20/", $citeStyle)) { // if '$citeStyle' still contains URL encoded data... ('%20' is the URL encoded form of a space, see note below!) $citeStyle = rawurldecode($citeStyle); } // ...URL decode 'citeStyle' statement (it was URL encoded before incorporation into a hidden tag of the 'sqlSearch' form to avoid any HTML syntax errors) // NOTE: URL encoded data that are included within a *link* will get URL decoded automatically *before* extraction via '$_REQUEST'! // But, opposed to that, URL encoded data that are included within a form by means of a *hidden form tag* will NOT get URL decoded automatically! Then, URL decoding has to be done manually (as is done here)! $citeOrder = $formVars['citeOrder']; $sqlQuery = $formVars['sqlQuery']; $sqlQuery = stripSlashesIfMagicQuotes($sqlQuery); // function 'stripSlashesIfMagicQuotes()' is defined in 'include.inc.php' if (isset($formVars['origQueryName'])) { $origQueryName = rawurldecode($formVars['origQueryName']); } else { $origQueryName = ""; } } // set display options according to the fetched attribute values: if ($showQuery == "1") { $checkQuery = " checked"; } else { $checkQuery = ""; } if ($showLinks == "1") { $checkLinks = " checked";
} // check if the user did mark any checkboxes (and set up variables accordingly) if (empty($recordSerialsArray)) { // no checkboxes were marked $nothingChecked = true; } else { // some checkboxes were marked $nothingChecked = false; } // -------------------------------------------------------------------- // CONSTRUCT SQL QUERY: // --- Embedded sql query: ---------------------- if ($formType == "sqlSearch") { $query = preg_replace("/ FROM {$tableUsers}/i", ", user_id FROM {$tableUsers}", $sqlQuery); // add 'user_id' column (which is required in order to obtain unique checkbox names as well as for use in the 'getUserID()' function) $query = stripSlashesIfMagicQuotes($query); } elseif ($formType == "refineSearch" or $formType == "displayOptions") { list($query, $displayType) = extractFormElementsRefineDisplay($tableUsers, $displayType, $originalDisplayType, $sqlQuery, $showLinks, "", ""); // function 'extractFormElementsRefineDisplay()' is defined in 'include.inc.php' since it's also used by 'users.php' } elseif ($formType == "groupSearch") { $query = extractFormElementsGroup($sqlQuery); } elseif ($formType == "queryResults") { list($query, $displayType) = extractFormElementsQueryResults($displayType, $originalDisplayType, $sqlQuery, $recordSerialsArray); } else { $query = "SELECT first_name, last_name, abbrev_institution, email, last_login, logins, user_id FROM {$tableUsers} WHERE user_id RLIKE \".+\" ORDER BY last_login DESC, last_name, first_name"; } // ---------------------------------------------- // (1) OPEN CONNECTION, (2) SELECT DATABASE connectToMySQLDatabase(); // function 'connectToMySQLDatabase()' is defined in 'include.inc.php' // (3) RUN the query on the database through the connection:
// IMPORTANT: We treat any 'call_number' query as specific to every user, i.e. a user can only query his own call numbers. $callNumber = ""; } if (isset($_REQUEST['userID']) and preg_match("/^[0-9]+\$/", $_REQUEST['userID'])) { $userID = $_REQUEST['userID']; } else { // will show every record where the user who's identified by user ID "2" has set the selected bit to "yes". $userID = ""; } if (isset($_REQUEST['by'])) { $browseByField = $_REQUEST['by']; } else { $browseByField = ""; } if (isset($_REQUEST['where'])) { $where = stripSlashesIfMagicQuotes($_REQUEST['where']); } else { $where = ""; } if (isset($_REQUEST['queryType'])) { $queryType = $_REQUEST['queryType']; } else { $queryType = ""; } if ($queryType == "or") { $queryType = "OR"; } // we allow for lowercase 'or' but convert it to uppercase (in an attempt to increase consistency & legibility of the SQL query) if ($queryType != "OR") { // if given value is 'OR' multiple parameters will be connected by 'OR', otherwise an 'AND' query will be performed $queryType = "AND";
// -------------------------------------------------------------------- // Initialize preferred display language: // (note that 'locales.inc.php' has to be included *after* the call to the 'start_session()' function) include 'includes/locales.inc.php'; // include the locales // -------------------------------------------------------------------- // [ Extract form variables sent through POST/GET by use of the '$_REQUEST' variable ] // [ !! NOTE !!: for details see <http://www.php.net/release_4_2_1.php> & <http://www.php.net/manual/en/language.variables.predefined.php> ] // Check if any error occurred while processing the database UPDATE/INSERT/DELETE $errorNo = $_REQUEST['errorNo']; $errorMsg = $_REQUEST['errorMsg']; $errorMsg = stripSlashesIfMagicQuotes($errorMsg); // function 'stripSlashesIfMagicQuotes()' is defined in 'include.inc.php' // Extract the header message that was returned by originating script: $HeaderString = $_REQUEST['headerMsg']; $HeaderString = stripSlashesIfMagicQuotes($HeaderString); // Extract the view type requested by the user (either 'Mobile', 'Print', 'Web' or ''): // ('' will produce the default 'Web' output style) if (isset($_REQUEST['viewType'])) { $viewType = $_REQUEST['viewType']; } else { $viewType = ""; } // Extract generic variables from the request: if (isset($_SESSION['oldQuery'])) { $oldQuery = $_SESSION['oldQuery']; } else { $oldQuery = array(); } // -------------------------------------------------------------------- // (4) DISPLAY HEADER & RESULTS
function explainSQLQuery($sourceSQLQuery) { // fix escape sequences within the SQL query: $translatedSQL = stripSlashesIfMagicQuotes($sourceSQLQuery); // $translatedSQL = str_replace('\"','"',$sourceSQLQuery); // replace any \" with " // $translatedSQL = preg_replace('/(\\\\)+/','\\\\',$translatedSQL); // define an array of search & replace actions: // (Note that the order of array elements IS important since it defines when a search/replace action gets executed) $sqlSearchReplacePatterns = array(" != " => " is not equal to ", " = " => " is equal to ", " > " => " is greater than ", " >= " => " is equal to or greater than ", " < " => " is less than ", " <= " => " is equal to or less than ", "NOT RLIKE \"\\^([^\"]+?)\\\$\"" => "is not equal to '\\1'", "NOT RLIKE \"\\^" => "does not start with '", "NOT RLIKE \"([^\"]+?)\\\$\"" => "does not end with '\\1'", "NOT RLIKE" => "does not contain", "RLIKE \"\\^([^\"]+?)\\\$\"" => "is equal to '\\1'", "RLIKE \"\\^" => "starts with '", "RLIKE \"([^\"]+?)\\\$\"" => "ends with '\\1'", "RLIKE" => "contains", "AND" => "and"); // Perform search & replace actions on the SQL query: $translatedSQL = searchReplaceText($sqlSearchReplacePatterns, $translatedSQL, false); $translatedSQL = str_replace('"', "'", $translatedSQL); // replace any remaining " with ' return $translatedSQL; }
function parseCQL($sruVersion, $sruQuery, $operation = "") { global $alnum, $alpha, $cntrl, $dash, $digit, $graph, $lower, $print, $punct, $space, $upper, $word, $patternModifiers; // defined in 'transtab_unicode_charset.inc.php' and 'transtab_latin1_charset.inc.php' // map CQL indexes to refbase field names: $indexNamesArray = mapCQLIndexes(); $searchArray = array(); // intialize array that will hold information about context set, index name, relation and search value $searchSubArray1 = array(); // -------------------------------- if (!empty($sruQuery)) { // check for presence of context set/index name and any of the main relations: if (!preg_match('/^[^\\" <>=]+( +(all|any|exact|within) +| *(<>|<=|>=|<|>|=) *)/', $sruQuery)) { // if no context set/index name and relation was given we'll add meaningful defaults: if (preg_match("/^suggest\$/i", $operation)) { $sruQuery = "main_fields all " . $sruQuery; } else { $sruQuery = "cql.serverChoice all " . $sruQuery; } // otherwise we currently use 'cql.serverChoice' (since 'main_fields' isn't yet supported for regular OpenSearch queries) } // extract the context set: if (preg_match('/^([^\\" <>=.]+)\\./', $sruQuery)) { $contextSet = preg_replace('/^([^\\" <>=.]+)\\..*/', '\\1', $sruQuery); } else { $contextSet = ""; } // use the default context set // extract the index: $indexName = preg_replace('/^(?:[^\\" <>=.]+\\.)?([^\\" <>=.]+).*/', '\\1', $sruQuery); // ---------------- // return a fatal diagnostic if the CQL query does contain an unrecognized 'set.index' identifier: // (a) verify that the given context set (if any) is recognized: if (!empty($contextSet)) { $contextSetIndexConnector = "."; $contextSetLabel = "context set '" . $contextSet . "'"; if (!preg_match("/^(dc|bath|rec|bib|cql)\$/", $contextSet)) { returnDiagnostic(15, $contextSet); // unsupported context set (function 'returnDiagnostic()' is defined in 'opensearch.php' and 'sru.php') exit; } } else { $contextSetIndexConnector = ""; $contextSetLabel = "empty context set"; } // (b) verify that the given 'set.index' term is recognized: if (!isset($indexNamesArray[$contextSet . $contextSetIndexConnector . $indexName])) { if (isset($indexNamesArray[$indexName]) or isset($indexNamesArray["dc." . $indexName]) or isset($indexNamesArray["bath." . $indexName]) or isset($indexNamesArray["rec." . $indexName]) or isset($indexNamesArray["bib." . $indexName]) or isset($indexNamesArray["cql." . $indexName])) { returnDiagnostic(10, "Unsupported combination of " . $contextSetLabel . " with index '" . $indexName . "'"); // unsupported combination of context set & index } else { returnDiagnostic(16, $indexName); // unsupported index } exit; } // ---------------- // extract the main relation (relation modifiers aren't supported yet!): $mainRelation = preg_replace('/^[^\\" <>=]+( +(all|any|exact|within) +| *(<>|<=|>=|<|>|=) *).*/', '\\1', $sruQuery); // remove any runs of leading or trailing whitespace: $mainRelation = trim($mainRelation); // ---------------- // extract the search term: $searchTerm = preg_replace('/^[^\\" <>=]+(?: +(?:all|any|exact|within) +| *(?:<>|<=|>=|<|>|=) *)(.*)/', '\\1', $sruQuery); // remove slashes from search term if 'magic_quotes_gpc = On': $searchTerm = stripSlashesIfMagicQuotes($searchTerm); // function 'stripSlashesIfMagicQuotes()' is defined in 'include.inc.php' // remove any leading or trailing quotes from the search term: // (note that multiple query parts connected with boolean operators aren't supported yet!) $searchTerm = preg_replace('/^\\"/', '', $searchTerm); $searchTerm = preg_replace('/\\"$/', '', $searchTerm); // OpenSearch search suggestions ('$operation=suggest'): since CQL matches full words (not sub-strings), // we need to make sure that every search term ends with the '*' masking character: if (preg_match("/^suggest\$/i", $operation) and $mainRelation != "exact") { $searchTerm = preg_replace("/([{$word}]+)(?![?*^])/{$patternModifiers}", "\\1*", $searchTerm); } // escape meta characters (including '/' that is used as delimiter for the PCRE replace functions below and which gets passed as second argument): $searchTerm = preg_quote($searchTerm, "/"); // escape special regular expression characters: . \ + * ? [ ^ ] $ ( ) { } = ! < > | : // account for CQL anchoring ('^') and masking ('*' and '?') characters: // NOTE: in the code block above we quote everything to escape possible meta characters, // so all special chars in the block below have to be matched in their escaped form! // (The expression '\\\\' in the patterns below describes only *one* backslash! -> '\'. // The reason for this is that before the regex engine can interpret the \\ into \, PHP interprets it. // Thus, you have to escape your backslashes twice: once for PHP, and once for the regex engine.) // // more info about masking characters in CQL: <http://zing.z3950.org/cql/intro.html#6> // more info about word anchoring in CQL: <http://zing.z3950.org/cql/intro.html#6.1> // recognize any anchor at the beginning of a search term (like '^foo'): // (in CQL, a word beginning with ^ must be the first in its field) $searchTerm = preg_replace('/(^| )\\\\\\^/', '\\1^', $searchTerm); // convert any anchor at the end of a search term (like 'foo^') to the correct MySQL variant ('foo$'): // (in CQL, a word ending with ^ must be the last in its field) $searchTerm = preg_replace('/\\\\\\^( |$)/', '$\\1', $searchTerm); // recognize any masking ('*' and '?') characters: // Note: by "character" we do refer to *word* characters here, i.e., any character that is not a space or punctuation character (see below); // however, I'm not sure if the masking characters '*' and '?' should also include non-word characters! $searchTerm = preg_replace('/(?<!\\\\)\\\\\\*/', '[^[:space:][:punct:]]*', $searchTerm); // a single asterisk ('*') is used to mask zero or more characters $searchTerm = preg_replace('/(?<!\\\\)\\\\\\?/', '[^[:space:][:punct:]]', $searchTerm); // a single question mark ('?') is used to mask a single character, thus N consecutive question-marks means mask N characters // ---------------- // construct the WHERE clause: $whereClausePart = $indexNamesArray[$contextSet . $contextSetIndexConnector . $indexName]; // start WHERE clause with field name if ($mainRelation == "all") { if (preg_match("/ /", $searchTerm)) { $searchTermArray = preg_split("/ +/", $searchTerm); foreach ($searchTermArray as $searchTermItem) { $whereClauseSubPartsArray[] = " RLIKE " . quote_smart("(^|[[:space:][:punct:]])" . $searchTermItem . "([[:space:][:punct:]]|\$)"); } // NOTE: For word-matching relations (like 'all', 'any' or '=') we could also use word boundaries which would be more (too?) restrictive: // // [[:<:]] , [[:>:]] // // They match the beginning and end of words, respectively. A word is a sequence of word characters that is not preceded by or // followed by word characters. A word character is an alphanumeric character in the alnum class or an underscore (_). $whereClausePart .= implode(" AND " . $indexNamesArray[$contextSet . $contextSetIndexConnector . $indexName], $whereClauseSubPartsArray); } else { $whereClausePart .= " RLIKE " . quote_smart("(^|[[:space:][:punct:]])" . $searchTerm . "([[:space:][:punct:]]|\$)"); } } elseif ($mainRelation == "any") { $searchTerm = splitAndMerge("/ +/", "|", $searchTerm); // function 'splitAndMerge()' is defined in 'include.inc.php' $whereClausePart .= " RLIKE " . quote_smart("(^|[[:space:][:punct:]])(" . $searchTerm . ")([[:space:][:punct:]]|\$)"); } elseif ($mainRelation == "exact") { // 'exact' is used for exact string matching, i.e., it matches field contents exactly $whereClausePart .= " = " . quote_smart($searchTerm); } elseif ($mainRelation == "within") { if (preg_match("/[^ ]+ [^ ]+/", $searchTerm)) { $searchTermArray = preg_split("/ +/", $searchTerm); $whereClausePart .= " >= " . quote_smart($searchTermArray[0]) . " AND " . $indexNamesArray[$contextSet . $contextSetIndexConnector . $indexName] . " <= " . quote_smart($searchTermArray[1]); } else { returnDiagnostic(36, "Search term requires two space-separated dimensions. Example: dc.date within \"2004 2005\""); exit; } } elseif ($mainRelation == "=") { // matches full words (not sub-strings); '=' is used for word adjacency, the words appear in that order with no others intervening $whereClausePart .= " RLIKE " . quote_smart("(^|[[:space:][:punct:]])" . $searchTerm . "([[:space:][:punct:]]|\$)"); } elseif ($mainRelation == "<>") { // does this also match full words (and not sub-strings) ?:-/ $whereClausePart .= " NOT RLIKE " . quote_smart("(^|[[:space:][:punct:]])" . $searchTerm . "([[:space:][:punct:]]|\$)"); } elseif ($mainRelation == "<") { $whereClausePart .= " < " . quote_smart($searchTerm); } elseif ($mainRelation == "<=") { $whereClausePart .= " <= " . quote_smart($searchTerm); } elseif ($mainRelation == ">") { $whereClausePart .= " > " . quote_smart($searchTerm); } elseif ($mainRelation == ">=") { $whereClausePart .= " >= " . quote_smart($searchTerm); } $searchSubArray1[] = array("_boolean" => "", "_query" => $whereClausePart); } else { $searchSubArray1[] = array("_boolean" => "", "_query" => "serial RLIKE " . quote_smart(".+")); } // -------------------------------- if (!empty($searchSubArray1)) { $searchArray[] = array("_boolean" => "", "_query" => $searchSubArray1); } return $searchArray; }