- add ResumptionToken for OAI-ListIdentifiers

- max identifiers and reciords via config
- add constants.php
- add clear-expired command for deleting obsolete cache
This commit is contained in:
Arno Kaimbacher 2020-05-07 19:29:18 +02:00
parent 9d8625225f
commit 79b51e93e7
11 changed files with 395 additions and 27 deletions

View file

@ -0,0 +1,68 @@
<?php
namespace App\Models\Oai;
class Configuration
{
/**
* Hold path where to store temporary resumption token files.
*
* @var string
*/
private $pathTokens = '';
/**
* Holds maximum number of identifiers to list per request.
*
* @var int
*/
private $maxListIds = 15;
/**
* Holds maximum number of records to list per request.
*
* @var int
*/
private $maxListRecs = 15;
public function __construct()
{
$this->maxListIds = config('oai.max.listidentifiers');
$this->maxListRecs = config('oai.max.listrecords');
$this->pathTokens = config('app.workspacePath')
. DIRECTORY_SEPARATOR .'tmp'
. DIRECTORY_SEPARATOR . 'resumption';
}
/**
* Return temporary path for resumption tokens.
*
* @return string Path.
*/
public function getResumptionTokenPath()
{
return $this->pathTokens;
}
/**
* Return maximum number of listable identifiers per request.
*
* @return int Maximum number of listable identifiers per request.
*/
public function getMaxListIdentifiers()
{
return $this->maxListIds;
}
/**
* Return maximum number of listable records per request.
*
* @return int Maximum number of listable records per request.
*/
public function getMaxListRecords()
{
return $this->maxListRecs;
}
}

View file

@ -7,13 +7,12 @@ namespace App\Models\Oai;
*/
class ResumptionToken
{
/**
* Holds dataset ids
/**
* Holds dcoument ids
*
* @var array
*/
private $datasetIds = array();
private $documentIds = array();
/**
* Holds metadata prefix information
@ -34,7 +33,7 @@ class ResumptionToken
*
* @var integer
*/
private $startPostition = 0;
private $startPosition = 0;
/**
* Holds total amount of document ids
@ -50,7 +49,7 @@ class ResumptionToken
*/
public function getDocumentIds()
{
return $this->_documentIds;
return $this->documentIds;
}
/**
@ -60,17 +59,17 @@ class ResumptionToken
*/
public function getMetadataPrefix()
{
return $this->_metadataPrefix;
return $this->metadataPrefix;
}
/**
* Return setted resumption id after successful storing of resumption token.
*
* @return string Returns resumption id
* @return string
*/
public function getResumptionId()
{
return $this->_resumptionId;
return $this->resumptionId;
}
/**
@ -80,7 +79,7 @@ class ResumptionToken
*/
public function getStartPosition()
{
return $this->_startPosition;
return $this->startPosition;
}
/**
@ -90,7 +89,7 @@ class ResumptionToken
*/
public function getTotalIds()
{
return $this->_totalIds;
return $this->totalIds;
}
/**
@ -105,7 +104,7 @@ class ResumptionToken
$idsToStore = array($idsToStore);
}
$this->_documentIds = $idsToStore;
$this->documentIds = $idsToStore;
}
/**
@ -116,7 +115,7 @@ class ResumptionToken
*/
public function setMetadataPrefix($prefix)
{
$this->_metadataPrefix = $prefix;
$this->metadataPrefix = $prefix;
}
/**
@ -126,7 +125,7 @@ class ResumptionToken
*/
public function setResumptionId($resumptionId)
{
$this->_resumptionId = $resumptionId;
$this->resumptionId = $resumptionId;
}
/**
@ -137,7 +136,7 @@ class ResumptionToken
*/
public function setStartPosition($startPosition)
{
$this->_startPosition = (int) $startPosition;
$this->startPosition = (int) $startPosition;
}
/**
@ -147,6 +146,6 @@ class ResumptionToken
*/
public function setTotalIds($totalIds)
{
$this->_totalIds = (int) $totalIds;
$this->totalIds = (int) $totalIds;
}
}

View file

@ -0,0 +1,8 @@
<?php
namespace App\Models\Oai;
use Exception;
class ResumptionTokenException extends Exception
{
}

View file

@ -0,0 +1,148 @@
<?php
namespace App\Models\Oai;
use App\Models\Oai\ResumptionToken;
use App\Models\Oai\ResumptionTokenException;
use Illuminate\Support\Facades\Cache;
/**
* Handling (read, write) of resumption tokens
*/
class ResumptionTokens
{
/**
* Holds resumption path without trailing slash.
*
* @var string
*/
private $resumptionPath = null;
private $resumptionId = null;
protected $filePrefix = 'rs_';
protected $fileExtension = 'txt';
/**
* Constructor of class
*
* @param $resPath (Optional) Initialise resumption path on create.
*
*/
public function __construct($resPath = null)
{
if (false === empty($resPath)) {
$this->setResumptionPath($resPath);
}
}
/**
* Generate a unique file name and resumption id for storing resumption token.
* Double action because file name 8without prefix and file extension)
* and resumption id should be equal.
*
* @return filename Generated filename including path and file extension.
*/
private function generateResumptionName()
{
$fc = 0;
// generate a unique partial name
// return value of time() should be enough
$uniqueId = time();
$fileExtension = $this->fileExtension;
if (false === empty($fileExtension)) {
$fileExtension = '.' . $fileExtension;
}
do {
$uniqueName = sprintf('%s%05d', $uniqueId, $fc++);
$file = $this->resumptionPath . DIRECTORY_SEPARATOR . $this->filePrefix . $uniqueName . $fileExtension;
} while (true === file_exists($file));
$this->resumptionId = $uniqueName;
return $uniqueName;
//return $file;
}
public function getResumptionToken($resId)
{
$token = null;
// $fileName = $this->resumptionPath . DIRECTORY_SEPARATOR . $this->filePrefix . $resId;
// if (false === empty($this->fileExtension)) {
// $fileName .= '.' . $this->fileExtension;
// }
// if (true === file_exists($fileName)) {
if (Cache::has($resId)) {
//$fileContents = file_get_contents($fileName);
$fileContents = Cache::get($resId);
// if data is not unserializueabke an E_NOTICE will be triggerd and false returned
// avoid this E_NOTICE
$token = @unserialize($fileContents);
if (false === ($token instanceof ResumptionToken)) {
$token = null;
}
}
return $token;
}
/**
* Set resumption path where the resumption token files are stored.
*
* @throws Oai_Model_ResumptionTokenException Thrown if directory operations failed.
* @return void
*/
public function setResumptionPath($resPath)
{
// expanding all symbolic links and resolving references
$realPath = realpath($resPath);
// if (empty($realPath) or false === is_dir($realPath)) {
// throw new Oai_Model_ResumptionTokenException(
// 'Given resumption path "' . $resPath . '" (real path: "' . $realPath . '") is not a directory.'
// );
// }
// if (false === is_writable($realPath)) {
// throw new Oai_Model_ResumptionTokenException(
// 'Given resumption path "' . $resPath . '" (real path: "' . $realPath . '") is not writeable.'
// );
// }
$this->resumptionPath = $realPath;
}
/**
* Store a resumption token
*
* @param Oai_Model_Resumptiontoken $token Token to store.
* @throws Oai_Model_ResumptionTokenException Thrown on file operation error.
* @return void
*/
public function storeResumptionToken(ResumptionToken $token)
{
// $fileName = $this->generateResumptionName();
$uniqueName = $this->generateResumptionName();
// $file = fopen($fileName, 'w+');
// if (false === $file) {
// throw new ResumptionTokenException('Could not open file "' . $fileName . '" for writing!');
// }
$serialToken = serialize($token);
// if (false === fwrite($file, $serialToken)) {
// throw new ResumptionTokenException('Could not write file "' . $fileName . '"!');
// }
// if (false === fclose($file)) {
// throw new ResumptionTokenException('Could not close file "' . $fileName . '"!');
// }
Cache::put($uniqueName, $serialToken, now()->addMinutes(60));
$token->setResumptionId($this->resumptionId);
}
}