| 1 |
<?php
|
| 2 |
//$Id: biblio.contributors.inc,v 1.1.2.30 2009/10/09 20:47:32 rjerome Exp $
|
| 3 |
/**
|
| 4 |
* @param $aid
|
| 5 |
* @return unknown_type
|
| 6 |
*/
|
| 7 |
function biblio_get_contributor($aid) {
|
| 8 |
static $contributor = array();
|
| 9 |
if (!isset($contributor[$aid])) {
|
| 10 |
$contributor[$aid] = db_fetch_object(db_query('SELECT * FROM {biblio_contributor_data} WHERE cid = %d', $aid));
|
| 11 |
}
|
| 12 |
|
| 13 |
return $contributor[$aid];
|
| 14 |
}
|
| 15 |
|
| 16 |
/**
|
| 17 |
* @param $vid
|
| 18 |
* @return unknown_type
|
| 19 |
*/
|
| 20 |
function biblio_load_contributors($vid) {
|
| 21 |
$contributors = array();
|
| 22 |
$query = "SELECT * FROM {biblio_contributor} bc
|
| 23 |
INNER JOIN {biblio_contributor_data} bcd ON bc.cid=bcd.cid
|
| 24 |
WHERE bc.vid=%d
|
| 25 |
ORDER BY bc.rank ASC"; // do not change order of presentation
|
| 26 |
|
| 27 |
$result = db_query($query, $vid);
|
| 28 |
while ($creator = db_fetch_array($result)) {
|
| 29 |
$contributors[$creator['auth_category']][] = $creator;
|
| 30 |
}
|
| 31 |
return $contributors;
|
| 32 |
}
|
| 33 |
/**
|
| 34 |
* Add separate author named "et al" to the end of the author array
|
| 35 |
*
|
| 36 |
* @param $authors - author array to augment
|
| 37 |
* @param $type - auth_type
|
| 38 |
* @return true if author was added, false if "etal" was already there
|
| 39 |
*/
|
| 40 |
function biblio_authors_add_etal (&$authors, $type) {
|
| 41 |
$etal = "et al"; $max_rank = 0;
|
| 42 |
foreach ($authors as $author) { // et al author should be added only once per type
|
| 43 |
if ($author['auth_type'] != $type) continue;
|
| 44 |
if ($author['name'] == $etal) return false;
|
| 45 |
$max_rank = max($max_rank, $author['rank']);
|
| 46 |
}
|
| 47 |
$authors[] = biblio_parse_author(array('name' => $etal, 'auth_type' => $type, 'lastname' => $etal, 'rank' => $max_rank + 1));
|
| 48 |
return true;
|
| 49 |
}
|
| 50 |
/**
|
| 51 |
* Parse initial contributor array and augment with additional info
|
| 52 |
* @param $contributors initial contributor array
|
| 53 |
* @return augmented contributor array
|
| 54 |
*/
|
| 55 |
function biblio_parse_contributors($contributors) {
|
| 56 |
$result = array();
|
| 57 |
foreach ($contributors as $cat => $authors) {
|
| 58 |
$etal = array();
|
| 59 |
foreach ($authors as $author) {
|
| 60 |
// remove any form of "et al" from name field, because it confuses biblio_parse_author
|
| 61 |
$author_cleaned = preg_replace("/et\.?\s+al\.?/",'',$author['name']);
|
| 62 |
if ($author_cleaned != $author['name']) { // if "et al" was present:
|
| 63 |
$author['name'] = $author_cleaned; // store cleaned name
|
| 64 |
$etal[$author['auth_type']] = true; // mark it as "to be added" in $etal array
|
| 65 |
}
|
| 66 |
$author['name'] = trim($author['name']);
|
| 67 |
if (strlen($author['name'])) {
|
| 68 |
$result[$cat][] = biblio_parse_author($author, $cat);
|
| 69 |
}
|
| 70 |
}
|
| 71 |
// add "et al" authors for all neccessary author types
|
| 72 |
foreach ($etal as $type => $dummy) {
|
| 73 |
if (isset($result[$cat])) { // add "et al" only if plain authors exists
|
| 74 |
biblio_authors_add_etal ($result[$cat], $type);
|
| 75 |
}
|
| 76 |
}
|
| 77 |
}
|
| 78 |
return $result;
|
| 79 |
}
|
| 80 |
/**
|
| 81 |
* Save $node->biblio_contributors to database
|
| 82 |
* @param $node
|
| 83 |
* @param $update
|
| 84 |
* @return success of database operations
|
| 85 |
*/
|
| 86 |
function biblio_save_contributors($node, $update = FALSE) {
|
| 87 |
if (empty ($node->biblio_contributors)) return true;
|
| 88 |
return _save_contributors($node->biblio_contributors, $node->nid, $node->vid, $update);
|
| 89 |
}
|
| 90 |
/**
|
| 91 |
* Save contributors to the database
|
| 92 |
* @param $authors
|
| 93 |
* @param $nid
|
| 94 |
* @param $vid
|
| 95 |
* @param $update
|
| 96 |
* @return success of database operations
|
| 97 |
*/
|
| 98 |
function _save_contributors($contributors, $nid, $vid, $update = FALSE) {
|
| 99 |
$md5 = _loadMD5();
|
| 100 |
db_query('DELETE FROM {biblio_contributor} WHERE nid = %d AND vid = %d', array($nid, $vid));
|
| 101 |
foreach ($contributors as $cat => $authors) {
|
| 102 |
foreach ($authors as $key => $author) {
|
| 103 |
if ($update && !empty($author['cid'])) $author['cid'] = null; // null out the cid so we don't do a global change
|
| 104 |
if (empty ($author['cid']) && !empty ($md5))
|
| 105 |
$author['cid'] = array_search($author['md5'], $md5);
|
| 106 |
if (empty ($author['cid'])) {
|
| 107 |
if (!drupal_write_record('biblio_contributor_data', $author)) return false;
|
| 108 |
$cid = db_last_insert_id('biblio_contributor_data', 'cid');
|
| 109 |
} else {
|
| 110 |
$cid = $author['cid'];
|
| 111 |
}
|
| 112 |
$link_array = array(
|
| 113 |
'nid' => $nid,
|
| 114 |
'vid' => $vid,
|
| 115 |
'cid' => $cid,
|
| 116 |
'rank' => (isset($author['rank']) && is_numeric($author['rank'])) ? $author['rank'] : $key,
|
| 117 |
'auth_type' => $author['auth_type'],
|
| 118 |
'auth_category' => $cat,
|
| 119 |
);
|
| 120 |
|
| 121 |
if (!drupal_write_record('biblio_contributor', $link_array)) return false;
|
| 122 |
}
|
| 123 |
}
|
| 124 |
db_query("UPDATE {biblio_contributor_data} SET aka = cid WHERE aka = 0 OR aka IS NULL");
|
| 125 |
return true; // successfully saved all contributors
|
| 126 |
}
|
| 127 |
/*
|
| 128 |
Released through http://bibliophile.sourceforge.net under the GPL licence.
|
| 129 |
Do whatever you like with this -- some credit to the author(s) would be appreciated.
|
| 130 |
|
| 131 |
A collection of PHP classes to manipulate bibtex files.
|
| 132 |
|
| 133 |
If you make improvements, please consider contacting the administrators at bibliophile.sourceforge.net so that your improvements can be added to the release package.
|
| 134 |
|
| 135 |
Mark Grimshaw 2004/2005
|
| 136 |
http://bibliophile.sourceforge.net
|
| 137 |
|
| 138 |
28/04/2005 - Mark Grimshaw.
|
| 139 |
Efficiency improvements.
|
| 140 |
|
| 141 |
11/02/2006 - Daniel Reidsma.
|
| 142 |
Changes to preg_matching to account for Latex characters in names such as {\"{o}}
|
| 143 |
*/
|
| 144 |
// For a quick command-line test (php -f PARSECREATORS.php) after installation, uncomment these lines:
|
| 145 |
/***********************
|
| 146 |
$authors = "Mark \~N. Grimshaw and Bush III, G.W. & M. C. H{\\'a}mmer Jr. and von Frankenstein, Ferdinand Cecil, P.H. & Charles Louis Xavier Joseph de la Vallee P{\\\"{o}}ussin";
|
| 147 |
$creator = new PARSECREATORS();
|
| 148 |
$creatorArray = $creator->parse($authors);
|
| 149 |
print_r($creatorArray);
|
| 150 |
***********************/
|
| 151 |
/* Create writer arrays from bibtex input.
|
| 152 |
'author field can be (delimiters between authors are 'and' or '&'):
|
| 153 |
1. <first-tokens> <von-tokens> <last-tokens>
|
| 154 |
2. <von-tokens> <last-tokens>, <first-tokens>
|
| 155 |
3. <von-tokens> <last-tokens>, <jr-tokens>, <first-tokens>
|
| 156 |
*/
|
| 157 |
/**
|
| 158 |
* @param $author_array
|
| 159 |
* @return unknown_type
|
| 160 |
*/
|
| 161 |
function biblio_parse_author($author_array, $cat = 0) {
|
| 162 |
if ($cat == 5){
|
| 163 |
$author_array['firstname'] = '';
|
| 164 |
$author_array['initials'] = '';
|
| 165 |
$author_array['lastname'] = trim($author_array['name']);
|
| 166 |
$author_array['prefix'] = '';
|
| 167 |
}
|
| 168 |
else {
|
| 169 |
$value = trim($author_array['name']);
|
| 170 |
$appellation = $prefix = $surname = $firstname = $initials = '';
|
| 171 |
$prefix = "";
|
| 172 |
$value = preg_replace("/\s{2,}/", ' ', $value); // replace multiple white space by single space
|
| 173 |
$author = explode(",", $value);
|
| 174 |
$size = sizeof($author);
|
| 175 |
// No commas therefore something like Mark Grimshaw, Mark Nicholas Grimshaw, M N Grimshaw, Mark N. Grimshaw
|
| 176 |
if ($size == 1) {
|
| 177 |
// Is complete surname enclosed in {...}, unless the string starts with a backslash (\) because then it is
|
| 178 |
// probably a special latex-sign..
|
| 179 |
// 2006.02.11 DR: in the last case, any NESTED curly braces should also be taken into account! so second
|
| 180 |
// clause rules out things such as author="a{\"{o}}"
|
| 181 |
//
|
| 182 |
if (preg_match("/(.*){([^\\\].*)}/", $value, $matches) && !(preg_match("/(.*){\\\.{.*}.*}/", $value, $matches2))) {
|
| 183 |
$author = split(" ", $matches[1]);
|
| 184 |
$surname = $matches[2];
|
| 185 |
}
|
| 186 |
else {
|
| 187 |
$author = split(" ", $value);
|
| 188 |
// last of array is surname (no prefix if entered correctly)
|
| 189 |
$surname = array_pop($author);
|
| 190 |
}
|
| 191 |
}
|
| 192 |
// Something like Grimshaw, Mark or Grimshaw, Mark Nicholas or Grimshaw, M N or Grimshaw, Mark N.
|
| 193 |
else
|
| 194 |
if ($size == 2) {
|
| 195 |
// first of array is surname (perhaps with prefix)
|
| 196 |
list ($surname, $prefix) = _grabSurname(array_shift($author));
|
| 197 |
}
|
| 198 |
// If $size is 3, we're looking at something like Bush, Jr. III, George W
|
| 199 |
else {
|
| 200 |
// middle of array is 'Jr.', 'IV' etc.
|
| 201 |
$appellation = join(' ', array_splice($author, 1, 1));
|
| 202 |
// first of array is surname (perhaps with prefix)
|
| 203 |
list ($surname, $prefix) = _grabSurname(array_shift($author));
|
| 204 |
}
|
| 205 |
$remainder = join(" ", $author);
|
| 206 |
list ($firstname, $initials, $prefix2) = _grabFirstnameInitials($remainder);
|
| 207 |
if (!empty ($prefix2))
|
| 208 |
$prefix .= $prefix2;
|
| 209 |
//var_dump($prefix);
|
| 210 |
//$surname = $surname . ' ' . $appellation;
|
| 211 |
$author_array['firstname'] = trim($firstname);
|
| 212 |
$author_array['initials'] = trim($initials);
|
| 213 |
$author_array['lastname'] = trim($surname);
|
| 214 |
$author_array['prefix'] = trim($prefix);
|
| 215 |
$author_array['suffix'] = trim($appellation);
|
| 216 |
}
|
| 217 |
$author_array['md5'] = _md5sum($author_array);
|
| 218 |
return $author_array;
|
| 219 |
}
|
| 220 |
/**
|
| 221 |
* @param $creator
|
| 222 |
* @return unknown_type
|
| 223 |
*/
|
| 224 |
function _md5sum($creator) {
|
| 225 |
$string = $creator['firstname'] . $creator['initials'] . $creator['prefix'] .$creator['lastname'];
|
| 226 |
$string = str_replace(' ', '', drupal_strtolower($string));
|
| 227 |
return md5($string);
|
| 228 |
}
|
| 229 |
// grab firstname and initials which may be of form "A.B.C." or "A. B. C. " or " A B C " etc.
|
| 230 |
/**
|
| 231 |
* @param $remainder
|
| 232 |
* @return unknown_type
|
| 233 |
*/
|
| 234 |
function _grabFirstnameInitials($remainder) {
|
| 235 |
$prefix = array();
|
| 236 |
$firstname = $initials = '';
|
| 237 |
$array = split(" ", $remainder);
|
| 238 |
foreach ($array as $value) {
|
| 239 |
$firstChar = drupal_substr($value, 0, 1);
|
| 240 |
if ((ord($firstChar) >= 97) && (ord($firstChar) <= 122)){
|
| 241 |
$prefix[] = $value;
|
| 242 |
} else if (preg_match("/[a-zA-Z]{2,}/", trim($value))){
|
| 243 |
$firstnameArray[] = trim($value);
|
| 244 |
} else {
|
| 245 |
$initialsArray[] = trim(str_replace(".", " ", trim($value)));
|
| 246 |
}
|
| 247 |
}
|
| 248 |
if (isset ($initialsArray)) {
|
| 249 |
$initials = join(" ", $initialsArray);
|
| 250 |
}
|
| 251 |
if (isset ($firstnameArray)) {
|
| 252 |
$firstname = join(" ", $firstnameArray);
|
| 253 |
}
|
| 254 |
if (!empty ($prefix)){
|
| 255 |
$prefix = join(" ", $prefix);
|
| 256 |
}
|
| 257 |
return array($firstname,$initials,$prefix);
|
| 258 |
}
|
| 259 |
// surname may have title such as 'den', 'von', 'de la' etc. - characterised by first character lowercased. Any
|
| 260 |
// uppercased part means lowercased parts following are part of the surname (e.g. Van den Bussche)
|
| 261 |
/**
|
| 262 |
* @param $input
|
| 263 |
* @return unknown_type
|
| 264 |
*/
|
| 265 |
function _grabSurname($input) {
|
| 266 |
$surnameArray = split(" ", $input);
|
| 267 |
$noPrefix = $surname = FALSE;
|
| 268 |
foreach ($surnameArray as $value) {
|
| 269 |
$firstChar = substr($value, 0, 1);
|
| 270 |
if (!$noPrefix && (ord($firstChar) >= 97) && (ord($firstChar) <= 122))
|
| 271 |
$prefix[] = $value;
|
| 272 |
else {
|
| 273 |
$surname[] = $value;
|
| 274 |
$noPrefix = TRUE;
|
| 275 |
}
|
| 276 |
}
|
| 277 |
if ($surname)
|
| 278 |
$surname = join(" ", $surname);
|
| 279 |
if (isset ($prefix)) {
|
| 280 |
$prefix = join(" ", $prefix);
|
| 281 |
return array(
|
| 282 |
$surname,
|
| 283 |
$prefix
|
| 284 |
);
|
| 285 |
}
|
| 286 |
return array(
|
| 287 |
$surname,
|
| 288 |
FALSE
|
| 289 |
);
|
| 290 |
}
|
| 291 |
/**
|
| 292 |
* @return unknown_type
|
| 293 |
*/
|
| 294 |
function _loadMD5() {
|
| 295 |
static $md5 = array();
|
| 296 |
static $count =0;
|
| 297 |
$db_count = db_result(db_query("SELECT COUNT(*) FROM {biblio_contributor_data"));
|
| 298 |
if ($db_count > $count){
|
| 299 |
$count = $db_count;
|
| 300 |
$result = db_query('SELECT md5,cid FROM {biblio_contributor_data} ');
|
| 301 |
while ($row = db_fetch_array($result)) {
|
| 302 |
$md5[$row['cid']] = $row['md5'];
|
| 303 |
}
|
| 304 |
}
|
| 305 |
return (count($md5)) ? $md5 : NULL;
|
| 306 |
}
|