1

The goal is to hack core so that the search module will populate the search_node_links table from uuid-link hrefs in node content.

Planned approach is to modify the parsing functions of search_index in the core search.module.

The targeted section of code is lines 633-643 of search.module.

if (preg_match($node_regexp, $value, $match)) {
  $path = drupal_get_normal_path($match[1]);
  if (preg_match('!(?:node|book)/(?:view/)?([0-9]+)!i', $path, $match)) {
    $linknid = $match[1];
    if ($linknid > 0) {
      $node = db_query('SELECT title, nid, vid FROM {node} WHERE nid = :nid', array(':nid' => $linknid), array('target' => 'slave'))->fetchObject();
      $link = TRUE;
      $linktitle = $node->title;
    }
  }
}

The plan is to use entity_uuid_load to grab the nid directly like so:

if (preg_match($uuid_regexp, $value, $match)) {
  $entity = entity_uuid_load('node',$match);
  $linknid = key($entity);
  if ($linknid > 0) {
    $node = db_query('SELECT title, nid, vid FROM {node} WHERE nid = :nid', array(':nid' => $linknid), array('target' => 'slave'))->fetchObject();
    $link = TRUE;
    $linktitle = $node->title;
  }
}

I've used this code to pull a node title with $value set to an HTML snippet containing a UUID-href link; however, this still seems to fail to populate the search_node_links table.

$uuid_regexp is working as expected, but here it is for reference along with $node_regexp for comparison.

$node_regexp = '@href=[\'"]?(?:' . preg_quote($base_url, '@') . '/|' . preg_quote(base_path(), '@') . ')(?:\?q=)?/?((?![a-z]+:)[^\'">]+)[\'">]@i';
$uuid_regexp = '@href=[\'"]?(?:\[uuid-link:node:)([0-9a-f]{8}-(([0-9a-f]{4}-){3})[0-9a-f]{12})(?:\])(?:[\'">])@i';

And here is the UUID link format:

<a href="[uuid-link:node:dc2c18f0-0abb-43b9-899c-f7c0a16934fd]">UUID link</a>

I'm sure there's something I'm just not seeing in search.module that is preventing this from working as desired. Any comments/support/pointers would be greatly appreciated.

UPDATE: Finding now that it's not UUIDs causing the issue, but aliased paths instead (probably combined with Global Redirect module). Tried the following code instead, still no change in search_node_links.

if (preg_match($node_regexp, $value, $match)) {
  $clean_url = preg_split('![(en)|(fr)]/!', $match[1])[1];
  $path = drupal_lookup_path("source", $clean_url);
  if (preg_match('!(?:node|book)/(?:view/)?([0-9]+)!i', $path, $match)) {
    $linknid = $match[1];
    if ($linknid > 0) {
      $node = db_query('SELECT title, nid, vid FROM {node} WHERE nid = :nid', array(':nid' => $linknid), array('target' => 'slave'))->fetchObject();
      $link = TRUE;
      $linktitle = $node->title;
    }
  }
}

Again, this code is able to pull a node title but is not contributing to search_node_links.

2
  • 1
    hmm, really not a great idea (maintenance nightmare). Can you not get like Rabbit Hole to hide your Node content and drupal.org/project/uuid_redirect to stuff the search index with uuid paths ??
    – tenken
    Commented Aug 13, 2014 at 17:43
  • No. The Search module parses through content in the database looking for links. The UUID references are substituted for actual links during render, so search will never find them.
    – Ginosuave
    Commented Aug 13, 2014 at 18:01

2 Answers 2

1

Ok, so this problem was being caused by the language prefix in our paths in conjunction with aliases. drupal_get_normal_path was returning aliases instead of node numbers, and it returned nothing when the path had a language prefix. Also found that the substitute function drupal_lookup_path only works for aliased paths. The final code replaces line 634 of search.module:

$path = drupal_get_normal_path($match[1]);

becomes

$clean_url = preg_split('!(^[a-z]{2})/!i', $match[1])[1];
if ($non_aliased = drupal_lookup_path("source", $clean_url)) {
  $path = $non_aliased;
} else {
  $path = drupal_get_normal_path($match[1]);
}

The search_node_links table is now being populated properly and the "What links here"/Backlinks views are working correctly.

0

yea sorry umm the Search API module can't help you to index and search your own content?

/**
 * Define new types of items that can be searched.
 *
 * This hook allows modules to define their own item types, for which indexes
 * can then be created. (Note that the Search API natively provides support for
 * all entity types that specify property information, so they should not be
 * added here. You should therefore also not use an existing entity type as the
 * identifier of a new item type.)
 *
 * The main part of defining a new item type is implementing its data source
 * controller class, which is responsible for loading items, providing metadata
 * and tracking existing items. The module defining a certain item type is also
 * responsible for observing creations, updates and deletions of items of that
 * type and notifying the Search API of them by calling
 * search_api_track_item_insert(), search_api_track_item_change() and
 * search_api_track_item_delete(), as appropriate.
 * The only other restriction for item types is that they have to have a single
 * item ID field, with a scalar value. This is, e.g., used to track indexed
 * items.
 *
 * Note, however, that you can also define item types where some of these
 * conditions are not met, as long as you are aware that some functionality of
 * the Search API and related modules might then not be available for that type.
 *
 * @return array
 *   An associative array keyed by item type identifier, and containing type
 *   information arrays with at least the following keys:
 *   - name: A human-readable name for the type.
 *   - datasource controller: A class implementing the
 *     SearchApiDataSourceControllerInterface interface which will be used as
 *     the data source controller for this type.
 *   - entity_type: (optional) If the type represents entities, the entity type.
 *     This is used by SearchApiAbstractDataSourceController for determining the
 *     entity type of items. Other datasource controllers might ignore this.
 *   Other, datasource-specific settings might also be placed here. These should
 *   be specified with the data source controller in question.
 *
 * @see hook_search_api_item_type_info_alter()
 */
function hook_search_api_item_type_info() { /* ... */ }
3
  • We're using Solr. Indexing our content isn't a problem, it's getting it added to the search_node_links table that is casuing issues.
    – Ginosuave
    Commented Aug 13, 2014 at 18:40
  • ok, maybe someone else here can help you. you may want to add a tag of Solr to you post. I'm not sure why you're using Core search and Solr at the same time ... see drupal.org/node/876364 and drupal.stackexchange.com/questions/44558/… and possibly janneaa.drupalgardens.com/content/… Yes i've used Solr, I'm just not sure what exactly your trying to do. best of luck.
    – tenken
    Commented Aug 13, 2014 at 18:49
  • We're trying to get the backlinks view working, which is populated by the search_node_links table, which is populated by the core search module. That's it.
    – Ginosuave
    Commented Aug 13, 2014 at 19:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.