From 027ed5aff6ced615a92a21b9ac171bd714fd4656 Mon Sep 17 00:00:00 2001 From: flashwave Date: Wed, 5 Jul 2023 01:33:12 +0000 Subject: [PATCH] Cleaned up various utility functions. --- lib/index | 2 +- public/manage/changelog/change.php | 8 ++- public/manage/users/user.php | 13 +++-- public/manage/users/warnings.php | 16 ++++-- src/AuthToken.php | 15 +++++- src/Forum/perms.php | 12 ++++- src/Memoizer.php | 3 +- src/News/NewsPost.php | 4 +- src/TwigMisuzu.php | 1 - src/Users/User.php | 3 +- src/Zalgo.php | 3 +- templates/forum/macros.twig | 6 ++- utility.php | 83 ------------------------------ 13 files changed, 63 insertions(+), 106 deletions(-) diff --git a/lib/index b/lib/index index bce5ba7..8f908d7 160000 --- a/lib/index +++ b/lib/index @@ -1 +1 @@ -Subproject commit bce5ba77a268ecd6338d0e3520e41ff4c40cbeda +Subproject commit 8f908d7f688bd95fdedd868c5bf8d25a3b500b99 diff --git a/public/manage/changelog/change.php b/public/manage/changelog/change.php index 5c82419..faaee59 100644 --- a/public/manage/changelog/change.php +++ b/public/manage/changelog/change.php @@ -68,12 +68,16 @@ if($_SERVER['REQUEST_METHOD'] === 'POST' && CSRF::validateRequest()) { ); } - if(isset($change) && !empty($_POST['tags']) && is_array($_POST['tags']) && array_test($_POST['tags'], 'ctype_digit')) { + if(isset($change) && !empty($_POST['tags']) && is_array($_POST['tags'])) { $applyTags = []; - foreach($_POST['tags'] as $tagId) + foreach($_POST['tags'] as $tagId) { + if(!ctype_digit($tagId)) + die('Invalid item encountered in roles list.'); + try { $applyTags[] = ChangelogTag::byId((int)filter_var($tagId, FILTER_SANITIZE_NUMBER_INT)); } catch(ChangelogTagNotFoundException $ex) {} + } $change->setTags($applyTags); } diff --git a/public/manage/users/user.php b/public/manage/users/user.php index 7f7ab2d..5d41ebb 100644 --- a/public/manage/users/user.php +++ b/public/manage/users/user.php @@ -61,16 +61,21 @@ if(CSRF::validateRequest() && $canEdit) { } } - if(!empty($_POST['roles']) && is_array($_POST['roles']) && array_test($_POST['roles'], 'ctype_digit')) { + if(!empty($_POST['roles']) && is_array($_POST['roles'])) { + // Read user input array and throw intval on em + $applyRoles = []; + foreach($_POST['roles'] as $item) { + if(!ctype_digit($item)) + die('Invalid item encountered in roles list.'); + $applyRoles[] = (int)$item; + } + // Fetch existing roles $existingRoles = $userInfo->getRoles(); // Initialise set array with existing roles $setRoles = $existingRoles; - // Read user input array and throw intval on em - $applyRoles = array_apply($_POST['roles'], 'intval'); - // Storage array for roles to dump $removeRoles = []; diff --git a/public/manage/users/warnings.php b/public/manage/users/warnings.php index 215ccbf..ee88525 100644 --- a/public/manage/users/warnings.php +++ b/public/manage/users/warnings.php @@ -50,12 +50,18 @@ if(!empty($_POST['warning']) && is_array($_POST['warning'])) { if(!empty($customDuration)) { switch($warningDuration) { case -100: // YYYY-MM-DD - $splitDate = array_apply(explode('-', $customDuration, 3), function ($a) { - return (int)$a; - }); + $splitDate = explode('-', $customDuration, 3); + if(count($splitDate) !== 3) + die('Invalid date specified.'); - if(checkdate($splitDate[1], $splitDate[2], $splitDate[0])) - $warningDuration = mktime(0, 0, 0, $splitDate[1], $splitDate[2], $splitDate[0]) - time(); + $wYear = (int)$splitDate[0]; + $wMonth = (int)$splitDate[1]; + $wDay = (int)$splitDate[2]; + + if(checkdate($wMonth, $wDay, $wYear)) + $warningDuration = mktime(0, 0, 0, $wMonth, $wDay, $wYear) - time(); + else + die('Invalid date specified.'); break; case -200: // Raw seconds diff --git a/src/AuthToken.php b/src/AuthToken.php index 56cf571..f51f17f 100644 --- a/src/AuthToken.php +++ b/src/AuthToken.php @@ -173,17 +173,28 @@ class AuthToken { return $token; } + public static function cookieDomain(bool $compatible = true): string { + $url = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST); + if(empty($url)) + $url = $_SERVER['HTTP_HOST']; + + if(!filter_var($url, FILTER_VALIDATE_IP) && $compatible) + $url = '.' . $url; + + return $url; + } + public function applyCookie(int $expires = 0): void { if($expires > 0) $this->cookieExpires = $expires; else $expires = $this->cookieExpires; - setcookie('msz_auth', $this->pack(), $expires, '/', msz_cookie_domain(), !empty($_SERVER['HTTPS']), true); + setcookie('msz_auth', $this->pack(), $expires, '/', self::cookieDomain(), !empty($_SERVER['HTTPS']), true); } public static function nukeCookie(): void { - setcookie('msz_auth', '', -9001, '/', msz_cookie_domain(), !empty($_SERVER['HTTPS']), true); + setcookie('msz_auth', '', -9001, '/', self::cookieDomain(), !empty($_SERVER['HTTPS']), true); setcookie('msz_auth', '', -9001, '/', '', !empty($_SERVER['HTTPS']), true); } diff --git a/src/Forum/perms.php b/src/Forum/perms.php index a574cc4..9d91a84 100644 --- a/src/Forum/perms.php +++ b/src/Forum/perms.php @@ -87,7 +87,11 @@ function forum_perms_get_user(?int $forum, int $user): array { $getPerms->bind('user_id_1', $user); $getPerms->bind('user_id_2', $user); - return $memo[$memoId] = array_bit_or($perms, $getPerms->fetch()); + $userPerms = $getPerms->fetch(); + foreach($perms as $key => $value) + $perms[$key] |= $userPerms[$key] ?? 0; + + return $memo[$memoId] = $perms; } function forum_perms_get_role(?int $forum, int $role): array { @@ -124,7 +128,11 @@ function forum_perms_get_role(?int $forum, int $role): array { $getPerms->bind('forum_id', $forum); $getPerms->bind('role_id', $role); - return $memo[$memoId] = array_bit_or($perms, $getPerms->fetch()); + $userPerms = $getPerms->fetch(); + foreach($perms as $key => $value) + $perms[$key] |= $userPerms[$key] ?? 0; + + return $memo[$memoId] = $perms; } function forum_perms_get_user_raw(?int $forum, int $user): array { diff --git a/src/Memoizer.php b/src/Memoizer.php index 40f7af5..fa0f419 100644 --- a/src/Memoizer.php +++ b/src/Memoizer.php @@ -2,6 +2,7 @@ namespace Misuzu; use InvalidArgumentException; +use Index\XArray; // get rid of this garbage as soon as possible @@ -16,7 +17,7 @@ class Memoizer { } if(is_callable($find)) { - $item = array_find($this->collection, $find) ?? $create(); + $item = XArray::first($this->collection, $find) ?? $create(); if(method_exists($item, 'getId')) $this->collection[$item->getId()] = $item; else diff --git a/src/News/NewsPost.php b/src/News/NewsPost.php index 01631b7..17907bc 100644 --- a/src/News/NewsPost.php +++ b/src/News/NewsPost.php @@ -128,7 +128,9 @@ class NewsPost implements JsonSerializable { return Parser::instance(Parser::MARKDOWN)->parseText($this->getText()); } public function getFirstParagraph(): string { - return first_paragraph($this->getText()); + $text = $this->getText(); + $index = mb_strpos($text, "\n"); + return $index === false ? $text : mb_substr($text, 0, $index); } public function getParsedFirstParagraph(): string { return Parser::instance(Parser::MARKDOWN)->parseText($this->getFirstParagraph()); diff --git a/src/TwigMisuzu.php b/src/TwigMisuzu.php index 9d739c3..af77cd2 100644 --- a/src/TwigMisuzu.php +++ b/src/TwigMisuzu.php @@ -23,7 +23,6 @@ final class TwigMisuzu extends AbstractExtension { new TwigFilter('byte_symbol', 'byte_symbol'), new TwigFilter('parse_text', fn(string $text, int $parser): string => Parser::instance($parser)->parseText($text)), new TwigFilter('perms_check', 'perms_check'), - new TwigFilter('clamp', 'clamp'), new TwigFilter('time_diff', [$this, 'timeDiff'], ['needs_environment' => true]), ]; } diff --git a/src/Users/User.php b/src/Users/User.php index 2947890..22cd277 100644 --- a/src/Users/User.php +++ b/src/Users/User.php @@ -4,6 +4,7 @@ namespace Misuzu\Users; use DateTime; use DateTimeZone; use JsonSerializable; +use Index\XString; use Index\Colour\Colour; use Misuzu\DB; use Misuzu\HasRankInterface; @@ -666,7 +667,7 @@ class User implements HasRankInterface, JsonSerializable { } public static function validatePassword(string $password): string { - if(unique_chars($password) < self::PASSWORD_UNIQUE) + if(XString::countUnique($password) < self::PASSWORD_UNIQUE) return 'weak'; return ''; diff --git a/src/Zalgo.php b/src/Zalgo.php index 784ba56..4a31680 100644 --- a/src/Zalgo.php +++ b/src/Zalgo.php @@ -55,9 +55,10 @@ final class Zalgo { public static function getString(array $array, int $length): string { $string = ''; + $rngMax = count($array) - 1; for($i = 0; $i < $length; $i++) - $string .= array_rand_value($array); + $string .= $array[mt_rand(0, $rngMax)]; return $string; } diff --git a/templates/forum/macros.twig b/templates/forum/macros.twig index 7444b04..da6345a 100644 --- a/templates/forum/macros.twig +++ b/templates/forum/macros.twig @@ -322,7 +322,8 @@ {% if topic.topic_pages|default(0) > 1 %}
- {% for i in 1..topic.topic_pages|clamp(0, 3) %} + {% set topic_pages_start_end = min(3, topic.topic_pages) %} + {% for i in 1..topic_pages_start_end %} {{ i }} @@ -334,7 +335,8 @@
{% endif %} - {% for i in (topic.topic_pages - 2)|clamp(4, topic.topic_pages)..topic.topic_pages %} + {% set topic_pages_end_start = max(4, min(topic.topic_pages, topic.topic_pages - 2)) %} + {% for i in topic_pages_end_start..topic.topic_pages %} {{ i }} diff --git a/utility.php b/utility.php index 4dcd629..d6a17da 100644 --- a/utility.php +++ b/utility.php @@ -1,62 +1,6 @@ $value) - $array1[$key] |= $array2[$key] ?? 0; - return $array1; -} - -function array_rand_value(array $array) { - return $array[mt_rand(0, count($array) - 1)]; -} - -function array_find(array $array, callable $callback) { - foreach($array as $item) - if($callback($item)) - return $item; - return null; -} - -function clamp($num, int $min, int $max): int { - return max($min, min($max, (int)$num)); -} - -function first_paragraph(string $text, string $delimiter = "\n"): string { - $index = mb_strpos($text, $delimiter); - return $index === false ? $text : mb_substr($text, 0, $index); -} - -function unique_chars(string $input, bool $multibyte = true): int { - $chars = []; - $strlen = $multibyte ? 'mb_strlen' : 'strlen'; - $substr = $multibyte ? 'mb_substr' : 'substr'; - $length = $strlen($input); - - for($i = 0; $i < $length; $i++) { - $current = $substr($input, $i, 1); - - if(!in_array($current, $chars, true)) { - $chars[] = $current; - } - } - - return count($chars); -} - function byte_symbol(int $bytes, bool $decimal = false, array $symbols = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): string { if($bytes < 1) return '0 B'; @@ -125,30 +69,3 @@ function html_colour(int|null|Colour $colour, $attribs = '--user-colour'): strin return $css; } - -function msz_server_timing(\Index\Performance\Timings $timings): string { - $laps = $timings->getLaps(); - $timings = []; - - foreach($laps as $lap) { - $timing = $lap->getName(); - if($lap->hasComment()) - $timing .= ';desc="' . strtr($lap->getComment(), ['"' => '\\"']) . '"'; - - $timing .= ';dur=' . round($lap->getDurationTime(), 5); - $timings[] = $timing; - } - - return sprintf('Server-Timing: %s', implode(', ', $timings)); -} - -function msz_cookie_domain(bool $compatible = true): string { - $url = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST); - if(empty($url)) - $url = $_SERVER['HTTP_HOST']; - - if(!filter_var($url, FILTER_VALIDATE_IP) && $compatible) - $url = '.' . $url; - - return $url; -}