[development] Restricting hook_db_rewrite_sql

Rob Thorne rob at torenware.com
Sun Apr 16 18:11:57 UTC 2006


I'm having problems getting hook_db_rewrite_sql to restrict its actions 
to queries where it has business rewriting, and am having difficulty 
figuring how what to look at in order to do this.

Here's the use case.  I have two node types  (call them 
"civinode_contact" and "civinode_access")  that I want viewable 
according to a couple of tables that test the current user.  This now 
works (i.e., it makes the right join and does the test I want),  but it 
also tries to rewrite the query that og.module creates to do its own 
listing in www.example.com/og, at least for the anonymous user:

    Unknown column 'og.type' in 'where clause' query: SELECT og.nid,
    n.title, r.body, n.uid, u.name, og.description FROM og og INNER JOIN
    node n ON og.nid = n.nid INNER JOIN node_revisions r ON r.vid =
    n.vid INNER JOIN users u ON n.uid = u.uid LEFT JOIN node_access cna
    ON cna.nid = og.nid WHERE ((og.type != 'civinode_access' AND og.type
    != 'civinode_contact') ) AND og.directory=1 AND n.status=1 ORDER BY
    n.nid DESC LIMIT 0, 50 in ......./includes/database.mysql.inc on
    line 120.

The code looks something like this:

    function civinode_db_rewrite_sql($query, $primary_table,
    $primary_field, $args){
        global $user;
       
        if ($primary_field == 'nid') {
            //check for access to contacts
            if (user_access('view all contacts') or
                    user_access('administer CiviCRM'))
                return; //no need to screen
           
            $result = array();
            $result['join'] = "LEFT JOIN {node_access} cna ON cna.nid =
    $primary_table.nid";
            $contact_limit = "";
            $accesses = civinode_get_accesses_for_user($user->uid);
            if ($accesses) {
                $contact_limit = " OR cna.gid IN (" .
                    implode(',', $accesses) . ")";
            }
            $result['where'] = "($primary_table.type !=
    'civinode_access' AND $primary_table.type != 'civinode_contact') 
    $contact_limit";
            //$result['where'] = $contact_limit;
            return $result;
        }

I've found that need to user $primary_table,  since at the very least, 
not every query aliases the node table to "n" (some alias it to "node", 
or just aren't aliasing it AFAIK).  But I don't want to be picking up 
this particular og query.

How do I restrict this hook so that it does not interfere with arbitrary 
queries, but picks up cases where it would restrict viewing my nodes (as 
I need it to do)?

Thanks,
Rob

Rob Thorne
Torenware Networks



More information about the development mailing list