? .svn ? translations/.svn Index: module_grants.module =================================================================== RCS file: /cvs/drupal-contrib/contributions/modules/module_grants/module_grants.module,v retrieving revision 1.8 diff -u -p -r1.8 module_grants.module --- module_grants.module 20 Apr 2009 00:22:53 -0000 1.8 +++ module_grants.module 4 May 2009 18:24:52 -0000 @@ -45,6 +45,13 @@ function module_grants_menu() { 'access arguments' => array('access content summary'), 'type' => MENU_LOCAL_TASK, ); + $items['admin/settings/module_grants'] = array( + 'title' => 'Module grants', + 'description' => 'Configure how multiple node access modules interact.', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('module_grants_admin_settings'), + 'access arguments' => array('administer site configuration'), + ); return $items; } @@ -63,6 +70,20 @@ function _show_viewable_nodes() { } /** + * Menu callback for admin settings. + */ +function module_grants_admin_settings() { + $form['module_grants_explicit'] = array( + '#type' => 'checkbox', + '#title' => t('Enforce explicit AND between multiple node access modules'), + '#default_value' => variable_get('module_grants_explicit', 0), + '#description' => t('Check this box if you want to consider the node access settings for a particular node for only those node access modules that have a node access row for that node. For example, if you have a node that is limited by node access module X but not module Y, with this box checked access would be granted even though module Y doesn\'t explicitly allow access. With this box unchecked, access would be denied. Whether or not this box is checked, the default behavior will apply when you have a node limited by both modules X and Y -- access will be granted only if both allow it.'), + ); + + return system_settings_form($form); +} + +/** * Implementation of hook_menu_alter(). * * Modify menu items defined in other modules (in particular the node module). @@ -188,8 +209,14 @@ function module_grants_node_access($op, } // If the module neither allows nor denies access, then find grants - // amongst modules that implement hook_node_grants() - $all_grants = grants_by_module($op, $account); + // amongst modules that implement hook_node_grants(), taking into + // account the module_grants_explicit setting. + if (variable_get('module_grants_explicit', 0)) { + $all_grants = grants_by_module($op, $account, $node->nid); + } + else { + $all_grants = grants_by_module($op, $account); + } $base_sql = "SELECT COUNT(*) FROM {node_access} WHERE (nid=0 OR nid=%d) AND ((gid=0 AND realm='all')"; @@ -219,16 +246,28 @@ function module_grants_node_access($op, * The operation, i.e 'view', 'update' or 'delete' * @param $account * User account object + * @param $nid + * Optional. If a nid is passed in, only modules with at least one node_access + * row for the given nid are included. * @return * Array of module grants SQL */ -function grants_by_module($op, $account) { +function grants_by_module($op, $account, $nid = NULL) { $hook = 'node_grants'; $all_grants = array(); foreach (module_implements($hook) as $module) { $module_grants = module_invoke($module, $hook, $account, $op); if (!empty($module_grants)) { $module_gids = array(); + // If a nid has been passed in, don't collect the grants for this module + // unless it has at least one row in the node_access table for this nid. + if ($nid) { + $result = db_result(db_query("SELECT COUNT(*) FROM {node_access} WHERE nid = %d AND realm IN ('%s')", $nid, implode("','", array_keys($module_grants)))); + if ($result == 0) { + // This module doesn't have a node_access row for this node, so continue to the next module. + continue; + } + } foreach ($module_grants as $realm => $gids) { foreach ($gids as $gid) { $module_gids[] = "(gid=$gid AND realm='$realm')";