Linkchecker seems to only scan the contents of node fields. Modules may add data to a node. It should be possible to scan this data with the linkchecker module. I'd like to introduce two hooks that other modules may implement in order to expose data to the linkchecker module:

1) hook_linkchecker_extract_node_links
2) hook_linkchecker_replace_link

Here is an example of how they can be used. I'll demonstrate with a hypothetical 'footer' module that adds some footer text to every node.

/**
 * Implements hook_node_load().
 */
function footer_node_load($nodes, $types) {
  // Decide whether any of $types are relevant to our purposes.
  if (count(array_intersect(variable_get('footer_node_types', array()), $types))) {
    // Gather footer data for each of these nodes.
    $result = db_query('SELECT nid, footer FROM {footer} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes)));
    // Add footer to the node objects.
    foreach ($result as $record) {
      $nodes[$record->nid]->footer = $record->footer;
    }
  }
}

/**
 * Implements hook_linkchecker_extract_node_links().
 */
function footer_linkchecker_extract_node_links($node) {
  $text_items = array();
  $text_items[] = $node->footer;
  return $text_items;
}

/**
 * Implements hook_linkchecker_replace_link().
 */
function footer_linkchecker_replace_link_alter(&$node, $context) {
  $node->footer = _linkchecker_link_replace($node->footer, $context['old'], $context['new']);
}
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

jtsnow’s picture

Status: Active » Needs review
FileSize
1.5 KB

I've attached a patch that allows the previously mentioned hooks to be used by modules.

This might also help with #1888102: Field Collection compatibility since the Field Collection module may be able to use these hooks.

jtsnow’s picture

When generating the link report, the _linkchecker_link_node_ids() performs access checks to see if a link is accessible. However, the function only checks links within fields rather than all the links potentially contained in a node. Here is an updated patch that addresses this.

hass’s picture

Linkchecker seems to only scan the contents of node fields.

That's in general correct, but are you able to explain this a bit more, please?

Modules may add data to a node.

I thought everything we are adding to a node is a field... at least it should be. You patch seems not covering all the logics in linkchecker and it looks like to require a lot more changes if I'm not totally wrong. It's also shown in reports, has auto replacement, batch api integration, cleanup features and so on. Not sure where you plan to save the links to be checked and their references.

ohthehugemanatee’s picture

Issue summary: View changes
FileSize
1.85 KB

Seems a bit nuts to run the hook for every link scanned, and as @hass points out, this approach requires a lot more work to integrate into all the behaviors of the module.

So I'm adding my own patch here. We call drupal_alter once for each "type" of content that linkchecker supports. This patch exposes hook_linkchecker_node_alter , hook_linkchecker_comment_alter, and hook_linkchecker_block_alter . In the context for each _alter, I try to include everything you need to re-run _linkchecker_extract_links the same way linkchecker itself does - basically that means including the path, but for hook_linkchecker_node_alter you also get $return_field_names.

With these alters, it's trivially easy to
* support other fields
* support other methods of rendering, ie page manager, panelizer, etc.
* add extra checks and behaviors to link discovery

Those are really common feature requests in the issue queue, and this allows people to do it on their own. None of this should interfere with the rest of the module - bulk operations, etc should all be unaltered. I used this to add a 20 line module that adds Panelizer support.

One caveat: permissions checks will only check fields it knows about, so links added here will default disallow in those reports. Of course, if you have field permissions and you're using a non-field content module, field permissions doesn't help anyway. So it's kind of a nonsensical situation.

perennial.sky’s picture

perennial.sky’s picture

Hello jtsnow ,
I just used patch 1 , There is no hook to alter old url to new url , so how can i change old url with new one.

rtdean93’s picture

@ohthehugemanatee - can you post your 20 line module for panelizer support for this?

azinck’s picture

@rtdean93: I work with ohthehugemanatee and posted it here: https://www.drupal.org/node/810948#comment-10883142

kristofferwiklund’s picture

Status: Needs review » Needs work
FileSize
799 bytes

I did a similar solution here, I just added a hook for providing text fields from a paragraph field.

All this solution should be merge together, and a linkchecker.api.inc file should be created explaining the hooks. And maybe get them introduced in to Paragraph and Field collection module.

solideogloria’s picture

Wouldn't it be better to allow any field to be checked for links, not just node fields? If I have added some fields to the User entity or some other type, and I want to check those for links, how would I do that?

Perhaps add hook_linkchecker_extract_TYPE_links() or hook_linkchecker_extract_links()?