2013-05-12 01:06:17 +02:00
|
|
|
<?php
|
2017-05-12 18:13:53 +02:00
|
|
|
/**
|
|
|
|
* Simple OAI-PMH 2.0 Data Provider
|
2017-05-13 12:08:11 +02:00
|
|
|
* Copyright (C) 2005 Heinrich Stamerjohanns <stamer@uni-oldenburg.de>
|
|
|
|
* Copyright (C) 2011 Jianfeng Li <jianfeng.li@adelaide.edu.au>
|
2017-05-12 18:13:53 +02:00
|
|
|
* Copyright (C) 2013 Daniel Neis Araujo <danielneis@gmail.com>
|
|
|
|
* Copyright (C) 2017 Sebastian Meyer <sebastian.meyer@opencultureconsulting.com>
|
|
|
|
*
|
|
|
|
* This program is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2020-01-24 00:13:17 +01:00
|
|
|
namespace OCC\OAI2;
|
2013-05-14 05:54:50 +02:00
|
|
|
|
|
|
|
/**
|
2013-05-14 23:24:59 +02:00
|
|
|
* This is an implementation of OAI Data Provider version 2.0.
|
|
|
|
* @see http://www.openarchives.org/OAI/2.0/openarchivesprotocol.htm
|
2013-05-12 02:18:36 +02:00
|
|
|
*/
|
2020-01-24 00:13:17 +01:00
|
|
|
class Server {
|
2013-05-12 01:06:17 +02:00
|
|
|
|
2020-01-08 17:24:22 +01:00
|
|
|
public $errors = [];
|
|
|
|
private $args = [];
|
2013-05-14 21:46:15 +02:00
|
|
|
private $verb = '';
|
2017-09-28 14:47:24 +02:00
|
|
|
private $max_records = 100;
|
2017-05-12 18:13:53 +02:00
|
|
|
private $token_prefix = '/tmp/oai2-';
|
2013-05-14 23:24:59 +02:00
|
|
|
private $token_valid = 86400;
|
2013-05-12 02:18:36 +02:00
|
|
|
|
2017-05-12 18:13:53 +02:00
|
|
|
public function __construct($uri, $args, $identifyResponse, $callbacks, $config) {
|
2017-10-19 09:51:33 +02:00
|
|
|
$this->uri = $uri;
|
2020-01-08 17:24:22 +01:00
|
|
|
$verbs = ['Identify', 'ListMetadataFormats', 'ListSets', 'ListIdentifiers', 'ListRecords', 'GetRecord'];
|
2017-10-15 18:05:50 +02:00
|
|
|
if (empty($args['verb']) || !in_array($args['verb'], $verbs)) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badVerb');
|
2017-10-15 18:05:50 +02:00
|
|
|
return;
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
2017-10-15 18:05:50 +02:00
|
|
|
$this->verb = $args['verb'];
|
|
|
|
unset($args['verb']);
|
|
|
|
$this->args = $args;
|
|
|
|
$this->identifyResponse = $identifyResponse;
|
|
|
|
$this->listMetadataFormatsCallback = $callbacks['ListMetadataFormats'];
|
2022-07-14 11:00:48 +02:00
|
|
|
$this->listSetsCallback = $callbacks['ListSets'];
|
2017-10-15 18:05:50 +02:00
|
|
|
$this->listRecordsCallback = $callbacks['ListRecords'];
|
|
|
|
$this->getRecordCallback = $callbacks['GetRecord'];
|
|
|
|
$this->max_records = $config['maxRecords'];
|
|
|
|
$this->token_prefix = $config['tokenPrefix'];
|
|
|
|
$this->token_valid = $config['tokenValid'];
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->response = new Response($this->uri, $this->verb, $this->args);
|
2020-01-08 17:24:22 +01:00
|
|
|
call_user_func([$this, $this->verb]);
|
2013-05-15 02:56:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function response() {
|
2013-05-14 21:46:15 +02:00
|
|
|
if (empty($this->errors)) {
|
2013-05-15 02:56:52 +02:00
|
|
|
return $this->response->doc;
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
2020-01-24 00:13:17 +01:00
|
|
|
$errorResponse = new Response($this->uri, $this->verb, $this->args);
|
2017-10-15 18:11:50 +02:00
|
|
|
$oai_node = $errorResponse->doc->documentElement;
|
2020-01-16 15:36:33 +01:00
|
|
|
foreach ($this->errors as $e) {
|
2017-10-15 18:11:50 +02:00
|
|
|
$node = $errorResponse->addChild($oai_node, 'error', $e->getMessage());
|
|
|
|
$node->setAttribute('code', $e->getOAI2Code());
|
|
|
|
}
|
|
|
|
return $errorResponse->doc;
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
|
|
|
|
2013-05-14 23:24:59 +02:00
|
|
|
public function Identify() {
|
2013-05-14 21:46:15 +02:00
|
|
|
if (count($this->args) > 0) {
|
2020-01-16 15:36:33 +01:00
|
|
|
foreach ($this->args as $key => $val) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
2020-01-16 15:36:33 +01:00
|
|
|
foreach ($this->identifyResponse as $key => $val) {
|
2013-05-14 23:24:59 +02:00
|
|
|
$this->response->addToVerbNode($key, $val);
|
|
|
|
}
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 23:24:59 +02:00
|
|
|
public function ListMetadataFormats() {
|
2017-10-15 17:51:27 +02:00
|
|
|
$identifier = '';
|
2013-05-14 21:46:15 +02:00
|
|
|
foreach ($this->args as $argument => $value) {
|
|
|
|
if ($argument != 'identifier') {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2017-10-15 17:51:27 +02:00
|
|
|
} else {
|
|
|
|
$identifier = $value;
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
|
|
|
}
|
2013-05-14 23:24:59 +02:00
|
|
|
if (empty($this->errors)) {
|
|
|
|
try {
|
2013-05-15 02:56:52 +02:00
|
|
|
if ($formats = call_user_func($this->listMetadataFormatsCallback, $identifier)) {
|
2020-01-16 15:36:33 +01:00
|
|
|
foreach ($formats as $key => $val) {
|
2017-05-12 18:13:53 +02:00
|
|
|
$cmf = $this->response->addToVerbNode('metadataFormat');
|
|
|
|
$this->response->addChild($cmf, 'metadataPrefix', $key);
|
|
|
|
$this->response->addChild($cmf, 'schema', $val['schema']);
|
2017-05-13 12:21:26 +02:00
|
|
|
$this->response->addChild($cmf, 'metadataNamespace', $val['namespace']);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('noMetadataFormats');
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
2020-01-24 00:13:17 +01:00
|
|
|
} catch (Exception $e) {
|
2013-05-14 23:24:59 +02:00
|
|
|
$this->errors[] = $e;
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 23:24:59 +02:00
|
|
|
public function ListSets() {
|
2013-05-14 21:46:15 +02:00
|
|
|
if (isset($this->args['resumptionToken'])) {
|
|
|
|
if (count($this->args) > 1) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
} else {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badResumptionToken');
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
2022-07-14 11:00:48 +02:00
|
|
|
} elseif (empty($this->errors)) {
|
|
|
|
try {
|
|
|
|
if ($sets = call_user_func($this->listSetsCallback, $identifier)) {
|
|
|
|
foreach ($sets as $key => $val) {
|
|
|
|
$cmf = $this->response->addToVerbNode('set');
|
|
|
|
$this->response->addChild($cmf, 'setSpec', $key);
|
|
|
|
$this->response->addChild($cmf, 'setName', $val['name']);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$this->errors[] = new Exception('noSetHierarchy#1');
|
|
|
|
}
|
|
|
|
} catch (Exception $e) {
|
|
|
|
$this->errors[] = $e;
|
|
|
|
}
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('noSetHierarchy');
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 23:24:59 +02:00
|
|
|
public function GetRecord() {
|
2017-05-13 13:23:24 +02:00
|
|
|
if (!isset($this->args['identifier']) || !isset($this->args['metadataPrefix'])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
} else {
|
|
|
|
$metadataFormats = call_user_func($this->listMetadataFormatsCallback);
|
|
|
|
if (!isset($metadataFormats[$this->args['metadataPrefix']])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('cannotDisseminateFormat');
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
|
|
|
}
|
2013-05-14 23:24:59 +02:00
|
|
|
if (empty($this->errors)) {
|
|
|
|
try {
|
|
|
|
if ($record = call_user_func($this->getRecordCallback, $this->args['identifier'], $this->args['metadataPrefix'])) {
|
|
|
|
$cur_record = $this->response->addToVerbNode('record');
|
2017-10-15 17:51:27 +02:00
|
|
|
$this->response->createHeader($record['identifier'], $this->formatDatestamp($record['timestamp']), $record['deleted'], $cur_record);
|
2017-09-28 14:47:24 +02:00
|
|
|
if (!$record['deleted']) {
|
2017-10-12 10:17:43 +02:00
|
|
|
$this->addMetadata($cur_record, $record['metadata']);
|
2017-09-28 14:47:24 +02:00
|
|
|
}
|
2013-05-14 05:54:50 +02:00
|
|
|
} else {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('idDoesNotExist');
|
2013-05-14 05:54:50 +02:00
|
|
|
}
|
2020-01-24 00:13:17 +01:00
|
|
|
} catch (Exception $e) {
|
2013-05-14 23:24:59 +02:00
|
|
|
$this->errors[] = $e;
|
2013-05-14 05:54:50 +02:00
|
|
|
}
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-05-14 23:24:59 +02:00
|
|
|
public function ListIdentifiers() {
|
2013-05-20 21:07:54 +02:00
|
|
|
$this->ListRecords();
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public function ListRecords() {
|
2017-05-12 18:13:53 +02:00
|
|
|
$maxItems = $this->max_records;
|
2013-05-14 23:24:59 +02:00
|
|
|
$deliveredRecords = 0;
|
2017-12-22 09:46:36 +01:00
|
|
|
$metadataPrefix = isset($this->args['metadataPrefix']) ? $this->args['metadataPrefix'] : '';
|
2013-05-14 23:24:59 +02:00
|
|
|
$from = isset($this->args['from']) ? $this->args['from'] : '';
|
|
|
|
$until = isset($this->args['until']) ? $this->args['until'] : '';
|
2022-07-14 11:00:48 +02:00
|
|
|
$set = isset($this->args['set']) ? $this->args['set'] : null;
|
|
|
|
|
2013-05-14 05:54:50 +02:00
|
|
|
if (isset($this->args['resumptionToken'])) {
|
2013-05-14 21:46:15 +02:00
|
|
|
if (count($this->args) > 1) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
} else {
|
2017-05-13 12:55:50 +02:00
|
|
|
if (!file_exists($this->token_prefix.$this->args['resumptionToken'])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badResumptionToken');
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
2017-05-13 12:55:50 +02:00
|
|
|
if (filemtime($this->token_prefix.$this->args['resumptionToken'])+$this->token_valid < time()) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badResumptionToken');
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
|
|
|
if ($readings = $this->readResumptionToken($this->token_prefix.$this->args['resumptionToken'])) {
|
2017-05-12 18:13:53 +02:00
|
|
|
list($deliveredRecords, $metadataPrefix, $from, $until) = $readings;
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badResumptionToken');
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
}
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
|
|
|
} else {
|
2013-05-14 21:46:15 +02:00
|
|
|
if (!isset($this->args['metadataPrefix'])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
} else {
|
|
|
|
$metadataFormats = call_user_func($this->listMetadataFormatsCallback);
|
|
|
|
if (!isset($metadataFormats[$this->args['metadataPrefix']])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('cannotDisseminateFormat');
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isset($this->args['from'])) {
|
2017-05-12 18:13:53 +02:00
|
|
|
if (!$this->checkDateFormat($this->args['from'])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (isset($this->args['until'])) {
|
2017-05-12 18:13:53 +02:00
|
|
|
if (!$this->checkDateFormat($this->args['until'])) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$this->errors[] = new Exception('badArgument');
|
2013-05-14 21:46:15 +02:00
|
|
|
}
|
|
|
|
}
|
2022-07-01 15:33:25 +02:00
|
|
|
if (isset($this->args['from']) && isset($this->args['until'])) {
|
|
|
|
if (strlen($this->args['from']) !== strlen($this->args['until'])) {
|
|
|
|
$this->errors[] = new Exception('badArgument');
|
|
|
|
}
|
|
|
|
}
|
2017-05-12 18:13:53 +02:00
|
|
|
if (isset($this->args['set'])) {
|
2022-07-14 11:00:48 +02:00
|
|
|
$ListSets = call_user_func($this->listSetsCallback);
|
|
|
|
if (!isset($ListSets[$this->args['set']])) {
|
|
|
|
$this->errors[] = new Exception('noSetHierarchy');
|
|
|
|
}
|
2017-05-12 18:13:53 +02:00
|
|
|
}
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
2013-05-15 02:56:52 +02:00
|
|
|
if (empty($this->errors)) {
|
2013-05-14 23:24:59 +02:00
|
|
|
try {
|
2022-07-14 11:00:48 +02:00
|
|
|
if (!($records_count = call_user_func($this->listRecordsCallback, $metadataPrefix, $this->formatTimestamp($from), $this->formatTimestamp($until), true, 0, 100, $set))) {
|
2020-01-24 00:13:17 +01:00
|
|
|
throw new Exception('noRecordsMatch');
|
2017-05-13 13:23:24 +02:00
|
|
|
}
|
2022-07-14 11:00:48 +02:00
|
|
|
$records = call_user_func($this->listRecordsCallback, $metadataPrefix, $this->formatTimestamp($from), $this->formatTimestamp($until), false, $deliveredRecords, $maxItems, $set);
|
2013-05-14 23:24:59 +02:00
|
|
|
foreach ($records as $record) {
|
2017-12-22 09:46:36 +01:00
|
|
|
$cur_record = null;
|
2017-10-12 10:14:05 +02:00
|
|
|
if ($this->verb == 'ListRecords') { // for ListIdentifiers, only headers will be returned.
|
2017-10-12 10:17:43 +02:00
|
|
|
$cur_record = $this->response->addToVerbNode('record');
|
2017-10-12 10:14:05 +02:00
|
|
|
}
|
2017-10-15 17:51:27 +02:00
|
|
|
$this->response->createHeader($record['identifier'], $this->formatDatestamp($record['timestamp']), $record['deleted'], $cur_record);
|
2017-10-12 10:14:05 +02:00
|
|
|
if (!$record['deleted'] && $this->verb == 'ListRecords') { // for ListIdentifiers, only headers will be returned.
|
2017-10-12 10:17:43 +02:00
|
|
|
$this->addMetadata($cur_record, $record['metadata']);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
// Will we need a new ResumptionToken?
|
|
|
|
if ($records_count - $deliveredRecords > $maxItems) {
|
|
|
|
$deliveredRecords += $maxItems;
|
2017-12-21 18:46:16 +01:00
|
|
|
$restoken = $this->createResumptionToken($deliveredRecords, $metadataPrefix, $from, $until);
|
2017-05-12 18:13:53 +02:00
|
|
|
$expirationDatetime = gmstrftime('%Y-%m-%dT%TZ', time()+$this->token_valid);
|
2017-10-15 17:51:27 +02:00
|
|
|
} elseif (isset($this->args['resumptionToken'])) {
|
2020-01-08 17:24:22 +01:00
|
|
|
// Last delivery, return empty resumptionToken
|
2013-05-14 23:24:59 +02:00
|
|
|
$restoken = null;
|
|
|
|
$expirationDatetime = null;
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
2013-05-14 23:24:59 +02:00
|
|
|
if (isset($restoken)) {
|
2017-05-13 13:23:24 +02:00
|
|
|
$this->response->createResumptionToken($restoken, $expirationDatetime, $records_count, $deliveredRecords-$maxItems);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
2020-01-24 00:13:17 +01:00
|
|
|
} catch (Exception $e) {
|
2013-05-14 23:24:59 +02:00
|
|
|
$this->errors[] = $e;
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-28 14:47:24 +02:00
|
|
|
private function addMetadata($cur_record, $file) {
|
2017-10-12 10:17:43 +02:00
|
|
|
$meta_node = $this->response->addChild($cur_record, 'metadata');
|
2020-01-24 00:13:17 +01:00
|
|
|
$fragment = new \DOMDocument();
|
2017-10-12 10:17:43 +02:00
|
|
|
$fragment->load($file);
|
|
|
|
$this->response->importFragment($meta_node, $fragment);
|
2013-05-14 05:54:50 +02:00
|
|
|
}
|
|
|
|
|
2017-12-21 18:46:16 +01:00
|
|
|
private function createResumptionToken($deliveredRecords, $metadataPrefix, $from, $until) {
|
2017-05-13 12:49:13 +02:00
|
|
|
list($usec, $sec) = explode(' ', microtime());
|
2017-12-22 10:50:55 +01:00
|
|
|
$token = ((int)($usec*1000) + (int)($sec*1000)).'_'.$metadataPrefix;
|
2017-12-22 10:47:40 +01:00
|
|
|
$file = fopen($this->token_prefix.$token, 'w');
|
2020-01-16 15:36:33 +01:00
|
|
|
if ($file == false) {
|
2017-05-12 18:13:53 +02:00
|
|
|
exit('Cannot write resumption token. Writing permission needs to be changed.');
|
|
|
|
}
|
2017-12-21 18:46:16 +01:00
|
|
|
fputs($file, $deliveredRecords.'#');
|
|
|
|
fputs($file, $metadataPrefix.'#');
|
|
|
|
fputs($file, $from.'#');
|
|
|
|
fputs($file, $until);
|
2017-10-15 18:05:50 +02:00
|
|
|
fclose($file);
|
2013-05-14 23:24:59 +02:00
|
|
|
return $token;
|
2013-05-14 05:54:50 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private function readResumptionToken($resumptionToken) {
|
|
|
|
$rtVal = false;
|
2017-10-15 18:05:50 +02:00
|
|
|
$file = fopen($resumptionToken, 'r');
|
|
|
|
if ($file != false) {
|
|
|
|
$filetext = fgets($file, 255);
|
2013-05-14 05:54:50 +02:00
|
|
|
$textparts = explode('#', $filetext);
|
2017-10-15 18:05:50 +02:00
|
|
|
fclose($file);
|
2013-05-14 05:54:50 +02:00
|
|
|
unlink($resumptionToken);
|
|
|
|
$rtVal = array_values($textparts);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
return $rtVal;
|
|
|
|
}
|
|
|
|
|
2017-05-12 18:13:53 +02:00
|
|
|
private function formatDatestamp($timestamp) {
|
|
|
|
return gmdate('Y-m-d\TH:i:s\Z', $timestamp);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
|
|
|
|
2017-05-12 18:13:53 +02:00
|
|
|
private function formatTimestamp($datestamp) {
|
|
|
|
if (is_array($time = strptime($datestamp, '%Y-%m-%dT%H:%M:%SZ')) || is_array($time = strptime($datestamp, '%Y-%m-%d'))) {
|
|
|
|
return gmmktime($time['tm_hour'], $time['tm_min'], $time['tm_sec'], $time['tm_mon'] + 1, $time['tm_mday'], $time['tm_year']+1900);
|
2013-05-14 23:24:59 +02:00
|
|
|
} else {
|
2017-05-12 18:13:53 +02:00
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function checkDateFormat($date) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$datetime = \DateTime::createFromFormat('Y-m-d\TH:i:s\Z', $date);
|
2017-10-15 18:05:50 +02:00
|
|
|
if ($datetime === false) {
|
2020-01-24 00:13:17 +01:00
|
|
|
$datetime = \DateTime::createFromFormat('Y-m-d', $date);
|
2013-05-14 23:24:59 +02:00
|
|
|
}
|
2017-10-15 18:09:01 +02:00
|
|
|
return ($datetime !== false) && !array_sum($datetime->getLastErrors());
|
2013-05-12 02:18:36 +02:00
|
|
|
}
|
2017-05-12 18:13:53 +02:00
|
|
|
|
2013-05-12 01:06:17 +02:00
|
|
|
}
|