/[drupal]/contributions/modules/oai2/oai2.module
ViewVC logotype

Contents of /contributions/modules/oai2/oai2.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.12 - (show annotations) (download) (as text)
Tue Jun 24 15:18:19 2008 UTC (17 months ago) by rjerome
Branch: MAIN
CVS Tags: HEAD
Changes since 1.11: +74 -58 lines
File MIME type: text/x-php
fixed validation issues.  liiscience.org now vaildates 100% at http://re.cs.uct.ac.za/
1 <?php
2 // $Id: oai2.module,v 1.9 2007/01/11 20:59:56 rjerome Exp $
3 /**
4 * oai2.module for Drupal
5 *
6 * Copyright (C) 2006 Ron Jerome
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 *
22 */
23
24 function oai2_help($section) {
25 switch ($section) {
26 case 'admin/modules#description':
27 // This description is shown in the listing at admin/modules.
28 return t('This module provides Open Archives 2 protocol access to the
29 information stored by the Biblio module' );
30 }
31 }
32 function oai2_node_name($node) {
33 return t('oai2');
34 }
35
36 function oai2_node_info() {
37 return array('oai2' => array('name' => t('oai2 provider'), 'base' => 'oai2'));
38 return array('oai2' => array(
39 'name' => t('oai2 provider'),
40 'module' => 'oai2',
41 'description' => t('This module provides Open Archives 2 protocol access to the
42 information stored by the Biblio module')));
43
44 }
45
46 function oai2_access($op, $node) {
47 global $user;
48
49 }
50
51 function oai2_perm() {
52 }
53 function oai2_cron(){
54 // cleanup expired resumption tokens
55 $expiretime = date("Y-m-d G:i:s", time()-(25*3600));
56 db_query("DELETE FROM {oai2_tokens} WHERE timestamp < '%s'",$expiretime);
57 }
58 function oai2_menu($may_cache) {
59 $items = array();
60
61 if ($may_cache) {
62 $items[] = array('path' => 'oai', 'title' => t(''),
63 'callback' => 'oai2_parse_request',
64 'access' => user_access('access content'),
65 'type' => MENU_CALLBACK);
66 }
67
68 return $items;
69 }
70 /**
71 * Parses the URL and calls the appropriate function to handle the request
72 *
73 */
74 function oai2_parse_request(){
75 global $base_url;
76 global $compress ;
77 global $error ;
78 $compress = true;
79 $error = null;
80
81 $xml = '<?xml version="1.0" encoding="UTF-8"?>
82 <OAI-PMH xmlns="http://www.openarchives.org/OAI/2.0/"
83 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
84 xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/
85 http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd">'."\n";
86
87 $responseDate = gmstrftime('%Y-%m-%dT%TZ');
88 // $responseDate = $datetime .'Z';
89 $xml .= ' <responseDate>'.$responseDate."</responseDate>\n";
90
91 if (!empty($_GET)) {
92 $args = $_GET;
93 $getarr = explode('&', $_SERVER['QUERY_STRING']);
94 if (count($getarr) != count($args)) {
95 $error .= oai2_oai_error( 'sameArgument');
96 }
97 }
98 if (!empty($_POST)) {
99 $args = $_POST;
100 }
101 if (!count($args)) {
102 $error .= oai2_oai_error( 'badRequestMethod', $_SERVER['REQUEST_METHOD']);
103 }
104
105 unset($args['q']); // get rid of the Drupal q
106
107
108 if (is_array($args)) {
109 foreach ($args as $key => $val) {
110 $reqattr .= ' '.$key.'="'.htmlspecialchars(stripslashes($val)).'"';
111 }
112 }
113 //$xml .= ' <request'. $reqattr.'>'.$base_url.'/'.$_GET['q']."</request>\n";
114 if (isset($args['verb']) && !$error) {
115 switch ($args['verb']) {
116
117 case 'GetRecord':
118 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
119 unset($args['verb']);
120 $xml .= oai2_get_record($args);
121 break;
122 case 'Identify':
123 $compress = false;
124 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
125 unset($args['verb']);
126 $xml .= oai2_identify( $args);
127 break;
128 case "ListIdentifiers":
129 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
130 unset($args['verb']);
131 $xml .= oai2_list_id_rec($args);
132 break;
133 case 'ListMetadataFormats':
134 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
135 unset($args['verb']);
136 $xml .= oai2_list_metadata_formats($args);
137 break;
138 case 'ListRecords':
139 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
140 unset($args['verb']);
141 $xml .= oai2_list_id_rec($args, true);
142 break;
143 case 'ListSets':
144 $xml .= ' <request verb="'.$args['verb'].'">'.$base_url.'/'.$_GET['q']."</request>\n";
145 unset($args['verb']);
146 $xml .= oai2_list_sets( $args);
147 break;
148 default:
149 // we never use compression with errors
150 $compress = false;
151 $xml .= ' <request>'.$base_url.'/'.$_GET['q']."</request>\n";
152 $error .= oai2_oai_error( 'badVerb', $args['verb']);
153
154 } /*switch */
155
156 } elseif (!$error) {
157 $error .= oai2_oai_error('noVerb');
158 } elseif ($error) {
159 $xml .= ' <request>'.$base_url.'/'.$_GET['q']."</request>\n";
160
161 }
162
163 if ($compress && !$error) {
164 ob_start('ob_gzhandler');
165 }
166
167 header('Content-Type: application/xml');
168 echo $xml;
169 if ($error) echo $error;
170 echo "</OAI-PMH>\n";
171 if ($compress && !$error) {
172 ob_end_flush();
173 }
174
175 }
176 /**
177 * Provides the repository identity information
178 *
179 * @param $args
180 * the arguments passed with the oai verb
181 *
182 */
183 function oai2_identify( $args){
184 global $base_url;
185 global $error;
186
187 if (!$errors && (count($args) > 0)){
188 foreach ($args as $key=>$val) {
189 $error .= oai2_oai_error('badArgument', $key, $val);
190 }
191 }
192
193 // break and clean up on error
194 if ($error) {
195 return false;
196 }
197
198 $result = db_query("SELECT min(changed) as date FROM {node} as n where n.type='biblio' ");
199 $datestamp = db_fetch_object($result);
200 $earliestDatestamp = gmstrftime('%Y-%m-%dT%TZ',$datestamp->date);
201
202 $indent = 2;
203
204 $output .= " <Identify>\n";
205 $output .= oai2_xmlformat(variable_get('site_name','Biblio OAI'), 'repositoryName', '', $indent);
206 $output .= oai2_xmlformat($base_url.'/'.$_GET['q'], 'baseURL', '', $indent);
207 $output .= oai2_xmlformat('2.0', 'protocolVersion', '', $indent);
208 $output .= oai2_xmlformat(variable_get('site_mail', ini_get('sendmail_from')), 'adminEmail', '', $indent);
209 $output .= oai2_xmlformat($earliestDatestamp, 'earliestDatestamp', '', $indent);
210 $output .= oai2_xmlformat('no','deletedRecord', '', $indent);
211 $output .= oai2_xmlformat('YYYY-MM-DDThh:mm:ssZ', 'granularity', '', $indent);
212 $output .= oai2_xmlformat('yes', 'compression', '', $indent);
213
214 // A description MAY be included.
215 // Use this if you choose to comply with a specific format of unique identifiers
216 // for items.
217 // See http://www.openarchives.org/OAI/2.0/guidelines-oai-identifier.htm
218 // for details
219
220 if ($show_identifier && $repositoryIdentifier && $delimiter && $sampleIdentifier) {
221 $output .=
222 ' <description>
223 <oai-identifier xmlns="http://www.openarchives.org/OAI/2.0/oai-identifier"
224 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
225 xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/oai-identifier
226 http://www.openarchives.org/OAI/2.0/oai-identifier.xsd">
227 <scheme>oai</scheme>
228 <repositoryIdentifier>'.$repositoryIdentifier.'</repositoryIdentifier>
229 <delimiter>'.$delimiter.'</delimiter>
230 <sampleIdentifier>'.$sampleIdentifier.'</sampleIdentifier>
231 </oai-identifier>
232 </description>'."\n";
233 }
234
235 // A description MAY be included.
236 // This example from arXiv.org is used by the e-prints community, please adjust
237 // see http://www.openarchives.org/OAI/2.0/guidelines-eprints.htm for details
238
239 // To include, change 'false' to 'true'.
240 if (false) {
241 $output .=
242 ' <description>
243 <eprints xmlns="http://www.openarchives.org/OAI/1.1/eprints"
244 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
245 xsi:schemaLocation="http://www.openarchives.org/OAI/1.1/eprints
246 http://www.openarchives.org/OAI/1.1/eprints.xsd">
247 <content>
248 <text>Author self-archived e-prints</text>
249 </content>
250 <metadataPolicy />
251 <dataPolicy />
252 <submissionPolicy />
253 </eprints>
254 </description>'."\n";
255 }
256
257 // If you want to point harvesters to other repositories, you can list their
258 // base URLs. Usage of friends container is RECOMMENDED.
259 // see http://www.openarchives.org/OAI/2.0/guidelines-friends.htm
260 // for details
261
262 // To include, change 'false' to 'true'.
263 if (false) {
264 $output .=
265 ' <description>
266 <friends xmlns="http://www.openarchives.org/OAI/2.0/friends/"
267 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
268 xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/friends/
269 http://www.openarchives.org/OAI/2.0/friends.xsd">
270 <baseURL>http://naca.larc.nasa.gov/oai2.0/</baseURL>
271 <baseURL>http://techreports.larc.nasa.gov/ltrs/oai2.0/</baseURL>
272 <baseURL>http://physnet.uni-oldenburg.de/oai/oai2.php</baseURL>
273 <baseURL>http://cogprints.soton.ac.uk/perl/oai</baseURL>
274 <baseURL>http://ub.uni-duisburg.de:8080/cgi-oai/oai.pl</baseURL>
275 <baseURL>http://rocky.dlib.vt.edu/~jcdlpix/cgi-bin/OAI1.1/jcdlpix.pl</baseURL>
276 </friends>
277 </description>'."\n";
278 }
279
280 // If you want to provide branding information, adjust accordingly.
281 // Usage of friends container is OPTIONAL.
282 // see http://www.openarchives.org/OAI/2.0/guidelines-branding.htm
283 // for details
284
285 // To include, change 'false' to 'true'.
286 if (false) {
287 $output .=
288 ' <description>
289 <branding xmlns="http://www.openarchives.org/OAI/2.0/branding/"
290 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
291 xsi:schemaLocation="http://www.openarchives.org/OAI/2.0/branding/
292 http://www.openarchives.org/OAI/2.0/branding.xsd">
293 <collectionIcon>
294 <url>http://my.site/icon.png</url>
295 <link>http://my.site/homepage.html</link>
296 <title>MySite(tm)</title>
297 <width>88</width>
298 <height>31</height>
299 </collectionIcon>
300 <metadataRendering
301 metadataNamespace="http://www.openarchives.org/OAI/2.0/oai_dc/"
302 mimeType="text/xsl">http://some.where/DCrender.xsl</metadataRendering>
303 <metadataRendering
304 metadataNamespace="http://another.place/MARC"
305 mimeType="text/css">http://another.place/MARCrender.css</metadataRendering>
306 </branding>
307 </description>'."\n";
308 }
309
310 // End Identify
311 $output .= " </Identify>\n";
312 return $output;
313 }
314
315 /**
316 * Lists sets available from the repository
317 *
318 * @param $args
319 * the arguments passed with the oai verb
320 *
321 */
322 function oai2_list_sets( $args){
323 global $error;
324
325 foreach($args as $key => $val) {
326
327 switch ($key) {
328 case 'resumptionToken':
329 $resumptionToken = $val;
330 $error .= oai2_oai_error('badResumptionToken', $key, $val);
331 return false;
332 break;
333
334 default:
335 $error .= oai2_oai_error('badArgument', $key, $val);
336 return false;
337 }
338 }
339
340 $result = db_query('SELECT t.* FROM {biblio_types} as t WHERE t.tid > 0');
341 if (db_num_rows($result)) {
342 $output .= " <ListSets>\n";
343
344 while ($row = db_fetch_object($result)) {
345 $output .= " <set>\n";
346 $row->name;
347 $setspec = str_replace(" ","_",strtolower($row->name));
348 $output .= oai2_xmlformat($setspec, 'setSpec', '', 4);
349 $output .= oai2_xmlformat($row->name, 'setName', '', 4);
350 if (isset($val['setDescription']) && $val['setDescription'] != '') {
351 $output .= " <setDescription>\n";
352 $prefix = 'oai_dc';
353 $output .= metadataHeader($prefix);
354 $output .= xmlrecord($val['setDescription'], 'dc:description', '', 7);
355 $output .=
356 ' </'.$prefix;
357 if (isset($METADATAFORMATS[$prefix]['record_prefix'])) {
358 $output .= ':'.$METADATAFORMATS[$prefix]['record_prefix'];
359 }
360 $output .= ">\n";
361 $output .= " </setDescription>\n";
362 }
363 $output .= " </set>\n";
364 }
365 $output .= " </ListSets>\n";
366
367 }
368 return $output;
369 }
370
371 /**
372 * Lists metadata formats available from the repository
373 *
374 * @param $args
375 * the arguments passed with the oai verb
376 *
377 */
378 function oai2_list_metadata_formats($args){
379 global $error;
380
381 foreach($args as $key => $val) {
382
383 switch ($key) {
384 case 'identifier':
385 $identifier = $val;
386 $result = db_query("SELECT nid FROM {node} n WHERE n.nid=%d",$val);
387 if (!db_num_rows($result)){
388 $error .= oai2_oai_error('idDoesNotExist', 'identifier', $identifier);
389 return false;
390 }
391
392 break;
393
394 case 'metadataPrefix':
395 $result = db_query("SELECT * FROM {oai2_metadata_formats} WHERE metadata_prefix='%s' ",$val);
396 if (db_num_rows($result)) {
397 $metadataPrefix = $val;
398 } else {
399 $error .= oai2_oai_error( 'cannotDisseminateFormat', $key, $val);
400 return false;
401 }
402
403 break;
404
405 default:
406 $error .= oai2_oai_error( 'badArgument', $key, $val);
407 return false;
408 }
409 }
410 $result = db_query("SELECT * FROM {oai2_metadata_formats} ");
411 if (db_num_rows($result)) {
412 $output .= " <ListMetadataFormats>\n";
413 while ($fmt = db_fetch_object($result)){
414 $output .= " <metadataFormat>\n";
415 $output .= oai2_xmlformat($fmt->metadata_prefix, 'metadataPrefix', '', 3);
416 $output .= oai2_xmlformat($fmt->schema, 'schema', '', 3);
417 $output .= oai2_xmlformat($fmt->metadata_namespace, 'metadataNamespace', '', 3);
418 $output .= " </metadataFormat>\n";
419 }
420 $output .= " </ListMetadataFormats>\n";
421
422 }else{
423 $error .= oai2_oai_error( 'noMetadataFormats');
424 return false;
425 }
426
427 return $output;
428 }
429 /**
430 * Lists Identifiers or Records based on the value of listrec
431 *
432 * @param $args
433 * the arguments passed with the oai verb
434 *
435 * @param $listrec
436 * if false (or not supplied) function will list identifiers
437 * if true function will list records
438 *
439 */
440 function oai2_list_id_rec( $args, $listrec=false){
441 global $error;
442
443 $query_args = array();
444 $MAXIDS = 20;
445 $tokenValid = 24*3600;
446 $expirationdatetime = gmstrftime('%Y-%m-%dT%TZ', time()+$tokenValid);
447 foreach($args as $key => $val) {
448 switch ($key) {
449 case 'from':
450 if (!isset($from)) {
451 $from = $val;
452 } else {
453 $error .= oai2_oai_error( 'badArgument', $key, $val);
454 return false;
455 }
456 break;
457
458 case 'until':
459 if (!isset($until)) {
460 $until = $val;
461 } else {
462 $error .= oai2_oai_error('badArgument', $key, $val);
463 return false;
464 }
465 break;
466
467 case 'set':
468 if (!isset($set)) {
469 $set = $val;
470 } else {
471 $error .= oai2_oai_error('badArgument', $key, $val);
472 return false;
473 }
474 break;
475
476 case 'metadataPrefix':
477 if (!isset($metadataPrefix)){
478 $result = db_query("SELECT * FROM {oai2_metadata_formats} WHERE metadata_prefix='%s' ",$val);
479 if (db_num_rows($result) && !isset($metadataPrefix) ){
480 $metadataPrefix = $val;
481 } else {
482 $error .= oai2_oai_error( 'cannotDisseminateFormat', $key, $val);
483 return false;
484 }
485 }else{
486 $error .= oai2_oai_error('badArgument', $key, $val);
487 return false;
488 }
489 break;
490
491 case 'resumptionToken':
492 if (!isset($resumptionToken)) {
493 $resumptionToken = $val;
494 } else {
495 $error .= oai2_oai_error('badArgument', $key, $val);
496 return false;
497 }
498 break;
499
500 default:
501 $error .= oai2_oai_error('badArgument', $key, $val);
502 return false;
503 }
504 }
505 // Resume previous session?
506 if (isset($args['resumptionToken'])) {
507 if (count($args) > 1) {
508 // overwrite all other errors
509 $error .= oai2_oai_error( 'exclusiveArgument');
510 return false;
511 } else {
512 $result = db_query("SELECT * FROM {oai2_tokens} WHERE id='%s' ",$resumptionToken);
513 if (db_num_rows($result)) {
514 $token = db_fetch_object($result);
515 $deliveredrecords = $token->deliveredrecords;
516 $extquery = $token->extquery;
517 $metadataPrefix = $token->metadata_prefix;
518 } else {
519 $error .= oai2_oai_error('badResumptionToken', '', $resumptionToken);
520 return false;
521 }
522 }
523 }
524 // no, new session
525 else {
526 $deliveredrecords = 0;
527 $extquery = '';
528
529 if (!isset($args['metadataPrefix'])) {
530 $error .= oai2_oai_error('missingArgument', 'metadataPrefix');
531 return false;
532 }
533
534 if (isset($args['from'])) {
535 if (!$fromgran = _checkDateFormat($from)) {
536 $error .= oai2_oai_error('badGranularity', 'from', $from);
537 return false;
538 }
539 $extquery .= ' AND changed >= %d';
540 $query_args[] = strtotime($from);
541 }
542
543 if (isset($args['until'])) {
544 if (!$untilgran = _checkDateFormat($until)) {
545 $error .= oai2_oai_error('badGranularity', 'until', $until);
546 return false;
547 }
548 $extquery .= ' AND changed <= %d';
549 $query_args[] = strtotime($until);
550 }
551
552 if (isset($args['set'])) {
553 $extquery .= " AND name LIKE '%s'";
554 $query_args[] = $set;
555 }
556 }
557 if((isset($fromgran) && isset($untilgran)) && ($fromgran != $untilgran) ) {
558 $error .= oai2_oai_error('badGranularity', 'mismatched Granularity', $until);
559 return false;
560 }
561 if ($listrec){ // list records...
562 $query = "SELECT * FROM {node} n
563 left join {biblio} b on n.vid=b.vid
564 left join {biblio_types} t on b.biblio_type=t.tid
565 WHERE n.type='biblio' ";
566
567 }else{ // list identifiers...
568 $query = "SELECT n.nid, n.changed, t.name FROM {node} n
569 left join {biblio} b on n.vid=b.vid
570 left join {biblio_types} t on b.biblio_type=t.tid
571 WHERE n.type='biblio' ";
572 }
573 $query_count = "SELECT COUNT(*) FROM {node} n
574 left join {biblio} b on n.vid=b.vid
575 left join {biblio_types} t on b.biblio_type=t.tid
576 WHERE n.type='biblio' ";
577
578 $query .= $extquery;
579 $query_count .= $extquery;
580 $maxresult = db_query($query_count, $query_args);
581 $num_rows = array_pop(db_fetch_array($maxresult));
582 $result = db_query_range($query, $query_args,$deliveredrecords,$MAXIDS);
583 if (db_num_rows($result)) {
584 $output .= ($listrec)?" <ListRecords>\n":" <ListIdentifiers>\n";
585
586 // Will we need a ResumptionToken?
587 if ($num_rows - $deliveredrecords > $MAXIDS) {
588 $token = _get_token();
589 $qargs = implode("#",$query_args);
590 $thendeliveredrecords = (int)$deliveredrecords + $MAXIDS;
591 $query = "INSERT INTO {oai2_tokens} (id,deliveredrecords,extquery,queryargs)
592 VALUES ('%s',%d,'%s','%s')";
593 db_query($query,$token,$thendeliveredrecords,$extquery,$qargs);
594
595 $restoken .= '<resumptionToken expirationDate="'.$expirationdatetime.'" '.
596 ' completeListSize="'.$num_rows.'" '.
597 'cursor="'.$deliveredrecords.'" >'. $token;
598 $restoken .= "</resumptionToken>\n";
599 }
600 // Last delivery, return empty ResumptionToken
601 else {
602
603 $restoken .= '<resumptionToken completeListSize="'.$num_rows.'" '.
604 'cursor="'.$deliveredrecords.'" >';
605 $restoken .= "</resumptionToken>\n";
606 }
607
608 $maxrec = min($num_rows - $deliveredrecords, $MAXIDS);
609
610 $countrec = 0;
611
612 while ($countrec++ < $maxrec) {
613 $record = db_fetch_object($result);
614
615 $identifier = $oaiprefix.$record->nid;
616 // $datestamp = date("Y-m-d\TH:i:s\Z",$record->changed);
617 $datestamp = gmstrftime('%Y-%m-%dT%TZ',$record->changed);
618
619 // if (isset($record[$SQL['deleted']]) && ($record[$SQL['deleted']] == 'true') &&
620 // ($deletedRecord == 'transient' || $deletedRecord == 'persistent')) {
621 // $status_deleted = TRUE;
622 // } else {
623 $status_deleted = FALSE;
624 // }
625 if ($listrec){ // list records...
626 $output .= ' <record>'."\n";
627 }
628 $output .= ' <header>'."\n";
629 $output .= oai2_xmlformat($identifier, 'identifier', '', 4);
630 $output .= oai2_xmlformat($datestamp, 'datestamp', '', 4);
631 $setspec = str_replace(" ","_",strtolower($record->name));
632 $output .= oai2_xmlformat($setspec, 'setSpec', '', 4);
633 $output .= ' </header>'."\n";
634 if ($listrec){ // list records...
635 $output .= ' <metadata>'."\n";
636 $prefix = 'oai_dc';
637 $result2 = db_query("SELECT * FROM {oai2_metadata_formats} WHERE name='%s' ",$prefix);
638 if (db_num_rows($result2)) {
639 $format = db_fetch_object($result2);
640 $output .= " <$prefix";
641 if ($format->record_prefix){
642 $output .= ":$format->record_prefix ";
643 }
644 $output .= ' xmlns:'.$prefix.'="'.$format->metadata_namespace.'"';
645 if ($format->record_prefix && $format->record_namespace) {
646 $output .= ' xmlns:'.$format->record_prefix.'="'.$format->record_namespace.'"';
647 }
648 $output .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
649 $output .= ' xsi:schemaLocation="'.$format->metadata_namespace."\n". $format->schema.'" >';
650
651 $output .= _get_record_oai_dc($record );
652
653 $output .= " </$prefix";
654 if ($format->record_prefix){
655 $output .= ":$format->record_prefix ";
656 }
657 $output .= ">\n";
658 $output .= "</metadata>\n";
659 }
660 }
661 if ($listrec) $output .= ' </record>'."\n";
662
663 }
664 if (isset($restoken)) {
665 $output .= $restoken;
666 }
667 $output .= ($listrec)?" </ListRecords>\n":" </ListIdentifiers>\n";
668
669 }else{
670 $error .= oai2_oai_error('noRecordsMatch');
671 return false;
672 }
673
674
675 return $output;
676
677 }
678
679 function oai2_get_record( $args){
680 global $error;
681
682 foreach($args as $key => $val) {
683 switch ($key) {
684 case 'identifier':
685 $identifier = $val;
686 break;
687
688 case 'metadataPrefix':
689 $result = db_query("SELECT * FROM {oai2_metadata_formats} WHERE metadata_prefix='%s' ",$val);
690 if (db_num_rows($result)) {
691 $metadataPrefix = $val;
692 } else {
693 $error .= oai2_oai_error('cannotDisseminateFormat', $key, $val);
694 return false;
695 }
696
697 break;
698 default:
699 $error .= oai2_oai_error('badArgument', $key, $val);
700 return false;
701
702 }
703 }
704
705 if (!isset($args['identifier'])) {
706 $error .= oai2_oai_error('missingArgument', 'identifier');
707 return false;
708 }
709 if (!isset($args['metadataPrefix'])) {
710 $error .= oai2_oai_error('missingArgument', 'metadataPrefix');
711 return false;
712 }
713
714 // remove the OAI part to get the identifier
715 $id = str_replace($oaiprefix, '', $identifier);
716 if ($id == '') {
717 $error .= oai2_oai_error('idDoesNotExist', '', $identifier);
718 return false;
719 }
720
721 $query = "SELECT * FROM {node} n
722 left join {biblio} b on n.nid=b.nid
723 left join {biblio_types} t on b.biblio_type=t.tid
724 WHERE n.nid=%d ";
725 $result = db_query(db_rewrite_sql($query),$id);
726 if (!db_num_rows($result)) {
727 $error .= oai2_oai_error('idDoesNotExist', '', $identifier);
728 return false;
729 }else{
730 $record = db_fetch_object($result);
731 }
732 $output .= " <GetRecord>\n";
733
734 $identifier = $oaiprefix.$record->nid;
735 // $datestamp = date("Y-m-d\TH:i:s\Z",$record->changed);
736 $datestamp = gmstrftime('%Y-%m-%dT%TZ',$record->changed);
737 // if (isset($record[$SQL['deleted']]) && ($record[$SQL['deleted']] == 'true') &&
738 // ($deletedRecord == 'transient' || $deletedRecord == 'persistent')) {
739 // $status_deleted = TRUE;
740 // } else {
741 $status_deleted = FALSE;
742 // }
743
744 $output .= ' <record>'."\n";
745 $output .= ' <header';
746 if ($status_deleted) {
747 $output .= ' status="deleted"';
748 }
749 $output .='>'."\n";
750 $output .= oai2_xmlformat($identifier, 'identifier', '', 4);
751 $output .= oai2_xmlformat($datestamp, 'datestamp', '', 4);
752 $setspec = str_replace(" ","_",strtolower($record->name));
753 $output .= oai2_xmlformat($setspec, 'setSpec', '', 4);
754 $output .= ' </header>'."\n";
755
756 $output .= ' <metadata>'."\n";
757 $prefix = 'oai_dc';
758 $result = db_query("SELECT * FROM {oai2_metadata_formats} WHERE name='%s' ",$prefix);
759 if (db_num_rows($result)) {
760 $format = db_fetch_object($result);
761 $output .= " <$prefix";
762 if ($format->record_prefix){
763 $output .= ":$format->record_prefix ";
764 }
765 $output .= 'xmlns:'.$prefix.'="'.$format->metadata_namespace.'"';
766 if ($format->record_prefix && $format->record_namespace) {
767 $output .= ' xmlns:'.$format->record_prefix.'="'.$format->record_namespace.'" ';
768 }
769 $output .= ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
770 $output .= ' xsi:schemaLocation="'.$format->metadata_namespace."\n". $format->schema.'" >';
771
772 $output .= _get_record_oai_dc($record );
773
774 $output .= " </$prefix";
775 if ($format->record_prefix){
776 $output .= ":$format->record_prefix ";
777 }
778 $output .= ">\n";
779 $output .= "</metadata>\n";
780 }
781 $output .= "</record>";
782 $output .= ' </GetRecord>'."\n";
783
784 return $output;
785
786 }
787
788 function _get_record_oai_dc($record ){
789 global $base_url;
790
791 $indent = 6;
792 $output .= oai2_xmlformat($record->title, 'dc:title', '', $indent);
793 $author_array = explode(";", $record->biblio_authors);
794 foreach($author_array as $auth) {
795 $output .= oai2_xmlformat(trim($auth), 'dc:creator', '', $indent);
796 }
797 $output .= oai2_xmlformat($record->biblio_year, 'dc:date', '', $indent);
798 $output .= oai2_xmlformat("Text", 'dc:type', '', $indent);
799 $output .= oai2_xmlformat($record->biblio_lang, 'dc:language', '', $indent);
800 if ($record->biblio_keywords)
801 $output .= oai2_xmlformat($record->biblio_keywords, 'dc:subject', '', $indent);
802 if ($record->biblio_abst_e)
803 $output .= oai2_xmlformat($record->biblio_abst_e, 'dc:description', '', $indent);
804 if ($record->biblio_publisher)
805 $output .= oai2_xmlformat($record->biblio_publisher, 'dc:publisher', '', $indent);
806 if ($record->biblio_url)
807 $output .= oai2_xmlformat($record->biblio_url, 'dc:identifier', '', $indent);
808 if ($record->biblio_isbn){
809 $output .= oai2_xmlformat($record->isbn, 'dc:identifier', '', $indent);
810 }else{
811 $output .= oai2_xmlformat($base_url."/node/".$record->nid, 'dc:identifier', '', $indent);
812 }
813 if ($record->biblio_corp_author)
814 $output .= oai2_xmlformat($record->biblio_corp_author, 'dc:contributor', '', $indent);
815
816 /* The following dc elements are currently not published...
817
818 $output .= xmlrecord($record['dc_format'], 'dc:format', '', $indent);
819 $output .= xmlrecord($record['dc_source'], 'dc:source', '', $indent);
820 $output .= xmlrecord($record['dc_relation'], 'dc:relation', '', $indent);
821 $output .= xmlrecord($record['dc_coverage'], 'dc:coverage', '', $indent);
822 $output .= xmlrecord($record['dc_rights'], 'dc:rights', '', $indent);
823 */
824
825 return $output;
826 }
827
828 function _get_token() {
829 //list($usec, $sec) = explode(" ", microtime());
830 return uniqid(); //(int)$sec + floor($usec*1000);//+ ;floor($usec*10000)
831 }
832
833 function _checkDateFormat($date) {
834
835 // global $granularity;
836 global $message;
837 // $granularity = variable_get('granularity', 'YYYY-MM-DDThh:mm:ssZ');
838 // if ($granularity == 'YYYY-MM-DDThh:mm:ssZ') {
839 $checkstr1 = '([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})T([0-9]{2}):([0-9]{2}):([0-9]{2})Z$';
840 // } else {
841 $checkstr2 = '([0-9]{4})-([0-9]{1,2})-([0-9]{1,2}$)';
842 // }
843 if (ereg($checkstr1, $date, $regs)) {
844 if (checkdate($regs[2], $regs[3], $regs[1])) {
845 return 1;
846 }
847 } elseif (ereg($checkstr2, $date, $regs)) {
848 if (checkdate($regs[2], $regs[3], $regs[1])) {
849 return 2;
850 }
851 } else {
852 $message = "Invalid Date: $date is not a valid date.";
853 return 0;
854 }
855 // else {
856 // $message = "Invalid Date Format: $date does not comply to the date format $granularity.";
857 // return 0;
858 // }
859 }
860
861
862 function oai2_oai_error($code, $argument='', $value='')
863 {
864 global $compress;
865
866 switch ($code) {
867 case 'badArgument' :
868 $text = "The argument $argument (value=$value) included in the request is not valid.";
869 break;
870
871 case 'badGranularity' :
872 $text = "The value $value of the argument '$argument' is not valid.";
873 $code = 'badArgument';
874 break;
875
876 case 'badResumptionToken' :
877 $text = "The resumptionToken $value does not exist or has already expired.";
878 break;
879
880 case 'badRequestMethod' :
881 $text = "The request method $argument is unknown.";
882 $code = 'badVerb';
883 break;
884
885 case 'badVerb' :
886 $text = "The verb $argument provided in the request is illegal.";
887 break;
888
889 case 'cannotDisseminateFormat' :
890 $text = "The metadata format $value given by $argument is not supported by this repository.";
891 break;
892
893 case 'exclusiveArgument' :
894 $text = 'The usage of resumptionToken as an argument allows no other arguments.';
895 $code = 'badArgument';
896 break;
897
898 case 'idDoesNotExist' :
899 $text = "The value $value of the identifier is illegal for this repository.";
900 break;
901
902 case 'missingArgument' :
903 $text = "The required argument $argument is missing in the request.";
904 $code = 'badArgument';
905 break;
906
907 case 'noRecordsMatch' :
908 $text = 'The combination of the given values results in an empty list.';
909 break;
910
911 case 'noMetadataFormats' :
912 $text = 'There are no metadata formats available for the specified item.';
913 break;
914
915 case 'noVerb' :
916 $text = 'The request does not provide any verb.';
917 $code = 'badVerb';
918 break;
919
920 case 'noSetHierarchy' :
921 $text = 'This repository does not support sets.';
922 break;
923
924 case 'sameArgument' :
925 $text = 'Do not use them same argument more than once.';
926 $code = 'badArgument';
927 break;
928
929 case 'sameVerb' :
930 $text = 'Do not use verb more than once.';
931 $code = 'badVerb';
932 break;
933
934 default:
935 $text = "Unknown error: code: $code, argument: $argument, value: $value";
936 $code = 'badArgument';
937 }
938
939 $error = ' <error code="'.oai2_xmlstr($code, 'iso8859-1', false).'">'.oai2_xmlstr($text, 'iso8859-1', false)."</error>\n";
940 return $error;
941 }
942 function oai2_xmlstr($string, $charset = 'iso8859-1', $xmlescaped = 'false')
943 {
944 $xmlstr = stripslashes(trim($string));
945 // just remove invalid characters
946 $pattern ="/[\x-\x8\xb-\xc\xe-\x1f]/";
947 $xmlstr = preg_replace($pattern, '', $xmlstr);
948
949 // escape only if string is not escaped
950 if (!$xmlescaped) {
951 $xmlstr = htmlspecialchars($xmlstr, ENT_QUOTES);
952 }
953
954 // if ($charset != "utf-8") {
955 // $xmlstr = utf8_encode($xmlstr);
956 // }
957
958 return $xmlstr;
959 }
960 function oai2_xmlformat($record, $element, $attr = '', $indent = 0)
961 {
962 global $charset;
963 global $xmlescaped;
964
965 if ($attr != '') {
966 $attr = ' '.$attr;
967 }
968
969 $str = '';
970 if (is_array($record)) {
971 foreach ($record as $val) {
972 $str .= str_pad('', $indent).'<'.$element.$attr.'>'.oai2_xmlstr($val, $charset, $xmlescaped).'</'.$element.">\n";
973 }
974 return $str;
975 } elseif ($record != '') {
976 return str_pad('', $indent).'<'.$element.$attr.'>'.oai2_xmlstr($record, $charset, $xmlescaped).'</'.$element.">\n";
977 } else {
978 return '';
979 }
980 }

  ViewVC Help
Powered by ViewVC 1.1.2