mirror of
https://code.mensbeam.com/MensBeam/Arsse.git
synced 2024-12-22 21:22:40 +00:00
Add class constant visibility
This commit is contained in:
parent
bc53a2d24a
commit
e60f7ea03f
33 changed files with 150 additions and 140 deletions
14
.php_cs.dist
14
.php_cs.dist
|
@ -25,11 +25,8 @@ $rules = [
|
|||
],
|
||||
'cast_spaces' => ['space' => "single"],
|
||||
'concat_space' => ['spacing' => "none"],
|
||||
'declare_equal_normalize' => ['space' => "none"],
|
||||
'function_typehint_space' => true,
|
||||
'list_syntax' => ['syntax' => "short"],
|
||||
'lowercase_cast' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'magic_constant_casing' => true,
|
||||
'magic_method_casing' => true,
|
||||
'modernize_types_casting' => true,
|
||||
|
@ -43,8 +40,6 @@ $rules = [
|
|||
'no_empty_phpdoc' => true,
|
||||
'no_empty_statement' => true,
|
||||
'no_extra_blank_lines' => true, // this could probably use more configuration
|
||||
'no_leading_import_slash' => true,
|
||||
'no_leading_namespace_whitespace' => true,
|
||||
'no_mixed_echo_print' => ['use' => "echo"],
|
||||
'no_short_bool_cast' => true,
|
||||
'no_trailing_comma_in_singleline_array' => true,
|
||||
|
@ -58,13 +53,20 @@ $rules = [
|
|||
'pow_to_exponentiation' => true,
|
||||
'return_type_declaration' => ['space_before' => "none"],
|
||||
'set_type_to_cast' => true,
|
||||
'short_scalar_cast' => true,
|
||||
'standardize_not_equals' => true,
|
||||
'trailing_comma_in_multiline_array' => 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
|
||||
'declare_equal_normalize' => ['space' => "none"],
|
||||
'lowercase_cast' => true,
|
||||
'lowercase_static_reference' => true,
|
||||
'no_leading_import_slash' => true,
|
||||
'no_leading_namespace_whitespace' => 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"],
|
||||
|
|
|
@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse;
|
||||
|
||||
abstract class AbstractException extends \Exception {
|
||||
const CODES = [
|
||||
public const CODES = [
|
||||
"Exception.uncoded" => -1,
|
||||
"Exception.unknown" => 10000,
|
||||
"Exception.constantUnknown" => 10001,
|
||||
|
|
|
@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse;
|
||||
|
||||
class Arsse {
|
||||
const VERSION = "0.8.3";
|
||||
public const VERSION = "0.8.3";
|
||||
|
||||
/** @var Lang */
|
||||
public static $lang;
|
||||
|
|
|
@ -10,7 +10,7 @@ use JKingWeb\Arsse\REST\Fever\User as Fever;
|
|||
use JKingWeb\Arsse\ImportExport\OPML;
|
||||
|
||||
class CLI {
|
||||
const USAGE = <<<USAGE_TEXT
|
||||
public const USAGE = <<<USAGE_TEXT
|
||||
Usage:
|
||||
arsse.php daemon
|
||||
arsse.php feed refresh-all
|
||||
|
|
|
@ -114,14 +114,14 @@ class Conf {
|
|||
/** @var \DateInterval|null (OBSOLETE) Number of seconds for SQLite to wait before returning a timeout error when trying to acquire a write lock on the database (zero does not wait) */
|
||||
public $dbSQLite3Timeout = null; // previously 60.0
|
||||
|
||||
const TYPE_NAMES = [
|
||||
protected const TYPE_NAMES = [
|
||||
Value::T_BOOL => "boolean",
|
||||
Value::T_STRING => "string",
|
||||
Value::T_FLOAT => "float",
|
||||
VALUE::T_INT => "integer",
|
||||
Value::T_INTERVAL => "interval",
|
||||
];
|
||||
const EXPECTED_TYPES = [
|
||||
protected const EXPECTED_TYPES = [
|
||||
'dbTimeoutExec' => "double",
|
||||
'dbTimeoutLock' => "double",
|
||||
'dbTimeoutConnect' => "double",
|
||||
|
|
|
@ -39,23 +39,23 @@ use JKingWeb\Arsse\Misc\URL;
|
|||
*/
|
||||
class Database {
|
||||
/** The version number of the latest schema the interface is aware of */
|
||||
const SCHEMA_VERSION = 6;
|
||||
/** The size of a set of values beyond which the set will be embedded into the query text */
|
||||
const LIMIT_SET_SIZE = 25;
|
||||
/** The length of a string in an embedded set beyond which a parameter placeholder will be used for the string */
|
||||
const LIMIT_SET_STRING_LENGTH = 200;
|
||||
public const SCHEMA_VERSION = 6;
|
||||
/** Makes tag/label association change operations remove members */
|
||||
const ASSOC_REMOVE = 0;
|
||||
public const ASSOC_REMOVE = 0;
|
||||
/** Makes tag/label association change operations add members */
|
||||
const ASSOC_ADD = 1;
|
||||
public const ASSOC_ADD = 1;
|
||||
/** Makes tag/label association change operations replace members */
|
||||
const ASSOC_REPLACE = 2;
|
||||
public const ASSOC_REPLACE = 2;
|
||||
/** A map of database driver short-names and their associated class names */
|
||||
const DRIVER_NAMES = [
|
||||
public const DRIVER_NAMES = [
|
||||
'sqlite3' => \JKingWeb\Arsse\Db\SQLite3\Driver::class,
|
||||
'postgresql' => \JKingWeb\Arsse\Db\PostgreSQL\Driver::class,
|
||||
'mysql' => \JKingWeb\Arsse\Db\MySQL\Driver::class,
|
||||
];
|
||||
/** The size of a set of values beyond which the set will be embedded into the query text */
|
||||
protected const LIMIT_SET_SIZE = 25;
|
||||
/** The length of a string in an embedded set beyond which a parameter placeholder will be used for the string */
|
||||
protected const LIMIT_SET_STRING_LENGTH = 200;
|
||||
|
||||
/** @var Db\Driver */
|
||||
public $db;
|
||||
|
|
|
@ -12,7 +12,7 @@ use JKingWeb\Arsse\Misc\ValueInfo;
|
|||
abstract class AbstractStatement implements Statement {
|
||||
use SQLState;
|
||||
|
||||
const TYPE_NORM_MAP = [
|
||||
public const TYPE_NORM_MAP = [
|
||||
self::T_INTEGER => ValueInfo::M_NULL | ValueInfo::T_INT,
|
||||
self::T_STRING => ValueInfo::M_NULL | ValueInfo::T_STRING,
|
||||
self::T_BOOLEAN => ValueInfo::M_NULL | ValueInfo::T_BOOL,
|
||||
|
|
|
@ -7,11 +7,11 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db;
|
||||
|
||||
interface Driver {
|
||||
const TR_PEND = 0;
|
||||
const TR_COMMIT = 1;
|
||||
const TR_ROLLBACK = 2;
|
||||
const TR_PEND_COMMIT = -1;
|
||||
const TR_PEND_ROLLBACK = -2;
|
||||
public const TR_PEND = 0;
|
||||
public const TR_COMMIT = 1;
|
||||
public const TR_ROLLBACK = 2;
|
||||
public const TR_PEND_COMMIT = -1;
|
||||
public const TR_PEND_ROLLBACK = -2;
|
||||
|
||||
/** Creates and returns an instance of the class; this is so that either a native or PDO driver may be returned depending on what is available on the server */
|
||||
public static function create(): Driver;
|
||||
|
|
|
@ -12,8 +12,8 @@ use JKingWeb\Arsse\Db\Exception;
|
|||
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||
use ExceptionBuilder;
|
||||
|
||||
const SQL_MODE = "ANSI_QUOTES,HIGH_NOT_PRECEDENCE,NO_BACKSLASH_ESCAPES,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,STRICT_ALL_TABLES";
|
||||
const TRANSACTIONAL_LOCKS = false;
|
||||
protected const SQL_MODE = "ANSI_QUOTES,HIGH_NOT_PRECEDENCE,NO_BACKSLASH_ESCAPES,NO_ENGINE_SUBSTITUTION,PIPES_AS_CONCAT,STRICT_ALL_TABLES";
|
||||
protected const TRANSACTIONAL_LOCKS = false;
|
||||
|
||||
/** @var \mysqli */
|
||||
protected $db;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\Db\MySQL;
|
|||
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
||||
use ExceptionBuilder;
|
||||
|
||||
const BINDINGS = [
|
||||
protected const BINDINGS = [
|
||||
self::T_INTEGER => "i",
|
||||
self::T_FLOAT => "d",
|
||||
self::T_DATETIME => "s",
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\Db;
|
|||
abstract class PDOStatement extends AbstractStatement {
|
||||
use PDOError;
|
||||
|
||||
const BINDINGS = [
|
||||
protected const BINDINGS = [
|
||||
self::T_INTEGER => \PDO::PARAM_INT,
|
||||
self::T_FLOAT => \PDO::PARAM_STR,
|
||||
self::T_DATETIME => \PDO::PARAM_STR,
|
||||
|
|
|
@ -12,7 +12,7 @@ use JKingWeb\Arsse\Db\Exception;
|
|||
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||
use Dispatch;
|
||||
|
||||
const TRANSACTIONAL_LOCKS = true;
|
||||
protected const TRANSACTIONAL_LOCKS = true;
|
||||
|
||||
protected $db;
|
||||
protected $transStart = 0;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse\Db\PostgreSQL;
|
|||
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
||||
use Dispatch;
|
||||
|
||||
const BINDINGS = [
|
||||
protected const BINDINGS = [
|
||||
self::T_INTEGER => "bigint",
|
||||
self::T_FLOAT => "decimal",
|
||||
self::T_DATETIME => "timestamp(0) without time zone",
|
||||
|
|
|
@ -12,12 +12,12 @@ use JKingWeb\Arsse\Db\Exception;
|
|||
class Driver extends \JKingWeb\Arsse\Db\AbstractDriver {
|
||||
use ExceptionBuilder;
|
||||
|
||||
const TRANSACTIONAL_LOCKS = true;
|
||||
protected const TRANSACTIONAL_LOCKS = true;
|
||||
|
||||
const SQLITE_BUSY = 5;
|
||||
const SQLITE_SCHEMA = 17;
|
||||
const SQLITE_CONSTRAINT = 19;
|
||||
const SQLITE_MISMATCH = 20;
|
||||
public const SQLITE_BUSY = 5;
|
||||
public const SQLITE_SCHEMA = 17;
|
||||
public const SQLITE_CONSTRAINT = 19;
|
||||
public const SQLITE_MISMATCH = 20;
|
||||
|
||||
protected $db;
|
||||
|
||||
|
|
|
@ -9,10 +9,10 @@ namespace JKingWeb\Arsse\Db\SQLite3;
|
|||
class Statement extends \JKingWeb\Arsse\Db\AbstractStatement {
|
||||
use ExceptionBuilder;
|
||||
|
||||
const SQLITE_BUSY = 5;
|
||||
const SQLITE_CONSTRAINT = 19;
|
||||
const SQLITE_MISMATCH = 20;
|
||||
const BINDINGS = [
|
||||
public const SQLITE_BUSY = 5;
|
||||
public const SQLITE_CONSTRAINT = 19;
|
||||
public const SQLITE_MISMATCH = 20;
|
||||
protected const BINDINGS = [
|
||||
self::T_INTEGER => \SQLITE3_INTEGER,
|
||||
self::T_FLOAT => \SQLITE3_FLOAT,
|
||||
self::T_DATETIME => \SQLITE3_TEXT,
|
||||
|
|
|
@ -7,7 +7,7 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\Db;
|
||||
|
||||
interface Statement {
|
||||
const TYPES = [
|
||||
public const TYPES = [
|
||||
'int' => self::T_INTEGER,
|
||||
'integer' => self::T_INTEGER,
|
||||
'float' => self::T_FLOAT,
|
||||
|
@ -43,13 +43,13 @@ interface Statement {
|
|||
'strict boolean' => self::T_NOT_NULL + self::T_BOOLEAN,
|
||||
'strict bit' => self::T_NOT_NULL + self::T_BOOLEAN,
|
||||
];
|
||||
const T_INTEGER = 1;
|
||||
const T_STRING = 2;
|
||||
const T_BOOLEAN = 3;
|
||||
const T_DATETIME = 4;
|
||||
const T_FLOAT = 5;
|
||||
const T_BINARY = 6;
|
||||
const T_NOT_NULL = 100;
|
||||
public const T_INTEGER = 1;
|
||||
public const T_STRING = 2;
|
||||
public const T_BOOLEAN = 3;
|
||||
public const T_DATETIME = 4;
|
||||
public const T_FLOAT = 5;
|
||||
public const T_BINARY = 6;
|
||||
public const T_NOT_NULL = 100;
|
||||
|
||||
public function run(...$values): Result;
|
||||
public function runArray(array $values = []): Result;
|
||||
|
|
|
@ -12,8 +12,8 @@ use GuzzleHttp\Exception\TooManyRedirectsException;
|
|||
use PicoFeed\PicoFeedException;
|
||||
|
||||
class Exception extends \JKingWeb\Arsse\AbstractException {
|
||||
const CURL_ERROR_MAP = [1 => "invalidUrl",3 => "invalidUrl",5 => "transmissionError","connectionFailed","connectionFailed","transmissionError","forbidden","unauthorized","transmissionError","transmissionError","transmissionError","transmissionError","connectionFailed","connectionFailed","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError","invalidUrl","transmissionError","transmissionError","transmissionError","transmissionError",28 => "timeout","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError",35 => "invalidCertificate","transmissionError","transmissionError","transmissionError","transmissionError",45 => "transmissionError","unauthorized","maxRedirect",52 => "transmissionError","invalidCertificate","invalidCertificate","transmissionError","transmissionError",58 => "invalidCertificate","invalidCertificate","invalidCertificate","transmissionError","invalidUrl","transmissionError","invalidCertificate","transmissionError","invalidCertificate","forbidden","invalidUrl","forbidden","transmissionError",73 => "transmissionError","transmissionError",77 => "invalidCertificate","invalidUrl",90 => "invalidCertificate","invalidCertificate","transmissionError",94 => "unauthorized","transmissionError","connectionFailed"];
|
||||
const HTTP_ERROR_MAP = [401 => "unauthorized",403 => "forbidden",404 => "invalidUrl",408 => "timeout",410 => "invalidUrl",414 => "invalidUrl",451 => "invalidUrl"];
|
||||
protected const CURL_ERROR_MAP = [1 => "invalidUrl",3 => "invalidUrl",5 => "transmissionError","connectionFailed","connectionFailed","transmissionError","forbidden","unauthorized","transmissionError","transmissionError","transmissionError","transmissionError","connectionFailed","connectionFailed","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError","invalidUrl","transmissionError","transmissionError","transmissionError","transmissionError",28 => "timeout","transmissionError","transmissionError","transmissionError","transmissionError","transmissionError",35 => "invalidCertificate","transmissionError","transmissionError","transmissionError","transmissionError",45 => "transmissionError","unauthorized","maxRedirect",52 => "transmissionError","invalidCertificate","invalidCertificate","transmissionError","transmissionError",58 => "invalidCertificate","invalidCertificate","invalidCertificate","transmissionError","invalidUrl","transmissionError","invalidCertificate","transmissionError","invalidCertificate","forbidden","invalidUrl","forbidden","transmissionError",73 => "transmissionError","transmissionError",77 => "invalidCertificate","invalidUrl",90 => "invalidCertificate","invalidCertificate","transmissionError",94 => "unauthorized","transmissionError","connectionFailed"];
|
||||
protected const HTTP_ERROR_MAP = [401 => "unauthorized",403 => "forbidden",404 => "invalidUrl",408 => "timeout",410 => "invalidUrl",414 => "invalidUrl",451 => "invalidUrl"];
|
||||
|
||||
public function __construct($url, \Throwable $e) {
|
||||
if ($e instanceof BadResponseException) {
|
||||
|
|
|
@ -7,8 +7,8 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse;
|
||||
|
||||
class Lang {
|
||||
const DEFAULT = "en"; // fallback locale
|
||||
const REQUIRED = [ // collection of absolutely required strings to handle pathological errors
|
||||
public const DEFAULT = "en"; // fallback locale
|
||||
protected const REQUIRED = [ // collection of absolutely required strings to handle pathological errors
|
||||
'Exception.JKingWeb/Arsse/Exception.uncoded' => 'The specified exception symbol {0} has no code specified in AbstractException.php',
|
||||
'Exception.JKingWeb/Arsse/Exception.unknown' => 'An unknown error has occurred',
|
||||
'Exception.JKingWeb/Arsse/Lang/Exception.defaultFileMissing' => 'Default language file "{0}" missing',
|
||||
|
|
|
@ -10,33 +10,33 @@ use JKingWeb\Arsse\ExceptionType;
|
|||
|
||||
class ValueInfo {
|
||||
// universal
|
||||
const VALID = 1 << 0;
|
||||
const NULL = 1 << 1;
|
||||
public const VALID = 1 << 0;
|
||||
public const NULL = 1 << 1;
|
||||
// integers
|
||||
const ZERO = 1 << 2;
|
||||
const NEG = 1 << 3;
|
||||
const FLOAT = 1 << 4;
|
||||
public const ZERO = 1 << 2;
|
||||
public const NEG = 1 << 3;
|
||||
public const FLOAT = 1 << 4;
|
||||
// strings
|
||||
const EMPTY = 1 << 2;
|
||||
const WHITE = 1 << 3;
|
||||
public const EMPTY = 1 << 2;
|
||||
public const WHITE = 1 << 3;
|
||||
// normalization types
|
||||
const T_MIXED = 0; // pass through unchanged
|
||||
const T_NULL = 1; // convert to null
|
||||
const T_BOOL = 2; // convert to boolean
|
||||
const T_INT = 3; // convert to integer
|
||||
const T_FLOAT = 4; // convert to floating point
|
||||
const T_DATE = 5; // convert to DateTimeInterface instance
|
||||
const T_STRING = 6; // convert to string
|
||||
const T_ARRAY = 7; // convert to array
|
||||
const T_INTERVAL = 8; // convert to time interval
|
||||
public const T_MIXED = 0; // pass through unchanged
|
||||
public const T_NULL = 1; // convert to null
|
||||
public const T_BOOL = 2; // convert to boolean
|
||||
public const T_INT = 3; // convert to integer
|
||||
public const T_FLOAT = 4; // convert to floating point
|
||||
public const T_DATE = 5; // convert to DateTimeInterface instance
|
||||
public const T_STRING = 6; // convert to string
|
||||
public const T_ARRAY = 7; // convert to array
|
||||
public const T_INTERVAL = 8; // convert to time interval
|
||||
// normalization modes
|
||||
const M_LOOSE = 0;
|
||||
const M_NULL = 1 << 28; // pass nulls through regardless of target type
|
||||
const M_DROP = 1 << 29; // drop the value (return null) if the type doesn't match
|
||||
const M_STRICT = 1 << 30; // throw an exception if the type doesn't match
|
||||
const M_ARRAY = 1 << 31; // the value should be a flat array of values of the specified type; indexed and associative are both acceptable
|
||||
public const M_LOOSE = 0;
|
||||
public const M_NULL = 1 << 28; // pass nulls through regardless of target type
|
||||
public const M_DROP = 1 << 29; // drop the value (return null) if the type doesn't match
|
||||
public const M_STRICT = 1 << 30; // throw an exception if the type doesn't match
|
||||
public const M_ARRAY = 1 << 31; // the value should be a flat array of values of the specified type; indexed and associative are both acceptable
|
||||
// symbolic date and time formats
|
||||
const DATE_FORMATS = [ // in out
|
||||
protected const DATE_FORMATS = [ // in out
|
||||
'iso8601' => ["!Y-m-d\TH:i:s", "Y-m-d\TH:i:s\Z" ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
|
||||
'iso8601m' => ["!Y-m-d\TH:i:s.u", "Y-m-d\TH:i:s.u\Z" ], // NOTE: ISO 8601 dates require special input processing because of varying formats for timezone offsets
|
||||
'microtime' => ["U.u", "0.u00 U" ], // NOTE: the actual input format at the user level matches the output format; pre-processing is required for PHP not to fail
|
||||
|
|
|
@ -14,7 +14,7 @@ use Laminas\Diactoros\ServerRequestFactory;
|
|||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class REST {
|
||||
const API_LIST = [
|
||||
public const API_LIST = [
|
||||
'ncn' => [ // Nextcloud News version enumerator
|
||||
'match' => '/index.php/apps/news/api',
|
||||
'strip' => '/index.php/apps/news/api',
|
||||
|
@ -55,7 +55,7 @@ class REST {
|
|||
// Proprietary (centralized) entities:
|
||||
// Feedly https://developer.feedly.com/
|
||||
];
|
||||
const DEFAULT_PORTS = [
|
||||
protected const DEFAULT_PORTS = [
|
||||
'http' => 80,
|
||||
'https' => 443,
|
||||
];
|
||||
|
|
|
@ -19,15 +19,15 @@ use Laminas\Diactoros\Response\XmlResponse;
|
|||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const LEVEL = 3;
|
||||
const GENERIC_ICON_TYPE = "image/png;base64";
|
||||
const GENERIC_ICON_DATA = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2NgYGBgAAAABQABijPjAAAAAABJRU5ErkJggg==";
|
||||
const ACCEPTED_TYPE = "application/x-www-form-urlencoded";
|
||||
public const LEVEL = 3;
|
||||
protected const GENERIC_ICON_TYPE = "image/png;base64";
|
||||
protected const GENERIC_ICON_DATA = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAZdEVYdFNvZnR3YXJlAHBhaW50Lm5ldCA0LjAuMjHxIGmVAAAADUlEQVQYV2NgYGBgAAAABQABijPjAAAAAABJRU5ErkJggg==";
|
||||
protected const ACCEPTED_TYPE = "application/x-www-form-urlencoded";
|
||||
|
||||
// GET parameters for which we only check presence: these will be converted to booleans
|
||||
const PARAM_BOOL = ["groups", "feeds", "items", "favicons", "links", "unread_item_ids", "saved_item_ids"];
|
||||
protected const PARAM_BOOL = ["groups", "feeds", "items", "favicons", "links", "unread_item_ids", "saved_item_ids"];
|
||||
// GET parameters which contain meaningful values
|
||||
const PARAM_GET = [
|
||||
protected const PARAM_GET = [
|
||||
'api' => V::T_STRING, // this parameter requires special handling
|
||||
'page' => V::T_INT, // parameter for hot links
|
||||
'range' => V::T_INT, // parameter for hot links
|
||||
|
@ -45,7 +45,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'unread_recently_read' => V::T_BOOL,
|
||||
];
|
||||
// POST parameters, all of which contain meaningful values
|
||||
const PARAM_POST = [
|
||||
protected const PARAM_POST = [
|
||||
'api_key' => V::T_STRING,
|
||||
'mark' => V::T_STRING,
|
||||
'as' => V::T_STRING,
|
||||
|
|
|
@ -23,9 +23,9 @@ use Laminas\Diactoros\Response\JsonResponse as Response;
|
|||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class V1_2 extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const REALM = "Nextcloud News API v1-2";
|
||||
const VERSION = "11.0.5";
|
||||
const ACCEPTED_TYPE = "application/json";
|
||||
public const VERSION = "11.0.5";
|
||||
protected const REALM = "Nextcloud News API v1-2";
|
||||
protected const ACCEPTED_TYPE = "application/json";
|
||||
|
||||
protected $dateFormat = "unix";
|
||||
|
||||
|
|
|
@ -24,27 +24,27 @@ use Laminas\Diactoros\Response\JsonResponse as Response;
|
|||
use Laminas\Diactoros\Response\EmptyResponse;
|
||||
|
||||
class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
||||
const LEVEL = 14; // emulated API level
|
||||
const VERSION = "17.4"; // emulated TT-RSS version
|
||||
const LABEL_OFFSET = 1024; // offset below zero at which labels begin, counting down
|
||||
const LIMIT_ARTICLES = 200; // maximum number of articles returned by getHeadlines
|
||||
const LIMIT_EXCERPT = 100; // maximum length of excerpts in getHeadlines, counted in grapheme units
|
||||
public const LEVEL = 14; // emulated API level
|
||||
public const VERSION = "17.4"; // emulated TT-RSS version
|
||||
protected const LABEL_OFFSET = 1024; // offset below zero at which labels begin, counting down
|
||||
protected const LIMIT_ARTICLES = 200; // maximum number of articles returned by getHeadlines
|
||||
protected const LIMIT_EXCERPT = 100; // maximum length of excerpts in getHeadlines, counted in grapheme units
|
||||
// special feeds
|
||||
const FEED_ARCHIVED = 0;
|
||||
const FEED_STARRED = -1;
|
||||
const FEED_PUBLISHED = -2;
|
||||
const FEED_FRESH = -3;
|
||||
const FEED_ALL = -4;
|
||||
const FEED_READ = -6;
|
||||
protected const FEED_ARCHIVED = 0;
|
||||
protected const FEED_STARRED = -1;
|
||||
protected const FEED_PUBLISHED = -2;
|
||||
protected const FEED_FRESH = -3;
|
||||
protected const FEED_ALL = -4;
|
||||
protected const FEED_READ = -6;
|
||||
// special categories
|
||||
const CAT_UNCATEGORIZED = 0;
|
||||
const CAT_SPECIAL = -1;
|
||||
const CAT_LABELS = -2;
|
||||
const CAT_NOT_SPECIAL = -3;
|
||||
const CAT_ALL = -4;
|
||||
protected const CAT_UNCATEGORIZED = 0;
|
||||
protected const CAT_SPECIAL = -1;
|
||||
protected const CAT_LABELS = -2;
|
||||
protected const CAT_NOT_SPECIAL = -3;
|
||||
protected const CAT_ALL = -4;
|
||||
// valid input
|
||||
const ACCEPTED_TYPES = ["application/json", "text/json"];
|
||||
const VALID_INPUT = [
|
||||
protected const ACCEPTED_TYPES = ["application/json", "text/json"];
|
||||
protected const VALID_INPUT = [
|
||||
'op' => ValueInfo::T_STRING, // the function ("operation") to perform
|
||||
'sid' => ValueInfo::T_STRING, // session ID
|
||||
'seq' => ValueInfo::T_INT, // request number from client
|
||||
|
@ -82,7 +82,7 @@ class API extends \JKingWeb\Arsse\REST\AbstractHandler {
|
|||
'data' => ValueInfo::T_STRING, // note text in `updateArticle` if setting a note
|
||||
];
|
||||
// generic error construct
|
||||
const FATAL_ERR = [
|
||||
protected const FATAL_ERR = [
|
||||
'seq' => null,
|
||||
'status' => 1,
|
||||
'content' => ['error' => "MALFORMED_INPUT"],
|
||||
|
|
|
@ -10,22 +10,22 @@ use JKingWeb\Arsse\Context\Context;
|
|||
use JKingWeb\Arsse\Misc\Date;
|
||||
|
||||
class Search {
|
||||
const STATE_BEFORE_TOKEN = 0;
|
||||
const STATE_BEFORE_TOKEN_QUOTED = 1;
|
||||
const STATE_IN_DATE = 2;
|
||||
const STATE_IN_DATE_QUOTED = 3;
|
||||
const STATE_IN_TOKEN_OR_TAG = 4;
|
||||
const STATE_IN_TOKEN_OR_TAG_QUOTED = 5;
|
||||
const STATE_IN_TOKEN = 6;
|
||||
const STATE_IN_TOKEN_QUOTED = 7;
|
||||
protected const STATE_BEFORE_TOKEN = 0;
|
||||
protected const STATE_BEFORE_TOKEN_QUOTED = 1;
|
||||
protected const STATE_IN_DATE = 2;
|
||||
protected const STATE_IN_DATE_QUOTED = 3;
|
||||
protected const STATE_IN_TOKEN_OR_TAG = 4;
|
||||
protected const STATE_IN_TOKEN_OR_TAG_QUOTED = 5;
|
||||
protected const STATE_IN_TOKEN = 6;
|
||||
protected const STATE_IN_TOKEN_QUOTED = 7;
|
||||
|
||||
const FIELDS_BOOLEAN = [
|
||||
protected const FIELDS_BOOLEAN = [
|
||||
"unread" => "unread",
|
||||
"star" => "starred",
|
||||
"note" => "annotated",
|
||||
"pub" => "published", // TODO: not implemented
|
||||
];
|
||||
const FIELDS_TEXT = [
|
||||
protected const FIELDS_TEXT = [
|
||||
"title" => "titleTerms",
|
||||
"author" => "authorTerms",
|
||||
"note" => "annotationTerms",
|
||||
|
@ -36,7 +36,6 @@ class Search {
|
|||
// normalize the input
|
||||
$search = strtolower(trim(preg_replace("<\s+>", " ", $search)));
|
||||
// set initial state
|
||||
$tokens = [];
|
||||
$pos = -1;
|
||||
$stop = strlen($search);
|
||||
$state = self::STATE_BEFORE_TOKEN;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse;
|
|||
use JKingWeb\Arsse\Misc\Date;
|
||||
|
||||
class Service {
|
||||
const DRIVER_NAMES = [
|
||||
public const DRIVER_NAMES = [
|
||||
'serial' => \JKingWeb\Arsse\Service\Serial\Driver::class,
|
||||
'subprocess' => \JKingWeb\Arsse\Service\Subprocess\Driver::class,
|
||||
];
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace JKingWeb\Arsse;
|
|||
use PasswordGenerator\Generator as PassGen;
|
||||
|
||||
class User {
|
||||
const DRIVER_NAMES = [
|
||||
public const DRIVER_NAMES = [
|
||||
'internal' => \JKingWeb\Arsse\User\Internal\Driver::class,
|
||||
];
|
||||
|
||||
|
|
|
@ -7,9 +7,9 @@ declare(strict_types=1);
|
|||
namespace JKingWeb\Arsse\User;
|
||||
|
||||
interface Driver {
|
||||
const FUNC_NOT_IMPLEMENTED = 0;
|
||||
const FUNC_INTERNAL = 1;
|
||||
const FUNC_EXTERNAL = 2;
|
||||
public const FUNC_NOT_IMPLEMENTED = 0;
|
||||
public const FUNC_INTERNAL = 1;
|
||||
public const FUNC_EXTERNAL = 2;
|
||||
|
||||
// returns an instance of a class implementing this interface.
|
||||
public function __construct();
|
||||
|
|
|
@ -421,6 +421,7 @@ trait SeriesArticle {
|
|||
}
|
||||
|
||||
public function provideContextMatches(): iterable {
|
||||
$setSize = (new \ReflectionClassConstant(Database::class, "LIMIT_SET_SIZE"))->getValue();
|
||||
return [
|
||||
'Blank context' => [new Context, [1,2,3,4,5,6,7,8,19,20]],
|
||||
'Folder tree' => [(new Context)->folder(1), [5,6,7,8]],
|
||||
|
@ -473,7 +474,7 @@ trait SeriesArticle {
|
|||
'Multiple unstarred articles' => [(new Context)->articles([1,2,3])->starred(false), [2,3]],
|
||||
'Multiple articles' => [(new Context)->articles([1,20,50]), [1,20]],
|
||||
'Multiple editions' => [(new Context)->editions([1,1001,50]), [1,20]],
|
||||
'150 articles' => [(new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3)), [1,2,3,4,5,6,7,8,19,20]],
|
||||
'150 articles' => [(new Context)->articles(range(1, $setSize * 3)), [1,2,3,4,5,6,7,8,19,20]],
|
||||
'Search title or content 1' => [(new Context)->searchTerms(["Article"]), [1,2,3]],
|
||||
'Search title or content 2' => [(new Context)->searchTerms(["one", "first"]), [1]],
|
||||
'Search title or content 3' => [(new Context)->searchTerms(["one first"]), []],
|
||||
|
@ -816,7 +817,8 @@ trait SeriesArticle {
|
|||
}
|
||||
|
||||
public function testMarkTooManyMultipleArticles(): void {
|
||||
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read' => false,'starred' => true], (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
|
||||
$setSize = (new \ReflectionClassConstant(Database::class, "LIMIT_SET_SIZE"))->getValue();
|
||||
$this->assertSame(7, Arsse::$db->articleMark($this->user, ['read' => false,'starred' => true], (new Context)->articles(range(1, $setSize * 3))));
|
||||
}
|
||||
|
||||
public function testMarkAMissingArticle(): void {
|
||||
|
@ -971,10 +973,11 @@ trait SeriesArticle {
|
|||
}
|
||||
|
||||
public function testCountArticles(): void {
|
||||
$setSize = (new \ReflectionClassConstant(Database::class, "LIMIT_SET_SIZE"))->getValue();
|
||||
$this->assertSame(2, Arsse::$db->articleCount("john.doe@example.com", (new Context)->starred(true)));
|
||||
$this->assertSame(4, Arsse::$db->articleCount("john.doe@example.com", (new Context)->folder(1)));
|
||||
$this->assertSame(0, Arsse::$db->articleCount("jane.doe@example.com", (new Context)->starred(true)));
|
||||
$this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, Database::LIMIT_SET_SIZE * 3))));
|
||||
$this->assertSame(10, Arsse::$db->articleCount("john.doe@example.com", (new Context)->articles(range(1, $setSize * 3))));
|
||||
}
|
||||
|
||||
public function testCountArticlesWithoutAuthority(): void {
|
||||
|
|
|
@ -35,10 +35,10 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function provideInClauses(): iterable {
|
||||
$l = Database::LIMIT_SET_SIZE + 1;
|
||||
$l = (new \ReflectionClassConstant(Database::class, "LIMIT_SET_SIZE"))->getValue() + 1;
|
||||
$strings = array_fill(0, $l, "");
|
||||
$ints = range(1, $l);
|
||||
$longString = str_repeat("0", Database::LIMIT_SET_STRING_LENGTH + 1);
|
||||
$longString = str_repeat("0", (new \ReflectionClassConstant(Database::class, "LIMIT_SET_STRING_LENGTH"))->getValue() + 1);
|
||||
$params = implode(",", array_fill(0, $l, "?"));
|
||||
$intList = implode(",", $ints);
|
||||
$stringList = implode(",", array_fill(0, $l, "''"));
|
||||
|
@ -70,9 +70,10 @@ class TestDatabase extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function provideSearchClauses(): iterable {
|
||||
$terms = array_fill(0, Database::LIMIT_SET_SIZE + 1, "a");
|
||||
$clause = array_fill(0, Database::LIMIT_SET_SIZE + 1, "test like '%a%' escape '^'");
|
||||
$longString = str_repeat("0", Database::LIMIT_SET_STRING_LENGTH + 1);
|
||||
$setSize = (new \ReflectionClassConstant(Database::class, "LIMIT_SET_SIZE"))->getValue();
|
||||
$terms = array_fill(0, $setSize + 1, "a");
|
||||
$clause = array_fill(0, $setSize + 1, "test like '%a%' escape '^'");
|
||||
$longString = str_repeat("0", (new \ReflectionClassConstant(Database::class, "LIMIT_SET_STRING_LENGTH"))->getValue() + 1);
|
||||
return [
|
||||
["test like ? escape '^'", ["%a%"], ["a"], ["test"], true],
|
||||
["(col1 like ? escape '^' or col2 like ? escape '^')", ["%a%", "%a%"], ["a"], ["col1", "col2"], true],
|
||||
|
|
|
@ -37,8 +37,9 @@ class TestBasic extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
* @depends testSetLanguage
|
||||
*/
|
||||
public function testLoadInternalStrings(): void {
|
||||
$exp = (new \ReflectionClassConstant(TestClass::class, "REQUIRED"))->getValue();
|
||||
$this->assertEquals("", $this->l->set("", true));
|
||||
$this->assertCount(sizeof(TestClass::REQUIRED), $this->l->dump());
|
||||
$this->assertCount(sizeof($exp), $this->l->dump());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -411,10 +411,11 @@ class TestValueInfo extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
$this->assertEquals($exp, I::normalize($value, $type | I::M_ARRAY, "iso8601"), "Failed test #$index");
|
||||
}
|
||||
// Date-to-string format tests
|
||||
$dateFormats = (new \ReflectionClassConstant(I::class, "DATE_FORMATS"))->getValue();
|
||||
$test = new \DateTimeImmutable("now", new \DateTimezone("UTC"));
|
||||
$exp = $test->format(I::DATE_FORMATS['iso8601'][1]);
|
||||
$exp = $test->format($dateFormats['iso8601'][1]);
|
||||
$this->assertSame($exp, I::normalize($test, I::T_STRING, null), "Failed test for null output date format");
|
||||
foreach (I::DATE_FORMATS as $name => $formats) {
|
||||
foreach ($dateFormats as $name => $formats) {
|
||||
$exp = $test->format($formats[1]);
|
||||
$this->assertSame($exp, I::normalize($test, I::T_STRING, null, $name), "Failed test for output date format '$name'");
|
||||
}
|
||||
|
|
|
@ -488,8 +488,10 @@ class TestAPI extends \JKingWeb\Arsse\Test\AbstractTest {
|
|||
}
|
||||
|
||||
public function testListFeedIcons(): void {
|
||||
$iconType = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_TYPE"))->getValue();
|
||||
$iconData = (new \ReflectionClassConstant(API::class, "GENERIC_ICON_DATA"))->getValue();
|
||||
$act = $this->h->dispatch($this->req("api&favicons"));
|
||||
$exp = new JsonResponse(['favicons' => [['id' => 0, 'data' => API::GENERIC_ICON_TYPE.",".API::GENERIC_ICON_DATA]]]);
|
||||
$exp = new JsonResponse(['favicons' => [['id' => 0, 'data' => $iconType.",".$iconData]]]);
|
||||
$this->assertMessage($exp, $act);
|
||||
}
|
||||
|
||||
|
|
|
@ -997,6 +997,7 @@ LONG_STRING;
|
|||
['id' => 3, 'name' => "Hardware"],
|
||||
['id' => 1, 'name' => "Politics"],
|
||||
];
|
||||
$labelOffset = (new \ReflectionClassConstant(API::class, "LABEL_OFFSET"))->getValue();
|
||||
// set of various mocks for testing
|
||||
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[0])->thenReturn(2)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
|
||||
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, $db[1])->thenReturn(3)->thenThrow(new ExceptionInput("constraintViolation")); // error on the second call
|
||||
|
@ -1007,14 +1008,14 @@ LONG_STRING;
|
|||
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => ""])->thenThrow(new ExceptionInput("missing"));
|
||||
\Phake::when(Arsse::$db)->labelAdd(Arsse::$user->id, ['name' => " "])->thenThrow(new ExceptionInput("whitespace"));
|
||||
// correctly add two labels
|
||||
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 2);
|
||||
$exp = $this->respGood((-1 * $labelOffset) - 2);
|
||||
$this->assertMessage($exp, $this->req($in[0]));
|
||||
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 3);
|
||||
$exp = $this->respGood((-1 * $labelOffset) - 3);
|
||||
$this->assertMessage($exp, $this->req($in[1]));
|
||||
// attempt to add the two labels again
|
||||
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 2);
|
||||
$exp = $this->respGood((-1 * $labelOffset) - 2);
|
||||
$this->assertMessage($exp, $this->req($in[0]));
|
||||
$exp = $this->respGood((-1 * API::LABEL_OFFSET) - 3);
|
||||
$exp = $this->respGood((-1 * $labelOffset) - 3);
|
||||
$this->assertMessage($exp, $this->req($in[1]));
|
||||
\Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Software", true);
|
||||
\Phake::verify(Arsse::$db)->labelPropertiesGet(Arsse::$user->id, "Hardware", true);
|
||||
|
|
Loading…
Reference in a new issue