I've long been frustrated by the manner in which GL searches are performed. If you search here (gl.sf.net) on "path, geeklog, install" or "path geeklog install", you'll get zero matches (even though all those words appear in
this article). This is because GL matches the entire string, not words within the string. While this is occasionally useful, most of the time I'm interested in finding any articles that contain all of the words I'm searching on, not the entire phrase.
Last night, I modified search.php to provide exactly that functionality. I modified both the stories/comments search and the links search ... but if you use events, you'll have to create a similar modification for that section (it's commented out on my site).
I managed to do this while not losing the existing functionality (except in one minor case). If you enter a search phrase in the usual way, GL will search on the phrase. But if you enter it with commas between terms, GL will now find all articles that contain each word (or phrase) between commas in the search line. The "minor case" that I've lost is the ability to search for a phrase that contains a comma, but I believe that to be a very very rare need. This hack will, however, successfully find words and phrases; a search on "geeklog, help with installation, path" will work as expected.The modifications are relatively easy and need to be made in two places (three if you want to modify the events search as well). First, in
function searchlinks, look for this bit:
Text Formatted Code
...
if (($type == 'links') || (($type == 'all') && empty ($author))) {
$sql = "SELECT lid,title,url,hits,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day FROM {$_TABLES['links']} WHERE ";
$sql .= " (title like '%$query%' ";
$sql .= " OR description like '%$query%')
...";
All you need to do is change it to look like this:
Text Formatted Code
...
if (($type == 'links') || (($type == 'all') && empty ($author))) {
$sql = "SELECT lid,title,url,hits,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day FROM {$_TABLES['links']} WHERE ";
if (substr_count($query,",") == 0) { // no commas, so no WORD searches
$sql .= " (title like '%$query%' ";
$sql .= " OR description like '%$query%') ";
} else {
$mywords = explode(",",$query);
$tmp = "";
foreach ($mywords as $mysearchterm) {
$tmp .= "(title like '%" . trim($mysearchterm) . "%' OR ";
$tmp .= "description like '%" . trim($mysearchterm) . "%') AND";
}
$tmp = substr($tmp,0,strlen($tmp)-4);
$sql .= $tmp;
}
...
Next, a similar change in
function searchstories. The original looks like:
Text Formatted Code
...
$sql = "SELECT sid,title,hits,uid,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day,'story' as type FROM {$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW()) ";
if (!empty ($query)) {
$sql .= "AND (introtext like '%$query%' ";
$sql .= "OR bodytext like '%$query%' ";
$sql .= "OR title like '%$query%') ";
}
...
Change the above section to look like this:
Text Formatted Code
...
$sql = "SELECT sid,title,hits,uid,group_id,owner_id,perm_owner,perm_group,perm_members,perm_anon,UNIX_TIMESTAMP(date) as day,'story' as type FROM {$_TABLES['stories']} WHERE (draft_flag = 0) AND (date <= NOW()) ";
if (!empty ($query)) {
if (substr_count($query,",") == 0) { // no commas, so no WORD searches
$sql .= "AND (introtext like '%$query%' ";
$sql .= "OR bodytext like '%$query%' ";
$sql .= "OR title like '%$query%') "
} else { // need to do WORD searches
$mywords = explode(",",$query);
$sql .= "AND ";
$tmp = "";
foreach ($mywords as $mysearchterm) {
$tmp .= "(introtext like '%" . trim($mysearchterm) . "%' OR ";
$tmp .= "bodytext like '%" . trim($mysearchterm) . "%' OR ";
$tmp .= "introtext like '%" . trim($mysearchterm) . "%') AND ";
}
$tmp = substr($tmp,0,strlen($tmp)-4);
$sql .= $tmp;
}
}
That's it! You should now be able to search on both phrases (words without commas) and multiple instances of words (separate them with commas). This hack has already saved me a bunch of time in finding previously published material. While not as cool as a full-blown logical search engine with 'and' and 'or' capabilities, it was much simpler to write!
I don't guarantee that this is the most efficient code, so improvements (and any potential traps you see) are welcomed...