--- system.module.1 2005-01-04 07:33:37.000000000 +0100 +++ system.module 2005-01-04 07:46:39.000000000 +0100 @@ -491,6 +491,10 @@ function system_listing_save($edit = arr $status = 1; } + if (($edit['type'] == 'module') && ($name!='node') && ($status == 1) && module_hook($name, 'access_grants')) { + $access_grants_present = TRUE; + } + db_query("UPDATE {system} SET status = %d, throttle = %d WHERE type = '%s' AND name = '%s'", $status, $edit['throttle'][$name], $edit['type'], $name); } @@ -498,6 +502,10 @@ function system_listing_save($edit = arr variable_set('theme_default', $edit['theme_default']); } + if ($edit['type'] == 'module') { + variable_set('access_grants_present', isset($access_grants_present)); + } + cache_clear_all(); menu_rebuild(); --- node.module.1 2005-01-04 07:38:17.000000000 +0100 +++ node.module 2005-01-04 07:38:01.000000000 +0100 @@ -7,6 +7,8 @@ */ define('NODE_NEW_LIMIT', time() - 30 * 24 * 60 * 60); +define('NODE_SQL_SEARCH',0x01); + /** * Implementation of hook_help(). @@ -578,7 +580,8 @@ function node_search($op = 'search', $ke 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()); + extract(_node_query(NODE_SQL_SEARCH)); + $find = do_search($keys, 'node', 'INNER JOIN {node} n ON n.nid = i.sid '. $join .' INNER JOIN {users} u ON n.uid = u.uid', 'n.status = 1 AND '. $where); $results = array(); foreach ($find as $item) { $node = node_load(array('nid' => $item)); @@ -1012,7 +1015,7 @@ function node_feed($nodes = 0, $channel global $base_url, $locale; if (!$nodes) { - $nodes = db_query_range('SELECT n.nid FROM {node} n '. node_access_join_sql() .' WHERE '. node_access_where_sql() .' AND n.promote = 1 AND n.status = 1 ORDER BY n.created DESC', 0, 15); + $nodes = db_query_range(node_query('SELECT n.nid FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.created DESC'), 0, 15); } while ($node = db_fetch_object($nodes)) { @@ -1463,7 +1466,7 @@ function node_delete($edit) { * Generate a listing of promoted nodes. */ function node_page_default() { - $result = pager_query('SELECT DISTINCT(n.nid), n.sticky, n.created FROM {node} n '. node_access_join_sql() .' WHERE n.promote = 1 AND n.status = 1 AND '. node_access_where_sql() .' ORDER BY n.sticky DESC, n.created DESC', variable_get('default_nodes_main', 10)); + $result = pager_query(node_query('SELECT n.nid, n.sticky, n.created FROM {node} n WHERE n.promote = 1 AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC'), variable_get('default_nodes_main', 10)); if (db_num_rows($result)) { drupal_set_html_head(''); @@ -1719,7 +1722,7 @@ function node_access($op, $node = NULL, * An SQL join clause. */ function node_access_join_sql($node_alias = 'n', $node_access_alias = 'na') { - if (user_access('administer nodes')) { + if (!variable_get('access_grants_present', FALSE) || user_access('administer nodes')) { return ''; } @@ -1740,7 +1743,7 @@ function node_access_join_sql($node_alia * An SQL where clause. */ function node_access_where_sql($op = 'view', $node_access_alias = 'na', $uid = NULL) { - if (user_access('administer nodes')) { + if (!variable_get('access_grants_present', FALSE) || user_access('administer nodes')) { // This number is being used in a SQL query as a boolean. // It is "'1'" instead of "1" for database compatibility, as both // PostgreSQL and MySQL treat it as boolean in this case. @@ -1790,4 +1793,86 @@ function node_access_grants($op, $uid = * @} End of "defgroup node_access". */ +/** + * Implementation of hook_sql(). + */ +function node_sql($op) { + switch ($op) { + case 'join': + return node_access_join_sql(); + case 'where': + return node_access_where_sql(); + } +} + +/* + * Helper function for node_query. + * + * Collects JOIN and WHERE statements via hook_sql. + * Decides whether to select nid or DISTINCT(nid) + * + * @param $hint + * Some hint about the query, passed on to hook_sql handlers. Use NODE_SQL_* flags. + * @param $node_alias + * If the node table has been given an SQL alias other than the default + * "n", that must be passed here. + * @return + * An associative array: join => join statements, where => where statements, nid_to_select => nid or DISTINCT(nid) + */ +function _node_query($hint = 0, $node_alias = 'n') { + static $called; + + if ($called) { // semaphore. if a function in the process of hook_sql calls _node_query, it won't fall into an infinite loop. + return array('join'=>'', 'where'=>"'1'", 'nid_to_select' => $node_alias.'.nid'); + } + $called = 1; + $join = implode('', module_invoke_all('sql', 'join', $hint)); + $where = implode('', module_invoke_all('sql', 'where', $hint)); + $called = 0; + return array('join'=>$join, 'where'=>$where, 'nid_to_select' => empty($join) ? $node_alias.'.nid' : 'DISTINCT('.$node_alias.'.nid)'); +} + +/* + * Rewrites node queries. + * + * @param $query + * query to be rewritten + * @param $hint + * Some hint about the query, passed on to hook_sql handlers. Use NODE_SQL_* flags. + * @param $node_alias + * If the node table has been given an SQL alias other than the default + * "n", that must be passed here. + * @return + * The original query with JOIN and WHERE statements inserted from hook_sql implementations. nid is rewritten if needed. + */ +function node_query($query, $hint = 0, $node_alias = 'n') { + + extract(_node_query($hint, $node_alias)); + $query = preg_replace('/^(SELECT.*)('.$node_alias.'\.)?nid(.*FROM)/U', '\1'. $nid_to_select .'\3', $query); + + $query = preg_replace('/FROM[^[:upper:]]+/','\0 '.$join.' ', $query); + if (strpos($query, 'WHERE')) { + $replace = 'WHERE'; + $add = 'AND'; + } + elseif (strpos($query, 'GROUP')) { + $replace = 'GROUP'; + $add = 'GROUP'; + } + elseif (strpos($query, 'ORDER')) { + $replace = 'ORDER'; + $add = 'ORDER'; + } + elseif (strpos($query, 'LIMIT')) { + $replace = 'LIMIT'; + $add = 'LIMIT'; + } + else + $query .= 'WHERE '. $where; + if (isset($replace)) { + $query = str_replace($replace, 'WHERE '.$where.' '.$add, $query); + } + return $query; +} + ?>