mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Move date formatting out of SQL and standardize on the DateFormatter trait
Fixes #56
This commit is contained in:
parent
7e7b204d85
commit
17ec6cf669
17 changed files with 130 additions and 188 deletions
|
@ -6,6 +6,7 @@ use JKingWeb\Arsse\Misc\Query;
|
|||
use JKingWeb\Arsse\Misc\Context;
|
||||
|
||||
class Database {
|
||||
use Misc\DateFormatter;
|
||||
|
||||
const SCHEMA_VERSION = 1;
|
||||
const FORMAT_TS = "Y-m-d h:i:s";
|
||||
|
@ -13,7 +14,6 @@ class Database {
|
|||
const FORMAT_TIME = "h:i:s";
|
||||
|
||||
public $db;
|
||||
protected $dateFormatDefault = "sql";
|
||||
|
||||
public function __construct() {
|
||||
$driver = Data::$conf->dbDriver;
|
||||
|
@ -27,15 +27,6 @@ class Database {
|
|||
protected function caller(): string {
|
||||
return debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3)[2]['function'];
|
||||
}
|
||||
|
||||
public function dateFormatDefault(string $set = null): string {
|
||||
if(is_null($set)) return $this->dateFormatDefault;
|
||||
$set = strtolower($set);
|
||||
if(in_array($set, ["sql", "iso8601", "unix", "http"])) {
|
||||
$this->dateFormatDefault = $set;
|
||||
}
|
||||
return $this->dateFormatDefault;
|
||||
}
|
||||
|
||||
static public function listDrivers(): array {
|
||||
$sep = \DIRECTORY_SEPARATOR;
|
||||
|
@ -349,17 +340,14 @@ class Database {
|
|||
$q = new Query(
|
||||
"SELECT
|
||||
arsse_subscriptions.id,
|
||||
url,favicon,source,folder,pinned,err_count,err_msg,order_type,
|
||||
DATEFORMAT(?, added) as added,
|
||||
url,favicon,source,folder,pinned,err_count,err_msg,order_type,added,
|
||||
topmost.top as top_folder,
|
||||
coalesce(arsse_subscriptions.title, arsse_feeds.title) as title,
|
||||
(SELECT count(*) from arsse_articles where feed is arsse_subscriptions.feed) - (SELECT count(*) from arsse_marks join user on user is owner join arsse_articles on article = arsse_articles.id where feed is arsse_feeds.id and read is 1) as unread
|
||||
from arsse_subscriptions
|
||||
join user on user is owner
|
||||
join arsse_feeds on feed = arsse_feeds.id
|
||||
left join topmost on folder=f_id",
|
||||
"str", // where terms
|
||||
$this->dateFormatDefault
|
||||
left join topmost on folder=f_id"
|
||||
);
|
||||
$q->setOrder("pinned desc, title");
|
||||
// define common table expressions
|
||||
|
@ -444,13 +432,13 @@ class Database {
|
|||
public function feedUpdate(int $feedID, bool $throwError = false): bool {
|
||||
$tr = $this->db->begin();
|
||||
// check to make sure the feed exists
|
||||
$f = $this->db->prepare("SELECT url, username, password, DATEFORMAT('http', modified) AS lastmodified, etag, err_count FROM arsse_feeds where id is ?", "int")->run($feedID)->getRow();
|
||||
$f = $this->db->prepare("SELECT url, username, password, modified, etag, err_count FROM arsse_feeds where id is ?", "int")->run($feedID)->getRow();
|
||||
if(!$f) throw new Db\ExceptionInput("subjectMissing", ["action" => __FUNCTION__, "field" => "feed", 'id' => $feedID]);
|
||||
// the Feed object throws an exception when there are problems, but that isn't ideal
|
||||
// here. When an exception is thrown it should update the database with the
|
||||
// error instead of failing; if other exceptions are thrown, we should simply roll back
|
||||
try {
|
||||
$feed = new Feed($feedID, $f['url'], (string)$f['lastmodified'], $f['etag'], $f['username'], $f['password']);
|
||||
$feed = new Feed($feedID, $f['url'], $this->dateTransform($f['modified'], "http", "sql"), $f['etag'], $f['username'], $f['password']);
|
||||
if(!$feed->modified) {
|
||||
// if the feed hasn't changed, just compute the next fetch time and record it
|
||||
$this->db->prepare("UPDATE arsse_feeds SET updated = CURRENT_TIMESTAMP, next_fetch = ? WHERE id is ?", 'datetime', 'int')->run($feed->nextFetch, $feedID);
|
||||
|
@ -556,7 +544,7 @@ class Database {
|
|||
|
||||
public function feedMatchLatest(int $feedID, int $count): Db\Result {
|
||||
return $this->db->prepare(
|
||||
"SELECT id, DATEFORMAT('unix', edited) AS edited_date, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? ORDER BY modified desc, id desc limit ?",
|
||||
"SELECT id, edited, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? ORDER BY modified desc, id desc limit ?",
|
||||
'int', 'int'
|
||||
)->run($feedID, $count);
|
||||
}
|
||||
|
@ -569,7 +557,7 @@ class Database {
|
|||
list($cHashTC, $tHashTC) = $this->generateIn($hashesTC, "str");
|
||||
// perform the query
|
||||
return $articles = $this->db->prepare(
|
||||
"SELECT id, DATEFORMAT('unix', edited) AS edited_date, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? and (guid in($cId) or url_title_hash in($cHashUT) or url_content_hash in($cHashUC) or title_content_hash in($cHashTC))",
|
||||
"SELECT id, edited, guid, url_title_hash, url_content_hash, title_content_hash FROM arsse_articles WHERE feed is ? and (guid in($cId) or url_title_hash in($cHashUT) or url_content_hash in($cHashUC) or title_content_hash in($cHashTC))",
|
||||
'int', $tId, $tHashUT, $tHashUC, $tHashTC
|
||||
)->run($feedID, $ids, $hashesUT, $hashesUC, $hashesTC);
|
||||
}
|
||||
|
@ -613,12 +601,12 @@ class Database {
|
|||
arsse_articles.id as id,
|
||||
arsse_articles.url as url,
|
||||
title,author,content,guid,
|
||||
DATEFORMAT(?, published) as published_date,
|
||||
DATEFORMAT(?, edited) as edited_date,
|
||||
DATEFORMAT(?, max(
|
||||
published as published_date,
|
||||
edited as edited_date,
|
||||
max(
|
||||
modified,
|
||||
coalesce((select modified from arsse_marks join user on user is owner where article is arsse_articles.id),'')
|
||||
)) as modified_date,
|
||||
) as modified_date,
|
||||
NOT (select count(*) from arsse_marks join user on user is owner where article is arsse_articles.id and read is 1) as unread,
|
||||
(select count(*) from arsse_marks join user on user is owner where article is arsse_articles.id and starred is 1) as starred,
|
||||
(select max(id) from arsse_editions where article is arsse_articles.id) as edition,
|
||||
|
@ -629,9 +617,7 @@ class Database {
|
|||
FROM arsse_articles
|
||||
join subscribed_feeds on arsse_articles.feed is subscribed_feeds.id
|
||||
left join arsse_enclosures on arsse_enclosures.article is arsse_articles.id
|
||||
",
|
||||
["str", "str", "str"],
|
||||
[$this->dateFormatDefault, $this->dateFormatDefault, $this->dateFormatDefault]
|
||||
"
|
||||
);
|
||||
$q->setOrder("edition".($context->reverse ? " desc" : ""));
|
||||
$q->setLimit($context->limit, $context->offset);
|
||||
|
|
|
@ -3,12 +3,13 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db;
|
||||
|
||||
abstract class AbstractStatement implements Statement {
|
||||
use \JKingWeb\Arsse\Misc\DateFormatter;
|
||||
|
||||
protected $types = [];
|
||||
protected $isNullable = [];
|
||||
protected $values = ['pre' => [], 'post' => []];
|
||||
|
||||
abstract function runArray(array $values = []): Result;
|
||||
abstract static function dateFormat(int $part = self::TS_BOTH): string;
|
||||
|
||||
public function run(...$values): Result {
|
||||
return $this->runArray($values);
|
||||
|
@ -44,13 +45,13 @@ abstract class AbstractStatement implements Statement {
|
|||
switch($t) {
|
||||
case "date":
|
||||
if(is_null($v) && !$nullable) $v = 0;
|
||||
return $this->formatDate($v, self::TS_DATE);
|
||||
return $this->dateTransform($v, "date");
|
||||
case "time":
|
||||
if(is_null($v) && !$nullable) $v = 0;
|
||||
return $this->formatDate($v, self::TS_TIME);
|
||||
return $this->dateTransform($v, "time");
|
||||
case "datetime":
|
||||
if(is_null($v) && !$nullable) $v = 0;
|
||||
return $this->formatDate($v, self::TS_BOTH);
|
||||
return $this->dateTransform($v, "sql");
|
||||
case "null":
|
||||
case "integer":
|
||||
case "float":
|
||||
|
@ -65,9 +66,12 @@ abstract class AbstractStatement implements Statement {
|
|||
// handle objects
|
||||
$value = $v;
|
||||
if($value instanceof \DateTimeInterface) {
|
||||
$value = $value->getTimestamp();
|
||||
if($t=="string") $value = $this->formatDate($value, self::TS_BOTH);
|
||||
settype($value, $t);
|
||||
if($t=="string") {
|
||||
$value = $this->dateTransform($value, "sql");
|
||||
} else {
|
||||
$value = $value->getTimestamp();
|
||||
settype($value, $t);
|
||||
}
|
||||
} else {
|
||||
$value = null;
|
||||
settype($value, $t);
|
||||
|
@ -78,24 +82,4 @@ abstract class AbstractStatement implements Statement {
|
|||
throw new Exception("paramTypeUnknown", $type);
|
||||
}
|
||||
}
|
||||
|
||||
protected function formatDate($date, int $part = self::TS_BOTH) {
|
||||
// convert input to a Unix timestamp
|
||||
if($date instanceof \DateTimeInterface) {
|
||||
$time = $date->getTimestamp();
|
||||
} else if(is_numeric($date)) {
|
||||
$time = (int) $date;
|
||||
} else if($date===null) {
|
||||
return null;
|
||||
} else if(is_string($date)) {
|
||||
$time = strtotime($date);
|
||||
if($time===false) return null;
|
||||
} else if (is_bool($date)) {
|
||||
return null;
|
||||
} else {
|
||||
$time = (int) $date;
|
||||
}
|
||||
// ISO 8601 with space in the middle instead of T.
|
||||
return gmdate($this->dateFormat($part), $time);
|
||||
}
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
<?php
|
||||
declare(strict_types=1);
|
||||
namespace JKingWeb\Arsse\Db\SQLite3;
|
||||
|
||||
class CustomFunctions {
|
||||
protected static $tz;
|
||||
|
||||
// Converts from SQL date format to a specified standard date format.
|
||||
public static function dateFormat(string $format, $date) {
|
||||
$format = strtolower($format);
|
||||
if($format=="sql") return $date;
|
||||
settype($date, "string");
|
||||
if($date=="") return null;
|
||||
if(is_null(self::$tz)) self::$tz = new \DateTimeZone("UTC");
|
||||
$date = \DateTime::createFromFormat('Y-m-d H:i:s', $date, self::$tz);
|
||||
switch ($format) {
|
||||
case 'unix':
|
||||
return $date->getTimestamp();
|
||||
case 'http':
|
||||
return $date->format("D, d M Y H:i:s \G\M\T");
|
||||
case 'iso8601':
|
||||
default:
|
||||
return $date->format(\DateTime::ATOM);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -40,8 +40,6 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
$this->db->enableExceptions(true);
|
||||
$this->exec("PRAGMA journal_mode = wal");
|
||||
$this->exec("PRAGMA foreign_keys = yes");
|
||||
// Create custom functions
|
||||
$this->db->createFunction('DATEFORMAT', [CustomFunctions::class, 'dateFormat'], 2);
|
||||
} catch(\Exception $e) {
|
||||
list($excClass, $excMsg, $excData) = $this->exceptionBuild();
|
||||
throw new $excClass($excMsg, $excData);
|
||||
|
|
|
@ -37,14 +37,6 @@ class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
|||
unset($this->st);
|
||||
}
|
||||
|
||||
public static function dateFormat(int $part = self::TS_BOTH): string {
|
||||
return ([
|
||||
self::TS_TIME => 'H:i:s',
|
||||
self::TS_DATE => 'Y-m-d',
|
||||
self::TS_BOTH => 'Y-m-d H:i:s',
|
||||
])[$part];
|
||||
}
|
||||
|
||||
public function runArray(array $values = []): \JKingWeb\Arsse\Db\Result {
|
||||
$this->st->clear();
|
||||
$this->bindValues($values);
|
||||
|
|
|
@ -3,9 +3,6 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db;
|
||||
|
||||
interface Statement {
|
||||
const TS_TIME = -1;
|
||||
const TS_DATE = 0;
|
||||
const TS_BOTH = 1;
|
||||
const TYPES = [
|
||||
"null" => "null",
|
||||
"nil" => "null",
|
||||
|
@ -30,8 +27,6 @@ interface Statement {
|
|||
"bit" => "boolean",
|
||||
];
|
||||
|
||||
static function dateFormat(int $part = self::TS_BOTH): string;
|
||||
|
||||
function run(...$values): Result;
|
||||
function runArray(array $values = []): Result;
|
||||
function rebind(...$bindings): bool;
|
||||
|
|
|
@ -7,6 +7,8 @@ use PicoFeed\Reader\Favicon;
|
|||
use PicoFeed\Config\Config;
|
||||
|
||||
class Feed {
|
||||
use Misc\DateFormatter;
|
||||
|
||||
public $data = null;
|
||||
public $favicon;
|
||||
public $parser;
|
||||
|
@ -24,7 +26,7 @@ class Feed {
|
|||
// format the HTTP Last-Modified date returned
|
||||
$lastMod = $this->resource->getLastModified();
|
||||
if(strlen($lastMod)) {
|
||||
$this->lastModified = \DateTime::createFromFormat("!D, d M Y H:i:s e", $lastMod);
|
||||
$this->lastModified = $this->dateNormalize($lastMod, "http");
|
||||
}
|
||||
$this->modified = $this->resource->isModified();
|
||||
//parse the feed, if it has been modified
|
||||
|
@ -229,7 +231,7 @@ class Feed {
|
|||
($i->urlContentHash && $i->urlContentHash === $a['url_content_hash']) ||
|
||||
($i->titleContentHash && $i->titleContentHash === $a['title_content_hash'])
|
||||
) {
|
||||
if($i->updatedDate && $i->updatedDate->getTimestamp() !== $a['edited_date']) {
|
||||
if($i->updatedDate && $this->dateTransform($i->updatedDate, "sql") !== $a['edited']) {
|
||||
// if the item has an edit timestamp and it doesn't match that of the article in the database, the the article has been edited
|
||||
// we store the item index and database record ID as a key/value pair
|
||||
$found = true;
|
||||
|
|
|
@ -4,36 +4,46 @@ namespace JKingWeb\Arsse\Misc;
|
|||
|
||||
trait DateFormatter {
|
||||
|
||||
protected function dateTransform($date, string $format = "iso8601", bool $local = false) {
|
||||
$date = $this->dateNormalize($date);
|
||||
$format = strtolower($format);
|
||||
if($format=="unix") return $date;
|
||||
switch ($format) {
|
||||
protected function dateTransform($date, string $outFormat = null, string $inFormat = null, bool $inLocal = false) {
|
||||
$date = $this->dateNormalize($date, $inFormat, $inLocal);
|
||||
if(is_null($date) || is_null($outFormat)) return $date;
|
||||
$outFormat = strtolower($outFormat);
|
||||
if($outFormat=="unix") return $date->getTimestamp();
|
||||
switch ($outFormat) {
|
||||
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
|
||||
case 'iso8601': $f = \DateTime::ATOM; break;
|
||||
case 'iso8601': $f = "Y-m-dTH:i:s"; break;
|
||||
case 'sql': $f = "Y-m-d H:i:s"; break;
|
||||
case 'date': $f = "Y-m-d"; break;
|
||||
case 'time': $f = "H:i:s"; break;
|
||||
default: $f = \DateTime::ATOM; break;
|
||||
}
|
||||
if($local) {
|
||||
return date($f, $date);
|
||||
} else {
|
||||
return gmdate($f, $date);
|
||||
default: $f = $outFormat; break;
|
||||
}
|
||||
return $date->format($f);
|
||||
}
|
||||
|
||||
protected function dateNormalize($date) {
|
||||
protected function dateNormalize($date, string $inFormat = null, bool $inLocal = false) {
|
||||
// convert input to a Unix timestamp
|
||||
if($date instanceof \DateTimeInterface) {
|
||||
$time = $date->getTimestamp();
|
||||
return $date;
|
||||
} else if(is_numeric($date)) {
|
||||
$time = (int) $date;
|
||||
} else if($date===null) {
|
||||
return null;
|
||||
} else if(is_string($date)) {
|
||||
try {
|
||||
$time = (new \DateTime($date, new \DateTimeZone("UTC")))->getTimestamp();
|
||||
$tz = (!$inLocal) ? new \DateTimeZone("UTC") : null;
|
||||
if(!is_null($inFormat)) {
|
||||
switch($inFormat) {
|
||||
case 'http': $f = "D, d M Y H:i:s \G\M\T"; break;
|
||||
case 'iso8601': $f = "Y-m-dTH:i:sP"; break;
|
||||
case 'sql': $f = "Y-m-d H:i:s"; break;
|
||||
case 'date': $f = "Y-m-d"; break;
|
||||
case 'time': $f = "H:i:s"; break;
|
||||
default: $f = $inFormat; break;
|
||||
}
|
||||
return \DateTime::createFromFormat("!".$f, $date, $tz);
|
||||
} else {
|
||||
return new \DateTime($date, $tz);
|
||||
}
|
||||
} catch(\Throwable $e) {
|
||||
return null;
|
||||
}
|
||||
|
@ -42,6 +52,8 @@ trait DateFormatter {
|
|||
} else {
|
||||
$time = (int) $date;
|
||||
}
|
||||
return $time;
|
||||
$d = new \DateTime();
|
||||
$d->setTimestamp($time);
|
||||
return $d;
|
||||
}
|
||||
}
|
|
@ -3,6 +3,8 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\REST;
|
||||
|
||||
abstract class AbstractHandler implements Handler {
|
||||
use \JKingWeb\Arsse\Misc\DateFormatter;
|
||||
|
||||
abstract function __construct();
|
||||
abstract function dispatch(Request $req): Response;
|
||||
|
||||
|
@ -16,9 +18,15 @@ abstract class AbstractHandler implements Handler {
|
|||
return $out;
|
||||
}
|
||||
|
||||
protected function fieldMapTypes(array $data, array $map): array {
|
||||
protected function fieldMapTypes(array $data, array $map, string $dateFormat = "sql"): array {
|
||||
foreach($map as $key => $type) {
|
||||
if(array_key_exists($key, $data)) settype($data[$key], $type);
|
||||
if(array_key_exists($key, $data)) {
|
||||
if($type=="datetime" && $dateFormat != "sql") {
|
||||
$data[$key] = $this->dateTransform($data[$key], $dateFormat, "sql");
|
||||
} else {
|
||||
settype($data[$key], $type);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $data;
|
||||
}
|
||||
|
@ -33,7 +41,7 @@ abstract class AbstractHandler implements Handler {
|
|||
return ($ch1 === $ch2);
|
||||
}
|
||||
|
||||
protected function NormalizeInput(array $data, array $types, string $dateFormat = "Y-m-d\TH:i:sP"): array {
|
||||
protected function NormalizeInput(array $data, array $types, string $dateFormat = null): array {
|
||||
$out = [];
|
||||
foreach($data as $key => $value) {
|
||||
if(!isset($types[$key])) {
|
||||
|
@ -67,7 +75,7 @@ abstract class AbstractHandler implements Handler {
|
|||
if(is_numeric($value)) $out[$key] = (float) $value;
|
||||
break;
|
||||
case "datetime":
|
||||
$t = \DateTime::createFromFormat($dateFormat, (string) $value);
|
||||
$t = $this->dateNormalize($value, $dateFormat);
|
||||
if($t) $out[$key] = $t;
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -14,6 +14,8 @@ use JKingWeb\Arsse\REST\Exception405;
|
|||
class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const REALM = "NextCloud News API v1-2";
|
||||
|
||||
protected $dateFormat = "unix";
|
||||
|
||||
protected $validInput = [
|
||||
'name' => "string",
|
||||
'url' => "string",
|
||||
|
@ -69,7 +71,6 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
if(!method_exists($this, $func)) return new Response(501);
|
||||
// dispatch
|
||||
try {
|
||||
Data::$db->dateFormatDefault("unix");
|
||||
return $this->$func($req->paths, $data);
|
||||
} catch(Exception $e) {
|
||||
// if there was a REST exception return 400
|
||||
|
@ -169,7 +170,8 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
$feed = $this->fieldMapTypes($feed, [
|
||||
'folderId' => "int",
|
||||
'pinned' => "bool",
|
||||
]);
|
||||
'added' => "datetime",
|
||||
], $this->dateFormat);
|
||||
return $feed;
|
||||
}
|
||||
|
||||
|
@ -194,9 +196,11 @@ class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
]);
|
||||
// cast values
|
||||
$article = $this->fieldMapTypes($article, [
|
||||
'unread' => "bool",
|
||||
'starred' => "bool",
|
||||
]);
|
||||
'unread' => "bool",
|
||||
'starred' => "bool",
|
||||
'pubDate' => "datetime",
|
||||
'lastModified' => "datetime",
|
||||
], $this->dateFormat);
|
||||
return $article;
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
protected $latest = [
|
||||
[
|
||||
'id' => 1,
|
||||
'edited_date' => 946684800,
|
||||
'edited' => '2000-01-01 00:00:00',
|
||||
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
|
||||
'url_title_hash' => 'f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6',
|
||||
'url_content_hash' => 'fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4',
|
||||
|
@ -20,7 +20,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 2,
|
||||
'edited_date' => 946771200,
|
||||
'edited' => '2000-01-02 00:00:00',
|
||||
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
|
||||
'url_title_hash' => '0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153',
|
||||
'url_content_hash' => '13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9',
|
||||
|
@ -28,7 +28,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 3,
|
||||
'edited_date' => 946857600,
|
||||
'edited' => '2000-01-03 00:00:00',
|
||||
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
|
||||
'url_title_hash' => 'f74b06b240bd08abf4d3fdfc20dba6a6f6eb8b4f1a00e9a617efd63a87180a4b',
|
||||
'url_content_hash' => 'b278380e984cefe63f0e412b88ffc9cb0befdfa06fdc00bace1da99a8daff406',
|
||||
|
@ -36,7 +36,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 4,
|
||||
'edited_date' => 946944000,
|
||||
'edited' => '2000-01-04 00:00:00',
|
||||
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
|
||||
'url_title_hash' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8',
|
||||
'url_content_hash' => 'f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3',
|
||||
|
@ -44,7 +44,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'edited_date' => 947030400,
|
||||
'edited' => '2000-01-05 00:00:00',
|
||||
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
|
||||
'url_title_hash' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022',
|
||||
'url_content_hash' => '834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900',
|
||||
|
@ -54,7 +54,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
protected $others = [
|
||||
[
|
||||
'id' => 6,
|
||||
'edited_date' => 947116800,
|
||||
'edited' => '2000-01-06 00:00:00',
|
||||
'guid' => 'b3461ab8e8759eeb1d65a818c65051ec00c1dfbbb32a3c8f6999434e3e3b76ab',
|
||||
'url_title_hash' => '91d051a8e6749d014506848acd45e959af50bf876427c4f0e3a1ec0f04777b51',
|
||||
'url_content_hash' => '211d78b1a040d40d17e747a363cc283f58767b2e502630d8de9b8f1d5e941d18',
|
||||
|
@ -62,7 +62,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 7,
|
||||
'edited_date' => 947203200,
|
||||
'edited' => '2000-01-07 00:00:00',
|
||||
'guid' => 'f4fae999d6531747523f4ff0c74f3f0c7c588b67e4f32d8f7dba5f6f36e8a45d',
|
||||
'url_title_hash' => 'b92f805f0d0643dad1d6c0bb5cbaec24729f5f71b37b831cf7ad31f6c9403ac8',
|
||||
'url_content_hash' => '4fc8789b787246e9be08ca1bac0d4a1ac4db1984f0db07f7142417598cf7211f',
|
||||
|
@ -70,7 +70,7 @@ class TestFeed extends \PHPUnit\Framework\TestCase {
|
|||
],
|
||||
[
|
||||
'id' => 8,
|
||||
'edited_date' => 947289600,
|
||||
'edited' => '2000-01-08 00:00:00',
|
||||
'guid' => 'b9d2d58e3172096b1d23b42a59961fabc89962836c3cd5de54f3d3a98ff08e6c',
|
||||
'url_title_hash' => '53a6cbcfeb66b46d09cbb7b25035df0562da35786933319c83b04be29acfb6f4',
|
||||
'url_content_hash' => 'c6f3722b4445b49d19d39c3bf5b11a7cf23dd69873e2a0a458aab662f1cd9438',
|
||||
|
|
|
@ -256,8 +256,6 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase {
|
|||
$this->assertEquals($exp, $this->h->dispatch(new Request("GET", "/feeds")));
|
||||
$exp = new Response(200, $exp2);
|
||||
$this->assertEquals($exp, $this->h->dispatch(new Request("GET", "/feeds")));
|
||||
// make sure the correct date format is actually requested
|
||||
Phake::verify(Data::$db, Phake::atLeast(1))->dateFormatDefault("unix");
|
||||
}
|
||||
|
||||
function testAddASubscription() {
|
||||
|
@ -295,8 +293,6 @@ class TestNCNV1_2 extends \PHPUnit\Framework\TestCase {
|
|||
// try to add a bad feed
|
||||
$exp = new Response(422);
|
||||
$this->assertEquals($exp, $this->h->dispatch(new Request("POST", "/feeds", json_encode($in[2]), 'application/json')));
|
||||
// make sure the correct date format is actually requested
|
||||
Phake::verify(Data::$db, Phake::atLeast(1))->dateFormatDefault("unix");
|
||||
}
|
||||
|
||||
function testRemoveASubscription() {
|
||||
|
|
|
@ -179,9 +179,9 @@ trait SeriesArticle {
|
|||
'author' => '',
|
||||
'content' => '<p>Article content 1</p>',
|
||||
'guid' => 'e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda',
|
||||
'published_date' => 946684800,
|
||||
'edited_date' => 946684801,
|
||||
'modified_date' => 946688400,
|
||||
'published_date' => '2000-01-01 00:00:00',
|
||||
'edited_date' => '2000-01-01 00:00:01',
|
||||
'modified_date' => '2000-01-01 01:00:00',
|
||||
'unread' => 1,
|
||||
'starred' => 0,
|
||||
'edition' => 101,
|
||||
|
@ -197,9 +197,9 @@ trait SeriesArticle {
|
|||
'author' => '',
|
||||
'content' => '<p>Article content 2</p>',
|
||||
'guid' => '5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7',
|
||||
'published_date' => 946771200,
|
||||
'edited_date' => 946771202,
|
||||
'modified_date' => 946778400,
|
||||
'published_date' => '2000-01-02 00:00:00',
|
||||
'edited_date' => '2000-01-02 00:00:02',
|
||||
'modified_date' => '2000-01-02 02:00:00',
|
||||
'unread' => 0,
|
||||
'starred' => 0,
|
||||
'edition' => 202,
|
||||
|
@ -215,9 +215,9 @@ trait SeriesArticle {
|
|||
'author' => '',
|
||||
'content' => '<p>Article content 3</p>',
|
||||
'guid' => '31a6594500a48b59fcc8a075ce82b946c9c3c782460d088bd7b8ef3ede97ad92',
|
||||
'published_date' => 946857600,
|
||||
'edited_date' => 946857603,
|
||||
'modified_date' => 946868400,
|
||||
'published_date' => '2000-01-03 00:00:00',
|
||||
'edited_date' => '2000-01-03 00:00:03',
|
||||
'modified_date' => '2000-01-03 03:00:00',
|
||||
'unread' => 1,
|
||||
'starred' => 1,
|
||||
'edition' => 203,
|
||||
|
@ -233,9 +233,9 @@ trait SeriesArticle {
|
|||
'author' => '',
|
||||
'content' => '<p>Article content 4</p>',
|
||||
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
|
||||
'published_date' => 946944000,
|
||||
'edited_date' => 946944004,
|
||||
'modified_date' => 946958400,
|
||||
'published_date' => '2000-01-04 00:00:00',
|
||||
'edited_date' => '2000-01-04 00:00:04',
|
||||
'modified_date' => '2000-01-04 04:00:00',
|
||||
'unread' => 0,
|
||||
'starred' => 1,
|
||||
'edition' => 204,
|
||||
|
@ -251,9 +251,9 @@ trait SeriesArticle {
|
|||
'author' => '',
|
||||
'content' => '<p>Article content 5</p>',
|
||||
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
|
||||
'published_date' => 947030400,
|
||||
'edited_date' => 947030405,
|
||||
'modified_date' => 947048400,
|
||||
'published_date' => '2000-01-05 00:00:00',
|
||||
'edited_date' => '2000-01-05 00:00:05',
|
||||
'modified_date' => '2000-01-05 05:00:00',
|
||||
'unread' => 1,
|
||||
'starred' => 0,
|
||||
'edition' => 305,
|
||||
|
@ -340,7 +340,6 @@ trait SeriesArticle {
|
|||
|
||||
function testListArticlesCheckingProperties() {
|
||||
$this->user = "john.doe@example.org";
|
||||
Data::$db->dateFormatDefault("unix");
|
||||
$this->assertResult($this->matches, Data::$db->articleList($this->user));
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ trait SeriesFeed {
|
|||
protected $matches = [
|
||||
[
|
||||
'id' => 4,
|
||||
'edited_date' => 946944000, // 2000-01-04T00:00:00Z
|
||||
'edited' => '2000-01-04 00:00:00',
|
||||
'guid' => '804e517d623390e71497982c77cf6823180342ebcd2e7d5e32da1e55b09dd180',
|
||||
'url_title_hash' => 'f3615c7f16336d3ea242d35cf3fc17dbc4ee3afb78376bf49da2dd7a5a25dec8',
|
||||
'url_content_hash' => 'f11c2b4046f207579aeb9c69a8c20ca5461cef49756ccfa5ba5e2344266da3b3',
|
||||
|
@ -20,7 +20,7 @@ trait SeriesFeed {
|
|||
],
|
||||
[
|
||||
'id' => 5,
|
||||
'edited_date' => 947030400, // 2000-01-05T00:00:00Z
|
||||
'edited' => '2000-01-05 00:00:00',
|
||||
'guid' => 'db3e736c2c492f5def5c5da33ddcbea1824040e9ced2142069276b0a6e291a41',
|
||||
'url_title_hash' => 'd40da96e39eea6c55948ccbe9b3d275b5f931298288dbe953990c5f496097022',
|
||||
'url_content_hash' => '834240f84501b5341d375414718204ec421561f3825d34c22bf9182203e42900',
|
||||
|
|
|
@ -253,14 +253,6 @@ trait SeriesSubscription {
|
|||
$this->assertResult($exp, Data::$db->subscriptionList($this->user, 2));
|
||||
}
|
||||
|
||||
function testListSubscriptionsWithDifferentDateFormats() {
|
||||
Data::$db->dateFormatDefault("iso8601");
|
||||
$d1 = Data::$db->subscriptionList($this->user, 2)->getRow()['added'];
|
||||
Data::$db->dateFormatDefault("http");
|
||||
$d2 = Data::$db->subscriptionList($this->user, 2)->getRow()['added'];
|
||||
$this->assertNotEquals($d1, $d2);
|
||||
}
|
||||
|
||||
function testListSubscriptionsInAMissingFolder() {
|
||||
$this->assertException("idMissing", "Db", "ExceptionInput");
|
||||
Data::$db->subscriptionList($this->user, 4);
|
||||
|
|
|
@ -3,7 +3,7 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Test\Db;
|
||||
use JKingWeb\Arsse\Db\Statement;
|
||||
|
||||
trait BindingTests {
|
||||
trait BindingTests {
|
||||
function testBindNull() {
|
||||
$input = null;
|
||||
$exp = [
|
||||
|
@ -24,9 +24,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 0,
|
||||
"float" => 0.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
|
||||
"date" => gmdate("Y-m-d", 0),
|
||||
"time" => gmdate("H:i:s", 0),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", 0),
|
||||
"binary" => "",
|
||||
"string" => "",
|
||||
"boolean" => 0,
|
||||
|
@ -74,9 +74,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 2112,
|
||||
"float" => 2112.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 2112),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 2112),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 2112),
|
||||
"date" => gmdate("Y-m-d", 2112),
|
||||
"time" => gmdate("H:i:s", 2112),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", 2112),
|
||||
"binary" => "2112",
|
||||
"string" => "2112",
|
||||
"boolean" => 1,
|
||||
|
@ -91,9 +91,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 0,
|
||||
"float" => 0.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
|
||||
"date" => gmdate("Y-m-d", 0),
|
||||
"time" => gmdate("H:i:s", 0),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", 0),
|
||||
"binary" => "0",
|
||||
"string" => "0",
|
||||
"boolean" => 0,
|
||||
|
@ -108,9 +108,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 2112,
|
||||
"float" => 2112.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 2112),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 2112),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 2112),
|
||||
"date" => gmdate("Y-m-d", 2112),
|
||||
"time" => gmdate("H:i:s", 2112),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", 2112),
|
||||
"binary" => "2112",
|
||||
"string" => "2112",
|
||||
"boolean" => 1,
|
||||
|
@ -125,9 +125,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 0,
|
||||
"float" => 0.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), 0),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), 0),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), 0),
|
||||
"date" => gmdate("Y-m-d", 0),
|
||||
"time" => gmdate("H:i:s", 0),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", 0),
|
||||
"binary" => "0",
|
||||
"string" => "0",
|
||||
"boolean" => 0,
|
||||
|
@ -195,9 +195,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 2017,
|
||||
"float" => 2017.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
|
||||
"date" => gmdate("Y-m-d", $time),
|
||||
"time" => gmdate("H:i:s", $time),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", $time),
|
||||
"binary" => $input,
|
||||
"string" => $input,
|
||||
"boolean" => 1,
|
||||
|
@ -213,9 +213,9 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => 0,
|
||||
"float" => 0.0,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
|
||||
"date" => gmdate("Y-m-d", $time),
|
||||
"time" => gmdate("H:i:s", $time),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", $time),
|
||||
"binary" => $input,
|
||||
"string" => $input,
|
||||
"boolean" => 1,
|
||||
|
@ -231,11 +231,11 @@ trait BindingTests {
|
|||
"null" => null,
|
||||
"integer" => $time,
|
||||
"float" => (float) $time,
|
||||
"date" => date(self::$imp::dateFormat(Statement::TS_DATE), $time),
|
||||
"time" => date(self::$imp::dateFormat(Statement::TS_TIME), $time),
|
||||
"datetime" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
|
||||
"binary" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
|
||||
"string" => date(self::$imp::dateFormat(Statement::TS_BOTH), $time),
|
||||
"date" => gmdate("Y-m-d", $time),
|
||||
"time" => gmdate("H:i:s", $time),
|
||||
"datetime" => gmdate("Y-m-d H:i:s", $time),
|
||||
"binary" => gmdate("Y-m-d H:i:s", $time),
|
||||
"string" => gmdate("Y-m-d H:i:s", $time),
|
||||
"boolean" => 1,
|
||||
];
|
||||
$this->checkBinding($input, $exp);
|
||||
|
|
|
@ -20,8 +20,8 @@ trait Tools {
|
|||
}
|
||||
|
||||
function assertTime($exp, $test) {
|
||||
$exp = $this->dateTransform($exp);
|
||||
$test = $this->dateTransform($test);
|
||||
$exp = $this->dateTransform($exp, "unix");
|
||||
$test = $this->dateTransform($test, "unix");
|
||||
$this->assertSame($exp, $test);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue