286 lines
7.9 KiB
PHP
286 lines
7.9 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/oai/PKPOAIDAO.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2003-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class PKPOAIDAO
|
|
*
|
|
* @ingroup oai
|
|
*
|
|
* @see OAI
|
|
*
|
|
* @brief Base class for DAO operations for the OAI interface.
|
|
*/
|
|
|
|
namespace PKP\oai;
|
|
|
|
use PKP\plugins\Hook;
|
|
|
|
abstract class PKPOAIDAO extends \PKP\db\DAO
|
|
{
|
|
/** @var OAI parent OAI object */
|
|
public $oai;
|
|
|
|
|
|
/**
|
|
* Set parent OAI object.
|
|
*
|
|
* @param OAI $oai
|
|
*/
|
|
public function setOAI($oai)
|
|
{
|
|
$this->oai = $oai;
|
|
}
|
|
|
|
//
|
|
// Resumption tokens
|
|
//
|
|
/**
|
|
* Clear stale resumption tokens.
|
|
*/
|
|
public function clearTokens()
|
|
{
|
|
$this->update(
|
|
'DELETE FROM oai_resumption_tokens WHERE expire < ?',
|
|
[time()]
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Retrieve a resumption token.
|
|
*
|
|
* @param string $tokenId OAI resumption token
|
|
*
|
|
* @return OAIResumptionToken
|
|
*/
|
|
public function getToken($tokenId)
|
|
{
|
|
$result = $this->retrieve('SELECT * FROM oai_resumption_tokens WHERE token = ?', [$tokenId]);
|
|
$row = $result->current();
|
|
return $row ? new OAIResumptionToken($row->token, $row->record_offset, unserialize($row->params), $row->expire) : null;
|
|
}
|
|
|
|
/**
|
|
* Insert an OAI resumption token, generating a new ID.
|
|
*
|
|
* @param OAIResumptionToken $token
|
|
*
|
|
* @return OAIResumptionToken
|
|
*/
|
|
public function insertToken($token)
|
|
{
|
|
do {
|
|
// Generate unique token ID
|
|
$token->id = md5(uniqid(random_int(0, PHP_INT_MAX), true));
|
|
$result = $this->retrieve(
|
|
'SELECT COUNT(*) AS row_count FROM oai_resumption_tokens WHERE token = ?',
|
|
[$token->id]
|
|
);
|
|
$row = $result->current();
|
|
$val = $row->row_count;
|
|
} while ($val != 0);
|
|
|
|
$this->update(
|
|
'INSERT INTO oai_resumption_tokens (token, record_offset, params, expire)
|
|
VALUES
|
|
(?, ?, ?, ?)',
|
|
[$token->id, $token->offset, serialize($token->params), $token->expire]
|
|
);
|
|
|
|
return $token;
|
|
}
|
|
|
|
|
|
/**
|
|
* Check if a data object ID specifies a data object.
|
|
*
|
|
* @param int $dataObjectId
|
|
* @param array $setIds optional Objects ids that specify an OAI set,
|
|
* in hierarchical order. If passed, will check for the data object id
|
|
* only inside the specified set.
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function recordExists($dataObjectId, $setIds = [])
|
|
{
|
|
return $this->getRecord($dataObjectId, $setIds) ? true : false;
|
|
}
|
|
|
|
/**
|
|
* Return OAI record for specified data object.
|
|
*
|
|
* @param int $dataObjectId
|
|
* @param array $setIds optional Objects ids that specify an OAI set,
|
|
* in hierarchical order. If passed, will check for the data object id
|
|
* only inside the specified set.
|
|
*
|
|
* @return OAIRecord
|
|
*/
|
|
public function getRecord($dataObjectId, $setIds = [])
|
|
{
|
|
$result = $this->_getRecordsRecordSetQuery($setIds, null, null, null, $dataObjectId);
|
|
$row = $result->first();
|
|
return $row ? $this->_returnRecordFromRow((array) $row) : null;
|
|
}
|
|
|
|
/**
|
|
* Return set of OAI records matching specified parameters.
|
|
*
|
|
* @param array $setIds Objects ids that specify an OAI set,
|
|
* in hierarchical order. The returned records will be part
|
|
* of this set.
|
|
* @param int $from timestamp
|
|
* @param int $until timestamp
|
|
* @param string $set setSpec
|
|
* @param int $offset
|
|
* @param int $limit
|
|
* @param int $total
|
|
*
|
|
* @return array OAIRecord
|
|
*/
|
|
public function getRecords($setIds, $from, $until, $set, $offset, $limit, &$total)
|
|
{
|
|
$query = $this->_getRecordsRecordSetQuery($setIds, $from, $until, $set);
|
|
$total = $query->count();
|
|
$results = $query->offset($offset)->limit($limit)->get();
|
|
|
|
$records = [];
|
|
foreach ($results as $row) {
|
|
$records[] = $this->_returnRecordFromRow((array) $row);
|
|
}
|
|
return $records;
|
|
}
|
|
|
|
/**
|
|
* Return set of OAI identifiers matching specified parameters.
|
|
*
|
|
* @param array $setIds Objects ids that specify an OAI set,
|
|
* in hierarchical order. The returned records will be part
|
|
* of this set.
|
|
* @param int $from timestamp
|
|
* @param int $until timestamp
|
|
* @param string $set setSpec
|
|
* @param int $offset
|
|
* @param int $limit
|
|
* @param int $total
|
|
*
|
|
* @return array OAIIdentifier
|
|
*/
|
|
public function getIdentifiers($setIds, $from, $until, $set, $offset, $limit, &$total)
|
|
{
|
|
$query = $this->_getRecordsRecordSetQuery($setIds, $from, $until, $set);
|
|
$total = $query->count();
|
|
$results = $query->offset($offset)->limit($limit)->get();
|
|
|
|
$records = [];
|
|
foreach ($results as $row) {
|
|
$records[] = $this->_returnIdentifierFromRow((array) $row);
|
|
}
|
|
return $records;
|
|
}
|
|
|
|
/**
|
|
* Return the *nix timestamp of the earliest published submission.
|
|
*
|
|
* @param array $setIds optional Objects ids that specify an OAI set,
|
|
* in hierarchical order. If empty, all records from
|
|
* all sets will be included.
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getEarliestDatestamp($setIds = [])
|
|
{
|
|
$query = $this->_getRecordsRecordSetQuery($setIds, null, null, null, null, 'last_modified');
|
|
if ($row = $query->first()) {
|
|
$record = $this->_returnRecordFromRow((array) $row);
|
|
return OAIUtils::UTCtoTimestamp($record->datestamp);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
//
|
|
// Private helper methods.
|
|
//
|
|
/**
|
|
* Return OAIRecord object from database row.
|
|
*
|
|
* @param array $row
|
|
*
|
|
* @return OAIRecord
|
|
*/
|
|
public function _returnRecordFromRow($row)
|
|
{
|
|
$record = new OAIRecord();
|
|
$record = $this->_doCommonOAIFromRowOperations($record, $row);
|
|
|
|
Hook::call('OAIDAO::_returnRecordFromRow', [&$record, &$row]);
|
|
|
|
return $record;
|
|
}
|
|
|
|
/**
|
|
* Return OAIIdentifier object from database row.
|
|
*
|
|
* @param array $row
|
|
*
|
|
* @return OAIIdentifier
|
|
*/
|
|
public function _returnIdentifierFromRow($row)
|
|
{
|
|
$record = new OAIIdentifier();
|
|
$record = $this->_doCommonOAIFromRowOperations($record, $row);
|
|
|
|
Hook::call('OAIDAO::_returnIdentifierFromRow', [&$record, &$row]);
|
|
|
|
return $record;
|
|
}
|
|
|
|
/**
|
|
* Common operations for OAIRecord and OAIIdentifier object data set.
|
|
*
|
|
* @param OAIRecord|OAIIdentifier $record
|
|
* @param array $row
|
|
*
|
|
* @return OAIRecord|OAIIdentifier
|
|
*/
|
|
public function _doCommonOAIFromRowOperations($record, $row)
|
|
{
|
|
$record->datestamp = OAIUtils::UTCDate(strtotime($this->datetimeFromDB($row['last_modified'])));
|
|
|
|
if (isset($row['tombstone_id'])) {
|
|
$record->identifier = $row['oai_identifier'];
|
|
$record->sets = [$row['set_spec']];
|
|
$record->status = OAI::OAIRECORD_STATUS_DELETED;
|
|
} else {
|
|
$record->status = OAI::OAIRECORD_STATUS_ALIVE;
|
|
$record = $this->setOAIData($record, $row, $record instanceof \PKP\oai\OAIRecord);
|
|
}
|
|
|
|
return $record;
|
|
}
|
|
|
|
/**
|
|
* Get a OAI records record set.
|
|
*
|
|
* @param array $setIds Objects ids that specify an OAI set,
|
|
* in hierarchical order.
|
|
* @param int|string $from *nix timestamp or ISO datetime string
|
|
* @param int|string $until *nix timestamp or ISO datetime string
|
|
* @param string $set
|
|
* @param int $submissionId optional
|
|
* @param string $orderBy UNFILTERED
|
|
*
|
|
* @return \Illuminate\Database\Query\Builder
|
|
*/
|
|
abstract public function _getRecordsRecordSetQuery($setIds, $from, $until, $set, $submissionId = null, $orderBy = 'journal_id, submission_id');
|
|
}
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\oai\PKPOAIDAO', '\PKPOAIDAO');
|
|
}
|