View source
<?php
function biblio_pm_cron() {
if (variable_get('biblio_pm_auto_update', 0)) {
module_load_include('inc', 'biblio', 'includes/biblio.import.export');
$interval = variable_get('biblio_pm_update_interval', 3600);
$count_limit = variable_get('biblio_pm_update_limit', 100);
$age = variable_get('biblio_pm_age_limit', 2419200);
$age_limit = time() - $age;
if (time() >= variable_get('biblio_pm_update_next_execution', 0)) {
$ids = array();
$result = db_select('biblio_pubmed', 'bpm')
->fields('bpm', array(
'nid',
'biblio_pubmed_id',
))
->condition('biblio_pm_changed', $age_limit, '<')
->orderBy('nid', 'ASC')
->range(0, $count_limit)
->execute();
foreach ($result as $pm) {
$ids[$pm->nid] = $pm->biblio_pubmed_id;
}
if (count($ids)) {
list($nids, $dups) = biblio_pm_import_ids($ids);
if (count($nids)) {
foreach ($nids as $nid) {
$message = '';
$message = t('!nid was updated due to changes originating at !url', array(
'!nid' => l($nid, 'node/' . $nid),
'!url' => l(t('PubMed'), 'https://www.ncbi.nlm.nih.gov/pubmed/' . $ids[$nid]),
));
watchdog('biblio_pm', $message, array(), WATCHDOG_WARNING);
}
}
if (count($dups)) {
$count = count($dups);
$message = format_plural($count, 'One duplicate PubMed entry was checked, but no changes were found.', '@count PubMed entries were checked, but no changes were found.');
watchdog('biblio_pm', $message, array(
'@count' => $count,
), WATCHDOG_INFO);
$now = time();
db_update('biblio_pubmed')
->fields(array(
'biblio_pm_changed' => $now,
))
->condition('nid', $dups, 'IN')
->execute();
}
}
else {
$message = t('There were no PubMed entries older than @age to check.', array(
'@age' => format_interval($age),
));
}
watchdog('biblio_pm', $message, array(), WATCHDOG_INFO);
variable_set('biblio_pm_update_next_execution', time() + $interval);
}
}
}
function biblio_pm_form_biblio_admin_settings_alter(&$form, &$form_state) {
module_load_include('inc', 'biblio_pm', 'biblio_pm.admin');
$form += biblio_pm_settings_form();
}
function biblio_pm_form_biblio_node_form_alter(&$form, &$form_state, $form_id) {
if ($form_id == 'biblio_node_form' && isset($form_state['biblio_fields'])) {
if (isset($form_state['values']['biblio_pubmed_id'])) {
$default_pubmed_id = $form_state['values']['biblio_pubmed_id'];
}
elseif (isset($form_state['node']->biblio_pubmed_id)) {
$default_pubmed_id = $form_state['node']->biblio_pubmed_id;
}
else {
$default_pubmed_id = '';
}
if (isset($form_state['values']['biblio_pmcid'])) {
$default_pmcid = $form_state['values']['biblio_pmcid'];
}
elseif (isset($form_state['node']->biblio_pmcid)) {
$default_pmcid = $form_state['node']->biblio_pmcid;
}
else {
$default_pmcid = '';
}
$form['biblio_tabs'][4]['biblio_pubmed_id'] = array(
'#type' => 'textfield',
'#title' => t('PMID'),
'#required' => FALSE,
'#description' => t('PubMed ID'),
'#default_value' => $default_pubmed_id,
'#size' => 50,
'#maxlength' => 50,
);
$form['biblio_tabs'][4]['biblio_pmcid'] = array(
'#type' => 'textfield',
'#title' => t('PMCID'),
'#required' => FALSE,
'#description' => t('PubMed Central ID'),
'#default_value' => $default_pmcid,
'#size' => 50,
'#maxlength' => 50,
);
}
if ((!isset($form_state['biblio_type']) || empty($form_state['biblio_type'])) && !isset($form_state['node']->nid)) {
$form['biblio_pubmed_lookup'] = array(
'#type' => 'fieldset',
'#title' => t('PubMed Lookup'),
'#weight' => -20,
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$form['biblio_pubmed_lookup']['PMID'] = array(
'#type' => 'textfield',
'#title' => t('PubMed ID'),
'#required' => FALSE,
'#default_value' => '',
'#description' => t('Enter a PubMed ID</b>'),
'#size' => 60,
'#maxlength' => 255,
'#weight' => -4,
);
$form['biblio_pubmed_lookup']['pubmed_submit'] = array(
'#type' => 'submit',
'#value' => t('Populate using PubMed'),
'#submit' => array(
'biblio_pm_form_biblio_node_form_submit',
),
);
}
if (isset($form_state['values']['biblio_pubmed_id'])) {
$form['biblio_pubmed_id'] = array(
'#type' => 'value',
'#value' => $form_state['values']['biblio_pubmed_id'],
);
}
if (isset($form_state['values']['biblio_pubmed_md5'])) {
$form['biblio_pubmed_md5'] = array(
'#type' => 'value',
'#value' => $form_state['values']['biblio_pubmed_md5'],
);
}
if (isset($form_state['values']['biblio_pmcid'])) {
$form['biblio_pmcid'] = array(
'#type' => 'value',
'#value' => $form_state['values']['biblio_pmcid'],
);
}
if (isset($form_state['values']['biblio_pubmed_grants'])) {
$form['biblio_pubmed_grants'] = array(
'#type' => 'value',
'#value' => $form_state['values']['biblio_pubmed_grants'],
);
}
}
function biblio_pm_form_biblio_node_form_submit($form, &$form_state) {
$node_data = array();
if (strlen($pmid = $form_state['values']['PMID'])) {
if (!($dup = biblio_pm_check_pmid($pmid))) {
module_load_include('php', 'biblio_pm', 'EntrezClient');
module_load_include('php', 'biblio_pm', 'EntrezPubmedArticle');
$Eclient = new BiblioEntrezClient();
try {
$result = $Eclient
->fetch($pmid);
} catch (Exception $e) {
form_set_error($e
->getMessage());
}
if (!isset($result->PubmedArticle)) {
unset($form_state['values']['biblio_type']);
unset($form_state['post']['biblio_type']);
form_set_error('PMID', 'No data available for PubMed ID: ' . check_plain($pmid));
return;
}
$data = new BiblioEntrezPubmedArticle($result->PubmedArticle);
$node_data = $data
->getBiblio();
}
else {
$message = t('The PubMed ID that you are trying to import already exists in the database, see !url', array(
'!url' => l('node/' . $dup, 'node/' . $dup),
));
form_set_error('PMID', $message);
$form_state['rebuild'] = TRUE;
$form_state['submitted'] = FALSE;
unset($form_state['values']['biblio_type']);
}
}
if (!empty($node_data)) {
$form_state['values'] = array_merge($form_state['values'], $node_data);
$form_state['input']['biblio_type'] = $form_state['biblio_type'] = $node_data['biblio_type'];
$form_state['input']['biblio_pmcid'] = $form_state['biblio_pmcid'] = isset($node_data['biblio_pmcid']) ? $node_data['biblio_pmcid'] : '';
$form_state['input']['biblio_pubmed_id'] = $form_state['biblio_pubmed_id'] = $node_data['biblio_pubmed_id'];
$form_state['input']['biblio_pubmed_grants'] = $form_state['biblio_pubmed_grants'] = isset($node_data['biblio_pmcid']) ? $node_data['biblio_pmcid'] : array();
$form_state['rebuild'] = TRUE;
}
}
function biblio_pm_biblio_import_options() {
return array(
'biblio_pm' => t('PubMed ID List'),
'biblio_pm_xml' => t('PubMed XML'),
);
}
function biblio_pm_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL, $save = TRUE, $string = FALSE) {
$nids = array();
$dups = array();
$pmids = file($file->uri, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
if (empty($pmids)) {
drupal_set_message(t("Could not open PubMed ID file"), 'error');
return;
}
return biblio_pm_import_ids($pmids, $terms, $batch, $session_id);
}
function biblio_pm_xml_biblio_import($file, $terms = array(), $batch = FALSE, $session_id = NULL) {
libxml_use_internal_errors(TRUE);
$xml = @simplexml_load_file($file->uri);
if (empty($xml) || isset($xml->body->pre->ERROR)) {
drupal_set_message(t("Could not parse file as PubMed XML"), 'error');
return;
}
return _biblio_pm_create_node_from_xml($xml, $terms, $batch, $session_id);
}
function biblio_pm_import_ids($pmids, $terms = array(), $batch = FALSE, $session_id = NULL) {
module_load_include('php', 'biblio_pm', 'EntrezClient');
$retmax = 100;
$resmax = count($pmids);
$start = 0;
$Eclient = new BiblioEntrezClient();
$Eclient
->post($pmids);
$Eclient
->setReturnMax($retmax);
$nids = array();
$dups = array();
while ($start < $resmax && ($result = $Eclient
->fetchRecords($start))) {
$start += count($result
->xpath('//PubmedArticle'));
list($nid, $dup) = _biblio_pm_create_node_from_xml($result, $terms, $batch, $session_id);
$nids = array_merge($nids, $nid);
$dups = array_merge($dups, $dup);
}
return array(
$nids,
$dups,
);
}
function biblio_pm_fetch_pmid($pmid) {
$node = new stdClass();
$Eclient = new BiblioEntrezClient();
$paser = new BiblioEntrezPubmedArticle();
try {
$xml = $Eclient
->fetch($pmid);
} catch (Exception $e) {
return $node;
}
$articles = $xml
->xpath('//PubmedArticle');
if (count($articles)) {
$node = $paser
->setArticle($articles[0])
->getBiblioAsObject();
if (!empty($node)) {
$node->type = 'biblio';
node_object_prepare($node);
}
}
return $node;
}
function _biblio_pm_create_node_from_xml($xml, $terms, $batch, $session_id) {
module_load_include('php', 'biblio_pm', 'EntrezPubmedArticle');
$nids = array();
$dups = array();
$node = new stdClass();
$data = new BiblioEntrezPubmedArticle();
foreach ($xml
->xpath('//PubmedArticle') as $article) {
$node = $data
->setArticle($article)
->getBiblioAsObject();
if (isset($node)) {
$dup = biblio_pm_check_md5($node->biblio_pubmed_id, $node->biblio_pubmed_md5);
$action = variable_get('biblio_pm_dup_action', 'newrev');
if ($dup < 0 && $action == 'newrev') {
$node = (object) array_merge((array) node_load(-$dup), (array) $node);
$node->nid = -$dup;
$node->revision = 1;
$curr_date = format_date(time());
$node->log = t('Automatically updated by the Biblio PubMed module on !date due to changes at !url', array(
'!date' => $curr_date,
'!url' => l('PubMed', 'https://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id),
));
$dup = NULL;
}
if ($dup < 0 && $action == 'replace') {
$node->nid = -$dup;
$existing_node = db_query("SELECT * FROM {node} WHERE nid=:nid", array(
':nid' => $node->nid,
))
->fetchObject();
$node = (object) array_merge((array) $existing_node, (array) $node);
$dup = NULL;
}
if (!$dup) {
drupal_alter('biblio_pm_node', $node, $article);
biblio_save_node($node, $terms, $batch, $session_id);
if (!empty($node->nid)) {
$nids[] = $node->nid;
}
}
else {
$dups[] = $dup;
}
$node = NULL;
}
}
return array(
$nids,
$dups,
);
}
function biblio_pm_check_pmid($pmid) {
return db_query("SELECT nid FROM {biblio_pubmed} WHERE biblio_pubmed_id = :pmid", array(
':pmid' => $pmid,
))
->fetchField();
}
function biblio_pm_biblio_lookup_link_settings() {
return array(
'pubmed' => t('PubMed'),
);
}
function biblio_pm_biblio_lookup_link($node) {
$show_link = variable_get('biblio_lookup_links', array(
'pubmed' => TRUE,
));
if (!isset($show_link['pubmed']) || !$show_link['pubmed'] || !isset($node) || $node->type != 'biblio' || !isset($node->biblio_pubmed_id)) {
return array();
}
$link = 'https://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id . '?dopt=Abstract';
$attrs = array(
'title' => t("Click to view the PubMed listing for this node"),
);
if (variable_get('biblio_links_target_new_window', NULL)) {
$attrs = array_merge($attrs, array(
'target' => '_blank',
));
}
return array(
'biblio_pubmed' => array(
'title' => t('PubMed'),
'href' => $link,
'attributes' => $attrs,
),
);
}
function biblio_pm_node_view($node, $view_mode, $langcode) {
if ($node->type == 'biblio' && isset($node->biblio_pubmed_id)) {
switch ($view_mode) {
case 'full':
case 'teaser':
$node->content['links']['biblio_pubmed'] = array(
'#links' => biblio_pm_biblio_lookup_link($node),
'#attributes' => array(
'class' => array(
'links',
'inline',
),
),
);
}
}
}
function biblio_pm_node_delete($node) {
if ($node->type != 'biblio') {
return;
}
db_delete('biblio_pubmed')
->condition('nid', $node->nid)
->execute();
db_delete('biblio_pubmed_grant_info')
->condition('nid', $node->nid)
->execute();
}
function biblio_pm_node_insert($node) {
if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) {
$node->biblio_pm_changed = time();
drupal_write_record('biblio_pubmed', $node);
}
if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants)) {
foreach ($node->biblio_pubmed_grants as $grant) {
$info = array(
'nid' => $node->nid,
'biblio_pubmed_id' => $node->biblio_pubmed_id,
);
$info += $grant;
drupal_write_record('biblio_pubmed_grant_info', $info);
}
}
}
function biblio_pm_node_update($node) {
if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) {
db_delete('biblio_pubmed')
->condition('nid', $node->nid)
->execute();
$node->biblio_pm_changed = time();
drupal_write_record('biblio_pubmed', $node);
}
if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants) && !empty($node->biblio_pubmed_grants)) {
db_delete('biblio_pubmed_grant_info')
->condition('nid', $node->nid)
->execute();
foreach ($node->biblio_pubmed_grants as $grant) {
$info = array(
'nid' => $node->nid,
'biblio_pubmed_id' => $node->biblio_pubmed_id,
);
$info += $grant;
drupal_write_record('biblio_pubmed_grant_info', $info);
}
}
}
function biblio_pm_node_load($nodes, $types) {
$result = db_select('biblio_pubmed', 'bpm')
->fields('bpm', array(
'nid',
'biblio_pubmed_id',
'biblio_pmcid',
'biblio_pubmed_md5',
))
->condition('nid', array_keys($nodes))
->execute();
foreach ($result as $record) {
$nodes[$record->nid]->biblio_pubmed_id = $record->biblio_pubmed_id;
$nodes[$record->nid]->biblio_pmcid = $record->biblio_pmcid;
$nodes[$record->nid]->biblio_pubmed_md5 = $record->biblio_pubmed_md5;
}
$result = db_select('biblio_pubmed_grant_info', 'bpmgi')
->fields('bpmgi')
->condition('nid', array_keys($nodes))
->execute();
foreach ($result as $record) {
$nodes[$record->nid]->biblio_pubmed_grants[] = array(
'grantid' => $record->grantid,
'acronym' => $record->acronym,
'agency' => $record->agency,
'country' => $record->country,
);
}
}
function biblio_pm_check_md5($pmid, $md5) {
static $pm_md5s = array();
static $pm_nids = array();
if (empty($pm_md5s)) {
$result = db_query("SELECT * FROM {biblio_pubmed} ");
foreach ($result as $row) {
$pm_md5s[$row->biblio_pubmed_md5] = $row->nid;
$pm_nids[$row->biblio_pubmed_id] = $row->nid;
}
}
if (isset($pm_nids[$pmid]) && isset($pm_md5s[$md5])) {
return $pm_md5s[$md5];
}
elseif (isset($pm_nids[$pmid]) && !isset($pm_md5s[$md5])) {
return -$pm_nids[$pmid];
}
else {
$pm_md5s[$md5] = TRUE;
$pm_nids[$pmid] = TRUE;
return;
}
}
function biblio_pm_views_api() {
return array(
'api' => 2,
);
}
function biblio_pm_biblio_node_table_rows_alter(&$rows, $node) {
if (isset($node->biblio_pubmed_id) && !empty($node->biblio_pubmed_id)) {
$rows[] = array(
array(
'data' => t('PubMed ID'),
'class' => array(
'biblio-row-title',
),
),
array(
'data' => l($node->biblio_pubmed_id, 'https://www.ncbi.nlm.nih.gov/pubmed/' . $node->biblio_pubmed_id . '?dopt=Abstract'),
),
);
}
if (isset($node->biblio_pmcid) && !empty($node->biblio_pmcid)) {
$rows[] = array(
array(
'data' => t('PubMed Central ID'),
'class' => array(
'biblio-row-title',
),
),
array(
'data' => check_plain($node->biblio_pmcid),
),
);
}
if (isset($node->biblio_pubmed_grants) && is_array($node->biblio_pubmed_grants)) {
foreach ($node->biblio_pubmed_grants as $grant) {
$list[] = check_plain(implode(' / ', $grant));
}
$rows[] = array(
array(
'data' => t('Grant List'),
'class' => array(
'biblio-row-title',
),
),
array(
'data' => implode('<br>', $list),
),
);
}
}