4

I am using hook_query_alter to make changes in get taxonomy terms query.

    function MYMODULE_query_alter(QueryAlterableInterface $query) { 
    global $user;
    if($user->uid > 1) {
        if ($query->hasTag('term_access') && strstr(current_path(), 'admin/structure/taxonomy')) {
            $permission = $query->leftJoin('term_permissions_user', 'tpu', "t.tid = tpu.tid");      
            $ored = db_or();        
            $ored->condition('uid', NULL, 'IS');        
            $ored->condition('uid', $user->uid, '=');
            $anded = db_and();
            $anded->condition($ored);
            $query->condition($anded);
        }
    }
}

I want to have above query clause on the page which lists taxonomy terms only but this hook is adding the clause on all pages. I mean this hook is called on any page load of my drupal site.

Other issue is that the alias for table taxonomy_term_data is base on same pages and t on other pages and if i join using alias t it gives me error on most of the pages and vice versa.

I am checking the table alias to ensure the use of table alias used in my query and have changed the code as

function MYMODULE_query_alter(QueryAlterableInterface $query) { 
    global $user;
    if($user->uid > 1) {
        if ($query->hasTag('term_access') && strstr(current_path(), 'admin/structure/taxonomy')) {          
            $tables = $query->getTables();
            if(isset($tables['t']) && isset($tables['t']['alias']) && $tables['t']['alias'] == 't' && $tables['t']['table'] == 'taxonomy_term_data') {
                $permission = $query->leftJoin('term_permissions_user', 'tpu', "t.tid = tpu.tid");      
                $ored = db_or();        
                $ored->condition('uid', NULL, 'IS');        
                $ored->condition('uid', $user->uid, '=');
                $anded = db_and();
                $anded->condition($ored);
                $query->condition($anded);          
            }
        }
    }
}

But I am not sure if I have used a correct check, as of now my aim of adding query clause is fulfilled. Just to ensure this will work for long and will not break in any case. Please help me to have this hook call on the page where I need this and use the exact table alias.

Thanks in advance for your help.

1 Answer 1

3

hook_query_alter() is executed for every dynamic query run by Drupal. If you want to execute the hook for queries having a specific tag, you should implement hook_query_TAG_alter().

The code for getting the alias for the main table is similar to the following one.

function mymodule_get_main_table_alias($tables) {
  $alias = '';

  foreach ($tables as $id => $info) {
    // If 'join type' is not set, then it's the main table.a
    if (empty($info['join type'])) {
      $alias = $id;
    }
  }

  return $alias;
}

I would write then the hook code as follows.

function mymodule_query_term_access_alter(QueryAlterableInterface $query) { 
  global $user;
  if ($user->uid > 1) {
    if (strstr(current_path(), 'admin/structure/taxonomy')) {
      if ($alias = mymodule_get_main_table_alias($query->getTables())) {
        $alias = $query->leftJoin('term_permissions_user', 'tpu', "$alias.tid = %alias.tid");      
        $query->condition(db_or()
          ->isNullcondition("$alias.uid");        
          ->condition("$alias.uid", $user->uid, '=')
        );          
      }
    }
  }
}

Notice that:

  • In $query->leftJoin(), %alias is replaced with the alias the query is using for the table being joined. As you are altering an existing query, you cannot know if the alias you chose is already used.
  • The result of $query->leftJoin() is the alias being used for the joined table. It is better not to hard core that alias, for the reason said in the previous point.
  • To check if a field is NULL, you should not use QueryConditionInterface::condition(); as the documentation says, you should use QueryConditionInterface::isNull().
  • There is not need to create a QueryCondition object with db_and(); the conditions used to a query with $query->condition() are ANDed with each other.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.