use strict types

This commit is contained in:
Shish 2020-01-26 13:19:35 +00:00
parent f5ccffdaf4
commit 9eb5acf2dc
414 changed files with 957 additions and 897 deletions

View file

@ -16,6 +16,7 @@ RUN mkdir -p data/config && \
echo "<?php define(\"DATABASE_DSN\", \"sqlite:data/shimmie.sqlite\");" > data/config/auto_install.conf.php && \ echo "<?php define(\"DATABASE_DSN\", \"sqlite:data/shimmie.sqlite\");" > data/config/auto_install.conf.php && \
echo === Installing === && php index.php && \ echo === Installing === && php index.php && \
echo === Smoke Test === && php index.php get-page /post/list && \ echo === Smoke Test === && php index.php get-page /post/list && \
echo === Unit Tests === && ./vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text && \ echo === Unit Tests === && ./vendor/bin/phpunit --configuration tests/phpunit.xml && \
echo === Cleaning === && rm -rf data echo === Cleaning === && rm -rf data
#echo === Unit Tests === && ./vendor/bin/phpunit --configuration tests/phpunit.xml --coverage-text && \
CMD "/app/tests/docker-init.sh" CMD "/app/tests/docker-init.sh"

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* /*
* Load all the files into memory, sanitise the environment, but don't * Load all the files into memory, sanitise the environment, but don't
* actually do anything as far as the app is concerned * actually do anything as far as the app is concerned

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class BaseThemelet * Class BaseThemelet
@ -85,13 +85,13 @@ class BaseThemelet
$page->add_block(new Block(null, $body, "main", 90, "paginator")); $page->add_block(new Block(null, $body, "main", 90, "paginator"));
} }
private function gen_page_link(string $base_url, ?string $query, string $page, string $name): string private function gen_page_link(string $base_url, ?string $query, int $page, string $name): string
{ {
$link = make_link($base_url.'/'.$page, $query); $link = make_link($base_url.'/'.$page, $query);
return '<a href="'.$link.'">'.$name.'</a>'; return '<a href="'.$link.'">'.$name.'</a>';
} }
private function gen_page_link_block(string $base_url, ?string $query, string $page, int $current_page, string $name): string private function gen_page_link_block(string $base_url, ?string $query, int $page, int $current_page, string $name): string
{ {
$paginator = ""; $paginator = "";
if ($page == $current_page) { if ($page == $current_page) {
@ -129,7 +129,7 @@ class BaseThemelet
$pages = []; $pages = [];
foreach (range($start, $end) as $i) { foreach (range($start, $end) as $i) {
$pages[] = $this->gen_page_link_block($base_url, $query, $i, $current_page, $i); $pages[] = $this->gen_page_link_block($base_url, $query, $i, $current_page, (string)$i);
} }
$pages_html = implode(" | ", $pages); $pages_html = implode(" | ", $pages);

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class Block * Class Block

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
interface CacheEngine interface CacheEngine
{ {
public function get(string $key); public function get(string $key);

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* CAPTCHA abstraction * * CAPTCHA abstraction *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Interface Config * Interface Config
@ -18,12 +18,12 @@ interface Config
/** /**
* Set a configuration option to a new value, regardless of what the value is at the moment. * Set a configuration option to a new value, regardless of what the value is at the moment.
*/ */
public function set_int(string $name, ?string $value): void; public function set_int(string $name, ?int $value): void;
/** /**
* Set a configuration option to a new value, regardless of what the value is at the moment. * Set a configuration option to a new value, regardless of what the value is at the moment.
*/ */
public function set_float(string $name, ?string $value): void; public function set_float(string $name, ?float $value): void;
/** /**
* Set a configuration option to a new value, regardless of what the value is at the moment. * Set a configuration option to a new value, regardless of what the value is at the moment.
@ -32,9 +32,8 @@ interface Config
/** /**
* Set a configuration option to a new value, regardless of what the value is at the moment. * Set a configuration option to a new value, regardless of what the value is at the moment.
* @param null|bool|string $value
*/ */
public function set_bool(string $name, $value): void; public function set_bool(string $name, ?bool $value): void;
/** /**
* Set a configuration option to a new value, regardless of what the value is at the moment. * Set a configuration option to a new value, regardless of what the value is at the moment.
@ -133,13 +132,13 @@ abstract class BaseConfig implements Config
{ {
public $values = []; public $values = [];
public function set_int(string $name, ?string $value): void public function set_int(string $name, ?int $value): void
{ {
$this->values[$name] = is_null($value) ? null : parse_shorthand_int($value); $this->values[$name] = is_null($value) ? null : $value;
$this->save($name); $this->save($name);
} }
public function set_float(string $name, ?string $value): void public function set_float(string $name, ?float $value): void
{ {
$this->values[$name] = $value; $this->values[$name] = $value;
$this->save($name); $this->save($name);
@ -151,9 +150,9 @@ abstract class BaseConfig implements Config
$this->save($name); $this->save($name);
} }
public function set_bool(string $name, $value): void public function set_bool(string $name, ?bool $value): void
{ {
$this->values[$name] = bool_escape($value) ? 'Y' : 'N'; $this->values[$name] = $value ? 'Y' : 'N';
$this->save($name); $this->save($name);
} }
@ -277,10 +276,10 @@ class StaticConfig extends BaseConfig
if (!empty($config)) { if (!empty($config)) {
$this->values = $config; $this->values = $config;
} else { } else {
throw new Exception("Config file '$filename' doesn't contain any config"); throw new ScoreException("Config file '$filename' doesn't contain any config");
} }
} else { } else {
throw new Exception("Config file '$filename' missing"); throw new ScoreException("Config file '$filename' missing");
} }
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
use FFSPHP\PDO; use FFSPHP\PDO;
abstract class DatabaseDriver abstract class DatabaseDriver
@ -168,7 +168,7 @@ class Database
$this->connect_db(); $this->connect_db();
} }
return $this->db->execute( return $this->db->execute(
"-- " . str_replace("%2F", "/", urlencode(@$_GET['q'])). "\n" . "-- " . str_replace("%2F", "/", urlencode($_GET['q'] ?? '')). "\n" .
$query, $query,
$args $args
); );

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
abstract class SCORE abstract class SCORE
{ {
const AIPK = "SCORE_AIPK"; const AIPK = "SCORE_AIPK";
@ -169,7 +169,7 @@ class SQLite extends DBEngine
public function init(PDO $db) public function init(PDO $db)
{ {
ini_set('sqlite.assoc_case', 0); ini_set('sqlite.assoc_case', '0');
$db->exec("PRAGMA foreign_keys = ON;"); $db->exec("PRAGMA foreign_keys = ON;");
$db->sqliteCreateFunction('UNIX_TIMESTAMP', '_unix_timestamp', 1); $db->sqliteCreateFunction('UNIX_TIMESTAMP', '_unix_timestamp', 1);
$db->sqliteCreateFunction('now', '_now', 0); $db->sqliteCreateFunction('now', '_now', 0);

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class Email * Class Email

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Generic parent class for all events. * Generic parent class for all events.
* *
@ -58,6 +58,7 @@ class PageRequestEvent extends Event
public function __construct(string $path) public function __construct(string $path)
{ {
parent::__construct();
global $config; global $config;
// trim starting slashes // trim starting slashes
@ -140,7 +141,7 @@ class PageRequestEvent extends Event
*/ */
public function count_args(): int public function count_args(): int
{ {
return int_escape($this->arg_count - $this->part_count); return $this->arg_count - $this->part_count;
} }
/* /*
@ -198,6 +199,7 @@ class CommandEvent extends Event
*/ */
public function __construct(array $args) public function __construct(array $args)
{ {
parent::__construct();
global $user; global $user;
$opts = []; $opts = [];
@ -278,6 +280,7 @@ class TextFormattingEvent extends Event
public function __construct(string $text) public function __construct(string $text)
{ {
parent::__construct();
$h_text = html_escape(trim($text)); $h_text = html_escape(trim($text));
$this->original = $h_text; $this->original = $h_text;
$this->formatted = $h_text; $this->formatted = $h_text;
@ -328,6 +331,7 @@ class LogEvent extends Event
public function __construct(string $section, int $priority, string $message, array $args) public function __construct(string $section, int $priority, string $message, array $args)
{ {
parent::__construct();
$this->section = $section; $this->section = $section;
$this->priority = $priority; $this->priority = $priority;
$this->message = $message; $this->message = $message;

View file

@ -1,15 +1,22 @@
<?php <?php declare(strict_types=1);
/** /**
* Class SCoreException * Class SCoreException
* *
* A base exception to be caught by the upper levels. * A base exception to be caught by the upper levels.
*/ */
class SCoreException extends Exception class SCoreException extends RuntimeException
{ {
/** @var string|null */
public $query;
/** @var string */
public $error;
public function __construct(string $msg, ?string $query=null) public function __construct(string $msg, ?string $query=null)
{ {
parent::__construct($msg); parent::__construct($msg);
$this->error = $msg;
$this->query = $query; $this->query = $query;
} }
} }
@ -47,15 +54,10 @@ class InvalidInput extends SCoreException
class InsufficientMemoryException extends SCoreException class InsufficientMemoryException extends SCoreException
{ {
} }
/* /*
* This is used by the image resizing code when there is an error while resizing * This is used by the image resizing code when there is an error while resizing
*/ */
class ImageResizeException extends SCoreException class ImageResizeException extends SCoreException
{ {
public $error;
public function __construct(string $error)
{
$this->error = $error;
}
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* \page eande Events and Extensions * \page eande Events and Extensions
* *
@ -83,11 +83,13 @@
*/ */
abstract class Extension abstract class Extension
{ {
/** @var string */
public $key; public $key;
/** @var Themelet this theme's Themelet object */ /** @var Themelet */
public $theme; protected $theme;
/** @var ExtensionInfo */
public $info; public $info;
private static $enabled_extensions = []; private static $enabled_extensions = [];
@ -98,7 +100,7 @@ abstract class Extension
$this->theme = $this->get_theme_object($class); $this->theme = $this->get_theme_object($class);
$this->info = ExtensionInfo::get_for_extension_class($class); $this->info = ExtensionInfo::get_for_extension_class($class);
if ($this->info===null) { if ($this->info===null) {
throw new Exception("Info class not found for extension $class"); throw new ScoreException("Info class not found for extension $class");
} }
$this->key = $this->info->key; $this->key = $this->info->key;
} }
@ -213,7 +215,10 @@ abstract class ExtensionInfo
/** @var array which DBs this ext supports (blank for 'all') */ /** @var array which DBs this ext supports (blank for 'all') */
public $db_support = []; public $db_support = [];
/** @var bool */
private $supported = null; private $supported = null;
/** @var string */
private $support_info = null; private $support_info = null;
public function is_supported(): bool public function is_supported(): bool
@ -302,12 +307,10 @@ abstract class ExtensionInfo
{ {
foreach (get_declared_classes() as $class) { foreach (get_declared_classes() as $class) {
$rclass = new ReflectionClass($class); $rclass = new ReflectionClass($class);
if ($rclass->isAbstract()) { if (!$rclass->isAbstract() && is_subclass_of($class, "ExtensionInfo")) {
// don't do anything
} elseif (is_subclass_of($class, "ExtensionInfo")) {
$extension_info = new $class(); $extension_info = new $class();
if (array_key_exists($extension_info->key, self::$all_info_by_key)) { if (array_key_exists($extension_info->key, self::$all_info_by_key)) {
throw new Exception("Extension Info $class with key $extension_info->key has already been loaded"); throw new ScoreException("Extension Info $class with key $extension_info->key has already been loaded");
} }
self::$all_info_by_key[$extension_info->key] = $extension_info; self::$all_info_by_key[$extension_info->key] = $extension_info;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* An image is being added to the database. * An image is being added to the database.
@ -20,18 +20,13 @@ class ImageAdditionEvent extends Event
*/ */
public function __construct(Image $image) public function __construct(Image $image)
{ {
parent::__construct();
$this->image = $image; $this->image = $image;
} }
} }
class ImageAdditionException extends SCoreException class ImageAdditionException extends SCoreException
{ {
public $error;
public function __construct(string $error)
{
$this->error = $error;
}
} }
/** /**
@ -53,6 +48,7 @@ class ImageDeletionEvent extends Event
*/ */
public function __construct(Image $image, bool $force = false) public function __construct(Image $image, bool $force = false)
{ {
parent::__construct();
$this->image = $image; $this->image = $image;
$this->force = $force; $this->force = $force;
} }
@ -77,6 +73,7 @@ class ImageReplaceEvent extends Event
*/ */
public function __construct(int $id, Image $image) public function __construct(int $id, Image $image)
{ {
parent::__construct();
$this->id = $id; $this->id = $id;
$this->image = $image; $this->image = $image;
} }
@ -84,13 +81,6 @@ class ImageReplaceEvent extends Event
class ImageReplaceException extends SCoreException class ImageReplaceException extends SCoreException
{ {
/** @var string */
public $error;
public function __construct(string $error)
{
$this->error = $error;
}
} }
/** /**
@ -108,12 +98,12 @@ class ThumbnailGenerationEvent extends Event
/** @var bool */ /** @var bool */
public $generated; public $generated;
/** /**
* Request a thumbnail be made for an image object * Request a thumbnail be made for an image object
*/ */
public function __construct(string $hash, string $type, bool $force=false) public function __construct(string $hash, string $type, bool $force=false)
{ {
parent::__construct();
$this->hash = $hash; $this->hash = $hash;
$this->type = $type; $this->type = $type;
$this->force = $force; $this->force = $force;
@ -139,6 +129,7 @@ class ParseLinkTemplateEvent extends Event
public function __construct(string $link, Image $image) public function __construct(string $link, Image $image)
{ {
parent::__construct();
$this->link = $link; $this->link = $link;
$this->original = $link; $this->original = $link;
$this->image = $image; $this->image = $image;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class Image * Class Image
* *
@ -27,6 +27,7 @@ class Image
/** @var string */ /** @var string */
public $hash; public $hash;
/** @var int */
public $filesize; public $filesize;
/** @var string */ /** @var string */
@ -65,7 +66,6 @@ class Image
/** @var int */ /** @var int */
public $length = null; public $length = null;
/** /**
* One will very rarely construct an image directly, more common * One will very rarely construct an image directly, more common
* would be to use Image::by_id, Image::by_hash, etc. * would be to use Image::by_id, Image::by_hash, etc.
@ -76,17 +76,18 @@ class Image
foreach ($row as $name => $value) { foreach ($row as $name => $value) {
// some databases use table.name rather than name // some databases use table.name rather than name
$name = str_replace("images.", "", $name); $name = str_replace("images.", "", $name);
$this->$name = $value; // hax, this is likely the cause of much scrutinizer-ci complaints.
// hax, this is likely the cause of much scrutinizer-ci complaints.
if(in_array($name, ["locked", "lossless", "video", "audio"])) {
$this->$name = bool_escape($value);
}
elseif(in_array($name, ["id", "owner_id", "height", "width", "filesize", "length"])) {
$this->$name = int_escape($value);
}
else {
$this->$name = $value;
}
} }
$this->locked = bool_escape($this->locked);
assert(is_numeric($this->id));
assert(is_numeric($this->height));
assert(is_numeric($this->width));
$this->id = int_escape($this->id);
$this->height = int_escape($this->height);
$this->width = int_escape($this->width);
} }
} }
@ -301,12 +302,12 @@ class Image
if ($tag_count === 0) { if ($tag_count === 0) {
$total = $cache->get("image-count"); $total = $cache->get("image-count");
if (!$total) { if (!$total) {
$total = $database->get_one("SELECT COUNT(*) FROM images"); $total = (int)$database->get_one("SELECT COUNT(*) FROM images");
$cache->set("image-count", $total, 600); $cache->set("image-count", $total, 600);
} }
} elseif ($tag_count === 1 && !preg_match("/[:=><\*\?]/", $tags[0])) { } elseif ($tag_count === 1 && !preg_match("/[:=><\*\?]/", $tags[0])) {
$total = $database->get_one( $total = (int)$database->get_one(
$database->scoreql_to_sql("SELECT count FROM tags WHERE LOWER(tag) = LOWER(:tag)"), "SELECT count FROM tags WHERE LOWER(tag) = LOWER(:tag)",
["tag"=>$tags[0]] ["tag"=>$tags[0]]
); );
} else { } else {
@ -317,7 +318,7 @@ class Image
$total = Image::get_accelerated_count($tag_conditions, $img_conditions); $total = Image::get_accelerated_count($tag_conditions, $img_conditions);
if (is_null($total)) { if (is_null($total)) {
$querylet = Image::build_search_querylet($tag_conditions, $img_conditions); $querylet = Image::build_search_querylet($tag_conditions, $img_conditions);
$total = $database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables); $total = (int)$database->get_one("SELECT COUNT(*) AS cnt FROM ($querylet->sql) AS tbl", $querylet->variables);
} }
} }
if (is_null($total)) { if (is_null($total)) {
@ -331,10 +332,10 @@ class Image
* *
* #param string[] $tags * #param string[] $tags
*/ */
public static function count_pages(array $tags=[]): float public static function count_pages(array $tags=[]): int
{ {
global $config; global $config;
return ceil(Image::count_images($tags) / $config->get_int(IndexConfig::IMAGES)); return (int)ceil(Image::count_images($tags) / $config->get_int(IndexConfig::IMAGES));
} }
private static function terms_to_conditions(array $terms): array private static function terms_to_conditions(array $terms): array

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Misc functions * * Misc functions *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class Querylet class Querylet
{ {
/** @var string */ /** @var string */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class Tag * Class Tag
* *
@ -88,13 +88,13 @@ class Tag
public static function sanitize(string $tag): string public static function sanitize(string $tag): string
{ {
$tag = preg_replace("/\s/", "", $tag); # whitespace $tag = preg_replace("/\s/", "", $tag); # whitespace
$tag = preg_replace('/\x20(\x0e|\x0f)/', '', $tag); # unicode RTL $tag = preg_replace('/\x20[\x0e\x0f]/', '', $tag); # unicode RTL
$tag = preg_replace("/\.+/", ".", $tag); # strings of dots? $tag = preg_replace("/\.+/", ".", $tag); # strings of dots?
$tag = preg_replace("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes? $tag = preg_replace("/^(\.+[\/\\\\])+/", "", $tag); # trailing slashes?
$tag = trim($tag, ", \t\n\r\0\x0B"); $tag = trim($tag, ", \t\n\r\0\x0B");
if (mb_strlen($tag, 'UTF-8') > 255) { if (mb_strlen($tag, 'UTF-8') > 255) {
throw new Exception("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n"); throw new ScoreException("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n");
} }
return $tag; return $tag;
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Logging convenience * * Logging convenience *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* \page themes Themes * \page themes Themes
* *
@ -44,8 +44,6 @@ abstract class PageMode
*/ */
class Page class Page
{ {
/** @name Overall */
//@{
/** @var string */ /** @var string */
public $mode = PageMode::PAGE; public $mode = PageMode::PAGE;
/** @var string */ /** @var string */
@ -75,11 +73,7 @@ class Page
} }
} }
//@}
// ============================================== // ==============================================
/** @name "data" mode */
//@{
/** @var string; public only for unit test */ /** @var string; public only for unit test */
public $data = ""; public $data = "";
@ -114,11 +108,7 @@ class Page
$this->disposition = $disposition; $this->disposition = $disposition;
} }
//@}
// ============================================== // ==============================================
/** @name "redirect" mode */
//@{
/** @var string */ /** @var string */
private $redirect = ""; private $redirect = "";
@ -132,11 +122,7 @@ class Page
$this->redirect = $redirect; $this->redirect = $redirect;
} }
//@}
// ============================================== // ==============================================
/** @name "page" mode */
//@{
/** @var int */ /** @var int */
public $code = 200; public $code = 200;
@ -268,8 +254,6 @@ class Page
$this->blocks[] = $block; $this->blocks[] = $block;
} }
//@}
// ============================================== // ==============================================
/** /**
@ -553,6 +537,7 @@ class PageSubNavBuildingEvent extends Event
public function __construct(string $parent) public function __construct(string $parent)
{ {
parent::__construct();
$this->parent= $parent; $this->parent= $parent;
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
abstract class Permissions abstract class Permissions
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Things which should be in the core API * * Things which should be in the core API *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@ -162,9 +162,7 @@ function list_files(string $base, string $_sub_dir=""): array
foreach ($files as $filename) { foreach ($files as $filename) {
$full_path = "$base/$_sub_dir/$filename"; $full_path = "$base/$_sub_dir/$filename";
if (is_link($full_path)) { if (!is_link($full_path) && is_dir($full_path)) {
// ignore
} elseif (is_dir($full_path)) {
if (!($filename == "." || $filename == "..")) { if (!($filename == "." || $filename == "..")) {
//subdirectory found //subdirectory found
$file_list = array_merge( $file_list = array_merge(
@ -549,7 +547,7 @@ function xml_tag(string $name, array $attrs=[], array $children=[]): string
{ {
$xml = "<$name "; $xml = "<$name ";
foreach ($attrs as $k => $v) { foreach ($attrs as $k => $v) {
$xv = str_replace('&#039;', '&apos;', htmlspecialchars($v, ENT_QUOTES)); $xv = str_replace('&#039;', '&apos;', htmlspecialchars((string)$v, ENT_QUOTES));
$xml .= "$k=\"$xv\" "; $xml .= "$k=\"$xv\" ";
} }
if (count($children) > 0) { if (count($children) > 0) {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* Event API * * Event API *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
@ -37,9 +37,7 @@ function _set_event_listeners(): void
foreach (get_declared_classes() as $class) { foreach (get_declared_classes() as $class) {
$rclass = new ReflectionClass($class); $rclass = new ReflectionClass($class);
if ($rclass->isAbstract()) { if (!$rclass->isAbstract() && is_subclass_of($class, "Extension")) {
// don't do anything
} elseif (is_subclass_of($class, "Extension")) {
/** @var Extension $extension */ /** @var Extension $extension */
$extension = new $class(); $extension = new $class();
@ -68,8 +66,7 @@ function _dump_event_listeners(array $event_listeners, string $path): void
foreach (get_declared_classes() as $class) { foreach (get_declared_classes() as $class) {
$rclass = new ReflectionClass($class); $rclass = new ReflectionClass($class);
if ($rclass->isAbstract()) { if (!$rclass->isAbstract() && is_subclass_of($class, "Extension")) {
} elseif (is_subclass_of($class, "Extension")) {
$p .= "\$$class = new $class(); "; $p .= "\$$class = new $class(); ";
} }
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* /*
* First, load the user-specified settings * First, load the user-specified settings
*/ */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
require_once "core/polyfills.php"; require_once "core/polyfills.php";
class PolyfillsTest extends \PHPUnit\Framework\TestCase class PolyfillsTest extends \PHPUnit\Framework\TestCase

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
require_once "core/util.php"; require_once "core/util.php";
class UtilTest extends \PHPUnit\Framework\TestCase class UtilTest extends \PHPUnit\Framework\TestCase

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\
* HTML Generation * * HTML Generation *
\* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ \* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
function _new_user(array $row): User function _new_user(array $row): User
{ {
@ -107,7 +107,7 @@ class User
{ {
$u = User::by_name($name); $u = User::by_name($name);
if (is_null($u)) { if (is_null($u)) {
throw SCoreException("Can't find any user named " . html_escape($name)); throw new ScoreException("Can't find any user named " . html_escape($name));
} else { } else {
return $u->id; return $u->id;
} }
@ -168,7 +168,7 @@ class User
{ {
global $database; global $database;
if (User::by_name($name)) { if (User::by_name($name)) {
throw new Exception("Desired username is already in use"); throw new ScoreException("Desired username is already in use");
} }
$old_name = $this->name; $old_name = $this->name;
$this->name = $name; $this->name = $name;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* @global UserClass[] $_shm_user_classes * @global UserClass[] $_shm_user_classes
*/ */
@ -48,8 +48,7 @@ class UserClass
public function can(string $ability): bool public function can(string $ability): bool
{ {
if (array_key_exists($ability, $this->abilities)) { if (array_key_exists($ability, $this->abilities)) {
$val = $this->abilities[$ability]; return $this->abilities[$ability];
return $val;
} elseif (!is_null($this->parent)) { } elseif (!is_null($this->parent)) {
return $this->parent->can($ability); return $this->parent->can($ability);
} else { } else {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
use function MicroHTML\emptyHTML; use function MicroHTML\emptyHTML;
use function MicroHTML\FORM; use function MicroHTML\FORM;
use function MicroHTML\INPUT; use function MicroHTML\INPUT;
@ -79,7 +79,7 @@ function blockcmp(Block $a, Block $b): int
if ($a->position == $b->position) { if ($a->position == $b->position) {
return 0; return 0;
} else { } else {
return ($a->position > $b->position); return ($a->position > $b->position) ? 1 : -1;
} }
} }
@ -92,7 +92,7 @@ function get_memory_limit(): int
// thumbnail generation requires lots of memory // thumbnail generation requires lots of memory
$default_limit = 8*1024*1024; // 8 MB of memory is PHP's default. $default_limit = 8*1024*1024; // 8 MB of memory is PHP's default.
$shimmie_limit = parse_shorthand_int($config->get_int(MediaConfig::MEM_LIMIT)); $shimmie_limit = $config->get_int(MediaConfig::MEM_LIMIT);
if ($shimmie_limit < 3*1024*1024) { if ($shimmie_limit < 3*1024*1024) {
// we aren't going to fit, override // we aren't going to fit, override
@ -117,7 +117,7 @@ function get_memory_limit(): int
// Shimmie wants more memory than what PHP is currently set for. // Shimmie wants more memory than what PHP is currently set for.
// Attempt to set PHP's memory limit. // Attempt to set PHP's memory limit.
if (ini_set("memory_limit", $shimmie_limit) === false) { if (ini_set("memory_limit", "$shimmie_limit") === false) {
/* We can't change PHP's limit, oh well, return whatever its currently set to */ /* We can't change PHP's limit, oh well, return whatever its currently set to */
return $memory; return $memory;
} }
@ -344,20 +344,17 @@ function join_url(string $base, string ...$paths)
function get_dir_contents(string $dir): array function get_dir_contents(string $dir): array
{ {
if (empty($dir)) { assert(!empty($dir));
throw new Exception("dir required");
}
if (!is_dir($dir)) { if (!is_dir($dir)) {
return []; return [];
} }
$results = array_diff( return array_diff(
scandir( scandir(
$dir $dir
), ),
['..', '.'] ['..', '.']
); );
return $results;
} }
/** /**
@ -460,8 +457,8 @@ function _sanitise_environment(): void
date_default_timezone_set(TIMEZONE); date_default_timezone_set(TIMEZONE);
} }
# ini_set('zend.assertions', 1); // generate assertions # ini_set('zend.assertions', '1'); // generate assertions
ini_set('assert.exception', 1); // throw exceptions when failed ini_set('assert.exception', '1'); // throw exceptions when failed
if (DEBUG) { if (DEBUG) {
error_reporting(E_ALL); error_reporting(E_ALL);
} }
@ -695,13 +692,11 @@ function SHM_FORM(string $target, string $method="POST", bool $multipart=false,
if ($onsubmit) { if ($onsubmit) {
$attrs["onsubmit"] = $onsubmit; $attrs["onsubmit"] = $onsubmit;
} }
$f = FORM( return FORM(
$attrs, $attrs,
INPUT(["type"=>"hidden", "name"=>"q", "value"=>$target]), INPUT(["type"=>"hidden", "name"=>"q", "value"=>$target]),
$method != "GET" ? "" : $user->get_auth_html() $method != "GET" ? "" : $user->get_auth_html()
); );
return $f;
} }
function SHM_SIMPLE_FORM($target, ...$children) { function SHM_SIMPLE_FORM($target, ...$children) {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AdminPageInfo extends ExtensionInfo class AdminPageInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Sent when the admin page is ready to be added to * Sent when the admin page is ready to be added to
@ -10,6 +10,7 @@ class AdminBuildingEvent extends Event
public function __construct(Page $page) public function __construct(Page $page)
{ {
parent::__construct();
$this->page = $page; $this->page = $page;
} }
} }
@ -23,12 +24,16 @@ class AdminActionEvent extends Event
public function __construct(string $action) public function __construct(string $action)
{ {
parent::__construct();
$this->action = $action; $this->action = $action;
} }
} }
class AdminPage extends Extension class AdminPage extends Extension
{ {
/** @var AdminPageTheme */
protected $theme;
public function onPageRequest(PageRequestEvent $event) public function onPageRequest(PageRequestEvent $event)
{ {
global $page, $user; global $page, $user;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AdminPageTest extends ShimmiePHPUnitTestCase class AdminPageTest extends ShimmiePHPUnitTestCase
{ {
public function testAuth() public function testAuth()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AdminPageTheme extends Themelet class AdminPageTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AliasEditorInfo extends ExtensionInfo class AliasEditorInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
use MicroCRUD\ActionColumn; use MicroCRUD\ActionColumn;
use MicroCRUD\TextColumn; use MicroCRUD\TextColumn;
@ -33,6 +33,7 @@ class AddAliasEvent extends Event
public function __construct(string $oldtag, string $newtag) public function __construct(string $oldtag, string $newtag)
{ {
parent::__construct();
$this->oldtag = trim($oldtag); $this->oldtag = trim($oldtag);
$this->newtag = trim($newtag); $this->newtag = trim($newtag);
} }
@ -44,6 +45,9 @@ class AddAliasException extends SCoreException
class AliasEditor extends Extension class AliasEditor extends Extension
{ {
/** @var AliasEditorTheme */
protected $theme;
public function onPageRequest(PageRequestEvent $event) public function onPageRequest(PageRequestEvent $event)
{ {
global $config, $database, $page, $user; global $config, $database, $page, $user;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AliasEditorTest extends ShimmiePHPUnitTestCase class AliasEditorTest extends ShimmiePHPUnitTestCase
{ {
public function testAliasList() public function testAliasList()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AliasEditorTheme extends Themelet class AliasEditorTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ApprovalInfo extends ExtensionInfo class ApprovalInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
abstract class ApprovalConfig abstract class ApprovalConfig
{ {
@ -9,6 +9,9 @@ abstract class ApprovalConfig
class Approval extends Extension class Approval extends Extension
{ {
/** @var ApprovalTheme */
protected $theme;
public function onInitExt(InitExtEvent $event) public function onInitExt(InitExtEvent $event)
{ {
global $config; global $config;
@ -59,8 +62,6 @@ class Approval extends Extension
public function onAdminBuilding(AdminBuildingEvent $event) public function onAdminBuilding(AdminBuildingEvent $event)
{ {
global $config;
$this->theme->display_admin_form(); $this->theme->display_admin_form();
} }
@ -128,7 +129,7 @@ class Approval extends Extension
$event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y "))); $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_Y ")));
} }
if(is_null($event->term)) return;
if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) { if (preg_match(self::SEARCH_REGEXP, strtolower($event->term), $matches)) {
if ($user->can(Permissions::APPROVE_IMAGE) && $matches[1] == "no") { if ($user->can(Permissions::APPROVE_IMAGE) && $matches[1] == "no") {
$event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_N "))); $event->add_querylet(new Querylet($database->scoreql_to_sql("approved = SCORE_BOOL_N ")));
@ -177,7 +178,7 @@ class Approval extends Extension
public static function disapprove_image($image_id) public static function disapprove_image($image_id)
{ {
global $database, $user; global $database;
$database->execute( $database->execute(
$database->scoreql_to_sql( $database->scoreql_to_sql(
@ -236,7 +237,6 @@ class Approval extends Extension
} }
} }
public function onDatabaseUpgrade(DatabaseUpgradeEvent $event) public function onDatabaseUpgrade(DatabaseUpgradeEvent $event)
{ {
global $database; global $database;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ApprovalTheme extends Themelet class ApprovalTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ArrowkeyNavigationInfo extends ExtensionInfo class ArrowkeyNavigationInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ArrowkeyNavigation extends Extension class ArrowkeyNavigation extends Extension
{ {
@ -85,11 +85,9 @@ class ArrowkeyNavigation extends Extension
} }
// Create return array // Create return array
$pageinfo = [ return [
"prev" => $prefix.$prev, "prev" => $prefix.$prev,
"next" => $prefix.$next, "next" => $prefix.$next,
]; ];
return $pageinfo;
} }
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ArtistsInfo extends ExtensionInfo class ArtistsInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AuthorSetEvent extends Event class AuthorSetEvent extends Event
{ {
@ -11,6 +11,7 @@ class AuthorSetEvent extends Event
public function __construct(Image $image, User $user, string $author) public function __construct(Image $image, User $user, string $author)
{ {
parent::__construct();
$this->image = $image; $this->image = $image;
$this->user = $user; $this->user = $user;
$this->author = $author; $this->author = $author;
@ -19,6 +20,9 @@ class AuthorSetEvent extends Event
class Artists extends Extension class Artists extends Extension
{ {
/** @var ArtistsTheme */
protected $theme;
public function onImageInfoSet(ImageInfoSetEvent $event) public function onImageInfoSet(ImageInfoSetEvent $event)
{ {
global $user; global $user;
@ -38,6 +42,8 @@ class Artists extends Extension
public function onSearchTermParse(SearchTermParseEvent $event) public function onSearchTermParse(SearchTermParseEvent $event)
{ {
if(is_null($event->term)) return;
$matches = []; $matches = [];
if (preg_match("/^(author|artist)[=|:](.*)$/i", $event->term, $matches)) { if (preg_match("/^(author|artist)[=|:](.*)$/i", $event->term, $matches)) {
$char = $matches[1]; $char = $matches[1];
@ -195,7 +201,7 @@ class Artists extends Extension
case "view": case "view":
{ {
$artistID = $event->get_arg(1); $artistID = int_escape($event->get_arg(1));
$artist = $this->get_artist($artistID); $artist = $this->get_artist($artistID);
$aliases = $this->get_alias($artist['id']); $aliases = $this->get_alias($artist['id']);
$members = $this->get_members($artist['id']); $members = $this->get_members($artist['id']);
@ -222,7 +228,7 @@ class Artists extends Extension
case "edit": case "edit":
{ {
$artistID = $event->get_arg(1); $artistID = int_escape($event->get_arg(1));
$artist = $this->get_artist($artistID); $artist = $this->get_artist($artistID);
$aliases = $this->get_alias($artistID); $aliases = $this->get_alias($artistID);
$members = $this->get_members($artistID); $members = $this->get_members($artistID);
@ -262,7 +268,7 @@ class Artists extends Extension
} }
case "nuke": case "nuke":
{ {
$artistID = $event->get_arg(1); $artistID = int_escape($event->get_arg(1));
$this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members $this->delete_artist($artistID); // this will delete the artist, its alias, its urls and its members
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("artist/list")); $page->set_redirect(make_link("artist/list"));
@ -300,7 +306,7 @@ class Artists extends Extension
} }
case "delete": case "delete":
{ {
$aliasID = $event->get_arg(2); $aliasID = int_escape($event->get_arg(2));
$artistID = $this->get_artistID_by_aliasID($aliasID); $artistID = $this->get_artistID_by_aliasID($aliasID);
$this->delete_alias($aliasID); $this->delete_alias($aliasID);
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
@ -341,7 +347,7 @@ class Artists extends Extension
} }
case "delete": case "delete":
{ {
$urlID = $event->get_arg(2); $urlID = int_escape($event->get_arg(2));
$artistID = $this->get_artistID_by_urlID($urlID); $artistID = $this->get_artistID_by_urlID($urlID);
$this->delete_url($urlID); $this->delete_url($urlID);
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
@ -415,7 +421,7 @@ class Artists extends Extension
{ {
global $database; global $database;
$result = $database->get_row("SELECT author FROM images WHERE id = :id", ['id'=>$imageID]); $result = $database->get_row("SELECT author FROM images WHERE id = :id", ['id'=>$imageID]);
return stripslashes($result['author']); return $result['author'] ?? "";
} }
private function url_exists_by_url(string $url): bool private function url_exists_by_url(string $url): bool
@ -435,7 +441,6 @@ class Artists extends Extension
private function alias_exists_by_name(string $alias): bool private function alias_exists_by_name(string $alias): bool
{ {
global $database; global $database;
$result = $database->get_one("SELECT COUNT(1) FROM artist_alias WHERE alias = :alias", ['alias'=>$alias]); $result = $database->get_one("SELECT COUNT(1) FROM artist_alias WHERE alias = :alias", ['alias'=>$alias]);
return ($result != 0); return ($result != 0);
} }
@ -507,25 +512,19 @@ class Artists extends Extension
private function get_alias_by_id(int $aliasID): array private function get_alias_by_id(int $aliasID): array
{ {
global $database; global $database;
$result = $database->get_row("SELECT * FROM artist_alias WHERE id = :id", ['id'=>$aliasID]); return $database->get_row("SELECT * FROM artist_alias WHERE id = :id", ['id'=>$aliasID]);
$result["alias"] = stripslashes($result["alias"]);
return $result;
} }
private function get_url_by_id(int $urlID): array private function get_url_by_id(int $urlID): array
{ {
global $database; global $database;
$result = $database->get_row("SELECT * FROM artist_urls WHERE id = :id", ['id'=>$urlID]); return $database->get_row("SELECT * FROM artist_urls WHERE id = :id", ['id'=>$urlID]);
$result["url"] = stripslashes($result["url"]);
return $result;
} }
private function get_member_by_id(int $memberID): array private function get_member_by_id(int $memberID): array
{ {
global $database; global $database;
$result = $database->get_row("SELECT * FROM artist_members WHERE id = :id", ['id'=>$memberID]); return $database->get_row("SELECT * FROM artist_members WHERE id = :id", ['id'=>$memberID]);
$result["name"] = stripslashes($result["name"]);
return $result;
} }
private function update_artist() private function update_artist()
@ -850,7 +849,7 @@ class Artists extends Extension
{ {
global $config, $database; global $config, $database;
$pageNumber = clamp($event->get_arg(1), 1, null) - 1; $pageNumber = clamp(int_escape($event->get_arg(1)), 1, null) - 1;
$artistsPerPage = $config->get_int("artistsPerPage"); $artistsPerPage = $config->get_int("artistsPerPage");
$listing = $database->get_all( $listing = $database->get_all(

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ArtistTest extends ShimmiePHPUnitTestCase class ArtistTest extends ShimmiePHPUnitTestCase
{ {
public function testSearch() public function testSearch()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ArtistsTheme extends Themelet class ArtistsTheme extends Themelet
{ {
public function get_author_editor_html(string $author): string public function get_author_editor_html(string $author): string

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AutoCompleteInfo extends ExtensionInfo class AutoCompleteInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AutoComplete extends Extension class AutoComplete extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class AutoCompleteTheme extends Themelet class AutoCompleteTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BanWordsInfo extends ExtensionInfo class BanWordsInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BanWords extends Extension class BanWords extends Extension
{ {
@ -75,7 +75,7 @@ xanax
/** /**
* Throws if the comment contains banned words. * Throws if the comment contains banned words.
*/ */
private function test_text(string $comment, Exception $ex): void private function test_text(string $comment, SCoreException $ex): void
{ {
$comment = strtolower($comment); $comment = strtolower($comment);

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BanWordsTest extends ShimmiePHPUnitTestCase class BanWordsTest extends ShimmiePHPUnitTestCase
{ {
public function check_blocked($image_id, $words) public function check_blocked($image_id, $words)

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BBCodeInfo extends ExtensionInfo class BBCodeInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BBCode extends FormatterExtension class BBCode extends FormatterExtension

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BBCodeTest extends ShimmiePHPUnitTestCase class BBCodeTest extends ShimmiePHPUnitTestCase
{ {
public function testBasics() public function testBasics()

View file

@ -4,7 +4,7 @@ class Blocks extends Extension
{ {
public function onDatabaseUpgrade(DatabaseUpgradeEvent $event) public function onDatabaseUpgrade(DatabaseUpgradeEvent $event)
{ {
global $config, $database; global $database;
if ($this->get_version("ext_blocks_version") < 1) { if ($this->get_version("ext_blocks_version") < 1) {
$database->create_table("blocks", " $database->create_table("blocks", "
id SCORE_AIPK, id SCORE_AIPK,

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BlotterInfo extends ExtensionInfo class BlotterInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class Blotter extends Extension class Blotter extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BlotterTest extends ShimmiePHPUnitTestCase class BlotterTest extends ShimmiePHPUnitTestCase
{ {
public function testLogin() public function testLogin()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BlotterTheme extends Themelet class BlotterTheme extends Themelet
{ {
public function display_editor($entries) public function display_editor($entries)

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BrowserSearchInfo extends ExtensionInfo class BrowserSearchInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BrowserSearch extends Extension class BrowserSearch extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BrowserSearchTest extends ShimmiePHPUnitTestCase class BrowserSearchTest extends ShimmiePHPUnitTestCase
{ {
public function testBasic() public function testBasic()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkActionsInfo extends ExtensionInfo class BulkActionsInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkActionBlockBuildingEvent extends Event class BulkActionBlockBuildingEvent extends Event
{ {
@ -39,13 +39,11 @@ class BulkActionEvent extends Event
public $action; public $action;
/** @var array */ /** @var array */
public $items; public $items;
/** @var PageRequestEvent */
public $page_request;
public function __construct(String $action, PageRequestEvent $pageRequestEvent, Generator $items) public function __construct(String $action, Generator $items)
{ {
parent::__construct();
$this->action = $action; $this->action = $action;
$this->page_request = $pageRequestEvent;
$this->items = $items; $this->items = $items;
} }
} }
@ -108,7 +106,7 @@ class BulkActions extends Extension
} }
$query = $event->args[0]; $query = $event->args[0];
$items = $this->yield_search_results($event->args[1]); $items = $this->yield_search_results($event->args[1]);
$newEvent = new BulkActionEvent($event->args[0], $event, $items); $newEvent = new BulkActionEvent($event->args[0], $items);
var_dump($newEvent); var_dump($newEvent);
# send_event($newEvent); # send_event($newEvent);
} }
@ -177,11 +175,10 @@ class BulkActions extends Extension
} }
if (is_iterable($items)) { if (is_iterable($items)) {
$newEvent = new BulkActionEvent($action, $event, $items); $newEvent = new BulkActionEvent($action, $items);
send_event($newEvent); send_event($newEvent);
} }
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
if (!isset($_SERVER['HTTP_REFERER'])) { if (!isset($_SERVER['HTTP_REFERER'])) {
$_SERVER['HTTP_REFERER'] = make_link(); $_SERVER['HTTP_REFERER'] = make_link();
@ -228,7 +225,7 @@ class BulkActions extends Extension
send_event(new ImageDeletionEvent($image)); send_event(new ImageDeletionEvent($image));
$total++; $total++;
} catch (Exception $e) { } catch (Exception $e) {
$page->flash("Error while removing {$image->id}: " . $e->getMessage(), "error"); $page->flash("Error while removing {$image->id}: " . $e->getMessage());
} }
} }
return $total; return $total;
@ -283,7 +280,7 @@ class BulkActions extends Extension
send_event(new SourceSetEvent($image, $source)); send_event(new SourceSetEvent($image, $source));
$total++; $total++;
} catch (Exception $e) { } catch (Exception $e) {
$page->flash("Error while setting source for {$image->id}: " . $e->getMessage(), "error"); $page->flash("Error while setting source for {$image->id}: " . $e->getMessage());
} }
} }
return $total; return $total;

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkActionsTheme extends Themelet class BulkActionsTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddInfo extends ExtensionInfo class BulkAddInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddEvent extends Event class BulkAddEvent extends Event
{ {
@ -7,6 +7,7 @@ class BulkAddEvent extends Event
public function __construct(string $dir) public function __construct(string $dir)
{ {
parent::__construct();
$this->dir = $dir; $this->dir = $dir;
$this->results = []; $this->results = [];
} }

View file

@ -1,4 +1,5 @@
<?php <?php declare(strict_types=1);
class BulkAddTest extends ShimmiePHPUnitTestCase class BulkAddTest extends ShimmiePHPUnitTestCase
{ {
public function testBulkAdd() public function testBulkAdd()
@ -26,15 +27,15 @@ class BulkAddTest extends ShimmiePHPUnitTestCase
# FIXME: test that the output here makes sense, no "adding foo.php ... ok" # FIXME: test that the output here makes sense, no "adding foo.php ... ok"
$this->get_page("post/list/hash=17fc89f372ed3636e28bd25cc7f3bac1/1"); $this->get_page("post/list/hash=17fc89f372ed3636e28bd25cc7f3bac1/1");
$this->assert_title(new PatternExpectation("/^Image \d+: data/")); $this->assert_title_matches(new PatternExpectation("/^Image \d+: data/"));
$this->click("Delete"); $this->click("Delete");
$this->get_page("post/list/hash=feb01bab5698a11dd87416724c7a89e3/1"); $this->get_page("post/list/hash=feb01bab5698a11dd87416724c7a89e3/1");
$this->assert_title(new PatternExpectation("/^Image \d+: data/")); $this->assert_title_matches(new PatternExpectation("/^Image \d+: data/"));
$this->click("Delete"); $this->click("Delete");
$this->get_page("post/list/hash=e106ea2983e1b77f11e00c0c54e53805/1"); $this->get_page("post/list/hash=e106ea2983e1b77f11e00c0c54e53805/1");
$this->assert_title(new PatternExpectation("/^Image \d+: data/")); $this->assert_title_matches(new PatternExpectation("/^Image \d+: data/"));
$this->click("Delete"); $this->click("Delete");
$this->log_out(); $this->log_out();

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddTheme extends Themelet class BulkAddTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddCSVInfo extends ExtensionInfo class BulkAddCSVInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddCSV extends Extension class BulkAddCSV extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkAddCSVTheme extends Themelet class BulkAddCSVTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class BulkRemoveInfo extends ExtensionInfo class BulkRemoveInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
//todo: removal by tag returns 1 less image in test for some reason, actually a combined search doesn't seem to work for shit either //todo: removal by tag returns 1 less image in test for some reason, actually a combined search doesn't seem to work for shit either

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CommentListInfo extends ExtensionInfo class CommentListInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
require_once "vendor/ifixit/php-akismet/akismet.class.php"; require_once "vendor/ifixit/php-akismet/akismet.class.php";
@ -13,6 +13,7 @@ class CommentPostingEvent extends Event
public function __construct(int $image_id, User $user, string $comment) public function __construct(int $image_id, User $user, string $comment)
{ {
parent::__construct();
$this->image_id = $image_id; $this->image_id = $image_id;
$this->user = $user; $this->user = $user;
$this->comment = $comment; $this->comment = $comment;
@ -31,6 +32,7 @@ class CommentDeletionEvent extends Event
public function __construct(int $comment_id) public function __construct(int $comment_id)
{ {
parent::__construct();
$this->comment_id = $comment_id; $this->comment_id = $comment_id;
} }
} }
@ -69,7 +71,7 @@ class Comment
public static function count_comments_by_user(User $user): int public static function count_comments_by_user(User $user): int
{ {
global $database; global $database;
return $database->get_one(" return (int)$database->get_one("
SELECT COUNT(*) AS count SELECT COUNT(*) AS count
FROM comments FROM comments
WHERE owner_id=:owner_id WHERE owner_id=:owner_id
@ -102,7 +104,7 @@ class CommentList extends Extension
public function onDatabaseUpgrade(DatabaseUpgradeEvent $event) public function onDatabaseUpgrade(DatabaseUpgradeEvent $event)
{ {
global $config, $database; global $database;
if ($this->get_version("ext_comments_version") < 3) { if ($this->get_version("ext_comments_version") < 3) {
// shortcut to latest // shortcut to latest
if ($this->get_version("ext_comments_version") < 1) { if ($this->get_version("ext_comments_version") < 1) {
@ -202,7 +204,7 @@ class CommentList extends Extension
if ($user->can(Permissions::DELETE_COMMENT)) { if ($user->can(Permissions::DELETE_COMMENT)) {
// FIXME: post, not args // FIXME: post, not args
if ($event->count_args() === 3) { if ($event->count_args() === 3) {
send_event(new CommentDeletionEvent($event->get_arg(1))); send_event(new CommentDeletionEvent(int_escape($event->get_arg(1))));
$page->flash("Deleted comment"); $page->flash("Deleted comment");
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
if (!empty($_SERVER['HTTP_REFERER'])) { if (!empty($_SERVER['HTTP_REFERER'])) {
@ -254,7 +256,7 @@ class CommentList extends Extension
$duser = User::by_name($search); $duser = User::by_name($search);
$i_comment_count = Comment::count_comments_by_user($duser); $i_comment_count = Comment::count_comments_by_user($duser);
$com_per_page = 50; $com_per_page = 50;
$total_pages = ceil($i_comment_count / $com_per_page); $total_pages = (int)ceil($i_comment_count / $com_per_page);
$page_num = clamp($page_num, 1, $total_pages); $page_num = clamp($page_num, 1, $total_pages);
$comments = $this->get_user_comments($duser->id, $com_per_page, ($page_num - 1) * $com_per_page); $comments = $this->get_user_comments($duser->id, $com_per_page, ($page_num - 1) * $com_per_page);
$this->theme->display_all_user_comments($comments, $page_num, $total_pages, $duser); $this->theme->display_all_user_comments($comments, $page_num, $total_pages, $duser);
@ -340,8 +342,9 @@ class CommentList extends Extension
public function onSearchTermParse(SearchTermParseEvent $event) public function onSearchTermParse(SearchTermParseEvent $event)
{ {
$matches = []; if(is_null($event->term)) return;
$matches = [];
if (preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) { if (preg_match("/^comments([:]?<|[:]?>|[:]?<=|[:]?>=|[:|=])(\d+)$/i", $event->term, $matches)) {
$cmp = ltrim($matches[1], ":") ?: "="; $cmp = ltrim($matches[1], ":") ?: "=";
$comments = $matches[2]; $comments = $matches[2];
@ -399,7 +402,7 @@ class CommentList extends Extension
$images = []; $images = [];
while ($row = $result->fetch()) { while ($row = $result->fetch()) {
$image = Image::by_id($row["image_id"]); $image = Image::by_id((int)$row["image_id"]);
if ( if (
Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) && Extension::is_enabled(RatingsInfo::KEY) && !is_null($image) &&
!in_array($image->rating, $user_ratings) !in_array($image->rating, $user_ratings)

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CommentListTest extends ShimmiePHPUnitTestCase class CommentListTest extends ShimmiePHPUnitTestCase
{ {
public function setUp(): void public function setUp(): void

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CommentListTheme extends Themelet class CommentListTheme extends Themelet
{ {
private $show_anon_id = false; private $show_anon_id = false;
@ -274,16 +274,15 @@ class CommentListTheme extends Themelet
{ {
global $config; global $config;
$i_image_id = int_escape($image_id);
$hash = CommentList::get_hash(); $hash = CommentList::get_hash();
$h_captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : ""; $h_captcha = $config->get_bool("comment_captcha") ? captcha_get_html() : "";
return ' return '
<div class="comment comment_add"> <div class="comment comment_add">
'.make_form(make_link("comment/add")).' '.make_form(make_link("comment/add")).'
<input type="hidden" name="image_id" value="'.$i_image_id.'" /> <input type="hidden" name="image_id" value="'.$image_id.'" />
<input type="hidden" name="hash" value="'.$hash.'" /> <input type="hidden" name="hash" value="'.$hash.'" />
<textarea id="comment_on_'.$i_image_id.'" name="comment" rows="5" cols="50"></textarea> <textarea id="comment_on_'.$image_id.'" name="comment" rows="5" cols="50"></textarea>
'.$h_captcha.' '.$h_captcha.'
<br><input type="submit" value="Post Comment" /> <br><input type="submit" value="Post Comment" />
</form> </form>

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
abstract class CronUploaderConfig abstract class CronUploaderConfig

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/* /*
* Name: Cron Uploader * Name: Cron Uploader

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
require_once "config.php"; require_once "config.php";
@ -109,13 +109,13 @@ class CronUploader extends Extension
{ {
global $page; global $page;
if (empty($folder)) { if (empty($folder)) {
throw new Exception("folder empty"); throw new SCoreException("folder empty");
} }
$queue_dir = $this->get_queue_dir(); $queue_dir = $this->get_queue_dir();
$stage_dir = join_path($this->get_failed_dir(), $folder); $stage_dir = join_path($this->get_failed_dir(), $folder);
if (!is_dir($stage_dir)) { if (!is_dir($stage_dir)) {
throw new Exception("Could not find $stage_dir"); throw new SCoreException("Could not find $stage_dir");
} }
$this->prep_root_dir(); $this->prep_root_dir();
@ -123,7 +123,7 @@ class CronUploader extends Extension
$results = get_dir_contents($queue_dir); $results = get_dir_contents($queue_dir);
if (count($results) > 0) { if (count($results) > 0) {
$page->flash("Queue folder must be empty to re-stage", "error"); $page->flash("Queue folder must be empty to re-stage");
return; return;
} }
@ -293,7 +293,7 @@ class CronUploader extends Extension
} }
$output_subdir = date('Ymd-His', time()); $output_subdir = date('Ymd-His', time());
$image_queue = $this->generate_image_queue($upload_count); $image_queue = $this->generate_image_queue(CronUploaderConfig::get_dir(), $upload_count);
// Throw exception if there's nothing in the queue // Throw exception if there's nothing in the queue
@ -408,9 +408,8 @@ class CronUploader extends Extension
send_event($event); send_event($event);
// Generate info message // Generate info message
$infomsg = ""; // Will contain info message
if ($event->image_id == -1) { if ($event->image_id == -1) {
throw new Exception("File type not recognised. Filename: {$filename}"); throw new UploadException("File type not recognised. Filename: {$filename}");
} elseif ($event->merged === true) { } elseif ($event->merged === true) {
$infomsg = "Image merged. ID: {$event->image_id} - Filename: {$filename}"; $infomsg = "Image merged. ID: {$event->image_id} - Filename: {$filename}";
} else { } else {
@ -473,8 +472,6 @@ class CronUploader extends Extension
private function log_message(int $severity, string $message): void private function log_message(int $severity, string $message): void
{ {
global $database;
log_msg(self::NAME, $severity, $message); log_msg(self::NAME, $severity, $message);
$time = "[" . date('Y-m-d H:i:s') . "]"; $time = "[" . date('Y-m-d H:i:s') . "]";

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CronUploaderTheme extends Themelet class CronUploaderTheme extends Themelet
{ {
@ -100,7 +100,7 @@ class CronUploaderTheme extends Themelet
public function display_form(array $failed_dirs) public function display_form(array $failed_dirs)
{ {
global $page, $database; global $page;
$link = make_http(make_link("cron_upload")); $link = make_http(make_link("cron_upload"));
$html = "<a href='$link'>Cron uploader documentation</a>"; $html = "<a href='$link'>Cron uploader documentation</a>";

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CustomHtmlHeadersInfo extends ExtensionInfo class CustomHtmlHeadersInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class CustomHtmlHeaders extends Extension class CustomHtmlHeaders extends Extension
{ {
@ -15,10 +15,10 @@ class CustomHtmlHeaders extends Extension
// modified title // modified title
$sb->add_choice_option("sitename_in_title", [ $sb->add_choice_option("sitename_in_title", [
"none" => 0, "none" => "none",
"as prefix" => 1, "as prefix" => "prefix",
"as suffix" => 2 "as suffix" => "suffix"
], "<br>Add website name in title"); ], "<br>Add website name in title");
$event->panel->add_block($sb); $event->panel->add_block($sb);
} }
@ -26,7 +26,7 @@ class CustomHtmlHeaders extends Extension
public function onInitExt(InitExtEvent $event) public function onInitExt(InitExtEvent $event)
{ {
global $config; global $config;
$config->set_default_int("sitename_in_title", 0); $config->set_default_string("sitename_in_title", "none");
} }
# Load Analytics tracking code on page request # Load Analytics tracking code on page request
@ -52,17 +52,16 @@ class CustomHtmlHeaders extends Extension
// get config values // get config values
$site_title = $config->get_string(SetupConfig::TITLE); $site_title = $config->get_string(SetupConfig::TITLE);
$sitename_in_title = $config->get_int("sitename_in_title"); $sitename_in_title = $config->get_string("sitename_in_title");
// if feature is enabled & sitename isn't already in title // sitename is already in title (can occur on index & other pages)
// (can occur on index & other pages) if(strstr($page->title, $site_title)) return;
if ($sitename_in_title != 0 && !strstr($page->title, $site_title)) {
if ($sitename_in_title == 1) { if ($sitename_in_title == "prefix") {
$page->title = "$site_title - $page->title"; $page->title = "$site_title - $page->title";
} // as prefix }
elseif ($sitename_in_title == 2) { elseif ($sitename_in_title == "suffix") {
$page->title = "$page->title - $site_title"; $page->title = "$page->title - $site_title";
} // as suffix
} }
} }
} }

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DanbooruApiInfo extends ExtensionInfo class DanbooruApiInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DanbooruApi extends Extension class DanbooruApi extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DanbooruApiTest extends ShimmiePHPUnitTestCase class DanbooruApiTest extends ShimmiePHPUnitTestCase
{ {
public function testSearch() public function testSearch()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DowntimeInfo extends ExtensionInfo class DowntimeInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class Downtime extends Extension class Downtime extends Extension
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DowntimeTest extends ShimmiePHPUnitTestCase class DowntimeTest extends ShimmiePHPUnitTestCase
{ {
public function tearDown(): void public function tearDown(): void

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class DowntimeTheme extends Themelet class DowntimeTheme extends Themelet
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class EmoticonsInfo extends ExtensionInfo class EmoticonsInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class EmoticonTest extends ShimmiePHPUnitTestCase class EmoticonTest extends ShimmiePHPUnitTestCase
{ {
public function testEmoticons() public function testEmoticons()

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class EmoticonListInfo extends ExtensionInfo class EmoticonListInfo extends ExtensionInfo
{ {

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
/** /**
* Class EmoticonList * Class EmoticonList

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class EmoticonListTheme extends Themelet class EmoticonListTheme extends Themelet
{ {
public function display_emotes(array $list) public function display_emotes(array $list)

View file

@ -1,4 +1,4 @@
<?php <?php declare(strict_types=1);
class ETInfo extends ExtensionInfo class ETInfo extends ExtensionInfo
{ {

Some files were not shown because too many files have changed in this diff Show more