function _linkchecker_link_node_ids in Link checker 7
Same name and namespace in other branches
- 6.2 linkchecker.module \_linkchecker_link_node_ids()
Returns IDs of nodes that contain a link which the current user may be allowed to view.
Important note: For performance reasons, this function is not always guaranteed to return the exact list of node IDs that the current user is allowed to view. It will, however, always return an empty array if the user does not have access to view *any* such nodes, thereby meeting the security goals of _linkchecker_link_access() and other places that call it.
In the case where a user has access to some of the nodes that contain the link, this function may return some node IDs that the user does not have access to. Therefore, use caution with its results.
Parameters
object $link: An object representing the link to check.
object $node_author_account: (optional) If a user account object is provided, the returned nodes will additionally be restricted to only those owned by this account. Otherwise, nodes owned by any user account may be returned.
Return value
array An array of node IDs that contain the provided link and that the current user may be allowed to view.
2 calls to _linkchecker_link_node_ids()
- _linkchecker_link_access in ./
linkchecker.module - Determines if the current user has access to view a link.
- _linkchecker_report_page in ./
linkchecker.pages.inc - Builds the HTML report page table with pager.
File
- ./
linkchecker.module, line 263 - This module periodically check links in given node types, blocks etc.
Code
function _linkchecker_link_node_ids($link, $node_author_account = NULL) {
static $fields_with_node_links = array();
// Exit if all node types are disabled or if the user cannot access content,
// there is no need to check further.
$linkchecker_scan_nodetypes = linkchecker_scan_node_types();
if (empty($linkchecker_scan_nodetypes) || !user_access('access content')) {
return array();
}
// Get a list of nodes containing the link, using addTag('node_access') to
// allow node access modules to exclude nodes that the current user does not
// have access to view.
if (!empty($node_author_account)) {
$query = db_select('node', 'n');
$query
->addTag('node_access');
$query
->innerJoin('linkchecker_node', 'ln', 'ln.nid = n.nid');
$query
->innerJoin('node_revision', 'r', 'r.vid = n.vid');
$query
->condition('ln.lid', $link->lid);
$query
->condition(db_or()
->condition('n.uid', $node_author_account->uid)
->condition('r.uid', $node_author_account->uid));
$query
->fields('n', array(
'nid',
));
}
else {
$query = db_select('node', 'n');
$query
->addTag('node_access');
$query
->innerJoin('linkchecker_node', 'ln', 'ln.nid = n.nid');
$query
->condition('ln.lid', $link->lid);
$query
->fields('n', array(
'nid',
));
}
$nodes = $query
->execute();
// Check if the current user has access to view the link in each node.
// However, for performance reasons, as soon as we find one node where that
// is the case, stop checking and return the remainder of the list.
$nids = array();
$access_allowed = FALSE;
foreach ($nodes as $node) {
if ($access_allowed) {
$nids[] = $node->nid;
continue;
}
$node = node_load($node->nid);
// We must check whether the link is currently part of the node; if not, we
// do not want to return it (and it is not safe to, since we cannot know if
// it contained access restrictions for the current user at the point which
// it was originally extracted by the Link checker module).
if (!isset($fields_with_node_links[$node->nid])) {
$fields_with_node_links[$node->nid] = _linkchecker_extract_node_links($node, TRUE);
}
if (empty($fields_with_node_links[$node->nid][$link->url])) {
continue;
}
// If the link appears in fields and a field access module is being used,
// we must check that the current user has access to view at least one field
// that contains the link; if they don't, we should not return the node.
$fields = $fields_with_node_links[$node->nid][$link->url];
if (module_implements('field_access')) {
$fields_with_access = array();
$bundle_instances = field_info_instances('node', $node->type);
foreach ($bundle_instances as $field_name => $field_instance) {
$field = field_info_field($field_name);
// Field types supported by linkchecker.
$fields_supported = array(
'text_with_summary',
'text_long',
'text',
'link_field',
);
// Only check link and text fields, since those are the only types we
// extract links from.
if (in_array($field['type'], $fields_supported) && field_access('view', $field, 'node', $node)) {
$fields_with_access[] = $field['field_name'];
}
}
if (!array_intersect($fields, $fields_with_access)) {
continue;
}
}
$nids[] = $node->nid;
$access_allowed = TRUE;
}
return $nids;
}