183 lines
5.4 KiB
PHP
183 lines
5.4 KiB
PHP
<?php
|
|
|
|
/**
|
|
* @file classes/oai/OAIUtils.php
|
|
*
|
|
* Copyright (c) 2014-2021 Simon Fraser University
|
|
* Copyright (c) 2000-2021 John Willinsky
|
|
* Distributed under the GNU GPL v3. For full terms see the file docs/COPYING.
|
|
*
|
|
* @class OAI
|
|
*
|
|
* @ingroup oai
|
|
*
|
|
* @see OAIDAO
|
|
*
|
|
* @brief Utility functions used by OAI related classes.
|
|
*/
|
|
|
|
namespace PKP\oai;
|
|
|
|
use Transliterator;
|
|
|
|
class OAIUtils
|
|
{
|
|
private static $TO_ASCII;
|
|
private static $NOT_IN_URI_NON_RESERVED_CHARS = '/[^A-Za-z0-9\-_\.!~*\'()]/';
|
|
|
|
public static function init()
|
|
{
|
|
self::$TO_ASCII = Transliterator::createFromRules(':: Any-Latin; :: Latin-ASCII; :: NFD; :: [:Nonspacing Mark:] Remove; :: NFC;', Transliterator::FORWARD);
|
|
}
|
|
|
|
/**
|
|
* Return a UTC-formatted datestamp from the specified UNIX timestamp.
|
|
*
|
|
* @param int $timestamp *nix timestamp (if not used, the current time is used)
|
|
* @param bool $includeTime include both the time and date
|
|
*
|
|
* @return string UTC datestamp
|
|
*/
|
|
public static function UTCDate($timestamp = 0, $includeTime = true)
|
|
{
|
|
$format = 'Y-m-d';
|
|
if ($includeTime) {
|
|
$format .= "\TH:i:s\Z";
|
|
}
|
|
|
|
if ($timestamp == 0) {
|
|
return gmdate($format);
|
|
} else {
|
|
return gmdate($format, $timestamp);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns a UNIX timestamp from a UTC-formatted datestamp.
|
|
* Returns the string "invalid" if datestamp is invalid,
|
|
* or "invalid_granularity" if unsupported granularity.
|
|
*
|
|
* @param string $date UTC datestamp
|
|
* @param string $requiredGranularity Datestamp granularity to require (default: not checked)
|
|
*
|
|
* @return int|string timestamp
|
|
*/
|
|
public static function UTCtoTimestamp($date, $requiredGranularity = null)
|
|
{
|
|
// FIXME Has limited range (see http://php.net/strtotime)
|
|
if (preg_match("/^\d\d\d\d\-\d\d\-\d\d$/", $date)) {
|
|
// Match date
|
|
$time = strtotime("{$date} UTC");
|
|
return ($time != -1) ? $time : 'invalid';
|
|
} elseif (preg_match("/^(\d\d\d\d\-\d\d\-\d\d)T(\d\d:\d\d:\d\d)Z$/", $date, $matches)) {
|
|
// Match datetime
|
|
// FIXME
|
|
$date = "{$matches[1]} {$matches[2]}";
|
|
if ($requiredGranularity && $requiredGranularity != 'YYYY-MM-DDThh:mm:ssZ') {
|
|
return 'invalid_granularity';
|
|
} else {
|
|
$time = strtotime("{$date} UTC");
|
|
return ($time != -1) ? $time : 'invalid';
|
|
}
|
|
} else {
|
|
return 'invalid';
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Clean input variables (by reference).
|
|
*
|
|
* @param mixed $data request parameter(s)
|
|
*/
|
|
public static function prepInput(&$data)
|
|
{ // REFERENCE REQUIRED
|
|
if (!is_array($data)) {
|
|
$data = urldecode($data);
|
|
} else {
|
|
foreach ($data as $k => $v) {
|
|
if (is_array($data[$k])) {
|
|
self::prepInput($data[$k]);
|
|
} else {
|
|
$data[$k] = urldecode($v);
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Prepare variables for output (by reference).
|
|
* Data is assumed to be UTF-8 encoded (FIXME?)
|
|
*
|
|
* @param mixed $data output parameter(s)
|
|
*
|
|
* @return mixed cleaned output parameter(s)
|
|
*/
|
|
public static function prepOutput(&$data)
|
|
{ // REFERENCE REQUIRED
|
|
if (!is_array($data)) {
|
|
$data = htmlspecialchars($data);
|
|
} else {
|
|
foreach ($data as $k => $v) {
|
|
if (is_array($data[$k])) {
|
|
self::prepOutput($data[$k]);
|
|
} else {
|
|
// FIXME FIXME FIXME
|
|
$data[$k] = htmlspecialchars($v);
|
|
}
|
|
}
|
|
}
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Parses string $string into an associate array $array.
|
|
* Acts like parse_str($string, $array) except duplicate
|
|
* variable names in $string are converted to an array.
|
|
*
|
|
* @param array $array of parsed parameters
|
|
*/
|
|
public static function parseStr($string, &$array)
|
|
{
|
|
$pairs = explode('&', $string);
|
|
foreach ($pairs as $p) {
|
|
$vars = explode('=', $p);
|
|
if (!empty($vars[0]) && isset($vars[1])) {
|
|
$key = $vars[0];
|
|
$value = join('=', array_splice($vars, 1));
|
|
|
|
if (!isset($array[$key])) {
|
|
$array[$key] = $value;
|
|
} elseif (is_array($array[$key])) {
|
|
array_push($array[$key], $value);
|
|
} else {
|
|
$array[$key] = [$array[$key], $value];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Valid characters in setSpec [1] are URI unreserved characters [2]
|
|
* Create a valid string by
|
|
* - transliterating all non-Latin characters
|
|
* - stripping all diacritics
|
|
* - dropping any remaining invalid characters
|
|
*
|
|
* [1] https://www.openarchives.org/OAI/2.0/openarchivesprotocol.htm#Set
|
|
* [2] http://www.ietf.org/rfc/rfc2396.txt
|
|
*
|
|
*/
|
|
public static function toValidSetSpec(string $string): string
|
|
{
|
|
$t = self::$TO_ASCII->transliterate($string);
|
|
return preg_replace(self::$NOT_IN_URI_NON_RESERVED_CHARS, '', $t);
|
|
}
|
|
}
|
|
OAIUtils::init();
|
|
|
|
if (!PKP_STRICT_MODE) {
|
|
class_alias('\PKP\oai\OAIUtils', '\OAIUtils');
|
|
}
|