mirror of
https://git.tt-rss.org/fox/tt-rss.git
synced 2025-08-06 06:07:29 +02:00
Merge branch 'feature/php-misc' into 'master'
More native typing, use some new PHP stuff See merge request tt-rss/tt-rss!88
This commit is contained in:
commit
e990a3c00f
@ -14,8 +14,7 @@ class API extends Handler {
|
|||||||
const E_OPERATION_FAILED = "E_OPERATION_FAILED";
|
const E_OPERATION_FAILED = "E_OPERATION_FAILED";
|
||||||
const E_NOT_FOUND = "E_NOT_FOUND";
|
const E_NOT_FOUND = "E_NOT_FOUND";
|
||||||
|
|
||||||
/** @var int|null */
|
private ?int $seq = null;
|
||||||
private $seq;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<int|string, mixed> $reply
|
* @param array<int|string, mixed> $reply
|
||||||
|
@ -252,17 +252,15 @@ class Config {
|
|||||||
Config::HTTP_429_THROTTLE_INTERVAL => [ 3600, Config::T_INT ]
|
Config::HTTP_429_THROTTLE_INTERVAL => [ 3600, Config::T_INT ]
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var Config|null */
|
private static ?Config $instance = null;
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
/** @var array<string, array<bool|int|string>> */
|
/** @var array<string, array<bool|int|string>> */
|
||||||
private $params = [];
|
private array $params = [];
|
||||||
|
|
||||||
/** @var array<string, mixed> */
|
/** @var array<string, mixed> */
|
||||||
private $version = [];
|
private array $version = [];
|
||||||
|
|
||||||
/** @var Db_Migrations|null $migrations */
|
private Db_Migrations $migrations;
|
||||||
private $migrations;
|
|
||||||
|
|
||||||
public static function get_instance() : Config {
|
public static function get_instance() : Config {
|
||||||
if (self::$instance == null)
|
if (self::$instance == null)
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
class Db
|
class Db {
|
||||||
{
|
private static ?Db $instance = null;
|
||||||
/** @var Db $instance */
|
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
/** @var PDO|null $pdo */
|
private ?PDO $pdo = null;
|
||||||
private $pdo;
|
|
||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
ORM::configure(self::get_dsn());
|
ORM::configure(self::get_dsn());
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
class DiskCache implements Cache_Adapter {
|
class DiskCache implements Cache_Adapter {
|
||||||
/** @var Cache_Adapter $adapter */
|
private Cache_Adapter $adapter;
|
||||||
private $adapter;
|
|
||||||
|
|
||||||
/** @var array<string, DiskCache> $instances */
|
/** @var array<string, DiskCache> $instances */
|
||||||
private static $instances = [];
|
private static array $instances = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* https://stackoverflow.com/a/53662733
|
* https://stackoverflow.com/a/53662733
|
||||||
@ -301,8 +300,11 @@ class DiskCache implements Cache_Adapter {
|
|||||||
if ($this->exists($local_filename) && !$force)
|
if ($this->exists($local_filename) && !$force)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
$data = UrlHelper::fetch(array_merge(["url" => $url,
|
$data = UrlHelper::fetch([
|
||||||
"max_size" => Config::get(Config::MAX_CACHE_FILE_SIZE)], $options));
|
'url' => $url,
|
||||||
|
'max_size' => Config::get(Config::MAX_CACHE_FILE_SIZE),
|
||||||
|
...$options,
|
||||||
|
]);
|
||||||
|
|
||||||
if ($data)
|
if ($data)
|
||||||
return $this->put($local_filename, $data) > 0;
|
return $this->put($local_filename, $data) > 0;
|
||||||
|
@ -1,21 +1,9 @@
|
|||||||
<?php
|
<?php
|
||||||
class FeedEnclosure {
|
class FeedEnclosure {
|
||||||
/** @var string */
|
public string $link = '';
|
||||||
public $link;
|
public string $type = '';
|
||||||
|
public string $length = '';
|
||||||
/** @var string */
|
public string $title = '';
|
||||||
public $type;
|
public string $height = '';
|
||||||
|
public string $width = '';
|
||||||
/** @var string */
|
|
||||||
public $length;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
public $title;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
public $height;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
public $width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -185,10 +185,9 @@ class FeedItem_Atom extends FeedItem_Common {
|
|||||||
|
|
||||||
if ($link->getAttribute("rel") == "enclosure") {
|
if ($link->getAttribute("rel") == "enclosure") {
|
||||||
$enc = new FeedEnclosure();
|
$enc = new FeedEnclosure();
|
||||||
|
$enc->type = clean($link->getAttribute('type'));
|
||||||
$enc->type = clean($link->getAttribute("type"));
|
$enc->length = clean($link->getAttribute('length'));
|
||||||
$enc->length = clean($link->getAttribute("length"));
|
$enc->link = clean($link->getAttribute('href'));
|
||||||
$enc->link = clean($link->getAttribute("href"));
|
|
||||||
|
|
||||||
if (!empty($base)) {
|
if (!empty($base)) {
|
||||||
$enc->link = UrlHelper::rewrite_relative($base, $enc->link);
|
$enc->link = UrlHelper::rewrite_relative($base, $enc->link);
|
||||||
|
@ -1,18 +1,13 @@
|
|||||||
<?php
|
<?php
|
||||||
abstract class FeedItem_Common extends FeedItem {
|
abstract class FeedItem_Common extends FeedItem {
|
||||||
/** @var DOMElement */
|
protected readonly DOMElement $elem;
|
||||||
protected $elem;
|
protected readonly DOMDocument $doc;
|
||||||
|
protected readonly DOMXPath $xpath;
|
||||||
/** @var DOMDocument */
|
|
||||||
protected $doc;
|
|
||||||
|
|
||||||
/** @var DOMXPath */
|
|
||||||
protected $xpath;
|
|
||||||
|
|
||||||
function __construct(DOMElement $elem, DOMDocument $doc, DOMXPath $xpath) {
|
function __construct(DOMElement $elem, DOMDocument $doc, DOMXPath $xpath) {
|
||||||
$this->elem = $elem;
|
$this->elem = $elem;
|
||||||
$this->xpath = $xpath;
|
|
||||||
$this->doc = $doc;
|
$this->doc = $doc;
|
||||||
|
$this->xpath = $xpath;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$source = $elem->getElementsByTagName("source")->item(0);
|
$source = $elem->getElementsByTagName("source")->item(0);
|
||||||
@ -98,12 +93,11 @@ abstract class FeedItem_Common extends FeedItem {
|
|||||||
|
|
||||||
foreach ($enclosures as $enclosure) {
|
foreach ($enclosures as $enclosure) {
|
||||||
$enc = new FeedEnclosure();
|
$enc = new FeedEnclosure();
|
||||||
|
$enc->type = clean($enclosure->getAttribute('type'));
|
||||||
$enc->type = clean($enclosure->getAttribute("type"));
|
$enc->link = clean($enclosure->getAttribute('url'));
|
||||||
$enc->link = clean($enclosure->getAttribute("url"));
|
$enc->length = clean($enclosure->getAttribute('length'));
|
||||||
$enc->length = clean($enclosure->getAttribute("length"));
|
$enc->height = clean($enclosure->getAttribute('height'));
|
||||||
$enc->height = clean($enclosure->getAttribute("height"));
|
$enc->width = clean($enclosure->getAttribute('width'));
|
||||||
$enc->width = clean($enclosure->getAttribute("width"));
|
|
||||||
|
|
||||||
$medium = clean($enclosure->getAttribute("medium"));
|
$medium = clean($enclosure->getAttribute("medium"));
|
||||||
if (!$enc->type && $medium) {
|
if (!$enc->type && $medium) {
|
||||||
@ -119,17 +113,16 @@ abstract class FeedItem_Common extends FeedItem {
|
|||||||
$enclosures = $this->xpath->query("media:group", $this->elem);
|
$enclosures = $this->xpath->query("media:group", $this->elem);
|
||||||
|
|
||||||
foreach ($enclosures as $enclosure) {
|
foreach ($enclosures as $enclosure) {
|
||||||
$enc = new FeedEnclosure();
|
|
||||||
|
|
||||||
/** @var DOMElement|null */
|
/** @var DOMElement|null */
|
||||||
$content = $this->xpath->query("media:content", $enclosure)->item(0);
|
$content = $this->xpath->query("media:content", $enclosure)->item(0);
|
||||||
|
|
||||||
if ($content) {
|
if ($content) {
|
||||||
$enc->type = clean($content->getAttribute("type"));
|
$enc = new FeedEnclosure();
|
||||||
$enc->link = clean($content->getAttribute("url"));
|
$enc->type = clean($content->getAttribute('type'));
|
||||||
$enc->length = clean($content->getAttribute("length"));
|
$enc->link = clean($content->getAttribute('url'));
|
||||||
$enc->height = clean($content->getAttribute("height"));
|
$enc->length = clean($content->getAttribute('length'));
|
||||||
$enc->width = clean($content->getAttribute("width"));
|
$enc->height = clean($content->getAttribute('height'));
|
||||||
|
$enc->width = clean($content->getAttribute('width'));
|
||||||
|
|
||||||
$medium = clean($content->getAttribute("medium"));
|
$medium = clean($content->getAttribute("medium"));
|
||||||
if (!$enc->type && $medium) {
|
if (!$enc->type && $medium) {
|
||||||
@ -152,11 +145,10 @@ abstract class FeedItem_Common extends FeedItem {
|
|||||||
|
|
||||||
foreach ($enclosures as $enclosure) {
|
foreach ($enclosures as $enclosure) {
|
||||||
$enc = new FeedEnclosure();
|
$enc = new FeedEnclosure();
|
||||||
|
$enc->type = 'image/generic';
|
||||||
$enc->type = "image/generic";
|
$enc->link = clean($enclosure->getAttribute('url'));
|
||||||
$enc->link = clean($enclosure->getAttribute("url"));
|
$enc->height = clean($enclosure->getAttribute('height'));
|
||||||
$enc->height = clean($enclosure->getAttribute("height"));
|
$enc->width = clean($enclosure->getAttribute('width'));
|
||||||
$enc->width = clean($enclosure->getAttribute("width"));
|
|
||||||
|
|
||||||
array_push($encs, $enc);
|
array_push($encs, $enc);
|
||||||
}
|
}
|
||||||
|
@ -142,12 +142,11 @@ class FeedItem_RSS extends FeedItem_Common {
|
|||||||
|
|
||||||
foreach ($enclosures as $enclosure) {
|
foreach ($enclosures as $enclosure) {
|
||||||
$enc = new FeedEnclosure();
|
$enc = new FeedEnclosure();
|
||||||
|
$enc->type = clean($enclosure->getAttribute('type'));
|
||||||
$enc->type = clean($enclosure->getAttribute("type"));
|
$enc->link = clean($enclosure->getAttribute('url'));
|
||||||
$enc->link = clean($enclosure->getAttribute("url"));
|
$enc->length = clean($enclosure->getAttribute('length'));
|
||||||
$enc->length = clean($enclosure->getAttribute("length"));
|
$enc->height = clean($enclosure->getAttribute('height'));
|
||||||
$enc->height = clean($enclosure->getAttribute("height"));
|
$enc->width = clean($enclosure->getAttribute('width'));
|
||||||
$enc->width = clean($enclosure->getAttribute("width"));
|
|
||||||
|
|
||||||
array_push($encs, $enc);
|
array_push($encs, $enc);
|
||||||
}
|
}
|
||||||
|
@ -1,29 +1,23 @@
|
|||||||
<?php
|
<?php
|
||||||
class FeedParser {
|
class FeedParser {
|
||||||
|
private DOMDocument $doc;
|
||||||
|
|
||||||
/** @var DOMDocument */
|
private ?string $error = null;
|
||||||
private $doc;
|
|
||||||
|
|
||||||
/** @var string|null */
|
|
||||||
private $error = null;
|
|
||||||
|
|
||||||
/** @var array<string> */
|
/** @var array<string> */
|
||||||
private $libxml_errors = [];
|
private array $libxml_errors = [];
|
||||||
|
|
||||||
/** @var array<FeedItem> */
|
/** @var array<FeedItem> */
|
||||||
private $items = [];
|
private array $items = [];
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $link = null;
|
||||||
private $link;
|
|
||||||
|
|
||||||
/** @var string|null */
|
private ?string $title = null;
|
||||||
private $title;
|
|
||||||
|
|
||||||
/** @var FeedParser::FEED_*|null */
|
/** @var FeedParser::FEED_*|null */
|
||||||
private $type;
|
private ?int $type = null;
|
||||||
|
|
||||||
/** @var DOMXPath|null */
|
private ?DOMXPath $xpath = null;
|
||||||
private $xpath;
|
|
||||||
|
|
||||||
const FEED_UNKNOWN = -1;
|
const FEED_UNKNOWN = -1;
|
||||||
const FEED_RDF = 0;
|
const FEED_RDF = 0;
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
class Logger {
|
class Logger {
|
||||||
/** @var Logger|null */
|
private static ?Logger $instance = null;
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
/** @var Logger_Adapter|null */
|
private ?Logger_Adapter $adapter = null;
|
||||||
private $adapter;
|
|
||||||
|
|
||||||
const LOG_DEST_SQL = "sql";
|
const LOG_DEST_SQL = "sql";
|
||||||
const LOG_DEST_STDOUT = "stdout";
|
const LOG_DEST_STDOUT = "stdout";
|
||||||
|
@ -23,8 +23,8 @@ class PluginHost {
|
|||||||
/** @var array<string, array<string, mixed>> plugin name -> (potential profile array) -> key -> value */
|
/** @var array<string, array<string, mixed>> plugin name -> (potential profile array) -> key -> value */
|
||||||
private array $storage = [];
|
private array $storage = [];
|
||||||
|
|
||||||
/** @var array<int, array<int, array{'id': int, 'title': string, 'sender': Plugin, 'icon': string}>> */
|
/** @var array<int, array{'id': int, 'title': string, 'sender': Plugin, 'icon': string}> */
|
||||||
private array $feeds = [];
|
private array $special_feeds = [];
|
||||||
|
|
||||||
/** @var array<string, Plugin> API method name, Plugin sender */
|
/** @var array<string, Plugin> API method name, Plugin sender */
|
||||||
private array $api_methods = [];
|
private array $api_methods = [];
|
||||||
@ -759,45 +759,51 @@ class PluginHost {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin feed functions are *EXPERIMENTAL*!
|
/**
|
||||||
|
* Add a special (plugin-provided) feed
|
||||||
|
*
|
||||||
|
* @param int $cat_id only -1 (Feeds::CATEGORY_SPECIAL) is supported
|
||||||
|
* @return false|int false if the feed wasn't added (e.g. $cat_id wasn't Feeds::CATEGORY_SPECIAL),
|
||||||
|
* otherwise an integer "feed ID" that might change between executions
|
||||||
|
*/
|
||||||
|
function add_feed(int $cat_id, string $title, string $icon, Plugin $sender): false|int {
|
||||||
|
if ($cat_id !== Feeds::CATEGORY_SPECIAL)
|
||||||
|
return false;
|
||||||
|
|
||||||
// cat_id: only -1 (Feeds::CATEGORY_SPECIAL) is supported (Special)
|
$id = count($this->special_feeds);
|
||||||
function add_feed(int $cat_id, string $title, string $icon, Plugin $sender): int {
|
|
||||||
|
|
||||||
if (empty($this->feeds[$cat_id]))
|
$this->special_feeds[] = [
|
||||||
$this->feeds[$cat_id] = [];
|
'id' => $id,
|
||||||
|
'title' => $title,
|
||||||
$id = count($this->feeds[$cat_id]);
|
'sender' => $sender,
|
||||||
|
'icon' => $icon,
|
||||||
array_push($this->feeds[$cat_id],
|
];
|
||||||
['id' => $id, 'title' => $title, 'sender' => $sender, 'icon' => $icon]);
|
|
||||||
|
|
||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Get special (plugin-provided) feeds
|
||||||
|
*
|
||||||
|
* @param int $cat_id only -1 (Feeds::CATEGORY_SPECIAL) is supported
|
||||||
* @return array<int, array{'id': int, 'title': string, 'sender': Plugin, 'icon': string}>
|
* @return array<int, array{'id': int, 'title': string, 'sender': Plugin, 'icon': string}>
|
||||||
*/
|
*/
|
||||||
function get_feeds(int $cat_id) {
|
function get_feeds(int $cat_id) {
|
||||||
return $this->feeds[$cat_id] ?? [];
|
return $cat_id === Feeds::CATEGORY_SPECIAL ? $this->special_feeds : [];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* convert feed_id (e.g. -129) to pfeed_id first
|
* Get the Plugin handling a specific virtual feed.
|
||||||
*
|
*
|
||||||
* @return (Plugin&IVirtualFeed)|null
|
* Convert feed_id (e.g. -129) to pfeed_id first.
|
||||||
|
*
|
||||||
|
* @return (Plugin&IVirtualFeed)|null a Plugin that implements IVirtualFeed, otherwise null
|
||||||
*/
|
*/
|
||||||
function get_feed_handler(int $pfeed_id): ?Plugin {
|
function get_feed_handler(int $pfeed_id): ?Plugin {
|
||||||
foreach ($this->feeds as $cat) {
|
foreach ($this->special_feeds as $feed) {
|
||||||
foreach ($cat as $feed) {
|
if ($feed['id'] == $pfeed_id) {
|
||||||
if ($feed['id'] == $pfeed_id) {
|
/** @var Plugin&IVirtualFeed $feed['sender'] */
|
||||||
if (implements_interface($feed['sender'], 'IVirtualFeed')) {
|
return implements_interface($feed['sender'], 'IVirtualFeed') ? $feed['sender'] : null;
|
||||||
/** @var Plugin&IVirtualFeed $feed['sender'] */
|
|
||||||
return $feed['sender'];
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -851,14 +857,12 @@ class PluginHost {
|
|||||||
*/
|
*/
|
||||||
function get_method_url(Plugin $sender, string $method, array $params = []): string {
|
function get_method_url(Plugin $sender, string $method, array $params = []): string {
|
||||||
return Config::get_self_url() . "/backend.php?" .
|
return Config::get_self_url() . "/backend.php?" .
|
||||||
http_build_query(
|
http_build_query([
|
||||||
array_merge(
|
'op' => 'pluginhandler',
|
||||||
[
|
'plugin' => strtolower(get_class($sender)),
|
||||||
"op" => "pluginhandler",
|
'method' => $method,
|
||||||
"plugin" => strtolower(get_class($sender)),
|
...$params,
|
||||||
"method" => $method
|
]);
|
||||||
],
|
|
||||||
$params));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// shortcut syntax (disabled for now)
|
// shortcut syntax (disabled for now)
|
||||||
@ -880,12 +884,10 @@ class PluginHost {
|
|||||||
function get_public_method_url(Plugin $sender, string $method, array $params = []): ?string {
|
function get_public_method_url(Plugin $sender, string $method, array $params = []): ?string {
|
||||||
if ($sender->is_public_method($method)) {
|
if ($sender->is_public_method($method)) {
|
||||||
return Config::get_self_url() . "/public.php?" .
|
return Config::get_self_url() . "/public.php?" .
|
||||||
http_build_query(
|
http_build_query([
|
||||||
array_merge(
|
'op' => strtolower(get_class($sender) . self::PUBLIC_METHOD_DELIMITER . $method),
|
||||||
[
|
...$params,
|
||||||
"op" => strtolower(get_class($sender) . self::PUBLIC_METHOD_DELIMITER . $method),
|
]);
|
||||||
],
|
|
||||||
$params));
|
|
||||||
}
|
}
|
||||||
user_error("get_public_method_url: requested method '$method' of '" . get_class($sender) . "' is private.");
|
user_error("get_public_method_url: requested method '$method' of '" . get_class($sender) . "' is private.");
|
||||||
return null;
|
return null;
|
||||||
|
@ -13,7 +13,7 @@ class Pref_Filters extends Handler_Protected {
|
|||||||
const MAX_ACTIONS_TO_DISPLAY = 3;
|
const MAX_ACTIONS_TO_DISPLAY = 3;
|
||||||
|
|
||||||
/** @var array<int,array<mixed>> $action_descriptions */
|
/** @var array<int,array<mixed>> $action_descriptions */
|
||||||
private $action_descriptions = [];
|
private array $action_descriptions = [];
|
||||||
|
|
||||||
function before(string $method) : bool {
|
function before(string $method) : bool {
|
||||||
|
|
||||||
|
@ -144,14 +144,12 @@ class Prefs {
|
|||||||
Prefs::_PREFS_MIGRATED
|
Prefs::_PREFS_MIGRATED
|
||||||
];
|
];
|
||||||
|
|
||||||
/** @var Prefs|null */
|
private static ?Prefs $instance = null;
|
||||||
private static $instance;
|
|
||||||
|
|
||||||
/** @var array<string, bool|int|string> */
|
/** @var array<string, bool|int|string> */
|
||||||
private $cache = [];
|
private array $cache = [];
|
||||||
|
|
||||||
/** @var PDO */
|
private ?PDO $pdo = null;
|
||||||
private $pdo;
|
|
||||||
|
|
||||||
public static function get_instance() : Prefs {
|
public static function get_instance() : Prefs {
|
||||||
if (self::$instance == null)
|
if (self::$instance == null)
|
||||||
|
@ -53,7 +53,6 @@ class Sessions implements \SessionHandlerInterface {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function read(string $id): false|string {
|
public function read(string $id): false|string {
|
||||||
$sth = Db::pdo()->prepare('SELECT data FROM ttrss_sessions WHERE id=?');
|
$sth = Db::pdo()->prepare('SELECT data FROM ttrss_sessions WHERE id=?');
|
||||||
$sth->execute([$id]);
|
$sth->execute([$id]);
|
||||||
@ -93,7 +92,6 @@ class Sessions implements \SessionHandlerInterface {
|
|||||||
/**
|
/**
|
||||||
* @return int|false the number of deleted sessions on success, or false on failure
|
* @return int|false the number of deleted sessions on success, or false on failure
|
||||||
*/
|
*/
|
||||||
#[\ReturnTypeWillChange]
|
|
||||||
public function gc(int $max_lifetime): false|int {
|
public function gc(int $max_lifetime): false|int {
|
||||||
$result = Db::pdo()->query('DELETE FROM ttrss_sessions WHERE expire < ' . time());
|
$result = Db::pdo()->query('DELETE FROM ttrss_sessions WHERE expire < ' . time());
|
||||||
return $result === false ? false : $result->rowCount();
|
return $result === false ? false : $result->rowCount();
|
||||||
|
@ -56,21 +56,21 @@
|
|||||||
* @param array<string, mixed> $attributes
|
* @param array<string, mixed> $attributes
|
||||||
*/
|
*/
|
||||||
function number_spinner_tag(string $name, string $value, array $attributes = [], string $id = ""): string {
|
function number_spinner_tag(string $name, string $value, array $attributes = [], string $id = ""): string {
|
||||||
return input_tag($name, $value, "text", array_merge(["dojoType" => "dijit.form.NumberSpinner"], $attributes), $id);
|
return input_tag($name, $value, 'text', ['dojoType' => 'dijit.form.NumberSpinner', ...$attributes], $id);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $attributes
|
* @param array<string, mixed> $attributes
|
||||||
*/
|
*/
|
||||||
function submit_tag(string $value, array $attributes = []): string {
|
function submit_tag(string $value, array $attributes = []): string {
|
||||||
return button_tag($value, "submit", array_merge(["class" => "alt-primary"], $attributes));
|
return button_tag($value, 'submit', ['class' => 'alt-primary', ...$attributes]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array<string, mixed> $attributes
|
* @param array<string, mixed> $attributes
|
||||||
*/
|
*/
|
||||||
function cancel_dialog_tag(string $value, array $attributes = []): string {
|
function cancel_dialog_tag(string $value, array $attributes = []): string {
|
||||||
return button_tag($value, "", array_merge(["onclick" => "App.dialogOf(this).hide()"], $attributes));
|
return button_tag($value, '', ['onclick' => 'App.dialogOf(this).hide()', ...$attributes]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,15 +5,13 @@
|
|||||||
*/
|
*/
|
||||||
function stylesheet_tag(string $filename, array $attributes = []): string {
|
function stylesheet_tag(string $filename, array $attributes = []): string {
|
||||||
|
|
||||||
$attributes_str = \Controls\attributes_to_string(
|
$attributes_str = \Controls\attributes_to_string([
|
||||||
array_merge(
|
'href' => "$filename?" . filemtime($filename),
|
||||||
[
|
'rel' => 'stylesheet',
|
||||||
"href" => "$filename?" . filemtime($filename),
|
'type' => 'text/css',
|
||||||
"rel" => "stylesheet",
|
'data-orig-href' => $filename,
|
||||||
"type" => "text/css",
|
...$attributes,
|
||||||
"data-orig-href" => $filename
|
]);
|
||||||
],
|
|
||||||
$attributes));
|
|
||||||
|
|
||||||
return "<link $attributes_str/>\n";
|
return "<link $attributes_str/>\n";
|
||||||
}
|
}
|
||||||
@ -22,14 +20,12 @@ function stylesheet_tag(string $filename, array $attributes = []): string {
|
|||||||
* @param array<string, mixed> $attributes
|
* @param array<string, mixed> $attributes
|
||||||
*/
|
*/
|
||||||
function javascript_tag(string $filename, array $attributes = []): string {
|
function javascript_tag(string $filename, array $attributes = []): string {
|
||||||
$attributes_str = \Controls\attributes_to_string(
|
$attributes_str = \Controls\attributes_to_string([
|
||||||
array_merge(
|
'src' => "$filename?" . filemtime($filename),
|
||||||
[
|
'type' => 'text/javascript',
|
||||||
"src" => "$filename?" . filemtime($filename),
|
'charset' => 'utf-8',
|
||||||
"type" => "text/javascript",
|
...$attributes,
|
||||||
"charset" => "utf-8"
|
]);
|
||||||
],
|
|
||||||
$attributes));
|
|
||||||
|
|
||||||
return "<script $attributes_str></script>\n";
|
return "<script $attributes_str></script>\n";
|
||||||
}
|
}
|
||||||
|
@ -3,12 +3,8 @@ use PHPUnit\Framework\TestCase;
|
|||||||
|
|
||||||
/** @group integration */
|
/** @group integration */
|
||||||
final class ApiTest extends TestCase {
|
final class ApiTest extends TestCase {
|
||||||
|
private string $api_url;
|
||||||
/** @var string */
|
private string $sid;
|
||||||
private $api_url;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $sid;
|
|
||||||
|
|
||||||
function __construct() {
|
function __construct() {
|
||||||
$this->api_url = getenv('API_URL');
|
$this->api_url = getenv('API_URL');
|
||||||
|
Loading…
Reference in New Issue
Block a user