class BiblioCrossRefClient in Bibliography Module 7
Same name and namespace in other branches
- 6.2 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 6
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 $contribtors;
private $org_count;
private $field_map;
private $type_map;
private $citation_list;
/**
*
*/
public function __construct($doi = '', $id = '') {
$this
->setDOI($doi);
$this
->setUserID($id);
$this
->setURL(self::BASE_URL);
$this->field_map = array();
$this->type_map = array();
$this->citation_list = FALSE;
}
/**
*
*/
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 = url($this->url, array(
'query' => array(
'pid' => $this->pid,
'noredirect' => 'true',
'format' => 'unixref',
'id' => 'doi:' . $this->doi,
),
));
$request_options = array(
'method' => 'GET',
);
$result = drupal_http_request($this->query, $request_options);
if ($result->code != 200) {
drupal_set_message(t('HTTP error: %error (@number) when trying to contact crossref.org for XML input.', array(
'%error' => empty($result->error) ? t('unspecified server error') : $result->error,
'@number' => $result->code,
)), 'error');
return;
}
if (empty($result->data)) {
drupal_set_message(t('Did not get any data from crossref.org'), 'error');
return;
}
$sxml = @simplexml_load_string($result->data);
if (!isset($sxml->doi_record)) {
drupal_set_message(t('Failed to retrieve data for doi %doi', array(
'%doi' => $this->doi,
)), 'error');
return;
}
if ($error = (string) $sxml->doi_record->crossref->error) {
drupal_set_message(t('CrossRef Error: @error', array(
'@error' => $error,
)), 'error');
return;
}
$this->nodes = array();
$this->parser = drupal_xml_parser_create($result->data);
// 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, $result->data)) {
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;
}
/**
*
*/
public function unixref_startElement($parser, $name, $attrs) {
switch ($name) {
case 'doi_record':
$this->node = array();
$this->node['biblio_contributors'] = array();
$this->contributors = 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;
// HTML font style tags.
case 'i':
case 'b':
case 'u':
case 'sub':
case 'sup':
$this
->unixref_characterData(NULL, ' <' . $name . '>');
break;
case 'doi_data':
$this->doi_data = TRUE;
break;
case 'citation_list':
$this->citation_list = TRUE;
break;
default:
$this->element = $name;
}
}
/**
*
*/
public function unixref_decode(&$item, $key) {
$item = html_entity_decode($item, NULL, 'UTF-8');
}
/**
*
*/
public function unixref_endElement($parser, $name) {
switch ($name) {
case 'doi_record':
$this->node['biblio_contributors'] += $this->contributors;
array_walk_recursive($this->node, array(
$this,
'unixref_decode',
));
$this->node['biblio_crossref_id'] = $this
->getDOI();
$this->node['biblio_crossref_md5'] = md5(serialize($this->node));
// biblio_save_node($node, $batch, $session_id, $save_node);.
$this->nodes[] = $this->node;
break;
case 'person_name':
$this->contributors[$this->contrib_count]['auth_type'] = _biblio_get_auth_type($this->auth_category, $this->node['biblio_type']);
$this->contributors[$this->contrib_count]['auth_category'] = $this->auth_category;
$this->contributors[$this->contrib_count]['name'] = $this->contributors[$this->contrib_count]['lastname'];
if (isset($this->contributors[$this->contrib_count]['firstname'])) {
$this->contributors[$this->contrib_count]['name'] .= ', ' . $this->contributors[$this->contrib_count]['firstname'];
}
$this->auth_category = '';
$this->contrib_count++;
break;
case 'organization':
$this->contributors[$this->contrib_count]['auth_type'] = _biblio_get_auth_type(5, $this->node['biblio_type']);
$this->contributors[$this->contrib_count]['auth_category'] = 5;
$this->contrib_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':
case 'journal_article':
if (!isset($this->node['biblio_date']) || empty($this->node['biblio_date'])) {
$day = !empty($this->node['day']) ? $this->node['day'] : 1;
$month = !empty($this->node['month']) ? $this->node['month'] : 1;
$year = !empty($this->node['year']) ? $this->node['year'] : 0;
if ($year) {
$this->node['biblio_date'] = date("M-d-Y", mktime(0, 0, 0, $day, $month, $year));
}
}
if ((!isset($this->node['biblio_year']) || empty($this->node['biblio_year'])) && isset($this->node['year'])) {
$this->node['biblio_year'] = $this->node['year'];
}
break;
case 'conference_paper':
case 'content_item':
case 'report-paper_metadata':
case 'standard_metadata':
case 'database_date':
case 'component':
if ((!isset($this->node['biblio_year']) || empty($this->node['biblio_year'])) && isset($this->node['year'])) {
$this->node['biblio_year'] = $this->node['year'];
unset($this->node['year']);
}
// $this->node['biblio_doi'] = $this->node['doi'];.
break;
case 'issn':
case 'isbn':
$this->attribute = '';
break;
// HTML font style tags.
case 'i':
case 'b':
case 'u':
case 'sub':
case 'sup':
$this
->unixref_characterData(NULL, '</' . $name . '> ');
break;
case 'doi_data':
$this->doi_data = FALSE;
break;
case 'citation_list':
$this->citation_list = FALSE;
break;
default:
}
}
/**
*
*/
public function unixref_characterData($parser, $data) {
$data = htmlspecialchars_decode($data);
if (trim($data) && !$this->citation_list) {
switch ($this->element) {
case 'surname':
$this
->_set_contrib_data('lastname', $data);
break;
case 'given_name':
$this
->_set_contrib_data('firstname', $data);
break;
case 'suffix':
$this
->_set_contrib_data('suffix', $data);
break;
case 'affiliation':
$this
->_set_contrib_data('affiliation', $data);
break;
case 'organization':
$this
->_set_contrib_data('name', $data);
break;
case 'year':
case 'month':
case 'day':
$this->node[$this->element] = $data;
break;
case 'issn':
case 'isbn':
if ($this->attribute == 'print') {
if ($field = $this
->_unixref_field_map(trim($this->element))) {
$this
->_set_data($field, $data);
}
}
break;
case 'doi':
if ($this->doi_data) {
if ($field = $this
->_unixref_field_map(trim($this->element))) {
$this
->_set_data($field, $data);
}
}
break;
case 'resource':
if ($this->doi_data) {
$this
->_set_data('biblio_url', $data);
}
break;
default:
if ($field = $this
->_unixref_field_map(trim($this->element))) {
$this
->_set_data($field, $data);
}
}
}
}
/**
*
*/
public function _set_contrib_data($field, $data) {
$this->contributors[$this->contrib_count][$field] = isset($this->contributors[$this->contrib_count][$field]) ? $this->contributors[$this->contrib_count][$field] . $data : $data;
}
/**
*
*/
public function _set_data($field, $data) {
$this->node[$field] = isset($this->node[$field]) ? $this->node[$field] . $data : $data;
}
/**
* Map a unixref XML field to a biblio field.
*/
public function _unixref_field_map($field) {
if (empty($this->field_map)) {
$this->field_map = unserialize(db_query("SELECT field_map FROM {biblio_type_maps} WHERE format='crossref'")
->fetchField());
}
return isset($this->field_map[$field]) ? $this->field_map[$field] : FALSE;
}
/**
*
*/
public function _unixref_type_map($type) {
if (empty($this->type_map)) {
$this->type_map = unserialize(db_query("SELECT type_map FROM {biblio_type_maps} WHERE format='crossref'")
->fetchField());
}
// Return the biblio type or 129 (Misc) if type not found.
return isset($this->type_map[$type]) ? $this->type_map[$type] : 129;
}
/**
*
*/
public 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;
}
}