- Patch #320591 by Moshe, Crell et al: tag specific alter hook for database queries.
							parent
							
								
									7e60d94f69
								
							
						
					
					
						commit
						634379299f
					
				| 
						 | 
				
			
			@ -291,7 +291,13 @@ class SelectQuery extends Query implements QueryConditionInterface, QueryAlterab
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  public function execute() {
 | 
			
		||||
    // Modules may alter all queries or only those having a particular tag.
 | 
			
		||||
    drupal_alter('query', $this);
 | 
			
		||||
    if (isset($this->alterTags)) {
 | 
			
		||||
      foreach ($this->alterTags as $tag => $value) {
 | 
			
		||||
        drupal_alter("query_$tag", $this);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $args = $this->getArguments();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2324,17 +2324,23 @@ function node_db_rewrite_sql($query, $primary_table, $primary_field) {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of hook_query_alter().
 | 
			
		||||
 * Implementation of hook_query_TAG_alter().
 | 
			
		||||
 */
 | 
			
		||||
function node_query_alter(QueryAlterableInterface $query) {
 | 
			
		||||
  if ($query->hasTag('node_access') && !node_access_view_all_nodes()) {
 | 
			
		||||
function node_query_node_access_alter(QueryAlterableInterface $query) {
 | 
			
		||||
  // Skip the extra expensive alterations if site has no node access control modules.
 | 
			
		||||
  if (!node_access_view_all_nodes()) {
 | 
			
		||||
    // Prevent duplicate records.
 | 
			
		||||
    $query->distinct();
 | 
			
		||||
    // The recognized operations are 'view', 'update', 'delete'.
 | 
			
		||||
    if (!$op = $query->getMetaData('op')) {
 | 
			
		||||
      $op = 'view';
 | 
			
		||||
    }
 | 
			
		||||
    // Skip the extra joins and conditions for node admins.
 | 
			
		||||
    if (!user_access('bypass node access')) {
 | 
			
		||||
      // The node_access table has the access grants for any given node.
 | 
			
		||||
      $access_alias = $query->join('node_access', 'na', 'na.nid = n.nid');
 | 
			
		||||
      $or = db_or();
 | 
			
		||||
      // If any grant exists for the specified user, then user has access to the node for the specified operation.
 | 
			
		||||
      foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) {
 | 
			
		||||
        foreach ($gids as $gid) {
 | 
			
		||||
          $or->condition(db_and()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,16 +4,12 @@
 | 
			
		|||
/**
 | 
			
		||||
 * Implementation of hook_query_alter().
 | 
			
		||||
 */
 | 
			
		||||
function database_test_query_alter(SelectQuery $query) {
 | 
			
		||||
function database_test_query_alter(QueryAlterableInterface $query) {
 | 
			
		||||
 | 
			
		||||
  if ($query->hasTag('database_test_alter_add_range')) {
 | 
			
		||||
    $query->range(0, 2);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ($query->hasTag('database_test_alter_remove_range')) {
 | 
			
		||||
    $query->range();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  if ($query->hasTag('database_test_alter_add_join')) {
 | 
			
		||||
    $people_alias = $query->join('test', 'people', "test_task.pid=people.id");
 | 
			
		||||
    $name_field = $query->addField('people', 'name', 'name');
 | 
			
		||||
| 
						 | 
				
			
			@ -36,6 +32,14 @@ function database_test_query_alter(SelectQuery $query) {
 | 
			
		|||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of hook_query_TAG_alter(). Called by DatabaseTestCase::testAlterRemoveRange.
 | 
			
		||||
 */
 | 
			
		||||
function database_test_query_database_test_alter_remove_range_alter(QueryAlterableInterface $query) {
 | 
			
		||||
  $query->range();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Implementation of hook_menu().
 | 
			
		||||
 */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1695,7 +1695,7 @@ class DatabaseAlter2TestCase extends DatabaseTestCase {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Test that we can remove a range() value from a query.
 | 
			
		||||
   * Test that we can remove a range() value from a query. This also tests hook_query_TAG_alter().
 | 
			
		||||
   */
 | 
			
		||||
  function testAlterRemoveRange() {
 | 
			
		||||
    $query = db_select('test');
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1374,6 +1374,68 @@ function hook_schema_alter(&$schema) {
 | 
			
		|||
  );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Perform alterations to a structured query.
 | 
			
		||||
 *
 | 
			
		||||
 * Structured (aka dynamic) queries that have tags associated may be altered by any module
 | 
			
		||||
 * before the query is executed.
 | 
			
		||||
 *
 | 
			
		||||
 * @see hook_query_TAG_alter()
 | 
			
		||||
 * @see node_query_node_access_alter()
 | 
			
		||||
 * 
 | 
			
		||||
 * @param $query
 | 
			
		||||
 *   A Query object describing the composite parts of a SQL query.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   None.
 | 
			
		||||
 */
 | 
			
		||||
function hook_query_alter(QueryAlterableInterface $query) {
 | 
			
		||||
  
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Perform alterations to a structured query for a given tag.
 | 
			
		||||
 *
 | 
			
		||||
 * @see hook_query_alter()
 | 
			
		||||
 * @see node_query_node_access_alter()
 | 
			
		||||
 * 
 | 
			
		||||
 * @param $query
 | 
			
		||||
 *   An Query object describing the composite parts of a SQL query.
 | 
			
		||||
 * @return
 | 
			
		||||
 *   None.
 | 
			
		||||
 */
 | 
			
		||||
function hook_query_TAG_alter(QueryAlterableInterface $query) {
 | 
			
		||||
  // Skip the extra expensive alterations if site has no node access control modules.
 | 
			
		||||
  if (!node_access_view_all_nodes()) {
 | 
			
		||||
    // Prevent duplicates records.
 | 
			
		||||
    $query->distinct();
 | 
			
		||||
    // The recognized operations are 'view', 'update', 'delete'.
 | 
			
		||||
    if (!$op = $query->getMetaData('op')) {
 | 
			
		||||
      $op = 'view';
 | 
			
		||||
    }
 | 
			
		||||
    // Skip the extra joins and conditions for node admins.
 | 
			
		||||
    if (!user_access('bypass node access')) {
 | 
			
		||||
      // The node_access table has the access grants for any given node.
 | 
			
		||||
      $access_alias = $query->join('node_access', 'na', 'na.nid = n.nid');
 | 
			
		||||
      $or = db_or();
 | 
			
		||||
      // If any grant exists for the specified user, then user has access to the node for the specified operation.
 | 
			
		||||
      foreach (node_access_grants($op, $query->getMetaData('account')) as $realm => $gids) {
 | 
			
		||||
        foreach ($gids as $gid) {
 | 
			
		||||
          $or->condition(db_and()
 | 
			
		||||
            ->condition("{$access_alias}.gid", $gid)
 | 
			
		||||
            ->condition("{$access_alias}.realm", $realm)
 | 
			
		||||
          );
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (count($or->conditions())) {
 | 
			
		||||
        $query->condition($or);
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      $query->condition("{$access_alias}.grant_$op", 1, '>=');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Install the current version of the database schema, and any other setup tasks.
 | 
			
		||||
 *
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue