Obtaining Correct Filepath for files on search results
SomebodySysop - June 11, 2008 - 21:46
| Project: | Swish-E Indexer |
| Version: | 5.x-1.1 |
| Component: | Code |
| Category: | bug report |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | needs review |
Jump to:
Description
On Drupal 5.7 system, getting this error when executing search after clicking on "Files" tab:
* warning: Invalid argument supplied for foreach() in modules/node/node.module on line 521.
* warning: implode(): Bad arguments. in modules/node/node.module on line 525.
* user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 query: SELECT n.nid, n.vid, n.type, n.status, n.created, n.changed, n.comment, n.promote, n.sticky, r.timestamp AS revision_timestamp, r.title, r.body, r.teaser, r.log, r.format, u.uid, u.name, u.picture, u.data FROM node n INNER JOIN users u ON u.uid = n.uid INNER JOIN node_revisions r ON r.vid = n.vid WHERE in includes/database.mysql.inc on line 172.Attached screenshot as well. Correct file is returned, but with these warnings.
Is this some configuration issue on my part? Thanks for any assistance.
| Attachment | Size |
|---|---|
| swishSearchError.jpg | 75.63 KB |

#1
OK, after a day or so, I believe I have a much better understanding of what's going on. There are three overall problems that I see. I think I should deal with each as a separate issue.
The first appears to be the path of files displayed on the search results. Swish-e indexes files recursively, so all applicable files under the "files" directory are indexed, including subdirectories.
However, on the search results, the swish.module code inserts variable_get('file_directory_path', 'files') as the default path to each file (regardless of it's actual filepath). Therefore, for example, on the file search results screen, files/file1.doc will display the correct link and "Containing node", but files/subdir/file2.doc will not, hence the warning:
warning: Invalid argument supplied for foreach() in modules/node/node.module on line 521.Now, it appears that each time you also do a
_swish_do_index(), you do an_swish_do_update()which populates the swish_fulltext table with all the correct filepaths.So, my proposed logic for the search results list would be to get the correct filepath for each file from the swish_fulltext table, which will also retrieve the correct node information. The proposed code changes:
<?php
/**
* This will be invoked by the search module.
* Returns the Header, and array of items found, if any.
*/
function swish_search ($op = 'search', $keys = null){
...
case 'search' :
$find = array();
$is_public = false;
$swish_bin = variable_get('swish_path', '/usr/local/bin/swish-e');
if (variable_get('file_downloads','1') == FILE_DOWNLOADS_PUBLIC) {
$is_public = true;
$swish_index = getcwd() .'/' . file_directory_path().'/'. 'my_swish_index';
} else {
$swish_index = file_directory_path().'/'. 'my_swish_index';
}
...
//
// We need to use the basename to retrieve the correct filepath for the file,
// not suppy a default file path
//
$text_item = db_fetch_object(db_query("SELECT `fulltext`, nid, filepath from {swish_fulltext} where filepath like '%$basename%'"));
$snippet = search_excerpt($keys,$text_item->fulltext);
//
// I use the filepath from fulltext since it's the one used to get to the actual file.
// I put 'system' in front of the path if the system controls file access (i.e., not 'public').
// Otherwise, I've got to look at the path permissions to determine if the file
// is in a public directory or not.
//
if ($is_public) {
$dir = str_replace($basename, "", $text_item->filepath);
$output = exec('ls -ld ' . $dir);
$permission = substr($output, 7, 1);
if ($permission == 'r') {
$link0 = file_create_url ($text_item->filepath);
} else {
$link0 = 'system/' . $text_item->filepath;
}
} else {
$link0 = 'system/' . $text_item->filepath;
}
$find[] = array('link' => $link0, 'title' => $title, 'snippet' => $snippet, 'extra' => $extra, 'node' => node_load($text_item->nid));
}
}
return $find;
}
}
?>
If this looks OK and makes sense, I'll happily supply a patch.
#2
Technical note on my proposed code change:
I know that:
<?php$text_item = db_fetch_object(db_query("SELECT `fulltext`, nid, filepath from {swish_fulltext} where filepath like '%$basename%'"));
?>
should actually look more like:
<?php$text_item = db_fetch_object(db_query("SELECT `fulltext`, nid, filepath from {swish_fulltext} where filepath like '%%s%'", $basename));
?>
The problem is that the latter code does not work. If someone has a more appropriate way to do this, I'd love to see it!
#3
#4
Hello,
To ensure your process, I suggest the check of $text_item object like this:
<?php$text_item = db_fetch_object(db_query("SELECT `fulltext`, nid, filepath from {swish_fulltext} where filepath like '%$basename%'"));
if(!isset($text_item)) continue;
$snippet = search_excerpt($keys,$text_item->fulltext);
?>
In my case, it happened that a file of $basename is actually existing but there is no result from {swish_fulltext}.
#5
To answer my question about how to format the query:
<?php$text_item = db_fetch_object(db_query("SELECT * FROM {swish_fulltext} WHERE filepath LIKE '%s'", "%" . "/" . $basename));
?>
This not only insures the correct
%character is inserted, but also that files/file.txt doesn't false match files/bigFile.txt. The previous code allowed this to occur.#6
Hello. Is there I solution for the problem. I have tried your code-changes but I get still the same error.
Thanx
Ben
#7
I ended up writing my own version of this module to specifically handle OG based files. I don't know if this will help you, but below is the code I use (successfully):
<?php$text_item = db_fetch_object(db_query("SELECT sf.filepath, f.nid, sf.fulltext, f.filename, fr.description FROM {swishe_fulltext} sf INNER JOIN {files} f ON sf.filepath = f.filepath INNER JOIN {file_revisions} fr ON f.fid = fr.fid WHERE sf.filepath LIKE '%s'", "%" . "/" . $basename));
$snippet = search_excerpt($keys,$text_item->fulltext);
?>
Note that in my code I search the "file" table as well. This is NOT a part of the official Swish-E module code.