Open Journal Systems  3.3.0
OAI.inc.php
1 <?php
2 
24 import('lib.pkp.classes.oai.OAIStruct');
25 import('lib.pkp.classes.oai.OAIUtils');
26 
27 abstract class OAI {
29  var $config;
30 
32  var $params;
33 
35  var $protocolVersion = '2.0';
36 
37 
43  function __construct($config) {
44  $this->config = $config;
45 
46  // Initialize parameters from GET or POST variables
47  $this->params = array();
48 
49  if (isset($GLOBALS['HTTP_RAW_POST_DATA']) && !empty($GLOBALS['HTTP_RAW_POST_DATA'])) {
50  OAIUtils::parseStr($GLOBALS['HTTP_RAW_POST_DATA'], $this->params);
51 
52  } else if (!empty($_SERVER['QUERY_STRING'])) {
53  OAIUtils::parseStr($_SERVER['QUERY_STRING'], $this->params);
54 
55  } else {
56  $this->params = array_merge($_GET, $_POST);
57  }
58 
59  // Clean input variables
60  OAIUtils::prepInput($this->params);
61 
62  // Encode data with gzip, deflate, or none, depending on browser support
63  ob_start('ob_gzhandler');
64  }
65 
70  function execute() {
71  switch ($this->getParam('verb')) {
72  case 'GetRecord':
73  $this->GetRecord();
74  break;
75  case 'Identify':
76  $this->Identify();
77  break;
78  case 'ListIdentifiers':
79  $this->ListIdentifiers();
80  break;
81  case 'ListMetadataFormats':
82  $this->ListMetadataFormats();
83  break;
84  case 'ListRecords':
85  $this->ListRecords();
86  break;
87  case 'ListSets':
88  $this->ListSets();
89  break;
90  default:
91  $this->error('badVerb', 'Illegal OAI verb');
92  break;
93  }
94  }
95 
96 
97  //
98  // Abstract implementation-specific functions
99  // (to be overridden in subclass)
100  //
101 
106  abstract function repositoryInfo();
107 
113  function validIdentifier($identifier) {
114  return false;
115  }
116 
122  function identifierExists($identifier) {
123  return false;
124  }
125 
131  abstract function record($identifier);
132 
144  function records($metadataPrefix, $from, $until, $set, $offset, $limit, &$total) {
145  return array();
146  }
147 
153  function identifiers($metadataPrefix, $from, $until, $set, $offset, $limit, &$total) {
154  return array();
155  }
156 
163  function sets($offset, $limit, &$total) {
164  return array();
165  }
166 
172  abstract function resumptionToken($tokenId);
173 
180  abstract function saveResumptionToken($offset, $params);
181 
188  function metadataFormats($namesOnly = false, $identifier = null) {
189  $formats = array();
190  HookRegistry::call('OAI::metadataFormats', array($namesOnly, $identifier, &$formats));
191 
192  return $formats;
193  }
194 
195  //
196  // Protocol request handlers
197  //
198 
203  function GetRecord() {
204  // Validate parameters
205  if (!$this->checkParams(array('identifier', 'metadataPrefix'))) {
206  return;
207  }
208 
209  $identifier = $this->getParam('identifier');
210  $metadataPrefix = $this->getParam('metadataPrefix');
211 
212  // Check that identifier is in valid format
213  if ($this->validIdentifier($identifier) === false) {
214  $this->error('badArgument', 'Identifier is not in a valid format');
215  return;
216  }
217 
218  // Get metadata for requested identifier
219  if (($record = $this->record($identifier)) === false) {
220  $this->error('idDoesNotExist', 'No matching identifier in this repository');
221  return;
222  }
223 
224  // Check that the requested metadata format is supported for this identifier
225  if (!in_array($metadataPrefix, $this->metadataFormats(true, $identifier))) {
226  $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
227  return;
228  }
229 
230  // Display response
231  $response = "\t<GetRecord>\n" .
232  "\t\t<record>\n" .
233  "\t\t\t<header" .(($record->status == OAIRECORD_STATUS_DELETED)?" status=\"deleted\">\n":">\n") .
234  "\t\t\t\t<identifier>" . $record->identifier ."</identifier>\n" .
235  "\t\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
236  // Output set memberships
237  foreach ($record->sets as $setSpec) {
238  $response .= "\t\t\t\t<setSpec>$setSpec</setSpec>\n";
239  }
240  $response .= "\t\t\t</header>\n";
241  if (!empty($record->data)) {
242  $response .= "\t\t\t<metadata>\n";
243  // Output metadata
244  $response .= $this->formatMetadata($metadataPrefix, $record);
245  $response .= "\t\t\t</metadata>\n";
246  }
247  $response .= "\t\t</record>\n" .
248  "\t</GetRecord>\n";
249 
250  $this->response($response);
251  }
252 
253 
258  function Identify() {
259  // Validate parameters
260  if (!$this->checkParams()) {
261  return;
262  }
263 
264  $info = $this->repositoryInfo();
265 
266  // Format body of response
267  $response = "\t<Identify>\n" .
268  "\t\t<repositoryName>" . OAIUtils::prepOutput($info->repositoryName) . "</repositoryName>\n" .
269  "\t\t<baseURL>" . $this->config->baseUrl . "</baseURL>\n" .
270  "\t\t<protocolVersion>" . $this->protocolVersion . "</protocolVersion>\n" .
271  "\t\t<adminEmail>" . $info->adminEmail . "</adminEmail>\n" .
272  "\t\t<earliestDatestamp>" . OAIUtils::UTCDate($info->earliestDatestamp) . "</earliestDatestamp>\n" .
273  "\t\t<deletedRecord>persistent</deletedRecord>\n" .
274  "\t\t<granularity>" . $this->config->granularity . "</granularity>\n";
275  if (extension_loaded('zlib')) {
276  // Show compression options if server supports Zlib
277  $response .= "\t\t<compression>gzip</compression>\n" .
278  "\t\t<compression>deflate</compression>\n";
279  }
280  $response .= "\t\t<description>\n" .
281  "\t\t\t<oai-identifier\n" .
282  "\t\t\t\txmlns=\"http://www.openarchives.org/OAI/2.0/oai-identifier\"\n" .
283  "\t\t\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
284  "\t\t\t\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai-identifier\n" .
285  "\t\t\t\t\thttp://www.openarchives.org/OAI/2.0/oai-identifier.xsd\">\n" .
286  "\t\t\t\t<scheme>oai</scheme>\n" .
287  "\t\t\t\t<repositoryIdentifier>" . $this->config->repositoryId . "</repositoryIdentifier>\n" .
288  "\t\t\t\t<delimiter>" . $info->delimiter . "</delimiter>\n" .
289  "\t\t\t\t<sampleIdentifier>" . $info->sampleIdentifier . "</sampleIdentifier>\n" .
290  "\t\t\t</oai-identifier>\n" .
291  "\t\t</description>\n";
292  $response .= "\t\t<description>\n" .
293  "\t\t\t<toolkit\n" .
294  "\t\t\t\txmlns=\"http://oai.dlib.vt.edu/OAI/metadata/toolkit\"\n" .
295  "\t\t\t\txsi:schemaLocation=\"http://oai.dlib.vt.edu/OAI/metadata/toolkit\n" .
296  "\t\t\t\t\thttp://oai.dlib.vt.edu/OAI/metadata/toolkit.xsd\">\n" .
297  "\t\t\t\t<title>" . $info->toolkitTitle . "</title>\n" .
298  "\t\t\t\t<author>\n" .
299  "\t\t\t\t\t<name>Public Knowledge Project</name>\n" .
300  "\t\t\t\t\t<email>pkp.contact@gmail.com</email>\n" .
301  "\t\t\t\t</author>\n" .
302  "\t\t\t\t<version>" . $info->toolkitVersion . "</version>\n" .
303  "\t\t\t\t<URL>" . $info->toolkitURL . "</URL>\n" .
304  "\t\t\t</toolkit>\n" .
305  "\t\t</description>\n";
306  $response .= "\t</Identify>\n";
307 
308  $this->response($response);
309  }
310 
315  function ListIdentifiers() {
316  $offset = 0;
317 
318  // Check for resumption token
319  if ($this->paramExists('resumptionToken')) {
320  // Validate parameters
321  if (!$this->checkParams(array('resumptionToken'))) {
322  return;
323  }
324 
325  // Get parameters from resumption token
326  if (($token = $this->resumptionToken($this->getParam('resumptionToken'))) === false) {
327  $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
328  return;
329  }
330 
331  $this->setParams($token->params);
332  $offset = $token->offset;
333  }
334 
335  // Validate parameters
336  if (!$this->checkParams(array('metadataPrefix'), array('from', 'until', 'set'))) {
337  return;
338  }
339 
340  $metadataPrefix = $this->getParam('metadataPrefix');
341  $set = $this->getParam('set');
342 
343  // Check that the requested metadata format is supported
344  if (!in_array($metadataPrefix, $this->metadataFormats(true))) {
345  $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
346  return;
347  }
348 
349  // If a set was passed in check if repository supports sets
350  if (isset($set) && $this->config->maxSets == 0) {
351  $this->error('noSetHierarchy', 'This repository does not support sets');
352  return;
353  }
354 
355  // Get UNIX timestamps for from and until dates, if applicable
356  if (!$this->extractDateParams($this->getParams(), $from, $until)) {
357  return;
358  }
359 
360  // Store current offset and total records for resumption token, if needed
361  $cursor = $offset;
362  $total = 0;
363 
364  // Get list of matching identifiers
365  $records = $this->identifiers($metadataPrefix, $from, $until, $set, $offset, $this->config->maxIdentifiers, $total);
366  if (empty($records)) {
367  $this->error('noRecordsMatch', 'No matching records in this repository');
368  return;
369  }
370 
371  // Format body of response
372  $response = "\t<ListIdentifiers>\n";
373 
374  // Output identifiers
375  for ($i = 0, $num = count($records); $i < $num; $i++) {
376  $record = $records[$i];
377  $response .= "\t\t<header" .(($record->status == OAIRECORD_STATUS_DELETED)?" status=\"deleted\">\n":">\n") .
378  "\t\t\t<identifier>" . $record->identifier . "</identifier>\n" .
379  "\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
380  // Output set memberships
381  foreach ($record->sets as $setSpec) {
382  $response .= "\t\t\t<setSpec>" . OAIUtils::prepOutput($setSpec) . "</setSpec>\n";
383  }
384  $response .= "\t\t</header>\n";
385  }
386  $offset += $num;
387 
388  if ($offset != 0 && $offset < $total) {
389  // Partial result, save resumption token
390  $token = $this->saveResumptionToken($offset, $this->getParams());
391 
392  $response .= "\t\t<resumptionToken expirationDate=\"" . OAIUtils::UTCDate($token->expire) . "\"\n" .
393  "\t\t\tcompleteListSize=\"$total\"\n" .
394  "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
395 
396  } else if (isset($token)) {
397  // Current request completes a previous incomplete list, add empty resumption token
398  $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
399  }
400 
401  $response .= "\t</ListIdentifiers>\n";
402 
403  $this->response($response);
404  }
405 
410  function ListMetadataFormats() {
411  // Validate parameters
412  if (!$this->checkParams(array(), array('identifier'))) {
413  return;
414  }
415 
416  // Get list of metadata formats for selected identifier, or all formats if no identifier was passed
417  if ($this->paramExists('identifier')) {
418  if (!$this->identifierExists($this->getParam('identifier'))) {
419  $this->error('idDoesNotExist', 'No matching identifier in this repository');
420  return;
421 
422  } else {
423  $formats = $this->metadataFormats(false, $this->getParam('identifier'));
424  }
425 
426  } else {
427  $formats = $this->metadataFormats();
428  }
429 
430  if (empty($formats) || !is_array($formats)) {
431  $this->error('noMetadataFormats', 'No metadata formats are available');
432  return;
433  }
434 
435  // Format body of response
436  $response = "\t<ListMetadataFormats>\n";
437 
438  // output metadata formats
439  foreach ($formats as $format) {
440  $response .= "\t\t<metadataFormat>\n" .
441  "\t\t\t<metadataPrefix>" . $format->prefix . "</metadataPrefix>\n" .
442  "\t\t\t<schema>" . $format->schema . "</schema>\n" .
443  "\t\t\t<metadataNamespace>" . $format->namespace . "</metadataNamespace>\n" .
444  "\t\t</metadataFormat>\n";
445  }
446 
447  $response .= "\t</ListMetadataFormats>\n";
448 
449  $this->response($response);
450  }
451 
456  function ListRecords() {
457  $offset = 0;
458 
459  // Check for resumption token
460  if ($this->paramExists('resumptionToken')) {
461  // Validate parameters
462  if (!$this->checkParams(array('resumptionToken'))) {
463  return;
464  }
465 
466  // get parameters from resumption token
467  if (($token = $this->resumptionToken($this->getParam('resumptionToken'))) === false) {
468  $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
469  return;
470  }
471 
472  $this->setParams($token->params);
473  $offset = $token->offset;
474 
475  }
476 
477  // Validate parameters
478  if (!$this->checkParams(array('metadataPrefix'), array('from', 'until', 'set'))) {
479  return;
480  }
481 
482  $metadataPrefix = $this->getParam('metadataPrefix');
483  $set = $this->getParam('set');
484 
485  // Check that the requested metadata format is supported
486  if (!in_array($metadataPrefix, $this->metadataFormats(true))) {
487  $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
488  return;
489  }
490 
491  // If a set was passed check if repository supports sets
492  if (isset($set) && $this->config->maxSets == 0) {
493  $this->error('noSetHierarchy', 'This repository does not support sets');
494  return;
495  }
496 
497  // Get UNIX timestamps for from and until dates, if applicable
498  if (!$this->extractDateParams($this->getParams(), $from, $until)) {
499  return;
500  }
501 
502  // Store current offset and total records for resumption token, if needed
503  $cursor = $offset;
504  $total = 0;
505 
506  // Get list of matching records
507  $records = $this->records($metadataPrefix, $from, $until, $set, $offset, $this->config->maxRecords, $total);
508  if (empty($records)) {
509  $this->error('noRecordsMatch', 'No matching records in this repository');
510  return;
511  }
512 
513  // Format body of response
514  $response = "\t<ListRecords>\n";
515 
516  // Output records
517  for ($i = 0, $num = count($records); $i < $num; $i++) {
518  $record = $records[$i];
519  $response .= "\t\t<record>\n" .
520  "\t\t\t<header" .(($record->status == OAIRECORD_STATUS_DELETED)?" status=\"deleted\">\n":">\n") .
521  "\t\t\t\t<identifier>" . $record->identifier . "</identifier>\n" .
522  "\t\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
523  // Output set memberships
524  foreach ($record->sets as $setSpec) {
525  $response .= "\t\t\t\t<setSpec>" . OAIUtils::prepOutput($setSpec) . "</setSpec>\n";
526  }
527  $response .= "\t\t\t</header>\n";
528  if (!empty($record->data)) {
529  $response .= "\t\t\t<metadata>\n";
530  // Output metadata
531  $response .= $this->formatMetadata($this->getParam('metadataPrefix'), $record);
532  $response .= "\t\t\t</metadata>\n";
533  }
534  $response .= "\t\t</record>\n";
535  }
536  $offset += $num;
537 
538  if ($offset != 0 && $offset < $total) {
539  // Partial result, save resumption token
540  $token = $this->saveResumptionToken($offset, $this->getParams());
541 
542  $response .= "\t\t<resumptionToken expirationDate=\"" . OAIUtils::UTCDate($token->expire) . "\"\n" .
543  "\t\t\tcompleteListSize=\"$total\"\n" .
544  "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
545 
546  } else if(isset($token)) {
547  // Current request completes a previous incomplete list, add empty resumption token
548  $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
549  }
550 
551  $response .= "\t</ListRecords>\n";
552 
553  $this->response($response);
554  }
555 
560  function ListSets() {
561  $offset = 0;
562 
563  // Check for resumption token
564  if ($this->paramExists('resumptionToken')) {
565  // Validate parameters
566  if (!$this->checkParams(array('resumptionToken'))) {
567  return;
568  }
569 
570  // Get parameters from resumption token
571  if (($token = $this->resumptionToken($this->getParam('resumptionToken'))) === false) {
572  $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
573  return;
574  }
575 
576  $this->setParams($token->params);
577  $offset = $token->offset;
578 
579  }
580 
581  // Validate parameters
582  if (!$this->checkParams()) {
583  return;
584  }
585 
586  // Store current offset and total sets for resumption token, if needed
587  $cursor = $offset;
588  $total = 0;
589 
590  // Get list of matching sets
591  $sets = $this->sets($offset, $this->config->maxRecords, $total);
592  if (empty($sets)) {
593  $this->error('noSetHierarchy', 'This repository does not support sets');
594  return;
595  }
596 
597  // Format body of response
598  $response = "\t<ListSets>\n";
599 
600  // Output sets
601  for ($i = 0, $num = count($sets); $i < $num; $i++) {
602  $set = $sets[$i];
603  $response .= "\t\t<set>\n" .
604  "\t\t\t<setSpec>" . OAIUtils::prepOutput($set->spec) . "</setSpec>\n" .
605  "\t\t\t<setName>" . OAIUtils::prepOutput($set->name) . "</setName>\n";
606  // output set description, if applicable
607  if (isset($set->description)) {
608  $response .= "\t\t\t<setDescription>\n" .
609  "\t\t\t\t<oai_dc:dc\n" .
610  "\t\t\t\t\txmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"\n" .
611  "\t\t\t\t\txmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" .
612  "\t\t\t\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
613  "\t\t\t\t\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/\n" .
614  "\t\t\t\t\t\thttp://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n" .
615  "\t\t\t\t\t<dc:description>" . OAIUtils::prepOutput($set->description) . "</dc:description>\n" .
616  "\t\t\t\t</oai_dc:dc>\n" .
617  "\t\t\t</setDescription>\n";
618 
619  }
620  $response .= "\t\t</set>\n";
621  }
622  $offset += $num;
623 
624  if ($offset != 0 && $offset < $total) {
625  // Partial result, set resumption token
626  $token = $this->saveResumptionToken($offset, $this->getParams());
627 
628  $response .= "\t\t<resumptionToken expirationDate=\"" . OAIUtils::UTCDate($token->expire) . "\"\n" .
629  "\t\t\tcompleteListSize=\"$total\"\n" .
630  "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
631 
632  } else if (isset($token)) {
633  // current request completes a previous incomplete list, add empty resumption token
634  $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
635  }
636 
637  $response .= "\t</ListSets>\n";
638 
639  $this->response($response);
640  }
641 
642 
643  //
644  // Private helper functions
645  //
646 
650  function error($code, $message) {
651  if (in_array($code, array('badVerb', 'badArgument'))) {
652  $printParams = false;
653 
654  } else {
655  $printParams = true;
656  }
657 
658  $this->response("\t<error code=\"$code\">$message</error>", $printParams);
659  }
660 
666  function response($response, $printParams = true) {
667  $request = Application::get()->getRequest();
668  header('Content-Type: text/xml');
669 
670  echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
671  "<?xml-stylesheet type=\"text/xsl\" href=\"" . $request->getBaseUrl() . "/lib/pkp/xml/oai2.xsl\" ?>\n" .
672  "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\"\n" .
673  "\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
674  "\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/\n" .
675  "\t\thttp://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n" .
676  "\t<responseDate>" . OAIUtils::UTCDate() . "</responseDate>\n" .
677  "\t<request";
678 
679  // print request params, if applicable
680  if($printParams) {
681  foreach($this->params as $k => $v) {
682  echo " $k=\"" . OAIUtils::prepOutput($v) . "\"";
683  }
684  }
685 
686  echo ">" . OAIUtils::prepOutput($this->config->baseUrl) . "</request>\n" .
687  $response .
688  "</OAI-PMH>\n";
689  }
690 
696  function getParam($name) {
697  return isset($this->params[$name]) ? $this->params[$name] : null;
698  }
699 
704  function getParams() {
706  }
707 
712  function setParams($params) {
713  $this->params = $params;
714  }
715 
721  function paramExists($name) {
722  return isset($this->params[$name]);
723  }
724 
729  function getNonPathInfoParams() {
730  return array();
731  }
732 
740  function checkParams($required = array(), $optional = array()) {
741  // Get allowed parameters for current request
742  $requiredParams = array_merge(array('verb'), $required);
743  $validParams = array_merge($requiredParams, $optional);
744 
745  // Check for missing or duplicate required parameters
746  foreach ($requiredParams as $k) {
747  if(!$this->paramExists($k)) {
748  $this->error('badArgument', "Missing $k parameter");
749  return false;
750 
751  } else if (is_array($this->getParam($k))) {
752  $this->error('badArgument', "Multiple values are not allowed for the $k parameter");
753  return false;
754  }
755  }
756 
757  // Check for duplicate optional parameters
758  foreach ($optional as $k) {
759  if ($this->paramExists($k) && is_array($this->getParam($k))) {
760  $this->error('badArgument', "Multiple values are not allowed for the $k parameter");
761  return false;
762  }
763  }
764 
765  // Check for illegal parameters
766  $request = Application::get()->getRequest();
767  foreach ($this->params as $k => $v) {
768  if (!in_array($k, $validParams)) {
769  // Ignore the "path" and "context" parameters if path_info is disabled.
770  if ($request->isPathInfoEnabled() || !in_array($k, $this->getNonPathInfoParams())) {
771  $this->error('badArgument', "$k is an illegal parameter");
772  return false;
773  }
774  }
775  }
776 
777  return true;
778  }
779 
786  function formatMetadata($format, $record) {
787  $formats = $this->metadataFormats();
788  $metadata = $formats[$format]->toXml($record);
789  return $metadata;
790  }
791 
800  function extractDateParams($params, &$from, &$until) {
801  if (isset($params['from'])) {
802  $from = OAIUtils::UTCtoTimestamp($params['from'], $this->config->granularity);
803 
804  if ($from == 'invalid') {
805  $this->error('badArgument', 'Illegal from parameter');
806  return false;
807 
808  } else if($from == 'invalid_granularity') {
809  $this->error('badArgument', 'Illegal granularity for from parameter');
810  return false;
811  }
812  }
813 
814  if(isset($params['until'])) {
815  $until = OAIUtils::UTCtoTimestamp($params['until'], $this->config->granularity);
816 
817  if($until == 'invalid') {
818  $this->error('badArgument', 'Illegal until parameter');
819  return false;
820 
821  } else if($until == 'invalid_granularity') {
822  $this->error('badArgument', 'Illegal granularity for until parameter');
823  return false;
824  }
825 
826  // Check that until value is greater than or equal to from value
827  if (isset($from) && $from > $until) {
828  $this->error('badArgument', 'until parameter must be greater than or equal to from parameter');
829  return false;
830  }
831 
832  // Check that granularities are equal
833  if (isset($from) && strlen($params['from']) != strlen($params['until'])) {
834  $this->error('badArgument', 'until and from parameters must be of the same granularity');
835  return false;
836  }
837 
838  if (strlen($params['until']) == 10) {
839  // Until date is inclusive
840  $until += 86399;
841  }
842  }
843 
844  return true;
845  }
846 }
847 
848 
OAI\extractDateParams
extractDateParams($params, &$from, &$until)
Definition: OAI.inc.php:809
OAI\response
response($response, $printParams=true)
Definition: OAI.inc.php:675
OAI\repositoryInfo
repositoryInfo()
OAIUtils\parseStr
static parseStr($string, &$array)
Definition: OAIUtils.inc.php:123
OAI\formatMetadata
formatMetadata($format, $record)
Definition: OAI.inc.php:795
OAI\GetRecord
GetRecord()
Definition: OAI.inc.php:212
OAI\ListIdentifiers
ListIdentifiers()
Definition: OAI.inc.php:324
OAIUtils\prepInput
static prepInput(&$data)
Definition: OAIUtils.inc.php:77
OAI\$params
$params
Definition: OAI.inc.php:38
OAI\resumptionToken
resumptionToken($tokenId)
OAI\Identify
Identify()
Definition: OAI.inc.php:267
OAI\$protocolVersion
$protocolVersion
Definition: OAI.inc.php:44
OAI\execute
execute()
Definition: OAI.inc.php:79
OAIUtils\UTCDate
static UTCDate($timestamp=0, $includeTime=true)
Definition: OAIUtils.inc.php:26
OAIUtils\prepOutput
static prepOutput(&$data)
Definition: OAIUtils.inc.php:99
OAIUtils\UTCtoTimestamp
static UTCtoTimestamp($date, $requiredGranularity=null)
Definition: OAIUtils.inc.php:48
OAI\record
record($identifier)
OAI\records
records($metadataPrefix, $from, $until, $set, $offset, $limit, &$total)
Definition: OAI.inc.php:153
OAI\metadataFormats
metadataFormats($namesOnly=false, $identifier=null)
Definition: OAI.inc.php:197
Seboettg\Collection\count
count()
Definition: ArrayListTrait.php:253
OAI\ListSets
ListSets()
Definition: OAI.inc.php:569
OAI\identifiers
identifiers($metadataPrefix, $from, $until, $set, $offset, $limit, &$total)
Definition: OAI.inc.php:162
OAI\setParams
setParams($params)
Definition: OAI.inc.php:721
OAI\ListRecords
ListRecords()
Definition: OAI.inc.php:465
$GLOBALS
$GLOBALS['PHPUNIT_COVERAGE_DATA_DIRECTORY']
Definition: prependCoverageReport.php:17
OAI\getParam
getParam($name)
Definition: OAI.inc.php:705
OAI\identifierExists
identifierExists($identifier)
Definition: OAI.inc.php:131
OAI\$config
$config
Definition: OAI.inc.php:32
OAI\getParams
getParams()
Definition: OAI.inc.php:713
OAI\ListMetadataFormats
ListMetadataFormats()
Definition: OAI.inc.php:419
OAI\getNonPathInfoParams
getNonPathInfoParams()
Definition: OAI.inc.php:738
OAI\error
error($code, $message)
Definition: OAI.inc.php:659
OAI\validIdentifier
validIdentifier($identifier)
Definition: OAI.inc.php:122
OAI\saveResumptionToken
saveResumptionToken($offset, $params)
OAI\sets
sets($offset, $limit, &$total)
Definition: OAI.inc.php:172
OAI
Class to process and respond to OAI requests.
Definition: OAI.inc.php:27
OAI\__construct
__construct($config)
Definition: OAI.inc.php:52
PKPApplication\get
static get()
Definition: PKPApplication.inc.php:235
OAI\paramExists
paramExists($name)
Definition: OAI.inc.php:730
HookRegistry\call
static call($hookName, $args=null)
Definition: HookRegistry.inc.php:86
OAI\checkParams
checkParams($required=array(), $optional=array())
Definition: OAI.inc.php:749