class BiblioCrossRefClient in Bibliography Module 6.2
Same name and namespace in other branches
- 7 modules/crossref/biblio.crossref.client.php \BiblioCrossRefClient
- 7.2 modules/crossref/biblio.crossref.client.php \BiblioCrossRefClient
Hierarchy
- class \BiblioCrossRefClient
Expanded class hierarchy of BiblioCrossRefClient
File
- modules/
crossref/ biblio.crossref.client.php, line 2
View source
class BiblioCrossRefClient {
const BASE_URL = 'http://www.crossref.org/openurl/';
private $pid;
private $doi;
private $query;
private $url;
private $nodes;
private $node;
private $parser;
private $element;
private $attribute;
private $auth_category;
private $contrib_count;
private $org_count;
private $field_map;
private $type_map;
public function __construct($doi = '', $id = '') {
$this
->setDOI($doi);
$this
->setUserID($id);
$this
->setURL(self::BASE_URL);
$this->field_map = array();
$this->type_map = array();
}
public function setURL($url) {
$this->url = $url;
}
public function setDOI($doi) {
$this->doi = $doi;
}
public function getDOI() {
return $this->doi;
}
public function setUserID($id) {
$this->pid = $id;
}
public function getUserID() {
return $this->pid;
}
public function getQuery() {
return $this->query;
}
public function fetch() {
$this->query = $this->url . '?pid=' . $this->pid . '&noredirect=true&format=unixref&id=doi%3A' . $this->doi;
if (!($xml = file_get_contents($this->query))) {
drupal_set_message(t('Could not open crossref.org for XML input'), 'error');
return;
}
$this->nodes = array();
$this->parser = drupal_xml_parser_create($xml);
// use case-folding so we are sure to find the tag in
xml_parser_set_option($this->parser, XML_OPTION_CASE_FOLDING, FALSE);
xml_parser_set_option($this->parser, XML_OPTION_SKIP_WHITE, TRUE);
xml_set_object($this->parser, $this);
xml_set_element_handler($this->parser, 'unixref_startElement', 'unixref_endElement');
xml_set_character_data_handler($this->parser, 'unixref_characterData');
if (!xml_parse($this->parser, $xml)) {
drupal_set_message(sprintf("XML error: %s at line %d", xml_error_string(xml_get_error_code($this->parser)), xml_get_current_line_number($this->parser)), 'error');
}
xml_parser_free($this->parser);
return $this->node;
}
function fetchByAuthorTitle($author, $title) {
$qdata = simplexml_load_string('<query_batch version="2.0" xsi:schemaLocation="http://www.crossref.org/qschema/2.0 http://www.crossref.org/qschema/crossref_query_input2.0.xsd" xmlns="http://www.crossref.org/qschema/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />');
$qdata->head->email_address = $this->pid;
$qdata->head->doi_batch_id = uniqid('NA');
$qdata->body->query = '';
$query = $qdata->body->query;
$query['enable-multiple-hits'] = 'exact';
$query['key'] = 'key';
$query->article_title = $title;
$query->article_title['match'] = 'fuzzy';
$query->author = $author;
$query->author['search-all-authors'] = 'true';
$this->query = url($this->url, array(
'external' => TRUE,
'query' => array(
'pid' => $this->pid,
'noredirect' => 'true',
'format' => 'unixref',
'qdata' => (string) $qdata
->asXml(),
),
));
$response = drupal_http_request($this->query);
if ($response->code != 200) {
drupal_set_message(t('Could not open crossref.org for XML author/title query.'), 'error');
return array();
}
$xml = simplexml_load_string($response->data);
$results = array();
foreach ($xml->doi_record as $record) {
$result = array(
'full' => $record
->asXml(),
'doi' => $record
->xpath('.//doi[1]'),
'title' => $record
->xpath('.//title[1]'),
);
$result['full'] = preg_replace('@<[^>]+>@s', '.', $result['full']);
$result['full'] = preg_replace('@\\.[\\s\\.]+@', '. ', $result['full']);
$result['full'] = trim($result['full'], '. ');
$result['doi'] = (string) $result['doi'][0];
$result['title'] = (string) $result['title'][0];
$results[] = $result;
}
return $results;
}
function unixref_startElement($parser, $name, $attrs) {
switch ($name) {
case 'doi_record':
$this->node = array();
$this->element = $name;
break;
case 'book':
case 'journal':
case 'standard':
case 'conference':
case 'report-paper':
case 'dissertation':
case 'database':
case 'sa_component':
$this->node['biblio_type'] = $this
->_unixref_type_map($name);
$this->element = $name;
break;
case 'journal_article':
case 'conference_paper':
case 'content_item':
case 'report-paper_metadata':
case 'standard_metadata':
case 'database_date':
case 'component':
$this->node['year'] = '';
$this->node['doi'] = '';
$this->element = $name;
break;
case 'person_name':
$this->auth_category = $this
->_unixref_get_contributor_category($attrs['contributor_role']);
if (!isset($this->contrib_count)) {
$this->contrib_count = 0;
}
$this->element = $name;
break;
case 'organization':
if (!isset($this->org_count)) {
$this->org_count = 0;
}
$this->element = $name;
break;
case 'issn':
if (isset($attrs['media_type'])) {
$this->attribute = $attrs['media_type'];
}
$this->element = $name;
break;
case 'isbn':
if (isset($attrs['media_type'])) {
$this->attribute = $attrs['media_type'];
}
$this->element = $name;
break;
case 'i':
// HTML font style tags
case 'b':
case 'u':
case 'sub':
case 'sup':
$this
->unixref_characterData(NULL, ' <' . $name . '>');
break;
default:
$this->element = $name;
}
}
function unixref_decode(&$item, $key) {
$item = html_entity_decode($item, NULL, 'UTF-8');
}
function unixref_endElement($parser, $name) {
switch ($name) {
case 'doi_record':
array_walk_recursive($this->node, array(
$this,
'unixref_decode',
));
$this->node['biblio_crossref_id'] = $this->node['biblio_doi'] = $this
->getDOI();
$this->node['biblio_crossref_md5'] = md5(serialize($this->node));
$this->nodes[] = $this->node;
//biblio_save_node($node, $batch, $session_id, $save_node);
break;
case 'person_name':
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['auth_type'] = _biblio_get_auth_type($this->auth_category, $this->node['biblio_type']);
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['name'] = $this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['lastname'];
if (isset($this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['firstname'])) {
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['name'] .= ', ' . $this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['firstname'];
}
$this->auth_category = '';
$this->contrib_count++;
break;
case 'organization':
$this->node['biblio_contributors'][5][$this->org_count]['auth_type'] = _biblio_get_auth_type(5, $this->node['biblio_type']);
$this->org_count++;
break;
case 'pages':
if (isset($this->node['biblio_first_page'])) {
$this->node['biblio_pages'] = $this->node['biblio_first_page'];
}
if (isset($this->node['biblio_last_page'])) {
$this->node['biblio_pages'] .= ' - ' . $this->node['biblio_last_page'];
}
break;
case 'publication_date':
break;
case 'journal_issue':
$this->node['biblio_date'] = (!empty($this->node['month']) ? $this->node['month'] . '/' : '') . $this->node['year'];
if (empty($this->node['biblio_year'])) {
$this->node['biblio_year'] = $this->node['year'];
}
break;
case 'journal_article':
case 'conference_paper':
case 'content_item':
case 'report-paper_metadata':
case 'standard_metadata':
case 'database_date':
case 'component':
if (!empty($this->node['year'])) {
$this->node['biblio_year'] = $this->node['year'];
}
// $this->node['biblio_doi'] = $this->node['doi'];
break;
case 'issn':
case 'isbn':
$this->attribute = '';
break;
case 'i':
// HTML font style tags
case 'b':
case 'u':
case 'sub':
case 'sup':
$this
->unixref_characterData(NULL, '</' . $name . '> ');
break;
default:
}
}
function unixref_characterData($parser, $data) {
$data = htmlspecialchars_decode($data);
if (trim($data)) {
switch ($this->element) {
case 'surname':
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['lastname'] .= $data;
break;
case 'given_name':
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['firstname'] .= $data;
break;
case 'suffix':
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['suffix'] .= $data;
break;
case 'affiliation':
$this->node['biblio_contributors'][$this->auth_category][$this->contrib_count]['affiliation'] .= $data;
break;
case 'organization':
$this->node['biblio_contributors'][5][$this->org_count]['name'] .= $data;
break;
case 'year':
$this->node['year'] = $data;
break;
case 'month':
$this->node['month'] = $data;
break;
case 'day':
$this->node['day'] = $data;
break;
case 'issn':
case 'isbn':
if ($this->attribute == 'print') {
if ($field = $this
->_unixref_field_map(trim($this->element))) {
$this->node[$field] = $data;
}
}
break;
default:
if ($field = $this
->_unixref_field_map(trim($this->element))) {
$this->node[$field] .= $data;
}
}
}
}
/*
* map a unixref XML field to a biblio field
*/
function _unixref_field_map($field) {
if (empty($this->field_map)) {
$this->field_map = biblio_get_map('field_map', 'crossref');
}
return isset($this->field_map[$field]) ? $this->field_map[$field] : FALSE;
}
function _unixref_type_map($type) {
if (empty($this->type_map)) {
$this->type_map = biblio_get_map('type_map', 'crossref');
}
return isset($this->type_map[$type]) ? $this->type_map[$type] : 129;
//return the biblio type or 129 (Misc) if type not found
}
function _unixref_get_contributor_category($role) {
if ($role == 'author') {
return 1;
}
if ($role == 'editor') {
return 2;
}
if ($role == 'chair') {
return 3;
}
if ($role == 'translator') {
return 4;
}
return NULL;
}
}