Ran PHPStan over everything and attempted some fixes.
This commit is contained in:
parent
3a118fef15
commit
d55585372e
49 changed files with 115 additions and 195 deletions
|
@ -1,104 +0,0 @@
|
|||
Misuzu.UserRelations = {};
|
||||
Misuzu.UserRelations.Type = DefineEnum({ none: 0, follow: 1, });
|
||||
Misuzu.UserRelations.init = function() {
|
||||
var buttons = document.getElementsByClassName('js-user-relation-action');
|
||||
|
||||
for(var i = 0; i < buttons.length; ++i) {
|
||||
switch(buttons[i].tagName.toLowerCase()) {
|
||||
case 'a':
|
||||
buttons[i].removeAttribute('href');
|
||||
buttons[i].removeAttribute('target');
|
||||
buttons[i].removeAttribute('rel');
|
||||
break;
|
||||
}
|
||||
|
||||
buttons[i].addEventListener('click', Misuzu.UserRelations.setRelationHandler);
|
||||
}
|
||||
};
|
||||
Misuzu.UserRelations.setRelation = function(user, type, onSuccess, onFailure) {
|
||||
var xhr = new XMLHttpRequest;
|
||||
xhr.addEventListener('readystatechange', function() {
|
||||
if(xhr.readyState !== 4)
|
||||
return;
|
||||
|
||||
Misuzu.CSRF.setToken(xhr.getResponseHeader('X-Misuzu-CSRF'));
|
||||
|
||||
var json = JSON.parse(xhr.responseText),
|
||||
message = json.error || json.message;
|
||||
|
||||
if(message && onFailure)
|
||||
onFailure(message);
|
||||
else if(!message && onSuccess)
|
||||
onSuccess(json);
|
||||
});
|
||||
xhr.open('GET', Misuzu.Urls.format('user-relation-create', [Misuzu.Urls.v('user', user), Misuzu.Urls.v('type', type)]));
|
||||
xhr.setRequestHeader('X-Misuzu-XHR', 'user_relation');
|
||||
xhr.setRequestHeader('X-Misuzu-CSRF', Misuzu.CSRF.getToken());
|
||||
xhr.send();
|
||||
};
|
||||
Misuzu.UserRelations.ICO_ADD = 'fas fa-user-plus';
|
||||
Misuzu.UserRelations.ICO_REM = 'fas fa-user-minus';
|
||||
Misuzu.UserRelations.ICO_BUS = 'fas fa-spinner fa-pulse';
|
||||
Misuzu.UserRelations.BTN_BUS = 'input__button--busy';
|
||||
Misuzu.UserRelations.setRelationHandler = function(ev) {
|
||||
var target = this,
|
||||
userId = parseInt(target.dataset.relationUser),
|
||||
relationType = parseInt(target.dataset.relationType),
|
||||
isButton = target.classList.contains('input__button'),
|
||||
icon = target.querySelector('[class^="fa"]');
|
||||
|
||||
if(isButton) {
|
||||
if(target.classList.contains(Misuzu.UserRelations.BTN_BUS))
|
||||
return;
|
||||
target.classList.add(Misuzu.UserRelations.BTN_BUS);
|
||||
}
|
||||
|
||||
if(icon)
|
||||
icon.className = Misuzu.UserRelations.ICO_BUS;
|
||||
|
||||
Misuzu.UserRelations.setRelation(
|
||||
userId,
|
||||
relationType,
|
||||
function(info) {
|
||||
target.classList.remove(Misuzu.UserRelations.BTN_BUS);
|
||||
|
||||
switch(info.relation_type) {
|
||||
case Misuzu.UserRelations.Type.none:
|
||||
if(isButton) {
|
||||
if(target.classList.contains('input__button--destroy'))
|
||||
target.classList.remove('input__button--destroy');
|
||||
|
||||
target.textContent = 'Follow';
|
||||
}
|
||||
|
||||
if(icon) {
|
||||
icon.className = Misuzu.UserRelations.ICO_ADD;
|
||||
target.title = 'Follow';
|
||||
}
|
||||
|
||||
target.dataset.relationType = Misuzu.UserRelations.Type.follow.toString();
|
||||
break;
|
||||
|
||||
case Misuzu.UserRelations.Type.follow:
|
||||
if(isButton) {
|
||||
if(!target.classList.contains('input__button--destroy'))
|
||||
target.classList.add('input__button--destroy');
|
||||
|
||||
target.textContent = 'Unfollow';
|
||||
}
|
||||
|
||||
if(icon) {
|
||||
icon.className = Misuzu.UserRelations.ICO_REM;
|
||||
target.title = 'Unfollow';
|
||||
}
|
||||
|
||||
target.dataset.relationType = Misuzu.UserRelations.Type.none.toString();
|
||||
break;
|
||||
}
|
||||
},
|
||||
function(msg) {
|
||||
target.classList.remove(Misuzu.UserRelations.BTN_BUS);
|
||||
Misuzu.showMessageBox(msg);
|
||||
}
|
||||
);
|
||||
};
|
|
@ -242,7 +242,7 @@ if(parse_url($_SERVER['PHP_SELF'], PHP_URL_PATH) !== '/index.php')
|
|||
if(!empty($userInfo))
|
||||
Template::set('current_user', $userInfo);
|
||||
|
||||
$inManageMode = starts_with($_SERVER['REQUEST_URI'], '/manage');
|
||||
$inManageMode = str_starts_with($_SERVER['REQUEST_URI'], '/manage');
|
||||
$hasManageAccess = User::hasCurrent()
|
||||
&& !User::getCurrent()->hasActiveWarning()
|
||||
&& perms_check_user(MSZ_PERMS_GENERAL, User::getCurrent()->getId(), MSZ_PERM_GENERAL_CAN_MANAGE);
|
||||
|
|
6
phpstan.neon
Normal file
6
phpstan.neon
Normal file
|
@ -0,0 +1,6 @@
|
|||
parameters:
|
||||
level: 5
|
||||
paths:
|
||||
- src
|
||||
bootstrapFiles:
|
||||
- misuzu.php
|
|
@ -149,7 +149,7 @@ class AuditLog {
|
|||
|
||||
public static function create(string $action, array $params = [], ?User $user = null, ?string $remoteAddr = null): void {
|
||||
$user = $user ?? User::getCurrent();
|
||||
$remoteAddr = $ipAddress ?? IPAddress::remote();
|
||||
$remoteAddr = $remoteAddr ?? IPAddress::remote();
|
||||
$createLog = DB::prepare(
|
||||
'INSERT INTO `' . DB::PREFIX . self::TABLE . '` (`log_action`, `user_id`, `log_params`, `log_ip`, `log_country`)'
|
||||
. ' VALUES (:action, :user, :params, INET6_ATON(:ip), :country)'
|
||||
|
@ -162,7 +162,7 @@ class AuditLog {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countAll(?User $user = null): int {
|
||||
$getCount = DB::prepare(
|
||||
|
|
|
@ -65,7 +65,7 @@ class AuthToken {
|
|||
}
|
||||
|
||||
public static function unpack(string $data, bool $base64 = true): self {
|
||||
$obj = new static;
|
||||
$obj = new AuthToken;
|
||||
|
||||
if(empty($data))
|
||||
return $obj;
|
||||
|
@ -83,7 +83,7 @@ class AuthToken {
|
|||
}
|
||||
|
||||
public static function create(User $user, UserSession $session): self {
|
||||
return (new static)
|
||||
return (new AuthToken)
|
||||
->setUser($user)
|
||||
->setSession($session);
|
||||
}
|
||||
|
|
|
@ -183,7 +183,7 @@ class ChangelogChange implements JsonSerializable {
|
|||
return [
|
||||
'id' => $this->getId(),
|
||||
'user' => $this->getUserId(),
|
||||
'action' => $this->getActionId(),
|
||||
'action' => $this->getAction(),
|
||||
'header' => $this->getHeader(),
|
||||
'body' => $this->getBody(),
|
||||
'comments' => $this->getCommentsCategoryName(),
|
||||
|
|
|
@ -78,7 +78,7 @@ class ChangelogChangeTag implements JsonSerializable {
|
|||
private static function byQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf(self::SELECT, self::TABLE));
|
||||
}
|
||||
public static function byExact(ChangelogChange $change, ChangelogTag $tag): array {
|
||||
public static function byExact(ChangelogChange $change, ChangelogTag $tag): self {
|
||||
$tag = DB::prepare(self::byQueryBase() . ' WHERE `tag_id` = :tag')
|
||||
->bind('change', $change->getId())
|
||||
->bind('tag', $tag->getId())
|
||||
|
|
|
@ -18,14 +18,14 @@ class Colour {
|
|||
}
|
||||
|
||||
public static function none(): self {
|
||||
return new static(self::FLAG_INHERIT);
|
||||
return new Colour(self::FLAG_INHERIT);
|
||||
}
|
||||
|
||||
public static function fromRgb(int $red, int $green, int $blue): self {
|
||||
return (new static)->setRed($red)->setGreen($green)->setBlue($blue);
|
||||
return (new Colour)->setRed($red)->setGreen($green)->setBlue($blue);
|
||||
}
|
||||
public static function fromHex(string $hex): self {
|
||||
return (new static)->setHex($hex);
|
||||
return (new Colour)->setHex($hex);
|
||||
}
|
||||
|
||||
public function getRaw(): int {
|
||||
|
@ -99,7 +99,7 @@ class Colour {
|
|||
return $this;
|
||||
}
|
||||
|
||||
public function getLuminance(): int {
|
||||
public function getLuminance(): float {
|
||||
return self::LUMINANCE_WEIGHT_RED * $this->getRed()
|
||||
+ self::LUMINANCE_WEIGHT_GREEN * $this->getGreen()
|
||||
+ self::LUMINANCE_WEIGHT_BLUE * $this->getBlue();
|
||||
|
|
|
@ -128,7 +128,7 @@ class CommentsVote implements JsonSerializable {
|
|||
}
|
||||
|
||||
private static function fake(CommentsPost $post, User $user, int $vote): CommentsVote {
|
||||
$fake = new static;
|
||||
$fake = new CommentsVote;
|
||||
$fake->comment_id = $post->getId();
|
||||
$fake->comment = $post;
|
||||
$fake->user_id = $user->getId();
|
||||
|
|
|
@ -4,6 +4,14 @@ namespace Misuzu;
|
|||
use PDO;
|
||||
use Misuzu\Database\Database;
|
||||
|
||||
/**
|
||||
* @method static PDO getPDO()
|
||||
* @method static int queries()
|
||||
* @method static int exec(string $stmt)
|
||||
* @method static \Misuzu\Database\DatabaseStatement prepare(string $stmt, array $options = [])
|
||||
* @method static \Misuzu\Database\DatabaseStatement query(string $stmt, ?int $fetchMode = null, ...$args)
|
||||
* @method static int lastId()
|
||||
*/
|
||||
final class DB {
|
||||
private static $instance;
|
||||
|
||||
|
|
|
@ -1,7 +1,14 @@
|
|||
<?php
|
||||
namespace Misuzu;
|
||||
|
||||
use InvalidArgumentException;
|
||||
|
||||
final class Emoticon {
|
||||
private int $emote_id;
|
||||
private int $emote_order;
|
||||
private int $emote_hierarchy;
|
||||
private string $emote_url;
|
||||
|
||||
public const ALL = PHP_INT_MAX;
|
||||
|
||||
public function __construct() {
|
||||
|
@ -132,7 +139,7 @@ final class Emoticon {
|
|||
|
||||
public static function byId(int $emoteId): self {
|
||||
if($emoteId < 1)
|
||||
return [];
|
||||
throw new InvalidArgumentException('$emoteId is not a valid emoticon id.');
|
||||
|
||||
$getEmote = DB::prepare('
|
||||
SELECT `emote_id`, `emote_order`, `emote_hierarchy`, `emote_url`
|
||||
|
|
|
@ -70,8 +70,6 @@ class Feed {
|
|||
return count($this->feedItems) > 0;
|
||||
}
|
||||
public function addItem(FeedItem $item): self {
|
||||
if($item === null)
|
||||
throw new InvalidArgumentException('item may not be null');
|
||||
$this->feedItems[] = $item;
|
||||
return $this;
|
||||
}
|
||||
|
|
|
@ -238,9 +238,8 @@ function forum_get_child_ids(int $forumId): array {
|
|||
}
|
||||
|
||||
function forum_topics_unread(int $forumId, int $userId): int {
|
||||
if($userId < 1 || $forumId < 1) {
|
||||
return false;
|
||||
}
|
||||
if($userId < 1 || $forumId < 1)
|
||||
return 0;
|
||||
|
||||
static $memoized = [];
|
||||
$memoId = "{$forumId}-{$userId}";
|
||||
|
|
|
@ -308,7 +308,7 @@ function forum_post_can_delete($postId, ?int $userId = null): int {
|
|||
return MSZ_E_FORUM_POST_DELETE_OWNER;
|
||||
}
|
||||
|
||||
if(strtotime($post['post_created']) <= time() - MSZ_FORUM_POST_DELETE_LIMIT) {
|
||||
if(strtotime($post['post_created']) <= (time() - MSZ_FORUM_POST_DELETE_LIMIT)) {
|
||||
return MSZ_E_FORUM_POST_DELETE_OLD;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -575,7 +575,7 @@ function forum_topic_can_delete($topicId, ?int $userId = null): int {
|
|||
return MSZ_E_FORUM_TOPIC_DELETE_OWNER;
|
||||
}
|
||||
|
||||
if(strtotime($topic['topic_created']) <= time() - MSZ_FORUM_TOPIC_DELETE_TIME_LIMIT) {
|
||||
if(strtotime($topic['topic_created']) <= (time() - MSZ_FORUM_TOPIC_DELETE_TIME_LIMIT)) {
|
||||
return MSZ_E_FORUM_TOPIC_DELETE_OLD;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ class ChangelogHandler extends Handler {
|
|||
if($filterDate !== null)
|
||||
try {
|
||||
$dateParts = explode('-', $filterDate, 3);
|
||||
$filterDate = gmmktime(12, 0, 0, $dateParts[1], $dateParts[2], $dateParts[0]);
|
||||
$filterDate = gmmktime(12, 0, 0, intval($dateParts[1]), intval($dateParts[2]), intval($dateParts[0]));
|
||||
} catch(ErrorException $ex) {
|
||||
return 404;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ final class ForumHandler extends Handler {
|
|||
$forumId = (int)$request->getQueryParam('forum', FILTER_SANITIZE_NUMBER_INT);
|
||||
$response->setTemplate('confirm', [
|
||||
'title' => 'Mark forum as read',
|
||||
'message' => 'Are you sure you want to mark ' . ($forumId === null ? 'the entire' : 'this') . ' forum as read?',
|
||||
'message' => 'Are you sure you want to mark ' . ($forumId === 0 ? 'the entire' : 'this') . ' forum as read?',
|
||||
'return' => url($forumId ? 'forum-category' : 'forum-index', ['forum' => $forumId]),
|
||||
'params' => [
|
||||
'forum' => $forumId,
|
||||
|
|
|
@ -20,7 +20,7 @@ final class InfoHandler extends Handler {
|
|||
'title' => '',
|
||||
];
|
||||
|
||||
$isMisuzuDoc = $name === 'misuzu' || starts_with($name, 'misuzu/');
|
||||
$isMisuzuDoc = $name === 'misuzu' || str_starts_with($name, 'misuzu/');
|
||||
|
||||
if($isMisuzuDoc) {
|
||||
$filename = substr($name, 7);
|
||||
|
@ -41,8 +41,8 @@ final class InfoHandler extends Handler {
|
|||
if(empty($document['content']))
|
||||
return 404;
|
||||
|
||||
if(empty($document['title'])) {
|
||||
if(starts_with($document['content'], '# ')) {
|
||||
if($document['title'] === '') {
|
||||
if(str_starts_with($document['content'], '# ')) {
|
||||
$titleOffset = strpos($document['content'], "\n");
|
||||
$document['title'] = trim(substr($document['content'], 2, $titleOffset - 1));
|
||||
$document['content'] = substr($document['content'], $titleOffset);
|
||||
|
|
|
@ -13,7 +13,7 @@ use Misuzu\Feeds\RssFeedSerializer;
|
|||
use Misuzu\News\NewsCategory;
|
||||
use Misuzu\News\NewsPost;
|
||||
use Misuzu\News\NewsCategoryNotFoundException;
|
||||
use Misuzu\News\NewsPostNotException;
|
||||
use Misuzu\News\NewsPostNotFoundException;
|
||||
use Misuzu\Parsers\Parser;
|
||||
use Misuzu\Users\User;
|
||||
|
||||
|
|
|
@ -67,12 +67,14 @@ final class SockChatHandler extends Handler {
|
|||
|
||||
$body = $request->getParsedBody();
|
||||
|
||||
if(isset($body['bump'], $body['hash']) && is_string($body['bump']) && is_string($body['hash']))
|
||||
return $this->bump(
|
||||
if(isset($body['bump'], $body['hash']) && is_string($body['bump']) && is_string($body['hash'])) {
|
||||
$this->bump(
|
||||
$response,
|
||||
$request->setHeader('X-SharpChat-Signature', $body['hash'])
|
||||
->setBody(Stream::create($body['bump']))
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$source = isset($body['user_id']) ? $body : $query;
|
||||
|
||||
|
@ -381,9 +383,10 @@ final class SockChatHandler extends Handler {
|
|||
$userInfo = User::byUsername($param);
|
||||
break;
|
||||
}
|
||||
} catch(UserNotFoundException $ex) {
|
||||
} catch(UserNotFoundException $ex) {}
|
||||
|
||||
if(!isset($userInfo))
|
||||
return [];
|
||||
}
|
||||
|
||||
return [
|
||||
'user_id' => $userInfo->getId(),
|
||||
|
|
|
@ -16,7 +16,7 @@ class AcceptHttpHeaderChild implements HasQualityInterface {
|
|||
if(isset($parts[1])) {
|
||||
$split = explode('=', $parts[1], 2);
|
||||
if($split[0] === 'q' && isset($split[1]))
|
||||
$this->quality = max(min(round(filter_var($split[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION) ?? 1, 2), 1), 0);
|
||||
$this->quality = max(min(round((float)filter_var($split[1], FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION), 2), 1), 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -52,7 +52,7 @@ class HttpHeader {
|
|||
case 'TE':
|
||||
return new AcceptHttpHeader($name, $line);
|
||||
default:
|
||||
return new static($name, $line);
|
||||
return new HttpHeader($name, $line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -190,7 +190,7 @@ class HttpRequestMessage extends HttpMessage {
|
|||
}
|
||||
}
|
||||
|
||||
if(!isset($headers['Authorization'])) {
|
||||
if(empty($headers['Authorization'])) {
|
||||
if(isset($_SERVER['REDIRECT_HTTP_AUTHORIZATION'])) {
|
||||
$headers['Authorization'] = $_SERVER['REDIRECT_HTTP_AUTHORIZATION'];
|
||||
} elseif(isset($_SERVER['PHP_AUTH_USER'])) {
|
||||
|
|
|
@ -131,7 +131,6 @@ class HttpResponseMessage extends HttpMessage {
|
|||
414 => 'URI Too Long',
|
||||
416 => 'Range Not Satisfiable',
|
||||
417 => 'Expectation Failed',
|
||||
417 => 'Expectation Failed',
|
||||
418 => 'I\'m a teapot',
|
||||
421 => 'Misdirected Request',
|
||||
422 => 'Unprocessable Entity',
|
||||
|
|
|
@ -23,7 +23,7 @@ class Route {
|
|||
}
|
||||
|
||||
public static function create(array $methods, string $path, ?string $method = null, ?string $class = null): self {
|
||||
return new static($methods, $path, $method, $class);
|
||||
return new Route($methods, $path, $method, $class);
|
||||
}
|
||||
public static function get(string $path, ?string $method = null, ?string $class = null): self {
|
||||
return self::create(['GET'], $path, $method, $class);
|
||||
|
|
|
@ -21,7 +21,7 @@ class Router {
|
|||
if($name[0] === '_')
|
||||
return null;
|
||||
if(self::$instance === null)
|
||||
(new static)->setInstance();
|
||||
(new Router)->setInstance();
|
||||
return self::$instance->{'_' . $name}(...$args);
|
||||
}
|
||||
|
||||
|
@ -92,7 +92,7 @@ class Router {
|
|||
|
||||
$handlerMethod = $route->getHandlerMethod();
|
||||
if(is_callable($handlerMethod)) {
|
||||
$result = call_user_func_array($handlerMethod, $args);
|
||||
$result = call_user_func_array($handlerMethod, $matches);
|
||||
} elseif($handlerMethod[0] === '/') {
|
||||
$response->redirect($handlerMethod);
|
||||
} else {
|
||||
|
|
|
@ -38,7 +38,7 @@ class UploadedFile {
|
|||
$this->stream = $fileNameOrStream;
|
||||
|
||||
if($size === null && $this->stream !== null)
|
||||
$this->size = $stream->getSize();
|
||||
$this->size = $this->stream->getSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ class UploadedFile {
|
|||
throw new RuntimeException('Can\'t open stream because of an upload error.');
|
||||
if($this->hasMoved)
|
||||
throw new RuntimeException('Can\'t open stream because file has already been moved.');
|
||||
if($this->steam === null)
|
||||
if($this->stream === null)
|
||||
$this->stream = Stream::createFromFile($this->fileName);
|
||||
|
||||
return $this->stream;
|
||||
|
@ -97,7 +97,7 @@ class UploadedFile {
|
|||
}
|
||||
|
||||
public static function createFromFILE(array $file): self {
|
||||
return new static(
|
||||
return new UploadedFile(
|
||||
$file['tmp_name'] ?? '',
|
||||
$file['error'] ?? UPLOAD_ERR_NO_FILE,
|
||||
$file['size'] ?? null,
|
||||
|
|
|
@ -26,7 +26,7 @@ final class GdImage extends Image {
|
|||
];
|
||||
|
||||
public function __construct($pathOrWidth, int $height = -1) {
|
||||
parent::__construct($pathOrWidth, $height);
|
||||
parent::__construct($pathOrWidth);
|
||||
|
||||
if(is_int($pathOrWidth)) {
|
||||
$this->gd = imagecreatetruecolor($pathOrWidth, $height < 1 ? $pathOrWidth : $height);
|
||||
|
|
|
@ -5,7 +5,7 @@ use InvalidArgumentException;
|
|||
use UnexpectedValueException;
|
||||
|
||||
abstract class Image {
|
||||
public function __construct($pathOrWidth, int $height = -1) {
|
||||
public function __construct($pathOrWidth) {
|
||||
if(!is_int($pathOrWidth) && !is_string($pathOrWidth))
|
||||
throw new InvalidArgumentException('The first argument must be or type string to open an image file, or int to set a width for a new image.');
|
||||
}
|
||||
|
|
|
@ -8,12 +8,12 @@ final class ImagickImage extends Image {
|
|||
private ?Imagick $imagick = null;
|
||||
|
||||
public function __construct($pathOrWidth, int $height = -1) {
|
||||
parent::__construct($pathOrWidth, $height);
|
||||
parent::__construct($pathOrWidth);
|
||||
|
||||
if(is_int($pathOrWidth)) {
|
||||
$this->imagick = new Imagick();
|
||||
$this->newImage($pathOrWidth, $height < 1 ? $pathOrWidth : $height, 'none');
|
||||
$this->setImageFormat('png');
|
||||
$this->imagick->newImage($pathOrWidth, $height < 1 ? $pathOrWidth : $height, 'none');
|
||||
$this->imagick->setImageFormat('png');
|
||||
} elseif(is_string($pathOrWidth)) {
|
||||
$imagick = new Imagick($pathOrWidth);
|
||||
$imagick->setImageFormat($imagick->getNumberImages() > 1 ? 'gif' : 'png');
|
||||
|
|
|
@ -14,6 +14,9 @@ final class Mailer {
|
|||
private static $dsn = 'null://null';
|
||||
private static $transport = null;
|
||||
|
||||
private static string $senderName = 'Flashii';
|
||||
private static string $senderAddr = 'sys@flashii.net';
|
||||
|
||||
public static function init(string $method, array $config): void {
|
||||
if($method !== 'smtp') {
|
||||
self::$dsn = 'null://null';
|
||||
|
@ -42,6 +45,12 @@ final class Mailer {
|
|||
$dsn .= $config['port'] ?? 25;
|
||||
|
||||
self::$dsn = $dsn;
|
||||
|
||||
if(!empty($config['sender_name']))
|
||||
self::$senderName = $config['sender_name'];
|
||||
|
||||
if(!empty($config['sender_addr']))
|
||||
self::$senderAddr = $config['sender_addr'];
|
||||
}
|
||||
|
||||
public static function getTransport() {
|
||||
|
@ -59,8 +68,8 @@ final class Mailer {
|
|||
$message = new SymfonyMessage;
|
||||
|
||||
$message->from(new SymfonyAddress(
|
||||
$config['sender_addr'] ?? 'sys@flashii.net',
|
||||
$config['sender_name'] ?? 'Flashii'
|
||||
self::$senderAddr,
|
||||
self::$senderName
|
||||
));
|
||||
|
||||
if($bcc)
|
||||
|
|
|
@ -68,7 +68,7 @@ class MediaType implements HasQualityInterface {
|
|||
}
|
||||
public function matchPattern(string $pattern): bool {
|
||||
try {
|
||||
$mediaType = new static($pattern);
|
||||
$mediaType = new MediaType($pattern);
|
||||
} catch(InvalidArgumentException $ex) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -27,7 +27,7 @@ final class Pagination {
|
|||
}
|
||||
|
||||
public function getPages(): int {
|
||||
return ceil($this->getCount() / $this->getRange());
|
||||
return (int)ceil($this->getCount() / $this->getRange());
|
||||
}
|
||||
|
||||
public function hasValidOffset(): bool {
|
||||
|
@ -50,7 +50,7 @@ final class Pagination {
|
|||
if($this->getOffset() < 1)
|
||||
return self::START_PAGE;
|
||||
|
||||
return floor($this->getOffset() / $this->getRange()) + self::START_PAGE;
|
||||
return (int)floor($this->getOffset() / $this->getRange()) + self::START_PAGE;
|
||||
}
|
||||
|
||||
public function setPage(int $page, bool $zeroBased = false): self {
|
||||
|
@ -70,7 +70,7 @@ final class Pagination {
|
|||
$source ??= $_GET;
|
||||
|
||||
if(isset($source[$name]) && is_string($source[$name]) && ctype_digit($source[$name]))
|
||||
return $source[$name];
|
||||
return intval($source[$name]);
|
||||
|
||||
return $default;
|
||||
}
|
||||
|
|
|
@ -47,7 +47,7 @@ class Stream {
|
|||
if($contents instanceof Stream)
|
||||
return $contents;
|
||||
|
||||
return new static($contents);
|
||||
return new Stream($contents);
|
||||
}
|
||||
public static function createFromFile(string $filename, string $mode = 'rb'): Stream {
|
||||
if(!in_array($mode[0], ['r', 'w', 'a', 'x', 'c']))
|
||||
|
@ -79,9 +79,9 @@ class Stream {
|
|||
return $this->readable;
|
||||
}
|
||||
|
||||
public function read($length): int {
|
||||
public function read($length): string {
|
||||
if(!$this->isReadable())
|
||||
throw RuntimeException('Can\'t read from this stream.');
|
||||
throw new RuntimeException('Can\'t read from this stream.');
|
||||
|
||||
return fread($this->stream, $length);
|
||||
}
|
||||
|
|
|
@ -32,6 +32,6 @@ class TOTP {
|
|||
$bin |= (ord($hash[$offset + 3]) & 0xFF);
|
||||
$otp = $bin % pow(10, self::DIGITS);
|
||||
|
||||
return str_pad($otp, self::DIGITS, STR_PAD_LEFT);
|
||||
return str_pad(strval($otp), self::DIGITS, '0', STR_PAD_LEFT);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ final class Template {
|
|||
define('MSZ_TPL_RENDER', microtime(true));
|
||||
}
|
||||
|
||||
if(!ends_with($file, self::FILE_EXT)) {
|
||||
if(!str_ends_with($file, self::FILE_EXT)) {
|
||||
$file = str_replace('.', DIRECTORY_SEPARATOR, $file) . self::FILE_EXT;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ class UserAvatarAsset extends UserImageAsset implements UserAssetScalableInterfa
|
|||
}
|
||||
public function getScaledFileExtension(int $dims): string {
|
||||
$imageSize = getimagesize($this->getScaledPath($dims));
|
||||
if($imageSize === null)
|
||||
if($imageSize === false)
|
||||
return 'img';
|
||||
return self::TYPES_EXT[$imageSize[2]] ?? 'img';
|
||||
}
|
||||
|
|
|
@ -94,7 +94,7 @@ class UserBackgroundAsset extends UserImageAsset {
|
|||
return $this;
|
||||
}
|
||||
public function isBlend(): bool {
|
||||
return $this->getAttributes() & self::ATTRIB_BLEND;
|
||||
return ($this->getAttributes() & self::ATTRIB_BLEND) > 0;
|
||||
}
|
||||
public function setBlend(bool $blend): self {
|
||||
$this->getUser()->setBackgroundSettings(
|
||||
|
@ -105,7 +105,7 @@ class UserBackgroundAsset extends UserImageAsset {
|
|||
return $this;
|
||||
}
|
||||
public function isSlide(): bool {
|
||||
return $this->getAttributes() & self::ATTRIB_SLIDE;
|
||||
return ($this->getAttributes() & self::ATTRIB_SLIDE) > 0;
|
||||
}
|
||||
public function setSlide(bool $slide): self {
|
||||
$this->getUser()->setBackgroundSettings(
|
||||
|
|
|
@ -120,7 +120,7 @@ abstract class UserImageAsset implements JsonSerializable, UserImageAssetInterfa
|
|||
|
||||
public function setFromData(string $data): void {
|
||||
$file = tempnam(sys_get_temp_dir(), 'msz');
|
||||
if($file === null || !is_file($file))
|
||||
if($file === false || !is_file($file))
|
||||
throw new UserImageAssetFileCreationFailedException;
|
||||
chmod($file, 0664);
|
||||
file_put_contents($file, $data);
|
||||
|
|
|
@ -790,7 +790,7 @@ class User implements HasRankInterface, JsonSerializable {
|
|||
************/
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countAll(bool $showDeleted = false): int {
|
||||
return (int)DB::prepare(
|
||||
|
|
|
@ -93,7 +93,7 @@ class UserLoginAttempt {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countAll(?User $user = null): int {
|
||||
$getCount = DB::prepare(
|
||||
|
|
|
@ -83,7 +83,7 @@ class UserRole implements ArrayAccess, HasRankInterface {
|
|||
public function getCanLeave(): bool {
|
||||
return boolval($this->role_can_leave);
|
||||
}
|
||||
public function setCanLeave(bool $canLeave): bool {
|
||||
public function setCanLeave(bool $canLeave): self {
|
||||
$this->role_can_leave = $canLeave ? 1 : 0;
|
||||
return $this;
|
||||
}
|
||||
|
@ -159,7 +159,7 @@ class UserRole implements ArrayAccess, HasRankInterface {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countAll(bool $showHidden = false): int {
|
||||
return (int)DB::prepare(
|
||||
|
|
|
@ -60,7 +60,7 @@ class UserRoleRelation {
|
|||
->execute();
|
||||
|
||||
// data is predictable, just create a "fake"
|
||||
$object = new static;
|
||||
$object = new UserRoleRelation;
|
||||
$object->user = $user;
|
||||
$object->user_id = $user->getId();
|
||||
$object->role = $role;
|
||||
|
@ -69,7 +69,7 @@ class UserRoleRelation {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countUsers(UserRole $role): int {
|
||||
return (int)DB::prepare(self::countQueryBase() . ' WHERE `role_id` = :role')
|
||||
|
|
|
@ -199,7 +199,7 @@ class UserSession {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countAll(?User $user = null): int {
|
||||
$getCount = DB::prepare(
|
||||
|
|
|
@ -197,7 +197,7 @@ class UserWarning {
|
|||
}
|
||||
|
||||
private static function countQueryBase(): string {
|
||||
return sprintf(self::QUERY_SELECT, sprintf('COUNT(*)', self::TABLE));
|
||||
return sprintf(self::QUERY_SELECT, 'COUNT(*)');
|
||||
}
|
||||
public static function countByRemoteAddress(?string $address = null, bool $withDuration = true): int {
|
||||
$address = $address ?? IPAddress::remote();
|
||||
|
|
|
@ -86,6 +86,7 @@ final class Zalgo {
|
|||
continue;
|
||||
|
||||
$str .= $char;
|
||||
$num_up = $num_mid = $num_down = 0;
|
||||
|
||||
switch($mode) {
|
||||
case self::MODE_MINI:
|
||||
|
|
|
@ -74,17 +74,15 @@ function perms_get_key(string $prefix, string $suffix): string {
|
|||
function perms_get_select(array $modes = MSZ_PERM_MODES, string $allow = MSZ_PERMS_ALLOW, string $deny = MSZ_PERMS_DENY): string {
|
||||
$select = '';
|
||||
|
||||
if(empty($select)) {
|
||||
foreach($modes as $mode) {
|
||||
$select .= sprintf(
|
||||
'(BIT_OR(`%1$s_perms_%2$s`) &~ BIT_OR(`%1$s_perms_%3$s`)) AS `%1$s`,',
|
||||
$mode, $allow, $deny
|
||||
);
|
||||
}
|
||||
|
||||
$select = substr($select, 0, -1);
|
||||
foreach($modes as $mode) {
|
||||
$select .= sprintf(
|
||||
'(BIT_OR(`%1$s_perms_%2$s`) &~ BIT_OR(`%1$s_perms_%3$s`)) AS `%1$s`,',
|
||||
$mode, $allow, $deny
|
||||
);
|
||||
}
|
||||
|
||||
$select = substr($select, 0, -1);
|
||||
|
||||
return $select;
|
||||
}
|
||||
|
||||
|
|
12
src/url.php
12
src/url.php
|
@ -132,7 +132,7 @@ function url(string $name, array $variables = []): string {
|
|||
|
||||
$info = MSZ_URLS[$name];
|
||||
|
||||
if(!is_string($info[0] ?? null)) {
|
||||
if(!isset($info[0]) || !is_string($info[0])) {
|
||||
return '';
|
||||
}
|
||||
|
||||
|
@ -175,13 +175,13 @@ function url_redirect(string $name, array $variables = []): void {
|
|||
}
|
||||
|
||||
function url_variable(string $value, array $variables): string {
|
||||
if(starts_with($value, '<') && ends_with($value, '>'))
|
||||
if(str_starts_with($value, '<') && str_ends_with($value, '>'))
|
||||
return $variables[trim($value, '<>')] ?? '';
|
||||
|
||||
if(starts_with($value, '[') && ends_with($value, ']'))
|
||||
if(str_starts_with($value, '[') && str_ends_with($value, ']'))
|
||||
return constant(trim($value, '[]'));
|
||||
|
||||
if(starts_with($value, '{') && ends_with($value, '}'))
|
||||
if(str_starts_with($value, '{') && str_ends_with($value, '}'))
|
||||
return \Misuzu\CSRF::token();
|
||||
|
||||
// Hack that allows variables with file extensions
|
||||
|
@ -201,7 +201,7 @@ function url_list(): array {
|
|||
$collection = [];
|
||||
|
||||
foreach(MSZ_URLS as $name => $urlInfo) {
|
||||
if(empty($hasManageAccess) && starts_with($name, 'manage-'))
|
||||
if(empty($hasManageAccess) && str_starts_with($name, 'manage-'))
|
||||
continue;
|
||||
|
||||
$item = [
|
||||
|
@ -271,5 +271,5 @@ function is_local_url(string $url): bool {
|
|||
if($url[0] === '/' && ($length > 1 ? $url[1] !== '/' : true))
|
||||
return true;
|
||||
|
||||
return starts_with($url, url_prefix());
|
||||
return str_starts_with($url, url_prefix());
|
||||
}
|
||||
|
|
12
utility.php
12
utility.php
|
@ -33,16 +33,12 @@ function clamp($num, int $min, int $max): int {
|
|||
return max($min, min($max, intval($num)));
|
||||
}
|
||||
|
||||
function starts_with(string $string, string $text, bool $multibyte = true): bool {
|
||||
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
|
||||
$substr = $multibyte ? 'mb_substr' : 'substr';
|
||||
return $substr($string, 0, $strlen($text)) === $text;
|
||||
function starts_with(string $string, string $text): bool {
|
||||
return str_starts_with($string, $text);
|
||||
}
|
||||
|
||||
function ends_with(string $string, string $text, bool $multibyte = true): bool {
|
||||
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
|
||||
$substr = $multibyte ? 'mb_substr' : 'substr';
|
||||
return $substr($string, 0 - $strlen($text)) === $text;
|
||||
function ends_with(string $string, string $text): bool {
|
||||
return str_ends_with($string, $text);
|
||||
}
|
||||
|
||||
function first_paragraph(string $text, string $delimiter = "\n"): string {
|
||||
|
|
Loading…
Add table
Reference in a new issue