00001 <?php
00002
00020
00021
00022
00023 import('oai.OAIStruct');
00024
00025
00026 import('oai.format.OAIMetadataFormat_DC');
00027 import('oai.format.OAIMetadataFormat_MARC');
00028 import('oai.format.OAIMetadataFormat_MARC21');
00029 import('oai.format.OAIMetadataFormat_RFC1807');
00030
00031 class OAI {
00033 var $config;
00034
00036 var $params;
00037
00039 var $protocolVersion = '2.0';
00040
00041
00047 function OAI(&$config) {
00048 $this->config = $config;
00049
00050
00051 $this->params = array();
00052
00053 if (isset($GLOBALS['HTTP_RAW_POST_DATA']) && !empty($GLOBALS['HTTP_RAW_POST_DATA'])) {
00054 $this->parseStr($GLOBALS['HTTP_RAW_POST_DATA'], $this->params);
00055
00056 } else if (!empty($_SERVER['QUERY_STRING'])) {
00057 $this->parseStr($_SERVER['QUERY_STRING'], $this->params);
00058
00059 } else {
00060 $this->params = array_merge($_GET, $_POST);
00061 }
00062
00063
00064 $this->prepInput($this->params);
00065
00066
00067 ob_start('ob_gzhandler');
00068 }
00069
00074 function execute() {
00075 switch ($this->getParam('verb')) {
00076 case 'GetRecord':
00077 $this->GetRecord();
00078 break;
00079 case 'Identify':
00080 $this->Identify();
00081 break;
00082 case 'ListIdentifiers':
00083 $this->ListIdentifiers();
00084 break;
00085 case 'ListMetadataFormats':
00086 $this->ListMetadataFormats();
00087 break;
00088 case 'ListRecords':
00089 $this->ListRecords();
00090 break;
00091 case 'ListSets':
00092 $this->ListSets();
00093 break;
00094 default:
00095 $this->error('badVerb', 'Illegal OAI verb');
00096 break;
00097 }
00098 }
00099
00100
00101
00102
00103
00104
00105
00110 function &repositoryInfo() {
00111 $info = false;
00112 return $info;
00113 }
00114
00120 function validIdentifier($identifier) {
00121 return false;
00122 }
00123
00129 function identifierExists($identifier) {
00130 return false;
00131 }
00132
00138 function &record($identifier) {
00139 $record = false;
00140 return $record;
00141 }
00142
00154 function &records($metadataPrefix, $from, $until, $set, $offset, $limit, &$total) {
00155 $records = array();
00156 return $records;
00157 }
00158
00164 function &identifiers($metadataPrefix, $from, $until, $set, $offset, $limit, &$total) {
00165 $identifiers = array();
00166 return $identifiers;
00167 }
00168
00174 function &sets($offset, &$total) {
00175 $sets = array();
00176 return $sets;
00177 }
00178
00184 function &resumptionToken($tokenId) {
00185 $token = false;
00186 return $token;
00187 }
00188
00195 function &saveResumptionToken($offset, $params) {
00196 $token = null;
00197 return $token;
00198 }
00199
00206 function &metadataFormats($namesOnly = false, $identifier = null) {
00207 if ($namesOnly) {
00208 $formats = array('oai_dc', 'oai_marc', 'marcxml', 'rfc1807');
00209
00210 } else {
00211 $formats = array(
00212
00213 'oai_dc' => new OAIMetadataFormat_DC($this, 'oai_dc', 'http://www.openarchives.org/OAI/2.0/oai_dc.xsd', 'http://www.openarchives.org/OAI/2.0/oai_dc/'),
00214
00215
00216 'oai_marc' => new OAIMetadataFormat_MARC($this, 'oai_marc', "http://www.openarchives.org/OAI/1.1/oai_marc.xsd", "http://www.openarchives.org/OAI/1.1/oai_marc"),
00217
00218
00219 'marcxml' => new OAIMetadataFormat_MARC21($this, 'marcxml', "http://www.loc.gov/standards/marcxml/schema/MARC21slim.xsd", "http://www.loc.gov/MARC21/slim"),
00220
00221
00222 'rfc1807' => new OAIMetadataFormat_RFC1807($this, 'rfc1807', "http://www.openarchives.org/OAI/1.1/rfc1807.xsd", "http://info.internet.isi.edu:80/in-notes/rfc/files/rfc1807.txt")
00223 );
00224 }
00225 return $formats;
00226 }
00227
00228
00229
00230
00231
00232
00237 function GetRecord() {
00238
00239 if (!$this->checkParams(array('identifier', 'metadataPrefix'))) {
00240 return;
00241 }
00242
00243 $identifier = $this->getParam('identifier');
00244 $metadataPrefix = $this->getParam('metadataPrefix');
00245
00246
00247 if ($this->validIdentifier($identifier) === false) {
00248 $this->error('badArgument', 'Identifier is not in a valid format');
00249 return;
00250 }
00251
00252
00253 if (($record = &$this->record($identifier)) === false) {
00254 $this->error('idDoesNotExist', 'No matching identifier in this repository');
00255 return;
00256 }
00257
00258
00259 if (!in_array($metadataPrefix, $this->metadataFormats(true, $identifier))) {
00260 $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
00261 return;
00262 }
00263
00264
00265 $response = "\t<GetRecord>\n" .
00266 "\t\t<record>\n" .
00267 "\t\t\t<header>\n" .
00268 "\t\t\t\t<identifier>" . $record->identifier ."</identifier>\n" .
00269 "\t\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
00270
00271 foreach ($record->sets as $setSpec) {
00272 $response .= "\t\t\t\t<setSpec>$setSpec</setSpec>\n";
00273 }
00274 $response .= "\t\t\t</header>\n" .
00275 "\t\t\t<metadata>\n";
00276
00277 $response .= $this->formatMetadata($metadataPrefix, $record);
00278 $response .= "\t\t\t</metadata>\n" .
00279 "\t\t</record>\n" .
00280 "\t</GetRecord>\n";
00281
00282 $this->response($response);
00283 }
00284
00285
00290 function Identify() {
00291
00292 if (!$this->checkParams()) {
00293 return;
00294 }
00295
00296 $info = &$this->repositoryInfo();
00297
00298
00299 $response = "\t<Identify>\n" .
00300 "\t\t<repositoryName>" . $this->prepOutput($info->repositoryName) . "</repositoryName>\n" .
00301 "\t\t<baseURL>" . $this->config->baseUrl . "</baseURL>\n" .
00302 "\t\t<protocolVersion>" . $this->protocolVersion . "</protocolVersion>\n" .
00303 "\t\t<adminEmail>" . $info->adminEmail . "</adminEmail>\n" .
00304 "\t\t<earliestDatestamp>" . $this->UTCDate($info->earliestDatestamp) . "</earliestDatestamp>\n" .
00305 "\t\t<deletedRecord>no</deletedRecord>\n" .
00306 "\t\t<granularity>" . $this->config->granularity . "</granularity>\n";
00307 if (extension_loaded('zlib')) {
00308
00309 $response .= "\t\t<compression>gzip</compression>\n" .
00310 "\t\t<compression>deflate</compression>\n";
00311 }
00312 $response .= "\t\t<description>\n" .
00313 "\t\t\t<oai-identifier\n" .
00314 "\t\t\t\txmlns=\"http://www.openarchives.org/OAI/2.0/oai-identifier\"\n" .
00315 "\t\t\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
00316 "\t\t\t\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai-identifier\n" .
00317 "\t\t\t\t\thttp://www.openarchives.org/OAI/2.0/oai-identifier.xsd\">\n" .
00318 "\t\t\t\t<scheme>oai</scheme>\n" .
00319 "\t\t\t\t<repositoryIdentifier>" . $this->config->repositoryId . "</repositoryIdentifier>\n" .
00320 "\t\t\t\t<delimiter>" . $info->delimiter . "</delimiter>\n" .
00321 "\t\t\t\t<sampleIdentifier>" . $info->sampleIdentifier . "</sampleIdentifier>\n" .
00322 "\t\t\t</oai-identifier>\n" .
00323 "\t\t</description>\n" .
00324 "\t</Identify>\n";
00325
00326 $this->response($response);
00327 }
00328
00333 function ListIdentifiers() {
00334 $offset = 0;
00335
00336
00337 if ($this->paramExists('resumptionToken')) {
00338
00339 if (!$this->checkParams(array('resumptionToken'))) {
00340 return;
00341 }
00342
00343
00344 if (($token = &$this->resumptionToken($this->getParam('resumptionToken'))) === false) {
00345 $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
00346 return;
00347 }
00348
00349 $this->setParams($token->params);
00350 $offset = $token->offset;
00351 }
00352
00353
00354 if (!$this->checkParams(array('metadataPrefix'), array('from', 'until', 'set'))) {
00355 return;
00356 }
00357
00358 $metadataPrefix = $this->getParam('metadataPrefix');
00359 $set = $this->getParam('set');
00360
00361
00362 if (!in_array($metadataPrefix, $this->metadataFormats(true))) {
00363 $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
00364 return;
00365 }
00366
00367
00368 if (isset($set) && $this->config->maxSets == 0) {
00369 $this->error('noSetHierarchy', 'This repository does not support sets');
00370 return;
00371 }
00372
00373
00374 if (!$this->extractDateParams($this->getParams(), $from, $until)) {
00375 return;
00376 }
00377
00378
00379 $cursor = $offset;
00380 $total = 0;
00381
00382
00383 $records = &$this->identifiers($metadataPrefix, $from, $until, $set, $offset, $this->config->maxIdentifiers, $total);
00384 if (empty($records)) {
00385 $this->error('noRecordsMatch', 'No matching records in this repository');
00386 return;
00387 }
00388
00389
00390 $response = "\t<ListIdentifiers>\n";
00391
00392
00393 for ($i = 0, $num = count($records); $i < $num; $i++) {
00394 $record = $records[$i];
00395 $response .= "\t\t<header>\n" .
00396 "\t\t\t<identifier>" . $record->identifier . "</identifier>\n" .
00397 "\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
00398
00399 foreach ($record->sets as $setSpec) {
00400 $response .= "\t\t\t<setSpec>" . $this->prepOutput($setSpec) . "</setSpec>\n";
00401 }
00402 $response .= "\t\t</header>\n";
00403 }
00404 $offset += $num;
00405
00406 if ($offset != 0 && $offset < $total) {
00407
00408 $token = &$this->saveResumptionToken($offset, $this->getParams());
00409
00410 $response .= "\t\t<resumptionToken expirationDate=\"" . $this->UTCDate($token->expire) . "\"\n" .
00411 "\t\t\tcompleteListSize=\"$total\"\n" .
00412 "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
00413
00414 } else if (isset($token)) {
00415
00416 $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
00417 }
00418
00419 $response .= "\t</ListIdentifiers>\n";
00420
00421 $this->response($response);
00422 }
00423
00428 function ListMetadataFormats() {
00429
00430 if (!$this->checkParams(array(), array('identifier'))) {
00431 return;
00432 }
00433
00434
00435 if ($this->paramExists('identifier')) {
00436 if (!$this->identifierExists($this->getParam('identifier'))) {
00437 $this->error('idDoesNotExist', 'No matching identifier in this repository');
00438 return;
00439
00440 } else {
00441 $formats = &$this->metadataFormats(false, $this->getParam('identifier'));
00442 }
00443
00444 } else {
00445 $formats = &$this->metadataFormats();
00446 }
00447
00448 if (empty($formats) || !is_array($formats)) {
00449 $this->error('noMetadataFormats', 'No metadata formats are available');
00450 return;
00451 }
00452
00453
00454 $response = "\t<ListMetadataFormats>\n";
00455
00456
00457 foreach ($formats as $prefix => $format) {
00458 $response .= "\t\t<metadataFormat>\n" .
00459 "\t\t\t<metadataPrefix>" . $format->prefix . "</metadataPrefix>\n" .
00460 "\t\t\t<schema>" . $format->schema . "</schema>\n" .
00461 "\t\t\t<metadataNamespace>" . $format->namespace . "</metadataNamespace>\n" .
00462 "\t\t</metadataFormat>\n";
00463 }
00464
00465 $response .= "\t</ListMetadataFormats>\n";
00466
00467 $this->response($response);
00468 }
00469
00474 function ListRecords() {
00475 $offset = 0;
00476
00477
00478 if ($this->paramExists('resumptionToken')) {
00479
00480 if (!$this->checkParams(array('resumptionToken'))) {
00481 return;
00482 }
00483
00484
00485 if (($token = &$this->resumptionToken($this->getParam('resumptionToken'))) === false) {
00486 $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
00487 return;
00488 }
00489
00490 $this->setParams($token->params);
00491 $offset = $token->offset;
00492
00493 }
00494
00495
00496 if (!$this->checkParams(array('metadataPrefix'), array('from', 'until', 'set'))) {
00497 return;
00498 }
00499
00500 $metadataPrefix = $this->getParam('metadataPrefix');
00501 $set = $this->getParam('set');
00502
00503
00504 if (!in_array($metadataPrefix, $this->metadataFormats(true))) {
00505 $this->error('cannotDisseminateFormat', 'The requested metadataPrefix is not supported by this repository');
00506 return;
00507 }
00508
00509
00510 if (isset($set) && $this->config->maxSets == 0) {
00511 $this->error('noSetHierarchy', 'This repository does not support sets');
00512 return;
00513 }
00514
00515
00516 if (!$this->extractDateParams($this->getParams(), $from, $until)) {
00517 return;
00518 }
00519
00520
00521 $cursor = $offset;
00522 $total = 0;
00523
00524
00525 $records = &$this->records($metadataPrefix, $from, $until, $set, $offset, $this->config->maxRecords, $total);
00526 if (empty($records)) {
00527 $this->error('noRecordsMatch', 'No matching records in this repository');
00528 return;
00529 }
00530
00531
00532 $response = "\t<ListRecords>\n";
00533
00534
00535 for ($i = 0, $num = count($records); $i < $num; $i++) {
00536 $record = $records[$i];
00537 $response .= "\t\t<record>\n" .
00538 "\t\t\t<header>\n" .
00539 "\t\t\t\t<identifier>" . $record->identifier . "</identifier>\n" .
00540 "\t\t\t\t<datestamp>" . $record->datestamp . "</datestamp>\n";
00541
00542 foreach ($record->sets as $setSpec) {
00543 $response .= "\t\t\t\t<setSpec>" . $this->prepOutput($setSpec) . "</setSpec>\n";
00544 }
00545 $response .= "\t\t\t</header>\n" .
00546 "\t\t\t<metadata>\n";
00547
00548 $response .= $this->formatMetadata($this->getParam('metadataPrefix'), $record);
00549 $response .= "\t\t\t</metadata>\n" .
00550 "\t\t</record>\n";
00551 }
00552 $offset += $num;
00553
00554 if ($offset != 0 && $offset < $total) {
00555
00556 $token = &$this->saveResumptionToken($offset, $this->getParams());
00557
00558 $response .= "\t\t<resumptionToken expirationDate=\"" . $this->UTCDate($token->expire) . "\"\n" .
00559 "\t\t\tcompleteListSize=\"$total\"\n" .
00560 "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
00561
00562 } else if(isset($token)) {
00563
00564 $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
00565 }
00566
00567 $response .= "\t</ListRecords>\n";
00568
00569 $this->response($response);
00570 }
00571
00576 function ListSets() {
00577 $offset = 0;
00578
00579
00580 if ($this->paramExists('resumptionToken')) {
00581
00582 if (!$this->checkParams(array('resumptionToken'))) {
00583 return;
00584 }
00585
00586
00587 if (($token = &$this->resumptionToken($this->getParam('resumptionToken'))) === false) {
00588 $this->error('badResumptionToken', 'The requested resumptionToken is invalid or has expired');
00589 return;
00590 }
00591
00592 $this->setParams($token->params);
00593 $offset = $token->offset;
00594
00595 }
00596
00597
00598 if (!$this->checkParams()) {
00599 return;
00600 }
00601
00602
00603 $cursor = $offset;
00604 $total = 0;
00605
00606
00607 $sets = &$this->sets($offset, $total);
00608 if (empty($sets)) {
00609 $this->error('noSetHierarchy', 'This repository does not support sets');
00610 return;
00611 }
00612
00613
00614 $response = "\t<ListSets>\n";
00615
00616
00617 for ($i = 0, $num = count($sets); $i < $num; $i++) {
00618 $set = $sets[$i];
00619 $response .= "\t\t<set>\n" .
00620 "\t\t\t<setSpec>" . $this->prepOutput($set->spec) . "</setSpec>\n" .
00621 "\t\t\t<setName>" . $this->prepOutput($set->name) . "</setName>\n";
00622
00623 if (isset($set->description)) {
00624 $response .= "\t\t\t<setDescription>\n" .
00625 "\t\t\t\t<oai_dc:dc\n" .
00626 "\t\t\t\t\txmlns:oai_dc=\"http://www.openarchives.org/OAI/2.0/oai_dc/\"\n" .
00627 "\t\t\t\t\txmlns:dc=\"http://purl.org/dc/elements/1.1/\"\n" .
00628 "\t\t\t\t\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
00629 "\t\t\t\t\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai_dc/\n" .
00630 "\t\t\t\t\t\thttp://www.openarchives.org/OAI/2.0/oai_dc.xsd\">\n" .
00631 "\t\t\t\t\t<dc:description>" . $this->prepOutput($set->description) . "</dc:description>\n" .
00632 "\t\t\t\t</oai_dc:dc>\n" .
00633 "\t\t\t</setDescription>\n";
00634
00635 }
00636 $response .= "\t\t</set>\n";
00637 }
00638
00639 if ($offset != 0 && $offset < $total) {
00640
00641 $token = &$this->saveResumptionToken($offset, $this->getParams());
00642
00643 $response .= "\t\t<resumptionToken expirationDate=\"" . $this->UTCDate($token->expire) . "\"\n" .
00644 "\t\t\tcompleteListSize=\"$total\"\n" .
00645 "\t\t\tcursor=\"$cursor\">" . $token->id . "</resumptionToken>\n";
00646
00647 } else if (isset($token)) {
00648
00649 $response .= "\t\t<resumptionToken completeListSize=\"$total\" cursor=\"$cursor\" />\n";
00650 }
00651
00652 $response .= "\t</ListSets>\n";
00653
00654 $this->response($response);
00655 }
00656
00657
00658
00659
00660
00661
00665 function error($code, $message) {
00666 if (in_array($code, array('badVerb', 'badArgument'))) {
00667 $printParams = false;
00668
00669 } else {
00670 $printParams = true;
00671 }
00672
00673 $this->response("\t<error code=\"$code\">$message</error>", $printParams);
00674 }
00675
00681 function response($response, $printParams = true) {
00682 header("Content-Type: text/xml");
00683
00684 echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
00685 "<OAI-PMH xmlns=\"http://www.openarchives.org/OAI/2.0/\"\n" .
00686 "\txmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" .
00687 "\txsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/\n" .
00688 "\t\thttp://www.openarchives.org/OAI/2.0/OAI-PMH.xsd\">\n" .
00689 "\t<responseDate>" . $this->UTCDate() . "</responseDate>\n" .
00690 "\t<request";
00691
00692
00693 if($printParams) {
00694 foreach($this->params as $k => $v) {
00695 echo " $k=\"" . $this->prepOutput($v) . "\"";
00696 }
00697 }
00698
00699 echo ">" . $this->config->baseUrl . "</request>\n" .
00700 $response .
00701 "</OAI-PMH>\n";
00702 }
00703
00709 function getParam($name) {
00710 return isset($this->params[$name]) ? $this->params[$name] : null;
00711 }
00712
00717 function getParams() {
00718 return $this->params;
00719 }
00720
00725 function setParams(&$params) {
00726 $this->params = $params;
00727 }
00728
00734 function paramExists($name) {
00735 return isset($this->params[$name]);
00736 }
00737
00745 function checkParams($required = array(), $optional = array()) {
00746
00747 $requiredParams = array_merge(array('verb'), $required);
00748 $validParams = array_merge($requiredParams, $optional);
00749
00750
00751 foreach ($requiredParams as $k) {
00752 if(!$this->paramExists($k)) {
00753 $this->error('badArgument', "Missing $k parameter");
00754 return false;
00755
00756 } else if (is_array($this->getParam($k))) {
00757 $this->error('badArgument', "Multiple values are not allowed for the $k parameter");
00758 return false;
00759 }
00760 }
00761
00762
00763 foreach ($optional as $k) {
00764 if ($this->paramExists($k) && is_array($this->getParam($k))) {
00765 $this->error('badArgument', "Multiple values are not allowed for the $k parameter");
00766 return false;
00767 }
00768 }
00769
00770
00771 foreach ($this->params as $k => $v) {
00772 if (!in_array($k, $validParams)) {
00773
00774 if (Request::isPathInfoEnabled() || ($k != 'journal' && $k != 'page')) {
00775 $this->error('badArgument', "$k is an illegal parameter");
00776 return false;
00777 }
00778 }
00779 }
00780
00781 return true;
00782 }
00783
00790 function &formatMetadata($format, $record) {
00791 $formats = &$this->metadataFormats();
00792 $metadata = $formats[$format]->toXML($record);
00793 return $metadata;
00794 }
00795
00802 function UTCDate($timestamp = 0, $includeTime = true) {
00803 $format = "Y-m-d";
00804 if($includeTime) {
00805 $format .= "\TH:i:s\Z";
00806 }
00807
00808 if($timestamp == 0) {
00809 return gmdate($format);
00810
00811 } else {
00812 return gmdate($format, $timestamp);
00813 }
00814 }
00815
00824 function UTCtoTimestamp($date, $checkGranularity = true) {
00825
00826 if (preg_match("/^\d\d\d\d\-\d\d\-\d\d$/", $date)) {
00827
00828 $time = strtotime("$date UTC");
00829 return ($time != -1) ? $time : 'invalid';
00830
00831 } else if (preg_match("/^(\d\d\d\d\-\d\d\-\d\d)T(\d\d:\d\d:\d\d)Z$/", $date, $matches)) {
00832
00833
00834 $date = "$matches[1] $matches[2]";
00835 if ($checkGranularity && $this->config->granularity != 'YYYY-MM-DDThh:mm:ssZ') {
00836 return 'invalid_granularity';
00837
00838 } else {
00839 $time = strtotime("$date UTC");
00840 return ($time != -1) ? $time : 'invalid';
00841 }
00842
00843 } else {
00844 return 'invalid';
00845 }
00846 }
00847
00856 function extractDateParams($params, &$from, &$until) {
00857 if (isset($params['from'])) {
00858 $from = $this->UTCtoTimestamp($params['from']);
00859
00860 if ($from == 'invalid') {
00861 $this->error('badArgument', 'Illegal from parameter');
00862 return false;
00863
00864 } else if($from == 'invalid_granularity') {
00865 $this->error('badArgument', 'Illegal granularity for from parameter');
00866 return false;
00867 }
00868 }
00869
00870 if(isset($params['until'])) {
00871 $until = $this->UTCtoTimestamp($params['until']);
00872
00873 if($until == 'invalid') {
00874 $this->error('badArgument', 'Illegal until parameter');
00875 return false;
00876
00877 } else if($until == 'invalid_granularity') {
00878 $this->error('badArgument', 'Illegal granularity for until parameter');
00879 return false;
00880 }
00881
00882
00883 if (isset($from) && $from > $until) {
00884 $this->error('badArgument', 'until parameter must be greater than or equal to from parameter');
00885 return false;
00886 }
00887
00888
00889 if (isset($from) && strlen($params['from']) != strlen($params['until'])) {
00890 $this->error('badArgument', 'until and from parameters must be of the same granularity');
00891 return false;
00892 }
00893
00894 if (strlen($params['until']) == 10) {
00895
00896 $until += 86399;
00897 }
00898 }
00899
00900 return true;
00901 }
00902
00908 function prepInput(&$data) {
00909 if (!is_array($data)) {
00910 $data = urldecode($data);
00911
00912 } else {
00913 foreach ($data as $k => $v) {
00914 if (is_array($data[$k])) {
00915 $this->prepInput($data[$k]);
00916 } else {
00917 $data[$k] = urldecode($v);
00918 }
00919 }
00920 }
00921 return $data;
00922 }
00923
00930 function prepOutput(&$data) {
00931 if (!is_array($data)) {
00932 $data = htmlspecialchars($data);
00933
00934 } else {
00935 foreach ($data as $k => $v) {
00936 if (is_array($data[$k])) {
00937 $this->prepOutput($data[$k]);
00938 } else {
00939
00940 $data[$k] = htmlspecialchars($v);
00941 }
00942 }
00943 }
00944 return $data;
00945 }
00946
00954 function parseStr($string, &$array) {
00955 $pairs = explode('&', $string);
00956 foreach ($pairs as $p) {
00957 $vars = explode('=', $p);
00958 if (!empty($vars[0]) && isset($vars[1])) {
00959 $key = $vars[0];
00960 $value = join('=', array_splice($vars, 1));
00961
00962 if (!isset($array[$key])) {
00963 $array[$key] = $value;
00964 } else if (is_array($array[$key])) {
00965 array_push($array[$key], $value);
00966 } else {
00967 $array[$key] = array($array[$key], $value);
00968 }
00969 }
00970 }
00971 }
00972 }
00973
00974 ?>