function tac_fields_field_access in Taxonomy Access Control 6
Implements hook_field_access().
See also
File
- tac_fields/
tac_fields.module, line 113 - Allows administrators to control access to individual CCK fields based on the node's taxonomy categories.
Code
function tac_fields_field_access($op, $field, $account, $node = NULL) {
switch ($op) {
case 'view':
$column = 'grant_view';
break;
case 'edit':
$column = 'grant_update';
break;
default:
return TRUE;
break;
}
$fieldname = $field['field_name'];
// If TAC Fields does not control the field, allow access.
if (!in_array($fieldname, _tac_fields_controlled_fields())) {
return TRUE;
}
// We can't do anything without a node, because we need the node's terms.
if (!isset($node)) {
return TRUE;
}
$nid = $node->nid;
if (!is_numeric($nid)) {
return TRUE;
}
if (is_array($account->roles)) {
$rids = array_keys($account->roles);
}
else {
$rids[] = 1;
}
// Get a list of all terms this node is in, regardless of user's access.
// Don't use API calls here.
// Cache.
static $tids = array();
// @todo: What's with the mixing of nid and revision id here (and in TAC)?
if (!isset($tids[$nid])) {
$tids[$nid] = array();
$r = db_query('SELECT tid FROM {term_node} WHERE vid = %d', $node->vid);
while ($row = db_fetch_object($r)) {
$tids[$nid][] = $row->tid;
}
}
$args = array_merge(array(
$node->vid,
$fieldname,
), $rids);
if (!empty($tids[$nid])) {
$result = db_query("SELECT \n tadg.rid, \n BIT_OR(COALESCE(\n ta." . db_escape_table($column) . ", \n tad." . db_escape_table($column) . ", \n tadg." . db_escape_table($column) . "\n )) AS " . db_escape_table($column) . "\n FROM {term_node} tn\n INNER JOIN {term_data} t ON t.tid = tn.tid\n INNER JOIN {term_field_access_defaults} tadg \n ON tadg.vid = 0\n LEFT JOIN {term_field_access_defaults} tad \n ON tad.vid = t.vid AND tad.rid = tadg.rid AND tad.field = tadg.field\n LEFT JOIN {term_field_access} ta \n ON ta.tid = t.tid AND ta.rid = tadg.rid AND ta.field = tadg.field\n WHERE tn.vid = %d \n AND tadg.field = '%s'\n AND tadg.rid IN (" . db_placeholders($rids, 'int') . ")\n GROUP BY tadg.rid\n ", $args);
}
else {
// Use the default for nodes with no taxonomy term.
$result = db_query("SELECT \n n.nid, \n tadg.rid AS rid, \n tadg." . db_escape_table($column) . " \n AS " . db_escape_table($column) . " \n FROM {node} n \n INNER JOIN {term_field_access_defaults} tadg ON tadg.vid = 0 \n WHERE n.nid = %d \n AND tadg.field = '%s'\n AND tadg.rid IN (" . db_placeholders($rids, 'int') . ")\n ", $args);
}
// Deny access by default for fields we do control.
$access = 0;
// Ignore => 0, Allow => 1, Deny => 2 ('10' in binary).
// With an Allow and no Deny, the value from the BIT_OR will be 1.
// If a Deny is present, the value will then be 3 ('11' in binary).
while ($row = db_fetch_array($result)) {
// If this role allows access to the field, then grant it to the user.
$access += $row[$column] == 1 ? 1 : 0;
}
return (bool) $access;
}