mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2025-01-08 17:02:41 +00:00
Merge branch 'dbtest' into redup
This commit is contained in:
commit
fbf7848c14
51 changed files with 1011 additions and 1321 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -11,6 +11,7 @@
|
|||
/arsse.db*
|
||||
/config.php
|
||||
/.php_cs.cache
|
||||
/.php-cs-fixer.cache
|
||||
/tests/.phpunit.result.cache
|
||||
|
||||
# Dependencies
|
||||
|
|
|
@ -16,6 +16,8 @@ $paths = [
|
|||
BASE."tests",
|
||||
];
|
||||
$rules = [
|
||||
// PSR standard to apply
|
||||
'@PSR12' => true,
|
||||
// house rules where PSR series is silent
|
||||
'align_multiline_comment' => ['comment_type' => "phpdocs_only"],
|
||||
'array_syntax' => ['syntax' => "short"],
|
||||
|
@ -48,30 +50,18 @@ $rules = [
|
|||
'pow_to_exponentiation' => true,
|
||||
'set_type_to_cast' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'trailing_comma_in_multiline_array' => true,
|
||||
'trailing_comma_in_multiline' => true,
|
||||
'unary_operator_spaces' => true,
|
||||
'yoda_style' => false,
|
||||
// PSR standard to apply
|
||||
'@PSR2' => true,
|
||||
// PSR-12 rules; php-cs-fixer does not yet support PSR-12 natively
|
||||
'compact_nullable_typehint' => true,
|
||||
'declare_equal_normalize' => ['space' => "none"],
|
||||
'function_typehint_space' => true,
|
||||
'lowercase_cast' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'no_alternative_syntax' => true,
|
||||
'no_empty_statement' => true,
|
||||
'no_leading_import_slash' => true,
|
||||
'no_leading_namespace_whitespace' => true,
|
||||
'no_whitespace_in_blank_line' => true,
|
||||
'return_type_declaration' => ['space_before' => "none"],
|
||||
'single_trait_insert_per_statement' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'visibility_required' => ['elements' => ["const", "property", "method"]],
|
||||
// house exceptions to PSR rules
|
||||
'braces' => ['position_after_functions_and_oop_constructs' => "same"],
|
||||
'function_declaration' => ['closure_function_spacing' => "none"],
|
||||
'new_with_braces' => false, // no option to specify absence of braces
|
||||
'new_with_braces' => [
|
||||
'anonymous_class' => false,
|
||||
'named_class' => false,
|
||||
],
|
||||
'single_blank_line_before_namespace' => false,
|
||||
'blank_line_after_opening_tag' => false,
|
||||
];
|
||||
|
||||
$finder = \PhpCsFixer\Finder::create();
|
||||
|
@ -82,4 +72,4 @@ foreach ($paths as $path) {
|
|||
$finder = $finder->in($path);
|
||||
}
|
||||
}
|
||||
return \PhpCsFixer\Config::create()->setRiskyAllowed(true)->setRules($rules)->setFinder($finder);
|
||||
return (new \PhpCsFixer\Config)->setRiskyAllowed(true)->setRules($rules)->setFinder($finder);
|
56
composer.lock
generated
56
composer.lock
generated
|
@ -58,16 +58,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "6.5.5",
|
||||
"version": "6.5.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e"
|
||||
"reference": "f092dd734083473658de3ee4bef093ed77d2689c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
||||
"reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/f092dd734083473658de3ee4bef093ed77d2689c",
|
||||
"reference": "f092dd734083473658de3ee4bef093ed77d2689c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -104,10 +104,40 @@
|
|||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Graham Campbell",
|
||||
"email": "hello@gjcampbell.co.uk",
|
||||
"homepage": "https://github.com/GrahamCampbell"
|
||||
},
|
||||
{
|
||||
"name": "Michael Dowling",
|
||||
"email": "mtdowling@gmail.com",
|
||||
"homepage": "https://github.com/mtdowling"
|
||||
},
|
||||
{
|
||||
"name": "Jeremy Lindblom",
|
||||
"email": "jeremeamia@gmail.com",
|
||||
"homepage": "https://github.com/jeremeamia"
|
||||
},
|
||||
{
|
||||
"name": "George Mponos",
|
||||
"email": "gmponos@gmail.com",
|
||||
"homepage": "https://github.com/gmponos"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Nyholm",
|
||||
"email": "tobias.nyholm@gmail.com",
|
||||
"homepage": "https://github.com/Nyholm"
|
||||
},
|
||||
{
|
||||
"name": "Márk Sági-Kazár",
|
||||
"email": "mark.sagikazar@gmail.com",
|
||||
"homepage": "https://github.com/sagikazarmark"
|
||||
},
|
||||
{
|
||||
"name": "Tobias Schultze",
|
||||
"email": "webmaster@tubo-world.de",
|
||||
"homepage": "https://github.com/Tobion"
|
||||
}
|
||||
],
|
||||
"description": "Guzzle is a PHP HTTP client library",
|
||||
|
@ -123,9 +153,23 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/6.5"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/6.5.6"
|
||||
},
|
||||
"time": "2020-06-16T21:01:06+00:00"
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/GrahamCampbell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/Nyholm",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/guzzlehttp/guzzle",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-05-25T13:19:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
|
|
|
@ -243,7 +243,6 @@ trait ExclusionMembers {
|
|||
return $this->act(__FUNCTION__, func_num_args(), $spec);
|
||||
}
|
||||
|
||||
|
||||
public function markedRange($start = null, $end = null) {
|
||||
if ($start === null && $end === null) {
|
||||
$spec = null;
|
||||
|
|
|
@ -280,7 +280,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Renames a user
|
||||
*
|
||||
*
|
||||
* This does not have an effect on their numeric ID, but has a cascading effect on many tables
|
||||
*/
|
||||
public function userRename(string $user, string $name): bool {
|
||||
|
@ -337,7 +337,7 @@ class Database {
|
|||
}
|
||||
|
||||
/** Retrieves any metadata associated with a user
|
||||
*
|
||||
*
|
||||
* @param string $user The user whose metadata is to be retrieved
|
||||
* @param bool $includeLarge Whether to include values which can be arbitrarily large text
|
||||
*/
|
||||
|
@ -813,8 +813,8 @@ class Database {
|
|||
public function subscriptionList(string $user, $folder = null, bool $recursive = true, int $id = null): Db\Result {
|
||||
// validate inputs
|
||||
$folder = $this->folderValidateId($user, $folder)['id'];
|
||||
// create a complex query
|
||||
$integer = $this->db->sqlToken("integer");
|
||||
// compile the query
|
||||
$integerType = $this->db->sqlToken("integer");
|
||||
$q = new Query(
|
||||
"WITH RECURSIVE
|
||||
topmost(f_id, top) as (
|
||||
|
@ -835,7 +835,7 @@ class Database {
|
|||
i.url as icon_url,
|
||||
folder, t.top as top_folder, d.name as folder_name, dt.name as top_folder_name,
|
||||
coalesce(s.title, f.title) as title,
|
||||
coalesce((articles - hidden - marked), coalesce(articles,0)) as unread
|
||||
cast(coalesce((articles - hidden - marked), coalesce(articles,0)) as $integerType) as unread -- this cast is required for MySQL for unclear reasons
|
||||
from arsse_subscriptions as s
|
||||
join arsse_feeds as f on f.id = s.feed
|
||||
left join topmost as t on t.f_id = s.folder
|
||||
|
@ -853,11 +853,11 @@ class Database {
|
|||
select
|
||||
subscription,
|
||||
sum(hidden) as hidden,
|
||||
sum(cast((\"read\" = 1 and hidden = 0) as $integer)) as marked
|
||||
sum(case when \"read\" = 1 and hidden = 0 then 1 else 0 end) as marked
|
||||
from arsse_marks group by subscription
|
||||
) as mark_stats on mark_stats.subscription = s.id",
|
||||
["str", "int"],
|
||||
[$user, $folder]
|
||||
["str", "int"],
|
||||
[$user, $folder]
|
||||
);
|
||||
$q->setWhere("s.owner = ?", ["str"], [$user]);
|
||||
$nocase = $this->db->sqlToken("nocase");
|
||||
|
@ -1614,26 +1614,26 @@ class Database {
|
|||
}
|
||||
// ensure any used array-type context options contain at least one member
|
||||
foreach ([
|
||||
"articles",
|
||||
"articles",
|
||||
"editions",
|
||||
"subscriptions",
|
||||
"folders",
|
||||
"foldersShallow",
|
||||
"labels",
|
||||
"labelNames",
|
||||
"tags",
|
||||
"tagNames",
|
||||
"searchTerms",
|
||||
"titleTerms",
|
||||
"authorTerms",
|
||||
"folders",
|
||||
"foldersShallow",
|
||||
"labels",
|
||||
"labelNames",
|
||||
"tags",
|
||||
"tagNames",
|
||||
"searchTerms",
|
||||
"titleTerms",
|
||||
"authorTerms",
|
||||
"annotationTerms",
|
||||
"modifiedRanges",
|
||||
"markedRanges",
|
||||
] as $m) {
|
||||
if ($context->$m() && !$context->$m) {
|
||||
throw new Db\ExceptionInput("tooShort", ['field' => $m, 'action' => $this->caller(), 'min' => 1]);
|
||||
}
|
||||
if ($context->$m() && !$context->$m) {
|
||||
throw new Db\ExceptionInput("tooShort", ['field' => $m, 'action' => $this->caller(), 'min' => 1]);
|
||||
}
|
||||
}
|
||||
// next compute the context, supplying the query to manipulate directly
|
||||
$this->articleFilter($context, $q);
|
||||
}
|
||||
|
@ -1922,8 +1922,8 @@ class Database {
|
|||
touched = 1
|
||||
where
|
||||
article in (select article from target_articles)
|
||||
and subscription in (select distinct subscription from target_articles)",
|
||||
[$subq->getTypes(), "bool"],
|
||||
and subscription in (select distinct subscription from target_articles)",
|
||||
[$subq->getTypes(), "bool"],
|
||||
[$subq->getValues(), $data['read']]
|
||||
);
|
||||
$this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues());
|
||||
|
@ -1953,7 +1953,7 @@ class Database {
|
|||
where
|
||||
article in (select article from target_articles)
|
||||
and subscription in (select distinct subscription from target_articles)",
|
||||
[$subq->getTypes(), $setTypes],
|
||||
[$subq->getTypes(), $setTypes],
|
||||
[$subq->getValues(), $setValues]
|
||||
);
|
||||
$this->db->prepare($q->getQuery(), $q->getTypes())->run($q->getValues());
|
||||
|
@ -2053,7 +2053,6 @@ class Database {
|
|||
|
||||
/** Deletes from the database articles which are beyond the configured clean-up threshold */
|
||||
public function articleCleanup(): bool {
|
||||
$integer = $this->db->sqlToken("integer");
|
||||
$query = $this->db->prepareArray(
|
||||
"WITH RECURSIVE
|
||||
exempt_articles as (
|
||||
|
@ -2079,8 +2078,8 @@ class Database {
|
|||
left join (
|
||||
select
|
||||
article,
|
||||
sum(cast((starred = 1 and hidden = 0) as $integer)) as starred,
|
||||
sum(cast((\"read\" = 1 or hidden = 1) as $integer)) as \"read\",
|
||||
sum(case when starred = 1 and hidden = 0 then 1 else 0 end) as starred,
|
||||
sum(case when \"read\" = 1 or hidden = 1 then 1 else 0 end) as \"read\",
|
||||
max(arsse_marks.modified) as marked_date
|
||||
from arsse_marks
|
||||
group by article
|
||||
|
@ -2211,14 +2210,14 @@ class Database {
|
|||
* @param boolean $includeEmpty Whether to include (true) or supress (false) labels which have no articles assigned to them
|
||||
*/
|
||||
public function labelList(string $user, bool $includeEmpty = true): Db\Result {
|
||||
$integer = $this->db->sqlToken("integer");
|
||||
$integerType = $this->db->sqlToken("integer");
|
||||
return $this->db->prepareArray(
|
||||
"SELECT * FROM (
|
||||
SELECT
|
||||
id,
|
||||
name,
|
||||
coalesce(articles - coalesce(hidden, 0), 0) as articles,
|
||||
coalesce(marked, 0) as \"read\"
|
||||
cast(coalesce(articles - coalesce(hidden, 0), 0) as $integerType) as articles, -- this cast is required for MySQL for unclear reasons
|
||||
cast(coalesce(marked, 0) as $integerType) as \"read\" -- this cast is required for MySQL for unclear reasons
|
||||
from arsse_labels
|
||||
left join (
|
||||
SELECT label, sum(assigned) as articles from arsse_label_members group by label
|
||||
|
@ -2227,7 +2226,7 @@ class Database {
|
|||
SELECT
|
||||
label,
|
||||
sum(hidden) as hidden,
|
||||
sum(cast((\"read\" = 1 and hidden = 0) as $integer)) as marked
|
||||
sum(case when \"read\" = 1 and hidden = 0 then 1 else 0 end) as marked
|
||||
from arsse_marks
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_marks.subscription
|
||||
join arsse_label_members on arsse_label_members.article = arsse_marks.article
|
||||
|
@ -2277,7 +2276,6 @@ class Database {
|
|||
$this->labelValidateId($user, $id, $byName, false);
|
||||
$field = $byName ? "name" : "id";
|
||||
$type = $byName ? "str" : "int";
|
||||
$integer = $this->db->sqlToken("integer");
|
||||
$out = $this->db->prepareArray(
|
||||
"SELECT
|
||||
id,
|
||||
|
@ -2292,7 +2290,7 @@ class Database {
|
|||
SELECT
|
||||
label,
|
||||
sum(hidden) as hidden,
|
||||
sum(cast((\"read\" = 1 and hidden = 0) as $integer)) as marked
|
||||
sum(case when \"read\" = 1 and hidden = 0 then 1 else 0 end) as marked
|
||||
from arsse_marks
|
||||
join arsse_subscriptions on arsse_subscriptions.id = arsse_marks.subscription
|
||||
join arsse_label_members on arsse_label_members.article = arsse_marks.article
|
||||
|
|
|
@ -204,4 +204,8 @@ abstract class AbstractDriver implements Driver {
|
|||
public function prepare(string $query, ...$paramType): Statement {
|
||||
return $this->prepareArray($query, $paramType);
|
||||
}
|
||||
|
||||
public function stringOutput(): bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,6 +72,7 @@ interface Driver {
|
|||
* The tokens the implementation must understand are:
|
||||
*
|
||||
* - "greatest": the GREATEST function implemented by PostgreSQL and MySQL
|
||||
* - "least": the LEAST function implemented by PostgreSQL and MySQL
|
||||
* - "nocase": the name of a general-purpose case-insensitive collation sequence
|
||||
* - "like": the case-insensitive LIKE operator
|
||||
* - "integer": the integer type to use for explicit casts
|
||||
|
@ -91,4 +92,7 @@ interface Driver {
|
|||
* This should be restricted to quick maintenance; in SQLite terms it might include ANALYZE, but not VACUUM
|
||||
*/
|
||||
public function maintenance(): bool;
|
||||
|
||||
/** Reports whether the implementation will coerce integer and float values to text (string) */
|
||||
public function stringOutput(): bool;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ use JKingWeb\Arsse\Db\Exception;
|
|||
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||
use ExceptionBuilder;
|
||||
|
||||
protected const SQL_MODE = "ANSI_QUOTES,HIGH_NOT_PRECEDENCE,NO_BACKSLASH_ESCAPES,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,STRICT_ALL_TABLES";
|
||||
protected const SQL_MODE = "ANSI_QUOTES,HIGH_NOT_PRECEDENCE,NO_BACKSLASH_ESCAPES,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,STRICT_ALL_TABLES,NO_UNSIGNED_SUBTRACTION";
|
||||
protected const TRANSACTIONAL_LOCKS = false;
|
||||
|
||||
/** @var \mysqli */
|
||||
|
@ -81,10 +81,10 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
switch (strtolower($token)) {
|
||||
case "nocase":
|
||||
return '"utf8mb4_unicode_ci"';
|
||||
case "integer":
|
||||
return "signed integer";
|
||||
case "asc":
|
||||
return "";
|
||||
case "integer":
|
||||
return "signed integer";
|
||||
default:
|
||||
return $token;
|
||||
}
|
||||
|
@ -167,7 +167,7 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
$drv->report_mode = \MYSQLI_REPORT_OFF;
|
||||
$this->db = mysqli_init();
|
||||
$this->db->options(\MYSQLI_SET_CHARSET_NAME, "utf8mb4");
|
||||
$this->db->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, false);
|
||||
$this->db->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
|
||||
$this->db->options(\MYSQLI_OPT_CONNECT_TIMEOUT, ceil(Arsse::$conf->dbTimeoutConnect));
|
||||
@$this->db->real_connect($host, $user, $password, $db, $port, $socket);
|
||||
if ($this->db->connect_errno) {
|
||||
|
|
|
@ -29,7 +29,7 @@ class PDODriver extends Driver {
|
|||
try {
|
||||
$this->db = new \PDO($dsn, $user, $password, [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
]);
|
||||
} catch (\PDOException $e) {
|
||||
$msg = $e->getMessage();
|
||||
|
|
|
@ -232,4 +232,8 @@ class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
|||
$this->exec("ANALYZE");
|
||||
return true;
|
||||
}
|
||||
|
||||
public function stringOutput(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -60,4 +60,8 @@ class PDODriver extends Driver {
|
|||
public function prepareArray(string $query, array $paramTypes): \JKingWeb\Arsse\Db\Statement {
|
||||
return new PDOStatement($this->db, $query, $paramTypes);
|
||||
}
|
||||
|
||||
public function stringOutput(): bool {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db\PostgreSQL;
|
||||
|
||||
class PDOResult extends \JKingWeb\Arsse\Db\PDOResult {
|
||||
|
||||
// This method exists to transparent handle byte-array results
|
||||
|
||||
public function valid() {
|
||||
|
|
|
@ -81,4 +81,8 @@ class PDODriver extends AbstractPDODriver {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function stringOutput(): bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ namespace JKingWeb\Arsse\Misc;
|
|||
* A collection of functions for manipulating URLs
|
||||
*/
|
||||
class URL {
|
||||
|
||||
/** Returns whether a URL is absolute i.e. has a scheme */
|
||||
public static function absolute(string $url): bool {
|
||||
return (bool) strlen((string) parse_url($url, \PHP_URL_SCHEME));
|
||||
|
|
|
@ -107,7 +107,7 @@ class ValueInfo {
|
|||
if ($strict && !$drop) {
|
||||
throw new ExceptionType("strictFailure", $type);
|
||||
}
|
||||
return (!$drop) ? (int) $value->getTimestamp(): null;
|
||||
return (!$drop) ? (int) $value->getTimestamp() : null;
|
||||
} elseif ($value instanceof \DateInterval) {
|
||||
if ($strict && !$drop) {
|
||||
throw new ExceptionType("strictFailure", $type);
|
||||
|
@ -159,7 +159,7 @@ class ValueInfo {
|
|||
if ($strict && !$drop) {
|
||||
throw new ExceptionType("strictFailure", $type);
|
||||
}
|
||||
return (!$drop) ? (float) $value->getTimestamp(): null;
|
||||
return (!$drop) ? (float) $value->getTimestamp() : null;
|
||||
} elseif ($value instanceof \DateInterval) {
|
||||
if ($drop) {
|
||||
return null;
|
||||
|
@ -203,13 +203,13 @@ class ValueInfo {
|
|||
if ($value->days) {
|
||||
$dateSpec = $value->days."D";
|
||||
} else {
|
||||
$dateSpec .= $value->y ? $value->y."Y": "";
|
||||
$dateSpec .= $value->m ? $value->m."M": "";
|
||||
$dateSpec .= $value->d ? $value->d."D": "";
|
||||
$dateSpec .= $value->y ? $value->y."Y" : "";
|
||||
$dateSpec .= $value->m ? $value->m."M" : "";
|
||||
$dateSpec .= $value->d ? $value->d."D" : "";
|
||||
}
|
||||
$timeSpec .= $value->h ? $value->h."H": "";
|
||||
$timeSpec .= $value->i ? $value->i."M": "";
|
||||
$timeSpec .= $value->s ? $value->s."S": "";
|
||||
$timeSpec .= $value->h ? $value->h."H" : "";
|
||||
$timeSpec .= $value->i ? $value->i."M" : "";
|
||||
$timeSpec .= $value->s ? $value->s."S" : "";
|
||||
$timeSpec = $timeSpec ? "T".$timeSpec : "";
|
||||
if (!$dateSpec && !$timeSpec) {
|
||||
return "PT0S";
|
||||
|
|
|
@ -125,14 +125,14 @@ class REST {
|
|||
$target = substr($url, strlen($api['strip']));
|
||||
} else {
|
||||
// if the match fails we are not able to handle the request
|
||||
throw new REST\Exception501();
|
||||
throw new REST\Exception501;
|
||||
}
|
||||
// return the API name, stripped URL, and API class name
|
||||
return [$id, $target, $api['class']];
|
||||
}
|
||||
}
|
||||
// or throw an exception otherwise
|
||||
throw new REST\Exception501();
|
||||
throw new REST\Exception501;
|
||||
}
|
||||
|
||||
public function authenticateRequest(ServerRequestInterface $req): ServerRequestInterface {
|
||||
|
|
|
@ -319,7 +319,7 @@ class Search {
|
|||
$start = $day."T00:00:00 $tz";
|
||||
$end = $day."T23:59:59 $tz";
|
||||
$cc = $neg ? $c->not : $c;
|
||||
// NOTE: TTRSS treats multiple positive dates as contradictory; we instead treat them as complimentary instead, because it makes more sense
|
||||
// NOTE: TTRSS treats multiple positive dates as contradictory; we instead treat them as complimentary instead, because it makes more sense
|
||||
return $cc->modifiedRanges(array_merge($cc->modifiedRanges, [[$start, $end]]));
|
||||
}
|
||||
|
||||
|
|
|
@ -21,13 +21,13 @@ class Service {
|
|||
|
||||
public function __construct() {
|
||||
$driver = Arsse::$conf->serviceDriver;
|
||||
$this->drv = new $driver();
|
||||
$this->drv = new $driver;
|
||||
}
|
||||
|
||||
public function watch(bool $loop = true): \DateTimeInterface {
|
||||
$this->loop = $loop;
|
||||
$this->signalInit();
|
||||
$t = new \DateTime();
|
||||
$t = new \DateTime;
|
||||
do {
|
||||
$this->checkIn();
|
||||
static::cleanupPre();
|
||||
|
@ -80,7 +80,7 @@ class Service {
|
|||
// get the checking interval
|
||||
$int = Arsse::$conf->serviceFrequency;
|
||||
// subtract twice the checking interval from the current time to yield the earliest acceptable check-in time
|
||||
$limit = new \DateTime();
|
||||
$limit = new \DateTime;
|
||||
$limit->sub($int);
|
||||
$limit->sub($int);
|
||||
// return whether the check-in time is within the acceptable limit
|
||||
|
|
|
@ -18,11 +18,7 @@ trait SeriesArticle {
|
|||
protected function setUpSeriesArticle(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "", 1],
|
||||
["john.doe@example.com", "", 2],
|
||||
|
@ -32,11 +28,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "url", "title"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/1", "Feed 1"],
|
||||
[2,"http://example.com/2", "Feed 2"],
|
||||
|
@ -54,12 +46,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "parent", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", null, "Technology"],
|
||||
[2, "john.doe@example.com", 1, "Software"],
|
||||
|
@ -73,11 +60,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_tags' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", "Technology"],
|
||||
[2, "john.doe@example.com", "Software"],
|
||||
|
@ -90,38 +73,27 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'folder' => "int",
|
||||
'title' => "str",
|
||||
'scrape' => "bool",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "folder", "title", "scrape"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com",1, null,"Subscription 1",0],
|
||||
[2, "john.doe@example.com",2, null,null,0],
|
||||
[3, "john.doe@example.com",3, 1,"Subscription 3",0],
|
||||
[4, "john.doe@example.com",4, 6,null,0],
|
||||
[5, "john.doe@example.com",10, 5,"Subscription 5",0],
|
||||
[6, "jane.doe@example.com",1, null,null,0],
|
||||
[7, "jane.doe@example.com",10,null,"Subscription 7",0],
|
||||
[8, "john.doe@example.org",11,null,null,0],
|
||||
[9, "john.doe@example.org",12,null,"Subscription 9",0],
|
||||
[10,"john.doe@example.org",13,null,null,0],
|
||||
[1, "john.doe@example.com",1, null,"Subscription 1", 0],
|
||||
[2, "john.doe@example.com",2, null,null, 0],
|
||||
[3, "john.doe@example.com",3, 1,"Subscription 3", 0],
|
||||
[4, "john.doe@example.com",4, 6,null, 0],
|
||||
[5, "john.doe@example.com",10, 5,"Subscription 5", 0],
|
||||
[6, "jane.doe@example.com",1, null,null, 0],
|
||||
[7, "jane.doe@example.com",10,null,"Subscription 7", 0],
|
||||
[8, "john.doe@example.org",11,null,null, 0],
|
||||
[9, "john.doe@example.org",12,null,"Subscription 9", 0],
|
||||
[10,"john.doe@example.org",13,null,null, 0],
|
||||
[11,"john.doe@example.net",10,null,"Subscription 11",0],
|
||||
[12,"john.doe@example.net",2, 9,null,0],
|
||||
[12,"john.doe@example.net",2, 9,null, 0],
|
||||
[13,"john.doe@example.net",3, 8,"Subscription 13",0],
|
||||
[14,"john.doe@example.net",4, 7,null,0],
|
||||
[15,"jill.doe@example.com",11,null,null,1],
|
||||
[14,"john.doe@example.net",4, 7,null, 0],
|
||||
[15,"jill.doe@example.com",11,null,null, 1],
|
||||
],
|
||||
],
|
||||
'arsse_tag_members' => [
|
||||
'columns' => [
|
||||
'tag' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
],
|
||||
'columns' => ["tag", "subscription", "assigned"],
|
||||
'rows' => [
|
||||
[1,3,1],
|
||||
[1,4,1],
|
||||
|
@ -137,20 +109,8 @@ trait SeriesArticle {
|
|||
],
|
||||
'arsse_articles' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'author' => "str",
|
||||
'published' => "datetime",
|
||||
'edited' => "datetime",
|
||||
'content' => "str",
|
||||
'guid' => "str",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'modified' => "datetime",
|
||||
'content_scraped' => "str",
|
||||
"id", "feed", "url", "title", "author", "published", "edited", "content", "guid",
|
||||
"url_title_hash", "url_content_hash", "title_content_hash", "modified", "content_scraped"
|
||||
],
|
||||
'rows' => [
|
||||
[1,1,null,"Title one", null,null,null,"First article", null,"","","","2000-01-01T00:00:00Z",null],
|
||||
|
@ -181,11 +141,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_enclosures' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
],
|
||||
'columns' => ["article", "url", "type"],
|
||||
'rows' => [
|
||||
[102,"http://example.com/text","text/plain"],
|
||||
[103,"http://example.com/video","video/webm"],
|
||||
|
@ -195,10 +151,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
],
|
||||
'columns' => ["id", "article"],
|
||||
'rows' => [
|
||||
[1,1],
|
||||
[2,2],
|
||||
|
@ -234,15 +187,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'columns' => [
|
||||
'subscription' => "int",
|
||||
'article' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'modified' => "datetime",
|
||||
'note' => "str",
|
||||
'hidden' => "bool",
|
||||
],
|
||||
'columns' => ["subscription", "article", "read", "starred", "modified", "note", "hidden"],
|
||||
'rows' => [
|
||||
[1, 1,1,1,'2000-01-01 00:00:00','',0],
|
||||
[5, 19,1,0,'2016-01-01 00:00:00','',0],
|
||||
|
@ -263,10 +208,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_categories' => [ // author-supplied categories
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["article", "name"],
|
||||
'rows' => [
|
||||
[19,"Fascinating"],
|
||||
[19,"Logical"],
|
||||
|
@ -274,12 +216,8 @@ trait SeriesArticle {
|
|||
[20,"Logical"],
|
||||
],
|
||||
],
|
||||
'arsse_labels' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'arsse_labels' => [ // labels applied to articles
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com","Interesting"],
|
||||
[2,"john.doe@example.com","Fascinating"],
|
||||
|
@ -288,13 +226,7 @@ trait SeriesArticle {
|
|||
],
|
||||
],
|
||||
'arsse_label_members' => [
|
||||
'columns' => [
|
||||
'label' => "int",
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["label", "article", "subscription", "assigned", "modified"],
|
||||
'rows' => [
|
||||
[1, 1,1,1,'2000-01-01 00:00:00'],
|
||||
[2, 1,1,1,'2000-01-01 00:00:00'],
|
||||
|
|
|
@ -27,23 +27,14 @@ trait SeriesCleanup {
|
|||
$faroff = (new Date("now + 1 hour", $tz))->format("Y-m-d H:i:s");
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_sessions' => [
|
||||
'columns' => [
|
||||
'id' => "str",
|
||||
'created' => "datetime",
|
||||
'expires' => "datetime",
|
||||
'user' => "str",
|
||||
],
|
||||
'columns' => ["id", "created", "expires", "user"],
|
||||
'rows' => [
|
||||
["a", $nowish, $faroff, "jane.doe@example.com"], // not expired and recently created, thus kept
|
||||
["b", $nowish, $soon, "jane.doe@example.com"], // not expired and recently created, thus kept
|
||||
|
@ -53,12 +44,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_tokens' => [
|
||||
'columns' => [
|
||||
'id' => "str",
|
||||
'class' => "str",
|
||||
'user' => "str",
|
||||
'expires' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "class", "user", "expires"],
|
||||
'rows' => [
|
||||
["80fa94c1a11f11e78667001e673b2560", "fever.login", "jane.doe@example.com", $faroff],
|
||||
["27c6de8da13311e78667001e673b2560", "fever.login", "jane.doe@example.com", $weeksago], // expired
|
||||
|
@ -67,11 +53,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_icons' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'orphaned' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "url", "orphaned"],
|
||||
'rows' => [
|
||||
[1,'http://localhost:8000/Icon/PNG',$daybefore],
|
||||
[2,'http://localhost:8000/Icon/GIF',$daybefore],
|
||||
|
@ -79,14 +61,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'orphaned' => "datetime",
|
||||
'size' => "int",
|
||||
'icon' => "int",
|
||||
],
|
||||
'columns' => ["id", "url", "title", "orphaned", "size", "icon"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/1","",$daybefore,2,null], //latest two articles should be kept
|
||||
[2,"http://example.com/2","",$yesterday,0,2],
|
||||
|
@ -95,11 +70,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed"],
|
||||
'rows' => [
|
||||
// one feed previously marked for deletion has a subscription again, and so should not be deleted
|
||||
[1,'jane.doe@example.com',1],
|
||||
|
@ -108,14 +79,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_articles' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "feed", "url_title_hash", "url_content_hash", "title_content_hash", "modified"],
|
||||
'rows' => [
|
||||
[1,1,"","","",$weeksago], // is the latest article, thus is kept
|
||||
[2,1,"","","",$weeksago], // is the second latest article, thus is kept
|
||||
|
@ -129,10 +93,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
],
|
||||
'columns' => ["id", "article"],
|
||||
'rows' => [
|
||||
[1,1],
|
||||
[2,2],
|
||||
|
@ -143,14 +104,7 @@ trait SeriesCleanup {
|
|||
],
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'hidden' => "bool",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["article", "subscription", "read", "starred", "hidden", "modified"],
|
||||
'rows' => [
|
||||
[3,1,0,1,0,$weeksago],
|
||||
[4,1,1,0,0,$daysago],
|
||||
|
|
|
@ -17,23 +17,14 @@ trait SeriesFeed {
|
|||
$now = gmdate("Y-m-d H:i:s", strtotime("now"));
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_icons' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
'data' => "blob",
|
||||
],
|
||||
'columns' => ["id", "url", "type", "data"],
|
||||
'rows' => [
|
||||
[1,'http://localhost:8000/Icon/PNG','image/png',base64_decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2NgYGBgAAAABQABijPjAAAAAABJRU5ErkJggg==")],
|
||||
[2,'http://localhost:8000/Icon/GIF','image/gif',base64_decode("R0lGODlhAQABAIABAAAAAP///yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==")],
|
||||
|
@ -42,17 +33,7 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'err_count' => "int",
|
||||
'err_msg' => "str",
|
||||
'modified' => "datetime",
|
||||
'next_fetch' => "datetime",
|
||||
'size' => "int",
|
||||
'icon' => "int",
|
||||
],
|
||||
'columns' => ["id", "url", "title", "err_count", "err_msg", "modified", "next_fetch", "size", "icon"],
|
||||
'rows' => [
|
||||
[1,"http://localhost:8000/Feed/Matching/3","Ook",0,"",$past,$past,0,null],
|
||||
[2,"http://localhost:8000/Feed/Matching/1","Eek",5,"There was an error last time",$past,$future,0,null],
|
||||
|
@ -67,13 +48,7 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'keep_rule' => "str",
|
||||
'block_rule' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "keep_rule", "block_rule"],
|
||||
'rows' => [
|
||||
[1,'john.doe@example.com',1,null,'^Sport$'],
|
||||
[2,'john.doe@example.com',2,"",null],
|
||||
|
@ -84,21 +59,7 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_articles' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'author' => "str",
|
||||
'published' => "datetime",
|
||||
'edited' => "datetime",
|
||||
'content' => "str",
|
||||
'guid' => "str",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "feed", "url", "title", "author", "published", "edited", "content", "guid", "url_title_hash", "url_content_hash", "title_content_hash", "modified"],
|
||||
'rows' => [
|
||||
[1,1,'http://example.com/1','Article title 1','','2000-01-01 00:00:00','2000-01-01 00:00:00','<p>Article content 1</p>','e433653cef2e572eee4215fa299a4a5af9137b2cefd6283c85bd69a32915beda','f5cb8bfc1c7396dc9816af212a3e2ac5221585c2a00bf7ccb6aabd95dcfcd6a6','fb0bc8f8cb08913dc5a497db700e327f1d34e4987402687d494a5891f24714d4','18fdd4fa93d693128c43b004399e5c9cea6c261ddfa002518d3669f55d8c2207',$past],
|
||||
[2,1,'http://example.com/2','Article title 2','','2000-01-02 00:00:00','2000-01-02 00:00:00','<p>Article content 2</p>','5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7','0e86d2de822a174fe3c44a466953e63ca1f1a58a19cbf475fce0855d4e3d5153','13075894189c47ffcfafd1dfe7fbb539f7c74a69d35a399b3abf8518952714f9','2abd0a8cba83b8214a66c8f0293ba63e467d720540e29ff8ddcdab069d4f1c9e',$past],
|
||||
|
@ -110,11 +71,7 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "article", "modified"],
|
||||
'rows' => [
|
||||
[1,1,$past],
|
||||
[2,2,$past],
|
||||
|
@ -124,14 +81,7 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'hidden' => "bool",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["article", "subscription", "read", "starred", "hidden", "modified"],
|
||||
'rows' => [
|
||||
// Jane's marks
|
||||
[1,6,1,0,0,$past],
|
||||
|
@ -146,20 +96,13 @@ trait SeriesFeed {
|
|||
],
|
||||
],
|
||||
'arsse_enclosures' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
],
|
||||
'columns' => ["article", "url", "type"],
|
||||
'rows' => [
|
||||
[7,'http://example.com/png','image/png'],
|
||||
],
|
||||
],
|
||||
'arsse_categories' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["article", "name"],
|
||||
'rows' => [
|
||||
[7,'Syrinx'],
|
||||
],
|
||||
|
|
|
@ -12,23 +12,14 @@ trait SeriesFolder {
|
|||
protected function setUpSeriesFolder(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "parent", "name"],
|
||||
/* Layout translates to:
|
||||
Jane
|
||||
Politics
|
||||
|
@ -49,11 +40,7 @@ trait SeriesFolder {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "url", "title"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/1", "Feed 1"],
|
||||
[2,"http://example.com/2", "Feed 2"],
|
||||
|
@ -71,12 +58,7 @@ trait SeriesFolder {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'folder' => "int",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "folder"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com",1, null],
|
||||
[2, "john.doe@example.com",2, null],
|
||||
|
|
|
@ -16,23 +16,14 @@ trait SeriesIcon {
|
|||
$now = gmdate("Y-m-d H:i:s", strtotime("now"));
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_icons' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
'data' => "blob",
|
||||
],
|
||||
'columns' => ["id", "url", "type", "data"],
|
||||
'rows' => [
|
||||
[1,'http://localhost:8000/Icon/PNG','image/png',base64_decode("iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2NgYGBgAAAABQABijPjAAAAAABJRU5ErkJggg==")],
|
||||
[2,'http://localhost:8000/Icon/GIF','image/gif',base64_decode("R0lGODlhAQABAIABAAAAAP///yH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==")],
|
||||
|
@ -41,17 +32,7 @@ trait SeriesIcon {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'err_count' => "int",
|
||||
'err_msg' => "str",
|
||||
'modified' => "datetime",
|
||||
'next_fetch' => "datetime",
|
||||
'size' => "int",
|
||||
'icon' => "int",
|
||||
],
|
||||
'columns' => ["id", "url", "title", "err_count", "err_msg", "modified", "next_fetch", "size", "icon"],
|
||||
'rows' => [
|
||||
[1,"http://localhost:8000/Feed/Matching/3","Ook",0,"",$past,$past,0,1],
|
||||
[2,"http://localhost:8000/Feed/Matching/1","Eek",5,"There was an error last time",$past,$future,0,2],
|
||||
|
@ -61,11 +42,7 @@ trait SeriesIcon {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed"],
|
||||
'rows' => [
|
||||
[1,'john.doe@example.com',1],
|
||||
[2,'john.doe@example.com',2],
|
||||
|
|
|
@ -14,11 +14,7 @@ trait SeriesLabel {
|
|||
protected function setUpSeriesLabel(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
|
@ -27,12 +23,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "parent", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", null, "Technology"],
|
||||
[2, "john.doe@example.com", 1, "Software"],
|
||||
|
@ -46,10 +37,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
],
|
||||
'columns' => ["id", "url"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/1"],
|
||||
[2,"http://example.com/2"],
|
||||
|
@ -67,12 +55,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'folder' => "int",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "folder"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com",1,null],
|
||||
[2,"john.doe@example.com",2,null],
|
||||
|
@ -91,21 +74,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_articles' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'author' => "str",
|
||||
'published' => "datetime",
|
||||
'edited' => "datetime",
|
||||
'content' => "str",
|
||||
'guid' => "str",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "feed", "url", "title", "author", "published", "edited", "content", "guid", "url_title_hash", "url_content_hash", "title_content_hash", "modified"],
|
||||
'rows' => [
|
||||
[1,1,null,null,null,null,null,null,null,"","","","2000-01-01T00:00:00Z"],
|
||||
[2,1,null,null,null,null,null,null,null,"","","","2010-01-01T00:00:00Z"],
|
||||
|
@ -135,11 +104,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_enclosures' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
],
|
||||
'columns' => ["article", "url", "type"],
|
||||
'rows' => [
|
||||
[102,"http://example.com/text","text/plain"],
|
||||
[103,"http://example.com/video","video/webm"],
|
||||
|
@ -149,10 +114,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
],
|
||||
'columns' => ["id", "article"],
|
||||
'rows' => [
|
||||
[1,1],
|
||||
[2,2],
|
||||
|
@ -188,14 +150,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'columns' => [
|
||||
'subscription' => "int",
|
||||
'article' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'modified' => "datetime",
|
||||
'hidden' => "bool",
|
||||
],
|
||||
'columns' => ["subscription", "article", "read", "starred", "modified", "hidden"],
|
||||
'rows' => [
|
||||
[1, 1,1,1,'2000-01-01 00:00:00',0],
|
||||
[5, 19,1,0,'2000-01-01 00:00:00',0],
|
||||
|
@ -213,11 +168,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_labels' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com","Interesting"],
|
||||
[2,"john.doe@example.com","Fascinating"],
|
||||
|
@ -226,12 +177,7 @@ trait SeriesLabel {
|
|||
],
|
||||
],
|
||||
'arsse_label_members' => [
|
||||
'columns' => [
|
||||
'label' => "int",
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
],
|
||||
'columns' => ["label", "article", "subscription", "assigned"],
|
||||
'rows' => [
|
||||
[1, 1,1,1],
|
||||
[2, 1,1,1],
|
||||
|
|
|
@ -13,13 +13,10 @@ trait SeriesMeta {
|
|||
protected function setUpSeriesMeta(): void {
|
||||
$dataBare = [
|
||||
'arsse_meta' => [
|
||||
'columns' => [
|
||||
'key' => 'str',
|
||||
'value' => 'str',
|
||||
],
|
||||
'columns' => ["key", "value"],
|
||||
'rows' => [
|
||||
//['schema_version', "".\JKingWeb\Arsse\Database::SCHEMA_VERSION],
|
||||
['album',"A Farewell to Kings"],
|
||||
//['schema_version', "".\JKingWeb\Arsse\Database::SCHEMA_VERSION],
|
||||
['album',"A Farewell to Kings"],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
|
|
@ -23,23 +23,14 @@ trait SeriesSession {
|
|||
$old = gmdate("Y-m-d H:i:s", strtotime("now - 2 days"));
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_sessions' => [
|
||||
'columns' => [
|
||||
'id' => "str",
|
||||
'user' => "str",
|
||||
'created' => "datetime",
|
||||
'expires' => "datetime",
|
||||
],
|
||||
'columns' => ["id", "user", "created", "expires"],
|
||||
'rows' => [
|
||||
["80fa94c1a11f11e78667001e673b2560", "jane.doe@example.com", $past, $faroff],
|
||||
["27c6de8da13311e78667001e673b2560", "jane.doe@example.com", $past, $past], // expired
|
||||
|
|
|
@ -15,11 +15,7 @@ trait SeriesSubscription {
|
|||
public function setUpSeriesSubscription(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "", 1],
|
||||
["john.doe@example.com", "", 2],
|
||||
|
@ -28,12 +24,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "parent", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", null, "Technology"],
|
||||
[2, "john.doe@example.com", 1, "Software"],
|
||||
|
@ -44,27 +35,14 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_icons' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'data' => "blob",
|
||||
],
|
||||
'columns' => ["id", "url", "data"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/favicon.ico", "ICON DATA"],
|
||||
[2,"http://example.net/favicon.ico", null],
|
||||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'username' => "str",
|
||||
'password' => "str",
|
||||
'updated' => "datetime",
|
||||
'next_fetch' => "datetime",
|
||||
'icon' => "int",
|
||||
],
|
||||
'columns' => ["id", "url", "title", "username", "password", "updated", "next_fetch", "icon"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/feed1", "Ook", "", "",strtotime("now"),strtotime("now"),null],
|
||||
[2,"http://example.com/feed2", "eek", "", "",strtotime("now - 1 hour"),strtotime("now - 1 hour"),1],
|
||||
|
@ -73,18 +51,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'title' => "str",
|
||||
'folder' => "int",
|
||||
'pinned' => "bool",
|
||||
'order_type' => "int",
|
||||
'keep_rule' => "str",
|
||||
'block_rule' => "str",
|
||||
'scrape' => "bool",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "title", "folder", "pinned", "order_type", "keep_rule", "block_rule", "scrape"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com",2,null,null,1,2,null,null,0],
|
||||
[2,"jane.doe@example.com",2,null,null,0,0,null,null,0],
|
||||
|
@ -95,11 +62,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_tags' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com","Interesting"],
|
||||
[2,"john.doe@example.com","Fascinating"],
|
||||
|
@ -108,11 +71,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_tag_members' => [
|
||||
'columns' => [
|
||||
'tag' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
],
|
||||
'columns' => ["tag", "subscription", "assigned"],
|
||||
'rows' => [
|
||||
[1,1,1],
|
||||
[1,3,0],
|
||||
|
@ -122,14 +81,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_articles' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "feed", "url_title_hash", "url_content_hash", "title_content_hash", "title"],
|
||||
'rows' => [
|
||||
[1,2,"","","","Title 1"],
|
||||
[2,2,"","","","Title 2"],
|
||||
|
@ -142,10 +94,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
],
|
||||
'columns' => ["id", "article"],
|
||||
'rows' => [
|
||||
[1,1],
|
||||
[2,2],
|
||||
|
@ -158,10 +107,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_categories' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["article", "name"],
|
||||
'rows' => [
|
||||
[1,"A"],
|
||||
[2,"B"],
|
||||
|
@ -173,13 +119,7 @@ trait SeriesSubscription {
|
|||
],
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'columns' => [
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'hidden' => "bool",
|
||||
],
|
||||
'columns' => ["article", "subscription", "read", "starred", "hidden"],
|
||||
'rows' => [
|
||||
[1,2,1,0,0],
|
||||
[2,2,1,0,0],
|
||||
|
|
|
@ -13,11 +13,7 @@ trait SeriesTag {
|
|||
protected function setUpSeriesTag(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
|
@ -26,11 +22,7 @@ trait SeriesTag {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "url", "title"],
|
||||
'rows' => [
|
||||
[1,"http://example.com/1",""],
|
||||
[2,"http://example.com/2",""],
|
||||
|
@ -48,12 +40,7 @@ trait SeriesTag {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "feed", "title"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", 1,"Lord of Carrots"],
|
||||
[2, "john.doe@example.com", 2,null],
|
||||
|
@ -72,11 +59,7 @@ trait SeriesTag {
|
|||
],
|
||||
],
|
||||
'arsse_tags' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1,"john.doe@example.com","Interesting"],
|
||||
[2,"john.doe@example.com","Fascinating"],
|
||||
|
@ -85,11 +68,7 @@ trait SeriesTag {
|
|||
],
|
||||
],
|
||||
'arsse_tag_members' => [
|
||||
'columns' => [
|
||||
'tag' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
],
|
||||
'columns' => ["tag", "subscription", "assigned"],
|
||||
'rows' => [
|
||||
[1,1,1],
|
||||
[1,3,0],
|
||||
|
|
|
@ -17,24 +17,14 @@ trait SeriesToken {
|
|||
$old = gmdate("Y-m-d H:i:s", strtotime("now - 2 days"));
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["jane.doe@example.com", "",1],
|
||||
["john.doe@example.com", "",2],
|
||||
],
|
||||
],
|
||||
'arsse_tokens' => [
|
||||
'columns' => [
|
||||
'id' => "str",
|
||||
'class' => "str",
|
||||
'user' => "str",
|
||||
'expires' => "datetime",
|
||||
'data' => "str",
|
||||
],
|
||||
'columns' => ["id", "class", "user", "expires", "data"],
|
||||
'rows' => [
|
||||
["80fa94c1a11f11e78667001e673b2560", "fever.login", "jane.doe@example.com", $faroff, null],
|
||||
["27c6de8da13311e78667001e673b2560", "fever.login", "jane.doe@example.com", $past, null], // expired
|
||||
|
|
|
@ -12,12 +12,7 @@ trait SeriesUser {
|
|||
protected function setUpSeriesUser(): void {
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
'admin' => 'bool',
|
||||
],
|
||||
'columns' => ["id", "password", "num", "admin"],
|
||||
'rows' => [
|
||||
["admin@example.net", '$2y$10$PbcG2ZR3Z8TuPzM7aHTF8.v61dtCjzjK78gdZJcp4UePE8T9jEgBW', 1, 1], // password is hash of "secret"
|
||||
["jane.doe@example.com", "", 2, 0],
|
||||
|
@ -25,11 +20,7 @@ trait SeriesUser {
|
|||
],
|
||||
],
|
||||
'arsse_user_meta' => [
|
||||
'columns' => [
|
||||
'owner' => "str",
|
||||
'key' => "str",
|
||||
'value' => "str",
|
||||
],
|
||||
'columns' => ["owner", "key", "value"],
|
||||
'rows' => [
|
||||
["admin@example.net", "lang", "en"],
|
||||
["admin@example.net", "tz", "America/Toronto"],
|
||||
|
|
|
@ -31,7 +31,7 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
*/
|
||||
public function testBaseClassWithoutMessage(): void {
|
||||
$this->assertException("unknown");
|
||||
throw new Exception();
|
||||
throw new Exception;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -150,10 +150,10 @@ class TestException extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function providePicoFeedException() {
|
||||
return [
|
||||
'Failed feed discovery' => [new \PicoFeed\Reader\SubscriptionNotFoundException(), "subscriptionNotFound"],
|
||||
'Unsupported format' => [new \PicoFeed\Reader\UnsupportedFeedFormatException(), "unsupportedFeedFormat"],
|
||||
'Malformed XML' => [new \PicoFeed\Parser\MalformedXmlException(), "malformedXml"],
|
||||
'XML entity expansion' => [new \PicoFeed\Parser\XmlEntityException(), "xmlEntity"],
|
||||
'Failed feed discovery' => [new \PicoFeed\Reader\SubscriptionNotFoundException, "subscriptionNotFound"],
|
||||
'Unsupported format' => [new \PicoFeed\Reader\UnsupportedFeedFormatException, "unsupportedFeedFormat"],
|
||||
'Malformed XML' => [new \PicoFeed\Parser\MalformedXmlException, "malformedXml"],
|
||||
'XML entity expansion' => [new \PicoFeed\Parser\XmlEntityException, "xmlEntity"],
|
||||
];
|
||||
}
|
||||
|
||||
|
|
|
@ -41,23 +41,14 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$db->driverSchemaUpdate();
|
||||
$this->data = [
|
||||
'arsse_users' => [
|
||||
'columns' => [
|
||||
'id' => 'str',
|
||||
'password' => 'str',
|
||||
'num' => 'int',
|
||||
],
|
||||
'columns' => ["id", "password", "num"],
|
||||
'rows' => [
|
||||
["john.doe@example.com", "", 1],
|
||||
["jane.doe@example.com", "", 2],
|
||||
],
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "parent", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", null, "Science"],
|
||||
[2, "john.doe@example.com", 1, "Rocketry"],
|
||||
|
@ -68,11 +59,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "url", "title"],
|
||||
'rows' => [
|
||||
[1, "http://localhost:8000/Import/nasa-jpl", "NASA JPL"],
|
||||
[2, "http://localhost:8000/Import/torstar", "Toronto Star"],
|
||||
|
@ -83,13 +70,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'folder' => "int",
|
||||
'feed' => "int",
|
||||
'title' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "folder", "feed", "title"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", 2, 1, "NASA JPL"],
|
||||
[2, "john.doe@example.com", 5, 2, "Toronto Star"],
|
||||
|
@ -100,11 +81,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
],
|
||||
'arsse_tags' => [
|
||||
'columns' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
],
|
||||
'columns' => ["id", "owner", "name"],
|
||||
'rows' => [
|
||||
[1, "john.doe@example.com", "canada"],
|
||||
[2, "john.doe@example.com", "frequent"],
|
||||
|
@ -115,11 +92,7 @@ class TestImportExport extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
],
|
||||
],
|
||||
'arsse_tag_members' => [
|
||||
'columns' => [
|
||||
'tag' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
],
|
||||
'columns' => ["tag", "subscription", "assigned"],
|
||||
'rows' => [
|
||||
[1, 2, 1],
|
||||
[1, 4, 1],
|
||||
|
|
|
@ -93,7 +93,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
'articleRange' => [[1, 100], [1, 100]],
|
||||
'editionRange' => [[1, 100], [1, 100]],
|
||||
];
|
||||
foreach($tests as $k => $t) {
|
||||
foreach ($tests as $k => $t) {
|
||||
yield $k => array_merge([$k], $t, [false]);
|
||||
if (method_exists(ExclusionContext::class, $k)) {
|
||||
yield "$k (not)" => array_merge([$k], $t, [true]);
|
||||
|
@ -103,7 +103,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testCleanIdArrayValues(): void {
|
||||
$methods = ["articles", "editions", "tags", "labels", "subscriptions"];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime, -1.0];
|
||||
$out = [1, 2, 4];
|
||||
$c = new Context;
|
||||
foreach ($methods as $method) {
|
||||
|
@ -113,7 +113,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testCleanFolderIdArrayValues(): void {
|
||||
$methods = ["folders", "foldersShallow"];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime(), -1.0];
|
||||
$in = [1, "2", 3.5, 4.0, 4, "ook", 0, -20, true, false, null, new \DateTime, -1.0];
|
||||
$out = [1, 2, 4, 0];
|
||||
$c = new Context;
|
||||
foreach ($methods as $method) {
|
||||
|
@ -169,7 +169,7 @@ class TestContext extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertTrue(isset($c1[2]));
|
||||
$c1[] = $c2;
|
||||
$act = [];
|
||||
foreach($c1 as $k => $v) {
|
||||
foreach ($c1 as $k => $v) {
|
||||
$act[$k] = $v;
|
||||
}
|
||||
$exp = [2 => $c3, $c2];
|
||||
|
|
|
@ -9,9 +9,9 @@ namespace JKingWeb\Arsse\TestCase\Misc;
|
|||
use JKingWeb\Arsse\Misc\Query;
|
||||
use JKingWeb\Arsse\Misc\QueryFilter;
|
||||
|
||||
/**
|
||||
/**
|
||||
* @covers \JKingWeb\Arsse\Misc\Query
|
||||
* @covers \JKingWeb\Arsse\Misc\QueryFilter
|
||||
* @covers \JKingWeb\Arsse\Misc\QueryFilter
|
||||
*/
|
||||
class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
public function testBasicQuery(): void {
|
||||
|
@ -112,4 +112,4 @@ class TestQuery extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertSame(["datetime", "str", "int", "str", "int"], $q->getTypes());
|
||||
$this->assertSame([1, "ook", 42, "ook", 42], $q->getValues());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,6 @@ use JKingWeb\Arsse\Misc\URL;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\Misc\URL */
|
||||
class TestURL extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
||||
/** @dataProvider provideNormalizations */
|
||||
public function testNormalizeAUrl(string $url, string $exp, string $user = null, string $pass = null): void {
|
||||
$this->assertSame($exp, URL::normalize($url, $user, $pass));
|
||||
|
|
|
@ -93,7 +93,7 @@ class TestV1 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$user->method("propertiesGet")->willReturn(['num' => 42, 'admin' => false, 'root_folder_name' => null, 'tz' => "Asia/Gaza"]);
|
||||
Arsse::$user->method("begin")->willReturn($this->transaction->get());
|
||||
//initialize a handler
|
||||
$this->h = new V1();
|
||||
$this->h = new V1;
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
|
|
|
@ -328,7 +328,7 @@ class TestV1_2 extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->dbMock->begin->returns($this->mock(Transaction::class));
|
||||
//initialize a handler
|
||||
$this->h = new V1_2();
|
||||
$this->h = new V1_2;
|
||||
}
|
||||
|
||||
protected function v($value) {
|
||||
|
|
|
@ -22,7 +22,6 @@ use Laminas\Diactoros\Response\EmptyResponse;
|
|||
|
||||
/** @covers \JKingWeb\Arsse\REST */
|
||||
class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
||||
|
||||
/** @dataProvider provideApiMatchData */
|
||||
public function testMatchAUrlToAnApi($apiList, string $input, array $exp): void {
|
||||
$r = new REST($apiList);
|
||||
|
@ -61,7 +60,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideAuthenticableRequests */
|
||||
public function testAuthenticateRequests(array $serverParams, array $expAttr): void {
|
||||
$r = new REST();
|
||||
$r = new REST;
|
||||
// create a mock user manager
|
||||
$this->userMock = $this->mock(User::class);
|
||||
$this->userMock->auth->returns(false);
|
||||
|
@ -95,7 +94,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
public function testSendAuthenticationChallenges(): void {
|
||||
self::setConf();
|
||||
$r = new REST();
|
||||
$r = new REST;
|
||||
$in = new EmptyResponse(401);
|
||||
$exp = $in->withHeader("WWW-Authenticate", 'Basic realm="OOK", charset="UTF-8"');
|
||||
$act = $r->challenge($in, "OOK");
|
||||
|
@ -107,7 +106,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideUnnormalizedOrigins */
|
||||
public function testNormalizeOrigins(string $origin, string $exp, array $ports = null): void {
|
||||
$r = new REST();
|
||||
$r = new REST;
|
||||
$act = $r->corsNormalizeOrigin($origin, $ports);
|
||||
$this->assertSame($exp, $act);
|
||||
}
|
||||
|
@ -188,7 +187,7 @@ class TestREST extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
|
||||
/** @dataProvider provideCorsHeaders */
|
||||
public function testAddCorsHeaders(string $reqMethod, array $reqHeaders, array $resHeaders, array $expHeaders): void {
|
||||
$r = new REST();
|
||||
$r = new REST;
|
||||
$req = new Request("", $reqMethod, "php://memory", $reqHeaders);
|
||||
$res = new EmptyResponse(204, $resHeaders);
|
||||
$exp = new EmptyResponse(204, $expHeaders);
|
||||
|
|
|
@ -147,7 +147,7 @@ LONG_STRING;
|
|||
'expires' => "2112-12-21 21:12:00",
|
||||
'user' => $this->userId,
|
||||
]);
|
||||
$this->h = new API();
|
||||
$this->h = new API;
|
||||
}
|
||||
|
||||
protected function req($data, string $method = "POST", string $target = "", string $strData = null, string $user = null): ResponseInterface {
|
||||
|
@ -1524,11 +1524,11 @@ LONG_STRING;
|
|||
'content' => '<p>Article content 1</p>',
|
||||
],
|
||||
[
|
||||
'id' => "102",
|
||||
'guid' => "SHA256:5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7",
|
||||
'title' => 'Article title 2',
|
||||
'link' => 'http://example.com/2',
|
||||
'labels' => [],
|
||||
'id' => "102",
|
||||
'guid' => "SHA256:5be8a5a46ecd52ed132191c8d27fb1af6b3d4edc00234c5d9f8f0e10562ed3b7",
|
||||
'title' => 'Article title 2',
|
||||
'link' => 'http://example.com/2',
|
||||
'labels' => [],
|
||||
'unread' => false,
|
||||
'marked' => false,
|
||||
'published' => false,
|
||||
|
|
|
@ -25,7 +25,7 @@ class TestIcon extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
Arsse::$user = $this->mock(User::class)->get();
|
||||
// create a mock database interface
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
$this->h = new Icon();
|
||||
$this->h = new Icon;
|
||||
}
|
||||
|
||||
protected function req(string $target, string $method = "GET", string $user = null): ResponseInterface {
|
||||
|
|
|
@ -20,7 +20,7 @@ class TestService extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
self::setConf();
|
||||
$this->dbMock = $this->mock(Database::class);
|
||||
Arsse::$db = $this->dbMock->get();
|
||||
$this->srv = new Service();
|
||||
$this->srv = new Service;
|
||||
}
|
||||
|
||||
public function testCheckIn(): void {
|
||||
|
|
|
@ -31,6 +31,152 @@ use Laminas\Diactoros\Response\XmlResponse;
|
|||
abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
||||
use \DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
|
||||
|
||||
protected const COL_DEFS = [
|
||||
'arsse_meta' => [
|
||||
'key' => "str",
|
||||
'value' => "str",
|
||||
],
|
||||
'arsse_users' => [
|
||||
'id' => "str",
|
||||
'password' => "str",
|
||||
'num' => "int",
|
||||
'admin' => "bool",
|
||||
],
|
||||
'arsse_user_meta' => [
|
||||
'owner' => "str",
|
||||
'key' => "str",
|
||||
'modified' => "datetime",
|
||||
'value' => "str",
|
||||
],
|
||||
'arsse_sessions' => [
|
||||
'id' => "str",
|
||||
'created' => "datetime",
|
||||
'expires' => "datetime",
|
||||
'user' => "str",
|
||||
],
|
||||
'arsse_tokens' => [
|
||||
'id' => "str",
|
||||
'class' => "str",
|
||||
'user' => "str",
|
||||
'created' => "datetime",
|
||||
'expires' => "datetime",
|
||||
'data' => "str",
|
||||
],
|
||||
'arsse_feeds' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'source' => "str",
|
||||
'updated' => "datetime",
|
||||
'modified' => "datetime",
|
||||
'next_fetch' => "datetime",
|
||||
'orphaned' => "datetime",
|
||||
'etag' => "str",
|
||||
'err_count' => "int",
|
||||
'err_msg' => "str",
|
||||
'username' => "str",
|
||||
'password' => "str",
|
||||
'size' => "int",
|
||||
'icon' => "int",
|
||||
],
|
||||
'arsse_icons' => [
|
||||
'id' => "int",
|
||||
'url' => "str",
|
||||
'modified' => "datetime",
|
||||
'etag' => "str",
|
||||
'next_fetch' => "datetime",
|
||||
'orphaned' => "datetime",
|
||||
'type' => "str",
|
||||
'data' => "blob",
|
||||
],
|
||||
'arsse_articles' => [
|
||||
'id' => "int",
|
||||
'feed' => "int",
|
||||
'url' => "str",
|
||||
'title' => "str",
|
||||
'author' => "str",
|
||||
'published' => "datetime",
|
||||
'edited' => "datetime",
|
||||
'modified' => "datetime",
|
||||
'guid' => "str",
|
||||
'url_title_hash' => "str",
|
||||
'url_content_hash' => "str",
|
||||
'title_content_hash' => "str",
|
||||
'content_scraped' => "str",
|
||||
'content' => "str",
|
||||
],
|
||||
'arsse_editions' => [
|
||||
'id' => "int",
|
||||
'article' => "int",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'arsse_enclosures' => [
|
||||
'article' => "int",
|
||||
'url' => "str",
|
||||
'type' => "str",
|
||||
],
|
||||
'arsse_categories' => [
|
||||
'article' => "int",
|
||||
'name' => "str",
|
||||
],
|
||||
'arsse_marks' => [
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'read' => "bool",
|
||||
'starred' => "bool",
|
||||
'modified' => "datetime",
|
||||
'note' => "str",
|
||||
'touched' => "bool",
|
||||
'hidden' => "bool",
|
||||
],
|
||||
'arsse_subscriptions' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'feed' => "int",
|
||||
'added' => "datetime",
|
||||
'modified' => "datetime",
|
||||
'title' => "str",
|
||||
'order_type' => "int",
|
||||
'pinned' => "bool",
|
||||
'folder' => "int",
|
||||
'keep_rule' => "str",
|
||||
'block_rule' => "str",
|
||||
'scrape' => "bool",
|
||||
],
|
||||
'arsse_folders' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'parent' => "int",
|
||||
'name' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'arsse_tags' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'arsse_tag_members' => [
|
||||
'tag' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'arsse_labels' => [
|
||||
'id' => "int",
|
||||
'owner' => "str",
|
||||
'name' => "str",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
'arsse_label_members' => [
|
||||
'label' => "int",
|
||||
'article' => "int",
|
||||
'subscription' => "int",
|
||||
'assigned' => "bool",
|
||||
'modified' => "datetime",
|
||||
],
|
||||
];
|
||||
|
||||
protected $objMock;
|
||||
protected $confMock;
|
||||
protected $langMock;
|
||||
|
@ -54,7 +200,7 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
Arsse::$$prop = null;
|
||||
}
|
||||
if ($loadLang) {
|
||||
Arsse::$lang = new \JKingWeb\Arsse\Lang();
|
||||
Arsse::$lang = new \JKingWeb\Arsse\Lang;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,17 +208,17 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
$defaults = [
|
||||
'dbSQLite3File' => ":memory:",
|
||||
'dbSQLite3Timeout' => 0,
|
||||
'dbPostgreSQLHost' => $_ENV['ARSSE_TEST_PGSQL_HOST'] ?: "",
|
||||
'dbPostgreSQLPort' => $_ENV['ARSSE_TEST_PGSQL_PORT'] ?: 5432,
|
||||
'dbPostgreSQLUser' => $_ENV['ARSSE_TEST_PGSQL_USER'] ?: "arsse_test",
|
||||
'dbPostgreSQLPass' => $_ENV['ARSSE_TEST_PGSQL_PASS'] ?: "arsse_test",
|
||||
'dbPostgreSQLDb' => $_ENV['ARSSE_TEST_PGSQL_DB'] ?: "arsse_test",
|
||||
'dbPostgreSQLHost' => $_ENV['ARSSE_TEST_PGSQL_HOST'] ?: "",
|
||||
'dbPostgreSQLPort' => $_ENV['ARSSE_TEST_PGSQL_PORT'] ?: 5432,
|
||||
'dbPostgreSQLUser' => $_ENV['ARSSE_TEST_PGSQL_USER'] ?: "arsse_test",
|
||||
'dbPostgreSQLPass' => $_ENV['ARSSE_TEST_PGSQL_PASS'] ?: "arsse_test",
|
||||
'dbPostgreSQLDb' => $_ENV['ARSSE_TEST_PGSQL_DB'] ?: "arsse_test",
|
||||
'dbPostgreSQLSchema' => $_ENV['ARSSE_TEST_PGSQL_SCHEMA'] ?: "arsse_test",
|
||||
'dbMySQLHost' => $_ENV['ARSSE_TEST_MYSQL_HOST'] ?: "localhost",
|
||||
'dbMySQLPort' => $_ENV['ARSSE_TEST_MYSQL_PORT'] ?: 3306,
|
||||
'dbMySQLUser' => $_ENV['ARSSE_TEST_MYSQL_USER'] ?: "arsse_test",
|
||||
'dbMySQLPass' => $_ENV['ARSSE_TEST_MYSQL_PASS'] ?: "arsse_test",
|
||||
'dbMySQLDb' => $_ENV['ARSSE_TEST_MYSQL_DB'] ?: "arsse_test",
|
||||
'dbMySQLHost' => $_ENV['ARSSE_TEST_MYSQL_HOST'] ?: "localhost",
|
||||
'dbMySQLPort' => $_ENV['ARSSE_TEST_MYSQL_PORT'] ?: 3306,
|
||||
'dbMySQLUser' => $_ENV['ARSSE_TEST_MYSQL_USER'] ?: "arsse_test",
|
||||
'dbMySQLPass' => $_ENV['ARSSE_TEST_MYSQL_PASS'] ?: "arsse_test",
|
||||
'dbMySQLDb' => $_ENV['ARSSE_TEST_MYSQL_DB'] ?: "arsse_test",
|
||||
];
|
||||
Arsse::$conf = (($force ? null : Arsse::$conf) ?? (new Conf))->import($defaults)->import($conf);
|
||||
}
|
||||
|
@ -241,14 +387,33 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
return $value;
|
||||
}
|
||||
|
||||
/** Inserts into the database test data in the following format:
|
||||
*
|
||||
* ```php
|
||||
* $data = [
|
||||
* 'some_table' => [
|
||||
* 'columns' => ["id", "name"],
|
||||
* 'rows' => [
|
||||
* [1,"Dupond"],
|
||||
* [2,"Dupont"],
|
||||
* ]
|
||||
* ],
|
||||
* 'other_table' => [
|
||||
* ...
|
||||
* ]
|
||||
* ];
|
||||
* ```
|
||||
*/
|
||||
public function primeDatabase(Driver $drv, array $data): bool {
|
||||
$tr = $drv->begin();
|
||||
foreach ($data as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
}, $info['columns']);
|
||||
$cols = implode(",", $cols);
|
||||
$bindings = array_values($info['columns']);
|
||||
$bindings = array_map(function($c) use ($table) {
|
||||
return self::COL_DEFS[$table][$c];
|
||||
}, $info['columns']);
|
||||
$params = implode(",", array_fill(0, sizeof($info['columns']), "?"));
|
||||
$s = $drv->prepareArray("INSERT INTO $table($cols) values($params)", $bindings);
|
||||
foreach ($info['rows'] as $row) {
|
||||
|
@ -260,70 +425,104 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
return true;
|
||||
}
|
||||
|
||||
public function compareExpectations(Driver $drv, array $expected): bool {
|
||||
public function compareExpectations(Driver $drv, array $expected): void {
|
||||
foreach ($expected as $table => $info) {
|
||||
$cols = array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, array_keys($info['columns']));
|
||||
$cols = implode(",", $cols);
|
||||
$types = $info['columns'];
|
||||
$data = $drv->prepare("SELECT $cols from $table")->run()->getAll();
|
||||
$cols = array_keys($info['columns']);
|
||||
foreach ($info['rows'] as $index => $row) {
|
||||
$this->assertCount(sizeof($cols), $row, "The number of columns in array index $index of expectations for table $table does not match its definition");
|
||||
$row = array_combine($cols, $row);
|
||||
foreach ($data as $index => $test) {
|
||||
foreach ($test as $col => $value) {
|
||||
switch ($types[$col]) {
|
||||
case "datetime":
|
||||
$test[$col] = $this->approximateTime($row[$col], $value);
|
||||
break;
|
||||
case "int":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_INT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "float":
|
||||
$test[$col] = ValueInfo::normalize($value, ValueInfo::T_FLOAT | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
case "bool":
|
||||
$test[$col] = (int) ValueInfo::normalize($value, ValueInfo::T_BOOL | ValueInfo::M_DROP | valueInfo::M_NULL);
|
||||
break;
|
||||
}
|
||||
// serialize the rows of the expected output
|
||||
$exp = [];
|
||||
$dates = [];
|
||||
foreach ($info['rows'] as $r) {
|
||||
$row = [];
|
||||
foreach ($r as $c => $v) {
|
||||
// store any date values for later comparison
|
||||
if (self::COL_DEFS[$table][$info['columns'][$c]] === "datetime") {
|
||||
$dates[] = $v;
|
||||
}
|
||||
if ($row === $test) {
|
||||
$data[$index] = $test;
|
||||
break;
|
||||
// serialize to CSV, null being represented by no value
|
||||
if ($v === null) {
|
||||
$row[] = "";
|
||||
} elseif ($drv->stringOutput() || is_string($v)) {
|
||||
$row[] = '"'.str_replace('"', '""', (string) $v).'"';
|
||||
} else {
|
||||
$row[] = (string) $v;
|
||||
}
|
||||
}
|
||||
$this->assertContains($row, $data, "Actual Table $table does not contain record at expected array index $index");
|
||||
$found = array_search($row, $data, true);
|
||||
unset($data[$found]);
|
||||
$exp[] = implode(",", $row);
|
||||
}
|
||||
$this->assertSame([], $data, "Actual table $table contains extra rows not in expectations");
|
||||
// serialize the rows of the actual output
|
||||
$cols = implode(",", array_map(function($v) {
|
||||
return '"'.str_replace('"', '""', $v).'"';
|
||||
}, $info['columns']));
|
||||
$data = $drv->prepare("SELECT $cols from $table")->run()->getAll();
|
||||
$act = [];
|
||||
$extra = [];
|
||||
foreach ($data as $r) {
|
||||
$row = [];
|
||||
foreach ($r as $c => $v) {
|
||||
// account for dates which might be off by one second
|
||||
if (self::COL_DEFS[$table][$c] === "datetime") {
|
||||
if (array_search($v, $dates, true) === false) {
|
||||
$v = Date::transform(Date::sub("PT1S", $v), "sql");
|
||||
if (array_search($v, $dates, true) === false) {
|
||||
$v = Date::transform(Date::add("PT2S", $v), "sql");
|
||||
if (array_search($v, $dates, true) === false) {
|
||||
$v = Date::transform(Date::sub("PT1S", $v), "sql");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if ($v === null) {
|
||||
$row[] = "";
|
||||
} elseif (is_string($v)) {
|
||||
$row[] = '"'.str_replace('"', '""', (string) $v).'"';
|
||||
} else {
|
||||
$row[] = (string) $v;
|
||||
}
|
||||
}
|
||||
$row = implode(",", $row);
|
||||
// now search for the actual output row in the expected output
|
||||
$found = array_keys($exp, $row, true);
|
||||
foreach ($found as $k) {
|
||||
if(!isset($act[$k])) {
|
||||
$act[$k] = $row;
|
||||
// skip to the next row
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
// if the row was not found, add it to a buffer which will be added to the actual output once all found rows are processed
|
||||
$extra[] = $row;
|
||||
}
|
||||
// add any unfound rows to the end of the actual array
|
||||
$base = sizeof($exp) + 1;
|
||||
foreach ($extra as $k => $v) {
|
||||
$act[$base + $k] = $v;
|
||||
}
|
||||
// sort the actual output by keys
|
||||
ksort($act);
|
||||
// finally perform the comparison to be shown to the tester
|
||||
$this->assertSame($exp, $act, "Actual table $table does not match expectations");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function primeExpectations(array $source, array $tableSpecs): array {
|
||||
$out = [];
|
||||
foreach ($tableSpecs as $table => $columns) {
|
||||
// make sure the source has the table we want
|
||||
$this->assertArrayHasKey($table, $source, "Source for expectations does not contain requested table $table.");
|
||||
if (!isset($source[$table])) {
|
||||
throw new Exception("Source for expectations does not contain requested table $table.");
|
||||
}
|
||||
// fill the output, particularly the correct number of (empty) rows
|
||||
$rows = sizeof($source[$table]['rows']);
|
||||
$out[$table] = [
|
||||
'columns' => [],
|
||||
'rows' => array_fill(0, sizeof($source[$table]['rows']), []),
|
||||
'columns' => $columns,
|
||||
'rows' => array_fill(0, $rows, []),
|
||||
];
|
||||
// make sure the source has all the columns we want for the table
|
||||
$cols = array_flip($columns);
|
||||
$cols = array_intersect_key($cols, $source[$table]['columns']);
|
||||
$this->assertSame(array_keys($cols), $columns, "Source for table $table does not contain all requested columns");
|
||||
// get a map of source value offsets and keys
|
||||
$targets = array_flip(array_keys($source[$table]['columns']));
|
||||
foreach ($cols as $key => $order) {
|
||||
// fill the column-spec
|
||||
$out[$table]['columns'][$key] = $source[$table]['columns'][$key];
|
||||
foreach ($source[$table]['rows'] as $index => $row) {
|
||||
// fill each row column-wise with re-ordered values
|
||||
$out[$table]['rows'][$index][$order] = $row[$targets[$key]];
|
||||
// fill the rows with the requested data, column-wise
|
||||
foreach ($columns as $c) {
|
||||
if (($index = array_search($c, $source[$table]['columns'], true)) === false) {
|
||||
throw new exception("Expected column $table.$c is not present in test data");
|
||||
}
|
||||
for ($a = 0; $a < $rows; $a++) {
|
||||
$out[$table]['rows'][$a][] = $source[$table]['rows'][$a][$index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -335,10 +534,6 @@ abstract class AbstractTest extends \PHPUnit\Framework\TestCase {
|
|||
// stringify our expectations if necessary
|
||||
if (static::$stringOutput ?? false) {
|
||||
$expected = $this->stringify($expected);
|
||||
// MySQL is extra-special and mixes strings and integers, so we cast the data, too
|
||||
if ((static::$implementation ?? "") === "MySQL") {
|
||||
$data = $this->stringify($data);
|
||||
}
|
||||
}
|
||||
$this->assertCount(sizeof($expected), $data, "Number of result rows (".sizeof($data).") differs from number of expected rows (".sizeof($expected).")");
|
||||
if (sizeof($expected)) {
|
||||
|
|
|
@ -16,7 +16,7 @@ trait MySQL {
|
|||
protected static $dbResultClass = \JKingWeb\Arsse\Db\MySQL\Result::class;
|
||||
protected static $dbStatementClass = \JKingWeb\Arsse\Db\MySQL\Statement::class;
|
||||
protected static $dbDriverClass = \JKingWeb\Arsse\Db\MySQL\Driver::class;
|
||||
protected static $stringOutput = true;
|
||||
protected static $stringOutput = false;
|
||||
|
||||
public static function dbInterface() {
|
||||
if (!class_exists("mysqli")) {
|
||||
|
@ -25,7 +25,7 @@ trait MySQL {
|
|||
$drv = new \mysqli_driver;
|
||||
$drv->report_mode = \MYSQLI_REPORT_OFF;
|
||||
$d = mysqli_init();
|
||||
$d->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, false);
|
||||
$d->options(\MYSQLI_OPT_INT_AND_FLOAT_NATIVE, true);
|
||||
$d->options(\MYSQLI_SET_CHARSET_NAME, "utf8mb4");
|
||||
@$d->real_connect(Arsse::$conf->dbMySQLHost, Arsse::$conf->dbMySQLUser, Arsse::$conf->dbMySQLPass, Arsse::$conf->dbMySQLDb, Arsse::$conf->dbMySQLPort);
|
||||
if ($d->connect_errno) {
|
||||
|
|
|
@ -16,7 +16,7 @@ trait MySQLPDO {
|
|||
protected static $dbResultClass = \JKingWeb\Arsse\Db\PDOResult::class;
|
||||
protected static $dbStatementClass = \JKingWeb\Arsse\Db\MySQL\PDOStatement::class;
|
||||
protected static $dbDriverClass = \JKingWeb\Arsse\Db\MySQL\PDODriver::class;
|
||||
protected static $stringOutput = true;
|
||||
protected static $stringOutput = false;
|
||||
|
||||
public static function dbInterface() {
|
||||
try {
|
||||
|
@ -33,7 +33,7 @@ trait MySQLPDO {
|
|||
$dsn = "mysql:".implode(";", $dsn);
|
||||
$d = new \PDO($dsn, Arsse::$conf->dbMySQLUser, Arsse::$conf->dbMySQLPass, [
|
||||
\PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => true,
|
||||
\PDO::ATTR_STRINGIFY_FETCHES => false,
|
||||
\PDO::MYSQL_ATTR_MULTI_STATEMENTS => false,
|
||||
]);
|
||||
foreach (\JKingWeb\Arsse\Db\MySQL\PDODriver::makeSetupQueries() as $q) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"require-dev": {
|
||||
"friendsofphp/php-cs-fixer": "^2.8"
|
||||
"friendsofphp/php-cs-fixer": "^3.0"
|
||||
}
|
||||
}
|
||||
|
|
692
vendor-bin/csfixer/composer.lock
generated
692
vendor-bin/csfixer/composer.lock
generated
File diff suppressed because it is too large
Load diff
113
vendor-bin/daux/composer.lock
generated
113
vendor-bin/daux/composer.lock
generated
|
@ -83,16 +83,16 @@
|
|||
},
|
||||
{
|
||||
"name": "guzzlehttp/guzzle",
|
||||
"version": "7.4.2",
|
||||
"version": "7.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/guzzle/guzzle.git",
|
||||
"reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4"
|
||||
"reference": "74a8602c6faec9ef74b7a9391ac82c5e65b1cdab"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/ac1ec1cd9b5624694c3a40be801d94137afb12b4",
|
||||
"reference": "ac1ec1cd9b5624694c3a40be801d94137afb12b4",
|
||||
"url": "https://api.github.com/repos/guzzle/guzzle/zipball/74a8602c6faec9ef74b7a9391ac82c5e65b1cdab",
|
||||
"reference": "74a8602c6faec9ef74b7a9391ac82c5e65b1cdab",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -187,7 +187,7 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/guzzle/guzzle/issues",
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.4.2"
|
||||
"source": "https://github.com/guzzle/guzzle/tree/7.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -203,7 +203,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-20T14:16:28+00:00"
|
||||
"time": "2022-05-25T13:24:33+00:00"
|
||||
},
|
||||
{
|
||||
"name": "guzzlehttp/promises",
|
||||
|
@ -898,16 +898,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v5.4.7",
|
||||
"version": "v5.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6"
|
||||
"reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/900275254f0a1a2afff1ab0e11abd5587a10e1d6",
|
||||
"reference": "900275254f0a1a2afff1ab0e11abd5587a10e1d6",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/829d5d1bf60b2efeb0887b7436873becc71a45eb",
|
||||
"reference": "829d5d1bf60b2efeb0887b7436873becc71a45eb",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -977,7 +977,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.7"
|
||||
"source": "https://github.com/symfony/console/tree/v5.4.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -993,29 +993,29 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-31T17:09:19+00:00"
|
||||
"time": "2022-05-18T06:17:34+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.0.0",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced"
|
||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
|
||||
"reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2"
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.0-dev"
|
||||
"dev-main": "3.1-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
@ -1044,7 +1044,7 @@
|
|||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0"
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1060,20 +1060,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-01T23:48:49+00:00"
|
||||
"time": "2022-02-25T11:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/http-foundation",
|
||||
"version": "v5.4.6",
|
||||
"version": "v5.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/http-foundation.git",
|
||||
"reference": "34e89bc147633c0f9dd6caaaf56da3b806a21465"
|
||||
"reference": "6b0d0e4aca38d57605dcd11e2416994b38774522"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/34e89bc147633c0f9dd6caaaf56da3b806a21465",
|
||||
"reference": "34e89bc147633c0f9dd6caaaf56da3b806a21465",
|
||||
"url": "https://api.github.com/repos/symfony/http-foundation/zipball/6b0d0e4aca38d57605dcd11e2416994b38774522",
|
||||
"reference": "6b0d0e4aca38d57605dcd11e2416994b38774522",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1117,7 +1117,7 @@
|
|||
"description": "Defines an object-oriented layer for the HTTP specification",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v5.4.6"
|
||||
"source": "https://github.com/symfony/http-foundation/tree/v5.4.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1133,20 +1133,20 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-05T21:03:43+00:00"
|
||||
"time": "2022-05-17T15:07:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/mime",
|
||||
"version": "v5.4.7",
|
||||
"version": "v5.4.9",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/mime.git",
|
||||
"reference": "92d27a34dea2e199fa9b687e3fff3a7d169b7b1c"
|
||||
"reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/92d27a34dea2e199fa9b687e3fff3a7d169b7b1c",
|
||||
"reference": "92d27a34dea2e199fa9b687e3fff3a7d169b7b1c",
|
||||
"url": "https://api.github.com/repos/symfony/mime/zipball/2b3802a24e48d0cfccf885173d2aac91e73df92e",
|
||||
"reference": "2b3802a24e48d0cfccf885173d2aac91e73df92e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -1200,7 +1200,7 @@
|
|||
"mime-type"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/mime/tree/v5.4.7"
|
||||
"source": "https://github.com/symfony/mime/tree/v5.4.9"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1216,7 +1216,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-11T16:08:05+00:00"
|
||||
"time": "2022-05-21T10:24:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
|
@ -1962,16 +1962,16 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v5.4.7",
|
||||
"version": "v5.4.8",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "38a44b2517b470a436e1c944bf9b9ba3961137fb"
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/38a44b2517b470a436e1c944bf9b9ba3961137fb",
|
||||
"reference": "38a44b2517b470a436e1c944bf9b9ba3961137fb",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -2004,7 +2004,7 @@
|
|||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.7"
|
||||
"source": "https://github.com/symfony/process/tree/v5.4.8"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2020,24 +2020,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-18T16:18:52+00:00"
|
||||
"time": "2022-04-08T05:07:18+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.0.0",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603"
|
||||
"reference": "d66cd8ab656780f62c4215b903a420eb86358957"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603",
|
||||
"reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/d66cd8ab656780f62c4215b903a420eb86358957",
|
||||
"reference": "d66cd8ab656780f62c4215b903a420eb86358957",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"psr/container": "^2.0"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -2049,7 +2049,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.0-dev"
|
||||
"dev-main": "3.1-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
@ -2059,7 +2059,10 @@
|
|||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Test/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
@ -2086,7 +2089,7 @@
|
|||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.0.0"
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2102,24 +2105,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-04T17:53:12+00:00"
|
||||
"time": "2022-05-07T08:07:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v6.0.3",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2"
|
||||
"reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2",
|
||||
"reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/d3edc75baf9f1d4f94879764dda2e1ac33499529",
|
||||
"reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-intl-grapheme": "~1.0",
|
||||
"symfony/polyfill-intl-normalizer": "~1.0",
|
||||
|
@ -2171,7 +2174,7 @@
|
|||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v6.0.3"
|
||||
"source": "https://github.com/symfony/string/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2187,7 +2190,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:55:41+00:00"
|
||||
"time": "2022-04-22T08:18:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
|
@ -2344,5 +2347,5 @@
|
|||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
2
vendor-bin/phpstan/composer.lock
generated
2
vendor-bin/phpstan/composer.lock
generated
|
@ -79,5 +79,5 @@
|
|||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
80
vendor-bin/phpunit/composer.lock
generated
80
vendor-bin/phpunit/composer.lock
generated
|
@ -448,16 +448,16 @@
|
|||
},
|
||||
{
|
||||
"name": "nikic/php-parser",
|
||||
"version": "v4.13.2",
|
||||
"version": "v4.14.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/nikic/PHP-Parser.git",
|
||||
"reference": "210577fe3cf7badcc5814d99455df46564f3c077"
|
||||
"reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077",
|
||||
"reference": "210577fe3cf7badcc5814d99455df46564f3c077",
|
||||
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1",
|
||||
"reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
|
@ -498,9 +498,9 @@
|
|||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/nikic/PHP-Parser/issues",
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2"
|
||||
"source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0"
|
||||
},
|
||||
"time": "2021-11-30T19:35:32+00:00"
|
||||
"time": "2022-05-31T20:59:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phar-io/manifest",
|
||||
|
@ -2417,21 +2417,20 @@
|
|||
},
|
||||
{
|
||||
"name": "webmozart/glob",
|
||||
"version": "4.4.0",
|
||||
"version": "4.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozarts/glob.git",
|
||||
"reference": "539b5dbc10021d3f9242e7a9e9b6b37843179e83"
|
||||
"reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozarts/glob/zipball/539b5dbc10021d3f9242e7a9e9b6b37843179e83",
|
||||
"reference": "539b5dbc10021d3f9242e7a9e9b6b37843179e83",
|
||||
"url": "https://api.github.com/repos/webmozarts/glob/zipball/3c17f7dec3d9d0e87b575026011f2e75a56ed655",
|
||||
"reference": "3c17f7dec3d9d0e87b575026011f2e75a56ed655",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3 || ^8.0.0",
|
||||
"webmozart/path-util": "^2.2"
|
||||
"php": "^7.3 || ^8.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.5",
|
||||
|
@ -2461,60 +2460,9 @@
|
|||
"description": "A PHP implementation of Ant's glob.",
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozarts/glob/issues",
|
||||
"source": "https://github.com/webmozarts/glob/tree/4.4.0"
|
||||
"source": "https://github.com/webmozarts/glob/tree/4.6.0"
|
||||
},
|
||||
"time": "2021-10-07T16:13:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/path-util",
|
||||
"version": "2.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/webmozart/path-util.git",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/webmozart/path-util/zipball/d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"reference": "d939f7edc24c9a1bb9c0dee5cb05d8e859490725",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.3",
|
||||
"webmozart/assert": "~1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.6",
|
||||
"sebastian/version": "^1.0.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.3-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Webmozart\\PathUtil\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Bernhard Schussek",
|
||||
"email": "bschussek@gmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A robust cross-platform utility for normalizing, comparing and modifying file paths.",
|
||||
"support": {
|
||||
"issues": "https://github.com/webmozart/path-util/issues",
|
||||
"source": "https://github.com/webmozart/path-util/tree/2.3.0"
|
||||
},
|
||||
"abandoned": "symfony/filesystem",
|
||||
"time": "2015-12-17T08:42:14+00:00"
|
||||
"time": "2022-05-24T19:45:58+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
@ -2524,5 +2472,5 @@
|
|||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
245
vendor-bin/robo/composer.lock
generated
245
vendor-bin/robo/composer.lock
generated
|
@ -90,22 +90,22 @@
|
|||
},
|
||||
{
|
||||
"name": "consolidation/annotated-command",
|
||||
"version": "4.5.3",
|
||||
"version": "4.5.5",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/consolidation/annotated-command.git",
|
||||
"reference": "1941a743e63993288e09d0686a4cb7ed47813213"
|
||||
"reference": "67cea8e8e7656b74da651ea6f49321853996c0fd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/consolidation/annotated-command/zipball/1941a743e63993288e09d0686a4cb7ed47813213",
|
||||
"reference": "1941a743e63993288e09d0686a4cb7ed47813213",
|
||||
"url": "https://api.github.com/repos/consolidation/annotated-command/zipball/67cea8e8e7656b74da651ea6f49321853996c0fd",
|
||||
"reference": "67cea8e8e7656b74da651ea6f49321853996c0fd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"consolidation/output-formatters": "^4.1.1",
|
||||
"php": ">=7.1.3",
|
||||
"psr/log": "^1|^2",
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/console": "^4.4.8|^5|^6",
|
||||
"symfony/event-dispatcher": "^4.4.8|^5|^6",
|
||||
"symfony/finder": "^4.4.8|^5|^6"
|
||||
|
@ -119,7 +119,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "5.x-dev"
|
||||
"dev-main": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
|
@ -140,9 +140,9 @@
|
|||
"description": "Initialize Symfony Console commands from annotated command class methods.",
|
||||
"support": {
|
||||
"issues": "https://github.com/consolidation/annotated-command/issues",
|
||||
"source": "https://github.com/consolidation/annotated-command/tree/4.5.3"
|
||||
"source": "https://github.com/consolidation/annotated-command/tree/4.5.5"
|
||||
},
|
||||
"time": "2022-04-02T00:17:53+00:00"
|
||||
"time": "2022-04-26T16:18:25+00:00"
|
||||
},
|
||||
{
|
||||
"name": "consolidation/config",
|
||||
|
@ -546,26 +546,25 @@
|
|||
},
|
||||
{
|
||||
"name": "grasmash/expander",
|
||||
"version": "2.0.2",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/grasmash/expander.git",
|
||||
"reference": "f4df21d01d1fbda38269cca89e3dbb6ba223da7f"
|
||||
"reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/grasmash/expander/zipball/f4df21d01d1fbda38269cca89e3dbb6ba223da7f",
|
||||
"reference": "f4df21d01d1fbda38269cca89e3dbb6ba223da7f",
|
||||
"url": "https://api.github.com/repos/grasmash/expander/zipball/b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e",
|
||||
"reference": "b7cbc1f2fdf9a9c0e253a424c2a4058316b7cb6e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"dflydev/dot-access-data": "^3.0.0",
|
||||
"php": ">=5.6",
|
||||
"psr/log": "^1 | ^2"
|
||||
"php": ">=7.1",
|
||||
"psr/log": "^1 | ^2 | ^3"
|
||||
},
|
||||
"require-dev": {
|
||||
"greg-1-anderson/composer-test-scenarios": "^1",
|
||||
"php-coveralls/php-coveralls": "^2.0",
|
||||
"phpunit/phpunit": "^6.0 || ^8.0 || ^9",
|
||||
"squizlabs/php_codesniffer": "^2.7 || ^3.3"
|
||||
},
|
||||
|
@ -592,9 +591,9 @@
|
|||
"description": "Expands internal property references in PHP arrays file.",
|
||||
"support": {
|
||||
"issues": "https://github.com/grasmash/expander/issues",
|
||||
"source": "https://github.com/grasmash/expander/tree/2.0.2"
|
||||
"source": "https://github.com/grasmash/expander/tree/2.0.3"
|
||||
},
|
||||
"time": "2022-02-24T03:58:20+00:00"
|
||||
"time": "2022-04-25T22:17:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/container",
|
||||
|
@ -1071,20 +1070,21 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/console",
|
||||
"version": "v6.0.7",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/console.git",
|
||||
"reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e"
|
||||
"reference": "c9646197ef43b0e2ff44af61e7f0571526fd4170"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e",
|
||||
"reference": "70dcf7b2ca2ea08ad6ebcc475f104a024fb5632e",
|
||||
"url": "https://api.github.com/repos/symfony/console/zipball/c9646197ef43b0e2ff44af61e7f0571526fd4170",
|
||||
"reference": "c9646197ef43b0e2ff44af61e7f0571526fd4170",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"symfony/deprecation-contracts": "^2.1|^3",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/service-contracts": "^1.1|^2|^3",
|
||||
"symfony/string": "^5.4|^6.0"
|
||||
|
@ -1146,7 +1146,7 @@
|
|||
"terminal"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/console/tree/v6.0.7"
|
||||
"source": "https://github.com/symfony/console/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1162,24 +1162,91 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-31T17:18:25+00:00"
|
||||
"time": "2022-05-27T06:34:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v6.0.3",
|
||||
"name": "symfony/deprecation-contracts",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934"
|
||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/6472ea2dd415e925b90ca82be64b8bc6157f3934",
|
||||
"reference": "6472ea2dd415e925b90ca82be64b8bc6157f3934",
|
||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.1-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"function.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "A generic function and convention to trigger deprecation notices",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-02-25T11:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher.git",
|
||||
"reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347",
|
||||
"reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"symfony/event-dispatcher-contracts": "^2|^3"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -1229,7 +1296,7 @@
|
|||
"description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v6.0.3"
|
||||
"source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1245,24 +1312,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:55:41+00:00"
|
||||
"time": "2022-05-05T16:51:07+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/event-dispatcher-contracts",
|
||||
"version": "v3.0.0",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/event-dispatcher-contracts.git",
|
||||
"reference": "aa5422287b75594b90ee9cd807caf8f0df491385"
|
||||
"reference": "02ff5eea2f453731cfbc6bc215e456b781480448"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385",
|
||||
"reference": "aa5422287b75594b90ee9cd807caf8f0df491385",
|
||||
"url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448",
|
||||
"reference": "02ff5eea2f453731cfbc6bc215e456b781480448",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"psr/event-dispatcher": "^1"
|
||||
},
|
||||
"suggest": {
|
||||
|
@ -1271,7 +1338,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.0-dev"
|
||||
"dev-main": "3.1-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
@ -1308,7 +1375,7 @@
|
|||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0"
|
||||
"source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1324,24 +1391,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-07-15T12:33:35+00:00"
|
||||
"time": "2022-02-25T11:15:52+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/filesystem",
|
||||
"version": "v6.0.7",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/filesystem.git",
|
||||
"reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff"
|
||||
"reference": "3132d2f43ca799c2aa099f9738d98228c56baa5d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff",
|
||||
"reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff",
|
||||
"url": "https://api.github.com/repos/symfony/filesystem/zipball/3132d2f43ca799c2aa099f9738d98228c56baa5d",
|
||||
"reference": "3132d2f43ca799c2aa099f9738d98228c56baa5d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-mbstring": "~1.8"
|
||||
},
|
||||
|
@ -1371,7 +1438,7 @@
|
|||
"description": "Provides basic utilities for the filesystem",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.0.7"
|
||||
"source": "https://github.com/symfony/filesystem/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1387,24 +1454,27 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-04-01T12:54:51+00:00"
|
||||
"time": "2022-05-21T13:34:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/finder",
|
||||
"version": "v6.0.3",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/finder.git",
|
||||
"reference": "8661b74dbabc23223f38c9b99d3f8ade71170430"
|
||||
"reference": "45b8beb69d6eb3b05a65689ebfd4222326773f8f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/8661b74dbabc23223f38c9b99d3f8ade71170430",
|
||||
"reference": "8661b74dbabc23223f38c9b99d3f8ade71170430",
|
||||
"url": "https://api.github.com/repos/symfony/finder/zipball/45b8beb69d6eb3b05a65689ebfd4222326773f8f",
|
||||
"reference": "45b8beb69d6eb3b05a65689ebfd4222326773f8f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2"
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/filesystem": "^6.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -1432,7 +1502,7 @@
|
|||
"description": "Finds files and directories via an intuitive fluent interface",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/finder/tree/v6.0.3"
|
||||
"source": "https://github.com/symfony/finder/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1448,7 +1518,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-26T17:23:29+00:00"
|
||||
"time": "2022-04-15T08:08:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/polyfill-ctype",
|
||||
|
@ -1782,20 +1852,20 @@
|
|||
},
|
||||
{
|
||||
"name": "symfony/process",
|
||||
"version": "v6.0.7",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/process.git",
|
||||
"reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4"
|
||||
"reference": "318718453c2be58266f1a9e74063d13cb8dd4165"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/e13f6757e267d687e20ec5b26ccfcbbe511cd8f4",
|
||||
"reference": "e13f6757e267d687e20ec5b26ccfcbbe511cd8f4",
|
||||
"url": "https://api.github.com/repos/symfony/process/zipball/318718453c2be58266f1a9e74063d13cb8dd4165",
|
||||
"reference": "318718453c2be58266f1a9e74063d13cb8dd4165",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2"
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
|
@ -1823,7 +1893,7 @@
|
|||
"description": "Executes commands in sub-processes",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/process/tree/v6.0.7"
|
||||
"source": "https://github.com/symfony/process/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1839,24 +1909,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-03-18T16:21:55+00:00"
|
||||
"time": "2022-05-11T12:12:29+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/service-contracts",
|
||||
"version": "v3.0.0",
|
||||
"version": "v3.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/service-contracts.git",
|
||||
"reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603"
|
||||
"reference": "d66cd8ab656780f62c4215b903a420eb86358957"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603",
|
||||
"reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603",
|
||||
"url": "https://api.github.com/repos/symfony/service-contracts/zipball/d66cd8ab656780f62c4215b903a420eb86358957",
|
||||
"reference": "d66cd8ab656780f62c4215b903a420eb86358957",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"psr/container": "^2.0"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -1868,7 +1938,7 @@
|
|||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.0-dev"
|
||||
"dev-main": "3.1-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
|
@ -1878,7 +1948,10 @@
|
|||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Service\\": ""
|
||||
}
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Test/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
|
@ -1905,7 +1978,7 @@
|
|||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.0.0"
|
||||
"source": "https://github.com/symfony/service-contracts/tree/v3.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -1921,24 +1994,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-11-04T17:53:12+00:00"
|
||||
"time": "2022-05-07T08:07:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/string",
|
||||
"version": "v6.0.3",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/string.git",
|
||||
"reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2"
|
||||
"reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/522144f0c4c004c80d56fa47e40e17028e2eefc2",
|
||||
"reference": "522144f0c4c004c80d56fa47e40e17028e2eefc2",
|
||||
"url": "https://api.github.com/repos/symfony/string/zipball/d3edc75baf9f1d4f94879764dda2e1ac33499529",
|
||||
"reference": "d3edc75baf9f1d4f94879764dda2e1ac33499529",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-ctype": "~1.8",
|
||||
"symfony/polyfill-intl-grapheme": "~1.0",
|
||||
"symfony/polyfill-intl-normalizer": "~1.0",
|
||||
|
@ -1990,7 +2063,7 @@
|
|||
"utf8"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/string/tree/v6.0.3"
|
||||
"source": "https://github.com/symfony/string/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2006,24 +2079,24 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-02T09:55:41+00:00"
|
||||
"time": "2022-04-22T08:18:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/yaml",
|
||||
"version": "v6.0.3",
|
||||
"version": "v6.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/yaml.git",
|
||||
"reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5"
|
||||
"reference": "84ce4f9d2d68f306f971a39d949d8f4b5550dba2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/e77f3ea0b21141d771d4a5655faa54f692b34af5",
|
||||
"reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5",
|
||||
"url": "https://api.github.com/repos/symfony/yaml/zipball/84ce4f9d2d68f306f971a39d949d8f4b5550dba2",
|
||||
"reference": "84ce4f9d2d68f306f971a39d949d8f4b5550dba2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.0.2",
|
||||
"php": ">=8.1",
|
||||
"symfony/polyfill-ctype": "^1.8"
|
||||
},
|
||||
"conflict": {
|
||||
|
@ -2064,7 +2137,7 @@
|
|||
"description": "Loads and dumps YAML files",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/yaml/tree/v6.0.3"
|
||||
"source": "https://github.com/symfony/yaml/tree/v6.1.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
|
@ -2080,7 +2153,7 @@
|
|||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2022-01-26T17:23:29+00:00"
|
||||
"time": "2022-04-15T14:25:02+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
|
@ -2090,5 +2163,5 @@
|
|||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"plugin-api-version": "2.2.0"
|
||||
"plugin-api-version": "2.3.0"
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue