diff --git a/app/Exceptions/OaiModelException.php b/app/Exceptions/OaiModelException.php
new file mode 100644
index 0000000..a60f020
--- /dev/null
+++ b/app/Exceptions/OaiModelException.php
@@ -0,0 +1,12 @@
+all();
$safeRemoveParameters = array('module', 'controller', 'action', 'role');
foreach ($safeRemoveParameters as $parameter) {
unset($oaiRequest[$parameter]);
}
- return $this->__handleRequest($oaiRequest);
+ try {
+ $this->__handleRequest($oaiRequest);
+ } catch (OaiModelException $e) {
+ $errorCode = OaiModelError::mapCode($e->getCode());
+ //$this->getLogger()->err($errorCode);
+ $this->_proc->setParameter('', 'oai_error_code', $errorCode);
+ //$this->getLogger()->err($e->getMessage());
+ $this->_proc->setParameter('', 'oai_error_message', htmlentities($e->getMessage()));
+ } catch (Exception $e) {
+ //$this->getLogger()->err($e);
+ $this->_proc->setParameter('', 'oai_error_code', 'unknown');
+ $this->_proc->setParameter('', 'oai_error_message', 'An internal error occured.');
+ //$this->getResponse()->setHttpResponseCode(500);
+ }
+ // $xml = $this->_xml->saveXML();
+ $xml = $this->_proc->transformToXML($this->_xml);
+
+ //$xml = $this->doc->asXML();
+ return response($xml)//->view('rss', array('rss'=>$this->rss))
+ ->header('Content-Type', 'application/xml')
+ ->header('charset', 'utf-8');
}
@@ -95,6 +119,8 @@ class RequestController extends Controller
$this->handleListMetadataFormats();
} elseif ($oaiRequest['verb'] == 'ListRecords') {
$this->handleListRecords($oaiRequest);
+ } elseif ($oaiRequest['verb'] == 'GetRecord') {
+ $this->handleGetRecord($oaiRequest);
} elseif ($oaiRequest['verb'] == 'ListIdentifiers') {
$this->handleListIdentifiers($oaiRequest);
} elseif ($oaiRequest['verb'] == 'ListSets') {
@@ -107,14 +133,6 @@ class RequestController extends Controller
$this->_proc->setParameter('', 'oai_verb', $oaiRequest['verb']);
$this->doc = $this->handleIdentify();
}
-
- //$xml = $this->_xml->saveXML();
- $xml = $this->_proc->transformToXML($this->_xml);
-
- //$xml = $this->doc->asXML();
- return response($xml)//->view('rss', array('rss'=>$this->rss))
- ->header('Content-Type', 'application/xml')
- ->header('charset', 'utf-8');
}
/**
@@ -139,6 +157,89 @@ class RequestController extends Controller
$this->_xml->appendChild($this->_xml->createElement('Documents'));
}
+ /**
+ * Implements response for OAI-PMH verb 'GetRecord'.
+ *
+ * @param array &$oaiRequest Contains full request information
+ * @return void
+ */
+ private function handleGetRecord(array &$oaiRequest)
+ {
+ // Identifier references metadata Urn, not plain Id!
+ // Currently implemented as 'oai:foo.bar.de:{docId}' or 'urn:nbn...-123'
+ $dataId = $this->getDocumentIdByIdentifier($oaiRequest['identifier']);
+
+ $dataset = null;
+ try {
+ //$dataset = new Opus_Document($docId);
+ $dataset = Dataset::findOrFail($dataId);
+ } catch (ModelNotFoundException $ex) {
+ throw new OaiModelException(
+ 'The value of the identifier argument is unknown or illegal in this repository.',
+ OaiModelError::IDDOESNOTEXIST
+ );
+ }
+
+ $metadataPrefix = $oaiRequest['metadataPrefix'];
+
+ // do not deliver datasets which are restricted by document state
+ if (is_null($dataset)
+ //or (false === in_array($dataset->getServerState(), $this->_deliveringDocumentStates))
+ or (false === $dataset->whereIn('server_state', $this->deliveringDocumentStates))
+
+
+ or (false === $dataset->hasEmbargoPassed())) {
+ throw new OaiModelException('Document is not available for OAI export!', OaiModelError::NORECORDSMATCH);
+ }
+
+ $this->_xml->appendChild($this->_xml->createElement('Documents'));
+ $this->createXmlRecord($dataset);
+ }
+
+ /**
+ * Retrieve a document id by an oai identifier.
+ *
+ * @param string $oaiIdentifier
+ * @result int
+ */
+ private function getDocumentIdByIdentifier($oaiIdentifier)
+ {
+ $identifierParts = explode(":", $oaiIdentifier);
+
+ $dataId = null;
+ switch ($identifierParts[0]) {
+ // case 'urn':
+ // //$finder = new Opus_DocumentFinder();
+ // $finder = Dataset::query();
+ // // $finder->setIdentifierTypeValue('urn', $oaiIdentifier);
+ // // $finder->setServerStateInList($this->_deliveringDocumentStates);
+ // $finder->whereIn('server_state', $this->deliveringDocumentStates);
+ // $docIds = $finder->ids();
+ // $docId = $docIds[0];
+ // break;
+ case 'oai':
+ if (isset($identifierParts[2])) {
+ $dataId = $identifierParts[2];
+ }
+ break;
+ default:
+ throw new OaiModelException(
+ 'The prefix of the identifier argument is unknown.',
+ OaiModelError::BADARGUMENT
+ );
+ break;
+ }
+
+ if (empty($dataId) or !preg_match('/^\d+$/', $dataId)) {
+ throw new Oai_Model_Exception(
+ 'The value of the identifier argument is unknown or illegal in this repository.',
+ Oai_Model_Error::IDDOESNOTEXIST
+ );
+ }
+
+ return $dataId;
+ }
+
diff --git a/app/Models/Dataset.php b/app/Models/Dataset.php
index 21fb13c..ac57892 100644
--- a/app/Models/Dataset.php
+++ b/app/Models/Dataset.php
@@ -11,6 +11,7 @@ use App\Models\Person;
use App\Models\XmlCache;
use App\Models\File;
use Illuminate\Database\Eloquent\Model;
+use Carbon\Carbon;
class Dataset extends Model
{
@@ -40,6 +41,7 @@ class Dataset extends Model
'server_date_created',
'server_date_modified',
'server_date_published',
+ 'embargo_date',
];
//protected $dateFormat = 'Y-m-d';
@@ -209,4 +211,31 @@ class Dataset extends Model
{
return $this->project()->exists();
}
+
+
+ public function hasEmbargoPassed($now = null)
+ {
+ $embargoDate = $this->embargo_date;
+ if (is_null($embargoDate)) {
+ return true;
+ }
+
+ if (is_null($now)) {
+ $now = $dt = Carbon::now();
+ }
+ // Embargo has passed on the day after the specified date
+ // $embargoDate->setHour(23);
+ // $embargoDate->setMinute(59);
+ // $embargoDate->setSecond(59);
+ // $embargoDate->setTimezone('Z');
+
+ // $dt->year = 2015;
+ // $dt->month = 04;
+ // $dt->day = 21;
+ $embargoDate->hour = 23;
+ $embargoDate->minute = 59;
+ $embargoDate->second = 59;
+
+ return ($embargoDate->gt($now) == true);
+ }
}
diff --git a/app/Models/OaiModelError.php b/app/Models/OaiModelError.php
new file mode 100644
index 0000000..784d613
--- /dev/null
+++ b/app/Models/OaiModelError.php
@@ -0,0 +1,42 @@
+ 'badVerb',
+ self::BADARGUMENT => 'badArgument',
+ self::NORECORDSMATCH => 'noRecordsMatch',
+ self::CANNOTDISSEMINATEFORMAT => 'cannotDisseminateFormat',
+ self::BADRESUMPTIONTOKEN => 'badResumptionToken',
+ self::IDDOESNOTEXIST => 'idDoesNotExist',
+ );
+ /**
+ * Map internal error codes to OAI error codes.
+ *
+ * @param int $code Internal error code.
+ * @return string OAI error code.
+ */
+ public static function mapCode($code)
+ {
+ if (false === array_key_exists($code, self::$oaiErrorCodes)) {
+ throw new Oai_Model_Exception("Unknown oai error code $code");
+ }
+ return self::$oaiErrorCodes[$code];
+ }
+}
diff --git a/config/laravellocalization.php b/config/laravellocalization.php
index 0d12ded..064e999 100644
--- a/config/laravellocalization.php
+++ b/config/laravellocalization.php
@@ -323,6 +323,6 @@ return [
// URLs which should not be processed, e.g. '/nova', '/nova/*', '/nova-api/*' or specific application URLs
// Defaults to []
- 'urlsIgnored' => ['/skipped', '/settings', '/settings/*'],
+ 'urlsIgnored' => ['/skipped', '/settings', '/settings/*', '/oai'],
];
diff --git a/public/oai-pmh.xslt b/public/oai-pmh.xslt
index 3250276..d096f38 100644
--- a/public/oai-pmh.xslt
+++ b/public/oai-pmh.xslt
@@ -214,6 +214,12 @@
+
+
+
+
+
+