Non-Views Answer
I finally figured out how this can be done without incurring the overhead of views. I'll leave the views answer below in case it is useful for someone, but this version seems snappier to me. As always, critique very welcome!
/**
* Implements hook_menu().
*/
function MYMODULE_menu()
{
$items = array();
$items['pub'] = array(
'title' => 'publications by Docid',
'access callback' => TRUE,
'page callback' => '_MYMODULE_pub_to_docid',
);
return $items;
}
/**
* Redirect to a publication page based on its legacy_docid
*/
function _MYMODULE_pub_to_docid() {
$path = current_path();
$path = str_ireplace('pub/', '', $path);
$args = explode('/', $path);
$query = new EntityFieldQuery();
if (_MYMODULE_isInteger($args[0])) { // Sanity check, local helper function just to check that the value is an integer.
$query->entityCondition('entity_type', 'node')
->fieldCondition('field_doc_legacy_docid', 'value', $args[0]);
$result = $query->execute();
if (isset($result['node']) && count($result['node'] == 1)) {
$node_holder = array_slice($result['node'],0,1)[0];
$node = node_load($node_holder->nid);
$language = language_list()[$node->language];
drupal_goto(drupal_get_path_alias('node/'.$node_holder->nid, $node->language), array('language' => $language), 301);
} else {
return MENU_NOT_FOUND;
}
}
return MENU_NOT_FOUND;
}
Views Answer
Here is a views answer, but I'd still like to know if there is a better or preferred way of doing this. I added a function in my_module:
function my_module_views_pre_render(&$view) {
if ($view->name=='staff_views') { // user redirect
drupal_goto(drupal_get_path_alias('user/'.$view->result[0]->uid));
}
if ($view->name=='pub_by_docid') {
if (count($view->result) == 1) {
$node = node_load($view->result[0]->nid);
$language = language_list()[$node->language];
drupal_goto(drupal_get_path_alias('node/'.$view->result[0]->nid, $node->language), array('language' => $language), 301);
}
}
}
Note that this function is actually redirecting for a view that matches users based on their legacy user id first, and then for a view that matches document id as mentioned originally in my question.
Update: I've updated the code here to reflect the suggestion from J. Reynolds that I include a http response code of 301 to avoid drupals default of 302.
I also found that to get things to work for non-English publications, I needed to add a language option to drupal_goto()
, which needs to be a language object. That is the reason for the line creating the $language
variable.