I'm trying to add a search tab using hook_search. Right now, I just want a regular search. I'll try and get fancy later. I began by coping the code from the hook_search api: http://api.drupal.org/api/function/hook_search/5. Turns out this code has incorrect syntax for node_access_join_sql(). Apparently nobody has looked at this since Drupal 4.6.

Fixed that and ended up with this code.

    /*
    * Impmentation of hook_search()
    */
    function lesspaper_search($op = 'search', $keys = null) {
    switch ($op) {
    case 'name':
    return t('My groups');
    case 'reset':
    variable_del('node_cron_last');
    return;
    case 'search':
    $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. _node_access_join_sql() .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 AND '. _node_access_where_sql());
    $results = array();
    foreach ($find as $item) {
    $node = node_load(array('nid' => $item));
    $extra = node_invoke_nodeapi($node, 'search result');
    $results[] = array('link' => url('node/'. $item),
    'type' => node_invoke($node, 'node_name'),
    'title' => $node->title,
    'user' => theme('username', $node),
    'date' => $node->changed,
    'extra' => $extra,
    'snippet' => search_excerpt($keys, check_output($node->body, $node->format)));
    }
    return $results;
    }
    }

It throws this error:


    * 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 'AND (i.word = 'test') AND i.type = 'node' GROUP BY i.type, i.sid HAVING COUNT(*)' at line 1 query: CREATE TEMPORARY TABLE temp_search_sids SELECT i.type, i.sid, SUM(i.score * t.count) AS relevance, COUNT(*) AS matches FROM search_index i INNER JOIN search_total t ON i.word = t.word INNER JOIN node n ON n.nid = i.sid INNER JOIN users u ON n.uid = u.uid WHERE n.status = 1 AND AND (i.word = 'test') AND i.type = 'node' GROUP BY i.type, i.sid HAVING COUNT(*) >= 1 in /var/www/html/websites/drupal/test01/includes/database.mysql.inc on line 172.
    * user warning: Table 'drupal_test01.temp_search_sids' doesn't exist query: SELECT MAX(relevance) FROM temp_search_sids in /var/www/html/websites/drupal/test01/includes/database.mysql.inc on line 172.

The word I entered to search for is "test".

I've been searching. Found several notes similar to this: http://drupal.org/node/78180

Give your db user the 'CREATE TEMPORARY TABLES' permission and all should be well.

My Drupal db user has already been granted ALL PRIVILEGES. Also, I noted that the error I get is not an "access denied" error, but a "syntax error" in the SQL. What the hey!

Mysql Version 1.2

Can someone shed some light on this! Thanks!

Comments

somebodysysop’s picture

Figured out some stuff on my own. The api docs are incredibly incorrect:

This

    $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. _node_access_join_sql() .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 AND '. _node_access_where_sql());

Should be this:

    $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. _node_access_join_sql() .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 '. _node_access_where_sql()); 

And, I think:

This:

    'snippet' => search_excerpt($keys, check_output($node->body, $node->format))); 

Should be this (I think):

    'snippet' => search_excerpt($keys, check_markup($node->body, $node->format))); 

check_output has been deprecated since Drupal 4.7 so why is it still in 5.x and 6.x api?

Anyway, now I'm getting this error on my custom search:

    warning: mysql_real_escape_string() expects parameter 1 to be string, object given in /var/www/html/websites/drupal/test01/includes/database.mysql.inc on line 400.

In my search results, all I see is:

     n/a ...

    Anonymous - comments

    n/a ...

    Anonymous - comments

Help!

fgm’s picture

Ah, I see what you mean : what you are taking as the doc used to be an example of something one could do when implementing hook_search, but it is not the doc itself, and is mostly irrelevant anyway : what you must refer to is the explanation, that is the: the syntax, parameters, return, and not this example, which could just as well be implemented in any other way as long as it complies with the API.

somebodysysop’s picture

What I ultimately decided to do was use the hook_search example from the node.module. With a little tweaking, that works. Thanks!