diff options
108 files changed, 1708 insertions, 3157 deletions
@@ -7,7 +7,6 @@ <p style="color: blue;background:black">this isn't for you</p> <p style="color: red;background:black">it's a 403</p> <br /> <br /> -<param name="movie" value="/static/congrats.swf"> </center> <audio autoplay loop> <source src="/static/cyberia.ogg" /> @@ -9,15 +9,15 @@ function getFilesInDirectory($dir) { return null; } - return array_diff(scandir($dir), array('.', '..')); + return array_diff(scandir($dir), ['.', '..']); } // Serve a random banner and exit. -function serveRandomBanner($dir, $files) { +function serveRandomBanner($dir, $files): never { $name = $files[array_rand($files)]; // snags the extension - $ext = pathinfo($name, PATHINFO_EXTENSION); + $ext = pathinfo((string) $name, PATHINFO_EXTENSION); // send the right headers header('Cache-Control: no-cache, no-store, must-revalidate'); // HTTP 1.1 @@ -39,7 +39,7 @@ $banners = getFilesInDirectory($bannerDir); $priority = getFilesInDirectory($priorityDir); // If there are priority banners, serve 1/3rd of the time. -if($priority !== null && count($priority) !== 0 && rand(0,2) === 0) { +if($priority !== null && (is_countable($priority) ? count($priority) : 0) !== 0 && random_int(0,2) === 0) { serveRandomBanner($priorityDir, $priority); } @@ -4,11 +4,7 @@ //If the user is not banned, show the "not banned" page. die( - Element('page.html', array( - 'title' => _('Not banned!'), - 'config' => $config, - 'nojavascript' => true, - 'body' => Element('notbanned.html', array() - )) + Element('page.html', ['title' => _('Not banned!'), 'config' => $config, 'nojavascript' => true, 'body' => Element('notbanned.html', [] + )] )); ?> @@ -2,7 +2,7 @@ //renaming to bg.php $dir = "walls/"; $files = scandir($dir); -$images = array_diff($files, array('.', '..')); +$images = array_diff($files, ['.', '..']); $name = $images[array_rand($images)]; // open the file in a binary mode $fp = fopen($dir . $name, 'rb'); @@ -1,7 +1,7 @@ <?php $dir = "banners/"; $files = scandir($dir); -$images = array_diff($files, array('.', '..')); +$images = array_diff($files, ['.', '..']); $name = $images[array_rand($images)]; $fp = fopen($dir . $name, 'rb'); diff --git a/composer.json b/composer.json index 9d09ed5b..fffab0b6 100644 --- a/composer.json +++ b/composer.json @@ -64,5 +64,9 @@ "ext-redis": "Allows the use of Redis for cache storage", "ext-memcached": "Allows the use of Memcached for cache storage", "ext-xcache": "Allows the use of XCache for cache storage" + }, + "require-dev": { + "rector/rector": "^0.14.3", + "giorgiosironi/eris": "^0.13.0" } } diff --git a/composer.lock b/composer.lock index 3cb3deae..4920e93b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "94d1f3d32a11d50a351b4c446da7bd07", + "content-hash": "c6d65f9086558147a92a018a27c2b898", "packages": [ { "name": "awsumchan/ip", @@ -1304,7 +1304,188 @@ "time": "2022-08-12T06:43:37+00:00" } ], - "packages-dev": [], + "packages-dev": [ + { + "name": "giorgiosironi/eris", + "version": "0.13.0", + "source": { + "type": "git", + "url": "https://github.com/giorgiosironi/eris.git", + "reference": "d3a07e2e30eff6e0ee0a478efab4c6bed4290033" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/giorgiosironi/eris/zipball/d3a07e2e30eff6e0ee0a478efab4c6bed4290033", + "reference": "d3a07e2e30eff6e0ee0a478efab4c6bed4290033", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^2.0", + "icomefromthenet/reverse-regex": "v0.0.6.3", + "phpstan/phpstan": "^1.2", + "phpunit/phpunit": ">=7", + "psalm/phar": "^4.13", + "sebastian/comparator": ">=1.2.4" + }, + "suggest": { + "icomefromthenet/reverse-regex": "v0.0.6.3 for the regex() Generator", + "phpunit/phpunit": "Standard way to run generated test cases" + }, + "type": "library", + "autoload": { + "files": [ + "src/Generator/functions.php" + ], + "psr-4": { + "Eris\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Giorgio Sironi", + "email": "info@giorgiosironi.com" + }, + { + "name": "Mirko Bonadei", + "email": "mirko.bonadei@gmail.com" + }, + { + "name": "Gabriele Lana", + "email": "gabriele.lana@gmail.com" + } + ], + "description": "PHP library for property-based testing. Integrates with PHPUnit.", + "support": { + "issues": "https://github.com/giorgiosironi/eris/issues", + "source": "https://github.com/giorgiosironi/eris/tree/0.13.0" + }, + "time": "2021-12-17T21:51:49+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.8.6", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "c386ab2741e64cc9e21729f891b28b2b10fe6618" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c386ab2741e64cc9e21729f891b28b2b10fe6618", + "reference": "c386ab2741e64cc9e21729f891b28b2b10fe6618", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.6" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-09-23T09:54:39+00:00" + }, + { + "name": "rector/rector", + "version": "0.14.3", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "c4ec650b298158fd7ccdf4613777792f0d1d13d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/c4ec650b298158fd7ccdf4613777792f0d1d13d7", + "reference": "c4ec650b298158fd7ccdf4613777792f0d1d13d7", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.8.3" + }, + "conflict": { + "rector/rector-cakephp": "*", + "rector/rector-doctrine": "*", + "rector/rector-laravel": "*", + "rector/rector-php-parser": "*", + "rector/rector-phpoffice": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.14-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.14.3" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-09-23T09:46:53+00:00" + } + ], "aliases": [], "minimum-stability": "stable", "stability-flags": [], diff --git a/inc/anti-bot.php b/inc/anti-bot.php index 4c321176..db30ebf8 100644 --- a/inc/anti-bot.php +++ b/inc/anti-bot.php @@ -6,10 +6,10 @@ defined('TINYBOARD') or exit; -$hidden_inputs_twig = array(); +$hidden_inputs_twig = []; class AntiBot { - public $salt, $inputs = array(), $index = 0; + public $salt, $inputs = [], $index = 0; public static function randomString($length, $uppercase = false, $special_chars = false, $unicode_chars = false) { $chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; @@ -20,17 +20,17 @@ class AntiBot { if ($unicode_chars) { $len = strlen($chars) / 10; for ($n = 0; $n < $len; $n++) - $chars .= mb_convert_encoding('&#' . mt_rand(0x2600, 0x26FF) . ';', 'UTF-8', 'HTML-ENTITIES'); + $chars .= mb_convert_encoding('&#' . random_int(0x2600, 0x26FF) . ';', 'UTF-8', 'HTML-ENTITIES'); } $chars = preg_split('//u', $chars, -1, PREG_SPLIT_NO_EMPTY); - $ch = array(); + $ch = []; // fill up $ch until we reach $length while (count($ch) < $length) { $n = $length - count($ch); - $keys = array_rand($chars, $n > count($chars) ? count($chars) : $n); + $keys = array_rand($chars, $n > (is_countable($chars) ? count($chars) : 0) ? count($chars) : $n); if ($n == 1) { $ch[] = $chars[$keys]; break; @@ -46,19 +46,19 @@ class AntiBot { } public static function make_confusing($string) { - $chars = preg_split('//u', $string, -1, PREG_SPLIT_NO_EMPTY); + $chars = preg_split('//u', (string) $string, -1, PREG_SPLIT_NO_EMPTY); foreach ($chars as &$c) { - if (mt_rand(0, 3) != 0) + if (random_int(0, 3) != 0) $c = utf8tohtml($c); else - $c = mb_encode_numericentity($c, array(0, 0xffff, 0, 0xffff), 'UTF-8'); + $c = mb_encode_numericentity((string) $c, [0, 0xffff, 0, 0xffff], 'UTF-8'); } return implode('', $chars); } - public function __construct(array $salt = array()) { + public function __construct(array $salt = []) { global $config; if (!empty($salt)) { @@ -70,60 +70,48 @@ class AntiBot { shuffle($config['spam']['hidden_input_names']); - $input_count = mt_rand($config['spam']['hidden_inputs_min'], $config['spam']['hidden_inputs_max']); + $input_count = random_int($config['spam']['hidden_inputs_min'], $config['spam']['hidden_inputs_max']); $hidden_input_names_x = 0; for ($x = 0; $x < $input_count ; $x++) { - if ($hidden_input_names_x === false || mt_rand(0, 2) == 0) { + if ($hidden_input_names_x === false || random_int(0, 2) == 0) { // Use an obscure name - $name = $this->randomString(mt_rand(10, 40), false, false, $config['spam']['unicode']); + $name = static::randomString(random_int(10, 40), false, false, $config['spam']['unicode']); } else { // Use a pre-defined confusing name $name = $config['spam']['hidden_input_names'][$hidden_input_names_x++]; - if ($hidden_input_names_x >= count($config['spam']['hidden_input_names'])) + if ($hidden_input_names_x >= (is_countable($config['spam']['hidden_input_names']) ? count($config['spam']['hidden_input_names']) : 0)) $hidden_input_names_x = false; } - if (mt_rand(0, 2) == 0) { + if (random_int(0, 2) == 0) { // Value must be null $this->inputs[$name] = ''; - } elseif (mt_rand(0, 4) == 0) { + } elseif (random_int(0, 4) == 0) { // Numeric value - $this->inputs[$name] = (string)mt_rand(0, 100000); + $this->inputs[$name] = (string)random_int(0, 100000); } else { // Obscure value - $this->inputs[$name] = $this->randomString(mt_rand(5, 100), true, true, $config['spam']['unicode']); + $this->inputs[$name] = static::randomString(random_int(5, 100), true, true, $config['spam']['unicode']); } } } public static function space() { - if (mt_rand(0, 3) != 0) + if (random_int(0, 3) != 0) return ' '; - return str_repeat(' ', mt_rand(1, 3)); + return str_repeat(' ', random_int(1, 3)); } public function html($count = false) { global $config; - $elements = array( - '<input type="hidden" name="%name%" value="%value%">', - '<input type="hidden" value="%value%" name="%name%">', - '<input name="%name%" value="%value%" type="hidden">', - '<input value="%value%" name="%name%" type="hidden">', - '<input style="display:none" type="text" name="%name%" value="%value%">', - '<input style="display:none" type="text" value="%value%" name="%name%">', - '<span style="display:none"><input type="text" name="%name%" value="%value%"></span>', - '<div style="display:none"><input type="text" name="%name%" value="%value%"></div>', - '<div style="display:none"><input type="text" name="%name%" value="%value%"></div>', - '<textarea style="display:none" name="%name%">%value%</textarea>', - '<textarea name="%name%" style="display:none">%value%</textarea>' - ); + $elements = ['<input type="hidden" name="%name%" value="%value%">', '<input type="hidden" value="%value%" name="%name%">', '<input name="%name%" value="%value%" type="hidden">', '<input value="%value%" name="%name%" type="hidden">', '<input style="display:none" type="text" name="%name%" value="%value%">', '<input style="display:none" type="text" value="%value%" name="%name%">', '<span style="display:none"><input type="text" name="%name%" value="%value%"></span>', '<div style="display:none"><input type="text" name="%name%" value="%value%"></div>', '<div style="display:none"><input type="text" name="%name%" value="%value%"></div>', '<textarea style="display:none" name="%name%">%value%</textarea>', '<textarea name="%name%" style="display:none">%value%</textarea>']; $html = ''; if ($count === false) { - $count = mt_rand(1, (int)abs(count($this->inputs) / 15) + 1); + $count = random_int(1, (int)abs((is_countable($this->inputs) ? count($this->inputs) : 0) / 15) + 1); } if ($count === true) { @@ -139,9 +127,9 @@ class AntiBot { while (!$element) { $element = $elements[array_rand($elements)]; $element = str_replace(' ', self::space(), $element); - if (mt_rand(0, 5) == 0) + if (random_int(0, 5) == 0) $element = str_replace('>', self::space() . '>', $element); - if (strpos($element, 'textarea') !== false && $value == '') { + if (str_contains($element, 'textarea') && $value == '') { // There have been some issues with mobile web browsers and empty <textarea>'s. $element = false; } @@ -149,13 +137,13 @@ class AntiBot { $element = str_replace('%name%', utf8tohtml($name), $element); - if (mt_rand(0, 2) == 0) - $value = $this->make_confusing($value); + if (random_int(0, 2) == 0) + $value = static::make_confusing($value); else $value = utf8tohtml($value); - if (strpos($element, 'textarea') === false) - $value = str_replace('"', '"', $value); + if (!str_contains($element, 'textarea')) + $value = str_replace('"', '"', (string) $value); $element = str_replace('%value%', $value, $element); @@ -193,7 +181,7 @@ class AntiBot { function _create_antibot($board, $thread) { global $config, $purged_old_antispam; - $antibot = new AntiBot(array($board, $thread)); + $antibot = new AntiBot([$board, $thread]); if (!isset($purged_old_antispam)) { $purged_old_antispam = true; @@ -220,7 +208,7 @@ function _create_antibot($board, $thread) { return $antibot; } -function checkSpam(array $extra_salt = array()) { +function checkSpam(array $extra_salt = []) { global $config, $pdo; if (!isset($_POST['hash'])) @@ -236,7 +224,7 @@ function checkSpam(array $extra_salt = array()) { } // Reconsturct the $inputs array - $inputs = array(); + $inputs = []; foreach ($_POST as $name => $value) { if (in_array($name, $config['spam']['valid_inputs'])) diff --git a/inc/api.php b/inc/api.php index b280c25b..e9601c6e 100644 --- a/inc/api.php +++ b/inc/api.php @@ -16,62 +16,18 @@ class Api { */ $this->config = $config; - $this->postFields = array( - 'id' => 'no', - 'thread' => 'resto', - 'subject' => 'sub', - 'body' => 'com', - 'email' => 'email', - 'name' => 'name', - 'trip' => 'trip', - 'capcode' => 'capcode', - 'time' => 'time', - 'omitted' => 'omitted_posts', - 'omitted_images' => 'omitted_images', - 'replies' => 'replies', - 'images' => 'images', - 'sticky' => 'sticky', - 'locked' => 'locked', - 'cycle' => 'cyclical', - 'bump' => 'last_modified', - 'embed' => 'embed', - ); + $this->postFields = ['id' => 'no', 'thread' => 'resto', 'subject' => 'sub', 'body' => 'com', 'email' => 'email', 'name' => 'name', 'trip' => 'trip', 'capcode' => 'capcode', 'time' => 'time', 'omitted' => 'omitted_posts', 'omitted_images' => 'omitted_images', 'replies' => 'replies', 'images' => 'images', 'sticky' => 'sticky', 'locked' => 'locked', 'cycle' => 'cyclical', 'bump' => 'last_modified', 'embed' => 'embed']; - $this->threadsPageFields = array( - 'id' => 'no', - 'bump' => 'last_modified' - ); + $this->threadsPageFields = ['id' => 'no', 'bump' => 'last_modified']; - $this->fileFields = array( - 'thumbheight' => 'tn_h', - 'thumbwidth' => 'tn_w', - 'height' => 'h', - 'width' => 'w', - 'size' => 'fsize', - ); + $this->fileFields = ['thumbheight' => 'tn_h', 'thumbwidth' => 'tn_w', 'height' => 'h', 'width' => 'w', 'size' => 'fsize']; if (isset($config['api']['extra_fields']) && gettype($config['api']['extra_fields']) == 'array'){ $this->postFields = array_merge($this->postFields, $config['api']['extra_fields']); } } - private static $ints = array( - 'no' => 1, - 'resto' => 1, - 'time' => 1, - 'tn_w' => 1, - 'tn_h' => 1, - 'w' => 1, - 'h' => 1, - 'fsize' => 1, - 'omitted_posts' => 1, - 'omitted_images' => 1, - 'replies' => 1, - 'images' => 1, - 'sticky' => 1, - 'locked' => 1, - 'last_modified' => 1 - ); + private static array $ints = ['no' => 1, 'resto' => 1, 'time' => 1, 'tn_w' => 1, 'tn_h' => 1, 'w' => 1, 'h' => 1, 'fsize' => 1, 'omitted_posts' => 1, 'omitted_images' => 1, 'replies' => 1, 'images' => 1, 'sticky' => 1, 'locked' => 1, 'last_modified' => 1]; private function translateFields($fields, $object, &$apiPost) { foreach ($fields as $local => $translated) { @@ -89,32 +45,32 @@ class Api { private function translateFile($file, $post, &$apiPost) { $this->translateFields($this->fileFields, $file, $apiPost); - $apiPost['filename'] = @substr($file->name, 0, strrpos($file->name, '.')); - $dotPos = strrpos($file->file, '.'); - $apiPost['ext'] = substr($file->file, $dotPos); - $apiPost['tim'] = substr($file->file, 0, $dotPos); + $apiPost['filename'] = @substr((string) $file->name, 0, strrpos((string) $file->name, '.')); + $dotPos = strrpos((string) $file->file, '.'); + $apiPost['ext'] = substr((string) $file->file, $dotPos); + $apiPost['tim'] = substr((string) $file->file, 0, $dotPos); if (isset ($file->hash) && $file->hash) { - $apiPost['md5'] = base64_encode(hex2bin($file->hash)); + $apiPost['md5'] = base64_encode(hex2bin((string) $file->hash)); } else if (isset ($post->filehash) && $post->filehash) { - $apiPost['md5'] = base64_encode(hex2bin($post->filehash)); + $apiPost['md5'] = base64_encode(hex2bin((string) $post->filehash)); } } private function translatePost($post, $threadsPage = false) { global $config, $board; - $apiPost = array(); + $apiPost = []; $fields = $threadsPage ? $this->threadsPageFields : $this->postFields; $this->translateFields($fields, $post, $apiPost); - if (isset($config['poster_ids']) && $config['poster_ids']) $apiPost['id'] = poster_id($post->ip, $post->thread, $board['uri']); + if (isset($config['poster_ids']) && $config['poster_ids']) $apiPost['id'] = poster_id($post->ip, $post->thread); if ($threadsPage) return $apiPost; // Handle country field if (isset($post->body_nomarkup) && $this->config['country_flags']) { $modifiers = extract_modifiers($post->body_nomarkup); - if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', $modifiers['flag'])) { - $country = strtoupper($modifiers['flag']); + if (isset($modifiers['flag']) && isset($modifiers['flag alt']) && preg_match('/^[a-z]{2}$/', (string) $modifiers['flag'])) { + $country = strtoupper((string) $modifiers['flag']); if ($country) { $apiPost['country'] = $country; $apiPost['country_name'] = $modifiers['flag alt']; @@ -132,11 +88,11 @@ class Api { $file = $post->files[0]; $this->translateFile($file, $post, $apiPost); if (sizeof($post->files) > 1) { - $extra_files = array(); + $extra_files = []; foreach ($post->files as $i => $f) { if ($i == 0) continue; - $extra_file = array(); + $extra_file = []; $this->translateFile($f, $post, $extra_file); $extra_files[] = $extra_file; @@ -149,7 +105,7 @@ class Api { } function translateThread(Thread $thread, $threadsPage = false) { - $apiPosts = array(); + $apiPosts = []; $op = $this->translatePost($thread, $threadsPage); if (!$threadsPage) $op['resto'] = 0; $apiPosts['posts'][] = $op; @@ -162,7 +118,7 @@ class Api { } function translatePage(array $threads) { - $apiPage = array(); + $apiPage = []; foreach ($threads as $thread) { $apiPage['threads'][] = $this->translateThread($thread); } @@ -170,7 +126,7 @@ class Api { } function translateCatalogPage(array $threads, $threadsPage = false) { - $apiPage = array(); + $apiPage = []; foreach ($threads as $thread) { $ts = $this->translateThread($thread, $threadsPage); $apiPage['threads'][] = current($ts['posts']); @@ -179,7 +135,7 @@ class Api { } function translateCatalog($catalog, $threadsPage = false) { - $apiCatalog = array(); + $apiCatalog = []; foreach ($catalog as $page => $threads) { $apiPage = $this->translateCatalogPage($threads, $threadsPage); $apiPage['page'] = $page; diff --git a/inc/bans.php b/inc/bans.php index a87fd12a..647a25c9 100644 --- a/inc/bans.php +++ b/inc/bans.php @@ -4,7 +4,7 @@ use AwsumChan\IP\CIDR; class Bans { static public function range_to_string($mask) { - list($ipstart, $ipend) = $mask; + [$ipstart, $ipend] = $mask; if (!isset($ipend) || $ipend === false) { // Not a range. Single IP address. @@ -12,7 +12,7 @@ class Bans { return $ipstr; } - if (strlen($ipstart) != strlen($ipend)) + if (strlen((string) $ipstart) != strlen((string) $ipend)) return '???'; // What the fuck are you doing, son? $range = CIDR::range_to_cidr(inet_ntop($ipstart), inet_ntop($ipend)); @@ -26,17 +26,17 @@ class Bans { $cidr = new CIDR($mask); $range = $cidr->getRange(); - return array(inet_pton($range[0]), inet_pton($range[1])); + return [inet_pton($range[0]), inet_pton($range[1])]; } public static function parse_time($str) { if (empty($str)) return false; - if (($time = @strtotime($str)) !== false) + if (($time = @strtotime((string) $str)) !== false) return $time; - if (!preg_match('/^((\d+)\s?ye?a?r?s?)?\s?+((\d+)\s?mon?t?h?s?)?\s?+((\d+)\s?we?e?k?s?)?\s?+((\d+)\s?da?y?s?)?((\d+)\s?ho?u?r?s?)?\s?+((\d+)\s?mi?n?u?t?e?s?)?\s?+((\d+)\s?se?c?o?n?d?s?)?$/', $str, $matches)) + if (!preg_match('/^((\d+)\s?ye?a?r?s?)?\s?+((\d+)\s?mon?t?h?s?)?\s?+((\d+)\s?we?e?k?s?)?\s?+((\d+)\s?da?y?s?)?((\d+)\s?ho?u?r?s?)?\s?+((\d+)\s?mi?n?u?t?e?s?)?\s?+((\d+)\s?se?c?o?n?d?s?)?$/', (string) $str, $matches)) return false; $expire = 0; @@ -77,9 +77,9 @@ class Bans { $ipstart = false; $ipend = false; - if (preg_match('@^(\d{1,3}\.){1,3}([\d*]{1,3})?$@', $mask) && substr_count($mask, '*') == 1) { + if (preg_match('@^(\d{1,3}\.){1,3}([\d*]{1,3})?$@', (string) $mask) && substr_count((string) $mask, '*') == 1) { // IPv4 wildcard mask - $parts = explode('.', $mask); + $parts = explode('.', (string) $mask); $ipv4 = ''; foreach ($parts as $part) { if ($part == '*') { @@ -93,24 +93,24 @@ class Bans { } $ipv4 .= "$part."; } - } elseif (preg_match('@^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d+$@', $mask)) { - list($ipv4, $bits) = explode('/', $mask); + } elseif (preg_match('@^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}/\d+$@', (string) $mask)) { + [$ipv4, $bits] = explode('/', (string) $mask); if ($bits > 32) return false; - list($ipstart, $ipend) = self::calc_cidr($mask); - } elseif (preg_match('@^[:a-z\d]+/\d+$@i', $mask)) { - list($ipv6, $bits) = explode('/', $mask); + [$ipstart, $ipend] = self::calc_cidr($mask); + } elseif (preg_match('@^[:a-z\d]+/\d+$@i', (string) $mask)) { + [$ipv6, $bits] = explode('/', (string) $mask); if ($bits > 128) return false; - list($ipstart, $ipend) = self::calc_cidr($mask); + [$ipstart, $ipend] = self::calc_cidr($mask); } else { if (($ipstart = @inet_pton($mask)) === false) return false; } - return array($ipstart, $ipend); + return [$ipstart, $ipend]; } static public function find($ip, $board = false, $get_mod_info = false) { @@ -129,15 +129,15 @@ class Bans { $query->bindValue(':ip', inet_pton($ip)); $query->execute() or error(db_error($query)); - $ban_list = array(); + $ban_list = []; while ($ban = $query->fetch(PDO::FETCH_ASSOC)) { if ($ban['expires'] && ($ban['seen'] || !$config['require_ban_view']) && $ban['expires'] < time()) { self::delete($ban['id']); } else { if ($ban['post']) - $ban['post'] = json_decode($ban['post'], true); - $ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $ban['post'] = json_decode((string) $ban['post'], true, 512, JSON_THROW_ON_ERROR); + $ban['mask'] = self::range_to_string([$ban['ipstart'], $ban['ipend']]); $ban_list[] = $ban; } } @@ -158,19 +158,19 @@ class Bans { $end = end($bans); foreach ($bans as &$ban) { - $ban['mask'] = self::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $ban['mask'] = self::range_to_string([$ban['ipstart'], $ban['ipend']]); $hide_message = false; foreach ($hide_regexes as $regex) { - if(preg_match($regex, $ban['reason'])) { + if(preg_match($regex, (string) $ban['reason'])) { $hide_message = true; break; } } if ($ban['post'] && !$hide_message) { - $post = json_decode($ban['post']); - $ban['message'] = isset($post->body) ? $post->body : 0; + $post = json_decode((string) $ban['post'], null, 512, JSON_THROW_ON_ERROR); + $ban['message'] = $post->body ?? 0; } unset($ban['ipstart'], $ban['ipend'], $ban['post'], $ban['creator']); @@ -185,7 +185,7 @@ class Bans { $ban['username'] = '?'; } if ($filter_ips || ($board_access !== false && !in_array($ban['board'], $board_access))) { - @list($ban['mask'], $subnet) = explode("/", $ban['mask']); + @[$ban['mask'], $subnet] = explode("/", (string) $ban['mask']); $ban['mask'] = preg_split("/[\.:]/", $ban['mask']); $ban['mask'] = array_slice($ban['mask'], 0, 2); $ban['mask'] = implode(".", $ban['mask']); @@ -196,7 +196,7 @@ class Bans { $ban['masked'] = true; } - $json = json_encode($ban); + $json = json_encode($ban, JSON_THROW_ON_ERROR); $out ? fputs($out, $json) : print($json); if ($ban['id'] != $end['id']) { @@ -233,7 +233,7 @@ class Bans { if ($boards !== false && !in_array($ban['board'], $boards)) error($config['error']['noaccess']); - $mask = self::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $mask = self::range_to_string([$ban['ipstart'], $ban['ipend']]); modLog("Removed ban #{$ban_id} for " . (filter_var($mask, FILTER_VALIDATE_IP) !== false ? "<a href=\"?/IP/$mask\">$mask</a>" : $mask)); @@ -250,7 +250,7 @@ class Bans { global $mod, $pdo, $board; if ($mod_id === false) { - $mod_id = isset($mod['id']) ? $mod['id'] : -1; + $mod_id = $mod['id'] ?? -1; } $range = self::parse_range($mask); @@ -292,7 +292,7 @@ class Bans { if ($post) { $post['board'] = $board['uri']; - $query->bindValue(':post', json_encode($post)); + $query->bindValue(':post', json_encode($post, JSON_THROW_ON_ERROR)); } else $query->bindValue(':post', null, PDO::PARAM_NULL); diff --git a/inc/cache.php b/inc/cache.php index 852aefa2..0c9bc8e2 100644 --- a/inc/cache.php +++ b/inc/cache.php @@ -25,7 +25,7 @@ class Cache { self::$cache->select($config['cache']['redis'][3]) or die('cache select failure'); break; case 'php': - self::$cache = array(); + self::$cache = []; break; } } @@ -48,7 +48,7 @@ class Cache { $data = xcache_get($key); break; case 'php': - $data = isset(self::$cache[$key]) ? self::$cache[$key] : false; + $data = self::$cache[$key] ?? false; break; case 'fs': $key = str_replace('/', '::', $key); @@ -58,13 +58,13 @@ class Cache { } else { $data = file_get_contents('tmp/cache/'.$key); - $data = json_decode($data, true); + $data = json_decode($data, true, 512, JSON_THROW_ON_ERROR); } break; case 'redis': if (!self::$cache) self::init(); - $data = json_decode(self::$cache->get($key), true); + $data = json_decode((string) self::$cache->get($key), true, 512, JSON_THROW_ON_ERROR); break; } @@ -90,7 +90,7 @@ class Cache { case 'redis': if (!self::$cache) self::init(); - self::$cache->setex($key, $expires, json_encode($value)); + self::$cache->setex($key, $expires, json_encode($value, JSON_THROW_ON_ERROR)); break; case 'apc': apc_store($key, $value, $expires); @@ -101,7 +101,7 @@ class Cache { case 'fs': $key = str_replace('/', '::', $key); $key = str_replace("\0", '', $key); - file_put_contents('tmp/cache/'.$key, json_encode($value)); + file_put_contents('tmp/cache/'.$key, json_encode($value, JSON_THROW_ON_ERROR)); break; case 'php': self::$cache[$key] = $value; @@ -153,7 +153,7 @@ class Cache { case 'apc': return apc_clear_cache('user'); case 'php': - self::$cache = array(); + self::$cache = []; break; case 'fs': $files = glob('tmp/cache/*'); diff --git a/inc/config.php b/inc/config.php index 61c5fe67..278aa5dc 100644 --- a/inc/config.php +++ b/inc/config.php @@ -50,7 +50,7 @@ // Directory where temporary files will be created. $config['tmp'] = sys_get_temp_dir(); - $config['overboards'] = array(); + $config['overboards'] = []; // The HTTP status code to use when redirecting. http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html // Can be either 303 "See Other" or 302 "Found". (303 is more correct but both should work.) // There is really no reason for you to ever need to change this. @@ -129,14 +129,12 @@ $config['cache']['prefix'] = ''; // Memcached servers to use. Read more: http://www.php.net/manual/en/memcached.addservers.php - $config['cache']['memcached'] = array( - array('localhost', 11211) - ); + $config['cache']['memcached'] = [['localhost', 11211]]; // Redis server to use. Location, port, password, database id. // Note that Tinyboard may clear the database at times, so you may want to pick a database id just for // Tinyboard to use. - $config['cache']['redis'] = array('localhost', 6379, '', 1); + $config['cache']['redis'] = ['localhost', 6379, '', 1]; // EXPERIMENTAL: Should we cache configs? Warning: this changes board behaviour, i'd say, a lot. // If you have any lambdas/includes present in your config, you should move them to instance-functions.php @@ -258,53 +256,10 @@ $config['spam']['unicode'] = true; // These are fields used to confuse the bots. Make sure they aren't actually used by Tinyboard, or it won't work. - $config['spam']['hidden_input_names'] = array( - 'user', - 'username', - 'login', - 'search', - 'q', - 'url', - 'firstname', - 'lastname', - 'text', - 'message' - ); + $config['spam']['hidden_input_names'] = ['user', 'username', 'login', 'search', 'q', 'url', 'firstname', 'lastname', 'text', 'message']; // Always update this when adding new valid fields to the post form, or EVERYTHING WILL BE DETECTED AS SPAM! - $config['spam']['valid_inputs'] = array( - 'hash', - 'board', - 'thread', - 'mod', - 'name', - 'email', - 'subject', - 'post', - 'body', - 'password', - 'sticky', - 'lock', - 'raw', - 'embed', - 'g-recaptcha-response', - 'spoiler', - 'page', - 'file_url', - 'file_url1', - 'file_url2', - 'file_url3', - 'file_url4', - 'file_url5', - 'file_url6', - 'file_url7', - 'file_url8', - 'file_url9', - 'json_response', - 'user_flag', - 'no_country', - 'tag' - ); + $config['spam']['valid_inputs'] = ['hash', 'board', 'thread', 'mod', 'name', 'email', 'subject', 'post', 'body', 'password', 'sticky', 'lock', 'raw', 'embed', 'g-recaptcha-response', 'spoiler', 'page', 'file_url', 'file_url1', 'file_url2', 'file_url3', 'file_url4', 'file_url5', 'file_url6', 'file_url7', 'file_url8', 'file_url9', 'json_response', 'user_flag', 'no_country', 'tag']; // Enable reCaptcha to make spam even harder. Rarely necessary. $config['recaptcha'] = false; @@ -346,35 +301,26 @@ $config['flood_time_same'] = 30; // Minimum time between posts by the same IP address (all boards). - $config['filters'][] = array( - 'condition' => array( - 'flood-match' => array('ip'), // Only match IP address - 'flood-time' => &$config['flood_time'] - ), - 'action' => 'reject', - 'message' => &$config['error']['flood'] - ); + $config['filters'][] = ['condition' => [ + 'flood-match' => ['ip'], + // Only match IP address + 'flood-time' => &$config['flood_time'], + ], 'action' => 'reject', 'message' => &$config['error']['flood']]; // Minimum time between posts by the same IP address with the same text. - $config['filters'][] = array( - 'condition' => array( - 'flood-match' => array('ip', 'body'), // Match IP address and post body - 'flood-time' => &$config['flood_time_ip'], - '!body' => '/^$/', // Post body is NOT empty - ), - 'action' => 'reject', - 'message' => &$config['error']['flood'] - ); + $config['filters'][] = ['condition' => [ + 'flood-match' => ['ip', 'body'], + // Match IP address and post body + 'flood-time' => &$config['flood_time_ip'], + '!body' => '/^$/', + ], 'action' => 'reject', 'message' => &$config['error']['flood']]; // Minimum time between posts with the same text. (Same content, but not always the same IP address.) - $config['filters'][] = array( - 'condition' => array( - 'flood-match' => array('body'), // Match only post body - 'flood-time' => &$config['flood_time_same'] - ), - 'action' => 'reject', - 'message' => &$config['error']['flood'] - ); + $config['filters'][] = ['condition' => [ + 'flood-match' => ['body'], + // Match only post body + 'flood-time' => &$config['flood_time_same'], + ], 'action' => 'reject', 'message' => &$config['error']['flood']]; // Example: Minimum time between posts with the same file hash. // $config['filters'][] = array( @@ -598,7 +544,7 @@ $config['user_flag'] = false; // List of user_flag the user can choose. Flags must be placed in the directory set by $config['uri_flags'] - $config['user_flags'] = array(); + $config['user_flags'] = []; /* example:Â $config['user_flags'] = array ( 'nz' => 'Nazi', @@ -652,10 +598,10 @@ */ // "Wiki" markup syntax ($config['wiki_markup'] in pervious versions): - $config['markup'][] = array("/'''(.+?)'''/", "<strong>\$1</strong>"); - $config['markup'][] = array("/''(.+?)''/", "<em>\$1</em>"); - $config['markup'][] = array("/\*\*(.+?)\*\*/", "<span class=\"spoiler\">\$1</span>"); - $config['markup'][] = array("/^[ |\t]*==(.+?)==[ |\t]*$/m", "<span class=\"heading\">\$1</span>"); + $config['markup'][] = ["/'''(.+?)'''/", "<strong>\$1</strong>"]; + $config['markup'][] = ["/''(.+?)''/", "<em>\$1</em>"]; + $config['markup'][] = ["/\*\*(.+?)\*\*/", "<span class=\"spoiler\">\$1</span>"]; + $config['markup'][] = ["/^[ |\t]*==(.+?)==[ |\t]*$/m", "<span class=\"heading\">\$1</span>"]; // Code markup. This should be set to a regular expression, using tags you want to use. Examples: // "/\[code\](.*?)\[\/code\]/is" @@ -935,7 +881,7 @@ // $config['uri_stylesheets'] = 'http://static.example.org/stylesheets/'; // The default stylesheet to use. - $config['default_stylesheet'] = array('Yotsuba B', $config['stylesheets']['Yotsuba B']); + $config['default_stylesheet'] = ['Yotsuba B', $config['stylesheets']['Yotsuba B']]; // Make stylesheet selections board-specific. $config['stylesheets_board'] = false; @@ -1055,32 +1001,7 @@ // Custom embedding (YouTube, vimeo, etc.) // It's very important that you match the entire input (with ^ and $) or things will not work correctly. - $config['embedding'] = array( - array( - '/^https?:\/\/(\w+\.)?youtube\.com\/watch\?v=([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', - '<iframe style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%" frameborder="0" id="ytplayer" src="http://www.youtube.com/embed/$2"></iframe>' - ), - array( - '/^https?:\/\/(\w+\.)?vimeo\.com\/(\d{2,10})(\?.+)?$/i', - '<iframe src="https://player.vimeo.com/video/$2" style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>' - ), - array( - '/^https?:\/\/(\w+\.)?dailymotion\.com\/video\/([a-zA-Z0-9]{2,10})(_.+)?$/i', - '<object style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%"><param name="movie" value="http://www.dailymotion.com/swf/video/$2"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"><embed type="application/x-shockwave-flash" src="http://www.dailymotion.com/swf/video/$2" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowfullscreen="true" allowscriptaccess="always"></object>' - ), - array( - '/^https?:\/\/(\w+\.)?metacafe\.com\/watch\/(\d+)\/([a-zA-Z0-9_\-.]+)\/(\?[^\'"<>]+)?$/i', - '<div style="float:left;margin:10px 20px;width:%%tb_width%%px;height:%%tb_height%%px"><embed flashVars="playerVars=showStats=no|autoPlay=no" src="http://www.metacafe.com/fplayer/$2/$3.swf" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowFullScreen="true" allowScriptAccess="always" name="Metacafe_$2" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></div>' - ), - array( - '/^https?:\/\/video\.google\.com\/videoplay\?docid=(\d+)([&#](.+)?)?$/i', - '<embed src="http://video.google.com/googleplayer.swf?docid=$1&hl=en&fs=true" style="width:%%tb_width%%px;height:%%tb_height%%px;float:left;margin:10px 20px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"></embed>' - ), - array( - '/^https?:\/\/(\w+\.)?vocaroo\.com\/i\/([a-zA-Z0-9]{2,15})$/i', - '<object style="float: left;margin: 10px 20px;" width="148" height="44"><param name="movie" value="http://vocaroo.com/player.swf?playMediaID=$2&autoplay=0"><param name="wmode" value="transparent"><embed src="http://vocaroo.com/player.swf?playMediaID=$2&autoplay=0" width="148" height="44" wmode="transparent" type="application/x-shockwave-flash"></object>' - ) - ); + $config['embedding'] = [['/^https?:\/\/(\w+\.)?youtube\.com\/watch\?v=([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', '<iframe style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%" frameborder="0" id="ytplayer" src="http://www.youtube.com/embed/$2"></iframe>'], ['/^https?:\/\/(\w+\.)?vimeo\.com\/(\d{2,10})(\?.+)?$/i', '<iframe src="https://player.vimeo.com/video/$2" style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>'], ['/^https?:\/\/(\w+\.)?dailymotion\.com\/video\/([a-zA-Z0-9]{2,10})(_.+)?$/i', '<object style="float: left;margin: 10px 20px;" width="%%tb_width%%" height="%%tb_height%%"><param name="movie" value="http://www.dailymotion.com/swf/video/$2"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><param name="wmode" value="transparent"><embed type="application/x-shockwave-flash" src="http://www.dailymotion.com/swf/video/$2" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowfullscreen="true" allowscriptaccess="always"></object>'], ['/^https?:\/\/(\w+\.)?metacafe\.com\/watch\/(\d+)\/([a-zA-Z0-9_\-.]+)\/(\?[^\'"<>]+)?$/i', '<div style="float:left;margin:10px 20px;width:%%tb_width%%px;height:%%tb_height%%px"><embed flashVars="playerVars=showStats=no|autoPlay=no" src="http://www.metacafe.com/fplayer/$2/$3.swf" width="%%tb_width%%" height="%%tb_height%%" wmode="transparent" allowFullScreen="true" allowScriptAccess="always" name="Metacafe_$2" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash"></div>'], ['/^https?:\/\/video\.google\.com\/videoplay\?docid=(\d+)([&#](.+)?)?$/i', '<embed src="http://video.google.com/googleplayer.swf?docid=$1&hl=en&fs=true" style="width:%%tb_width%%px;height:%%tb_height%%px;float:left;margin:10px 20px" allowFullScreen="true" allowScriptAccess="always" type="application/x-shockwave-flash"></embed>'], ['/^https?:\/\/(\w+\.)?vocaroo\.com\/i\/([a-zA-Z0-9]{2,15})$/i', '<object style="float: left;margin: 10px 20px;" width="148" height="44"><param name="movie" value="http://vocaroo.com/player.swf?playMediaID=$2&autoplay=0"><param name="wmode" value="transparent"><embed src="http://vocaroo.com/player.swf?playMediaID=$2&autoplay=0" width="148" height="44" wmode="transparent" type="application/x-shockwave-flash"></object>']]; // Embedding width and height. $config['embed_width'] = 300; @@ -1168,9 +1089,9 @@ if (isset($_SERVER['REQUEST_URI'])) { $request_uri = $_SERVER['REQUEST_URI']; if (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] !== '') - $request_uri = substr($request_uri, 0, - 1 - strlen($_SERVER['QUERY_STRING'])); - $config['root'] = str_replace('\\', '/', dirname($request_uri)) == '/' - ? '/' : str_replace('\\', '/', dirname($request_uri)) . '/'; + $request_uri = substr((string) $request_uri, 0, - 1 - strlen((string) $_SERVER['QUERY_STRING'])); + $config['root'] = str_replace('\\', '/', dirname((string) $request_uri)) == '/' + ? '/' : str_replace('\\', '/', dirname((string) $request_uri)) . '/'; unset($request_uri); } else $config['root'] = '/'; // CLI mode @@ -1178,7 +1099,7 @@ // The scheme and domain. This is used to get the site's absolute URL (eg. for image identification links). // If you use the CLI tools, it would be wise to override this setting. $config['domain'] = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off') ? 'https://' : 'http://'; - $config['domain'] .= isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'; + $config['domain'] .= $_SERVER['HTTP_HOST'] ?? 'localhost'; // If for some reason the folders and static HTML index files aren't in the current working direcotry, // enter the directory path here. Otherwise, keep it false. @@ -1287,7 +1208,7 @@ // 5. enable smart_build_helper (see below) // 6. edit the strategies (see inc/functions.php for the builtin ones). You can use lambdas. I will test // various ones and include one that works best for me. - $config['generation_strategies'] = array(); + $config['generation_strategies'] = []; // Add a sane strategy. It forces to immediately generate a page user is about to land on. Otherwise, // it has no opinion, so it needs a fallback strategy. $config['generation_strategies'][] = 'strategy_sane'; @@ -1310,7 +1231,7 @@ $config['page_404'] = '/404.html'; // Extra controller entrypoints. Controller is used only by smart_build and advanced build. - $config['controller_entrypoints'] = array(); + $config['controller_entrypoints'] = []; /* * ==================== @@ -1439,13 +1360,13 @@ // Probably best not to change this unless you are smart enough to figure out what you're doing. If you // decide to change it, remember that it is impossible to redefinite/overwrite groups; you may only add // new ones. - $config['mod']['groups'] = array( - 10 => 'Janitor', - 20 => 'Mod', - 30 => 'Admin', - // 98 => 'God', - 99 => 'Disabled' - ); + $config['mod']['groups'] = [ + 10 => 'Janitor', + 20 => 'Mod', + 30 => 'Admin', + // 98 => 'God', + 99 => 'Disabled', + ]; // If you add stuff to the above, you'll need to call this function immediately after. define_groups(); @@ -1455,11 +1376,7 @@ // define_groups(); // Capcode permissions. - $config['mod']['capcode'] = array( - JANITOR => array('Janitor'), - MOD => array('Mod'), - ADMIN => true - ); + $config['mod']['capcode'] = [JANITOR => ['Janitor'], MOD => ['Mod'], ADMIN => true]; // Example: Allow mods to post with "## Moderator" as well // $config['mod']['capcode'][MOD][] = 'Moderator'; @@ -1615,26 +1532,19 @@ $config['pages_max'] = 10; // Config editor permissions - $config['mod']['config'] = array(); + $config['mod']['config'] = []; // Disable the following configuration variables from being changed via ?/config. The following default // banned variables are considered somewhat dangerous. - $config['mod']['config'][DISABLED] = array( - 'mod>config', - 'mod>config_editor_php', - 'mod>groups', - 'convert_args', - 'db>password', - ); + $config['mod']['config'][DISABLED] = ['mod>config', 'mod>config_editor_php', 'mod>groups', 'convert_args', 'db>password']; - $config['mod']['config'][JANITOR] = array( - '!', // Allow editing ONLY the variables listed (in this case, nothing). - ); + $config['mod']['config'][JANITOR] = ['!']; - $config['mod']['config'][MOD] = array( - '!', // Allow editing ONLY the variables listed (plus that in $config['mod']['config'][JANITOR]). - 'global_message', - ); + $config['mod']['config'][MOD] = [ + '!', + // Allow editing ONLY the variables listed (plus that in $config['mod']['config'][JANITOR]). + 'global_message', + ]; // Example: Disallow ADMIN from editing (and viewing) $config['db']['password']. // $config['mod']['config'][ADMIN] = array( @@ -1664,16 +1574,16 @@ */ // Public post search settings - $config['search'] = array(); + $config['search'] = []; // Enable the search form $config['search']['enable'] = false; // Maximal number of queries per IP address per minutes - $config['search']['queries_per_minutes'] = Array(15, 2); + $config['search']['queries_per_minutes'] = [15, 2]; // Global maximal number of queries per minutes - $config['search']['queries_per_minutes_all'] = Array(50, 2); + $config['search']['queries_per_minutes_all'] = [50, 2]; // Limit of search results $config['search']['search_limit'] = 100; @@ -1729,7 +1639,7 @@ * state. Please join #nntpchan on Rizon in order to peer with someone. */ - $config['nntpchan'] = array(); + $config['nntpchan'] = []; // Enable NNTPChan integration $config['nntpchan']['enabled'] = false; @@ -1739,7 +1649,7 @@ // Global dispatch array. Add your boards to it to enable them. Please make // sure that this setting is set in a global context. - $config['nntpchan']['dispatch'] = array(); // 'overchan.test' => 'test' + $config['nntpchan']['dispatch'] = []; // 'overchan.test' => 'test' // Trusted peer - an IP address of your NNTPChan instance. This peer will have // increased capabilities, eg.: will evade spamfilter. @@ -1888,4 +1798,4 @@ $config['home_link'] = true; //Empty board alias - $config['boards_alias'] = array(); + $config['boards_alias'] = []; diff --git a/inc/controller.php b/inc/controller.php index 02e33443..ceb4fe41 100644 --- a/inc/controller.php +++ b/inc/controller.php @@ -12,7 +12,7 @@ function sb_board($b, $page = 1) { global $config, $build_pages; $page = (int)$p if (!openBoard($b)) return false; if ($page > $config['max_pages']) return false; $config['try_smarter'] = true; - $build_pages = array($page); + $build_pages = [$page]; buildIndex("skip"); return true; } @@ -24,7 +24,7 @@ function sb_api_board($b, $page = 0) { $page = (int)$page; function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = (int)$thread; if ($thread < 1) return false; - if (!preg_match('/^'.$config['board_regex'].'$/u', $b)) return false; + if (!preg_match('/^'.$config['board_regex'].'$/u', (string) $b)) return false; if (Cache::get("thread_exists_".$b."_".$thread) == "no") return false; @@ -47,7 +47,7 @@ function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = if ($slugcheck && $config['slugify']) { global $request; - $link = link_for(array("id" => $thread), $slugcheck === 50, array("uri" => $b)); + $link = link_for(["id" => $thread], $slugcheck === 50, ["uri" => $b]); $link = "/".$b."/".$config['dir']['res'].$link; if ($link != $request) { @@ -58,7 +58,7 @@ function sb_thread($b, $thread, $slugcheck = false) { global $config; $thread = if ($slugcheck == 50) { // Should we really generate +50 page? Maybe there are not enough posts anyway global $request; - $r = str_replace("+50", "", $request); + $r = str_replace("+50", "", (string) $request); $r = substr($r, 1); // Cut the slash if (file_exists($r)) return false; @@ -79,7 +79,7 @@ function sb_thread_slugcheck50($b, $thread) { function sb_api($b) { global $config, $build_pages; if (!openBoard($b)) return false; $config['try_smarter'] = true; - $build_pages = array(-1); + $build_pages = [-1]; buildIndex(); return true; } diff --git a/inc/database.php b/inc/database.php index 9fe303a4..53249314 100644 --- a/inc/database.php +++ b/inc/database.php @@ -18,7 +18,8 @@ class PreparedQueryDebug { $this->explain_query = $pdo->prepare("EXPLAIN $query"); } public function __call($function, $args) { - global $config, $debug; + $start = null; + global $config, $debug; if ($config['debug'] && $function == 'execute') { if ($this->explain_query) { @@ -28,18 +29,13 @@ class PreparedQueryDebug { } if ($this->explain_query && $function == 'bindValue') - call_user_func_array(array($this->explain_query, $function), $args); + call_user_func_array([$this->explain_query, $function], $args); - $return = call_user_func_array(array($this->query, $function), $args); + $return = call_user_func_array([$this->query, $function], $args); if ($config['debug'] && $function == 'execute') { $time = microtime(true) - $start; - $debug['sql'][] = array( - 'query' => $this->query->queryString, - 'rows' => $this->query->rowCount(), - 'explain' => $this->explain_query ? $this->explain_query->fetchAll(PDO::FETCH_ASSOC) : null, - 'time' => '~' . round($time * 1000, 2) . 'ms' - ); + $debug['sql'][] = ['query' => $this->query->queryString, 'rows' => $this->query->rowCount(), 'explain' => $this->explain_query ? $this->explain_query->fetchAll(PDO::FETCH_ASSOC) : null, 'time' => '~' . round($time * 1000, 2) . 'ms']; $debug['time']['db_queries'] += $time; } @@ -48,7 +44,8 @@ class PreparedQueryDebug { } function sql_open() { - global $pdo, $config, $debug; + $start = null; + global $pdo, $config, $debug; if ($pdo) return true; @@ -57,7 +54,7 @@ function sql_open() { $start = microtime(true); if (isset($config['db']['server'][0]) && $config['db']['server'][0] == ':') - $unix_socket = substr($config['db']['server'], 1); + $unix_socket = substr((string) $config['db']['server'], 1); else $unix_socket = false; @@ -67,9 +64,7 @@ function sql_open() { if (!empty($config['db']['dsn'])) $dsn .= ';' . $config['db']['dsn']; try { - $options = array( - PDO::ATTR_TIMEOUT => $config['db']['timeout'], - ); + $options = [PDO::ATTR_TIMEOUT => $config['db']['timeout']]; if ($config['db']['type'] == "mysql") $options[PDO::MYSQL_ATTR_USE_BUFFERED_QUERY] = true; @@ -104,7 +99,7 @@ function mysql_version() { global $pdo; $version = $pdo->getAttribute(PDO::ATTR_SERVER_VERSION); - $v = explode('.', $version); + $v = explode('.', (string) $version); if (count($v) != 3) return false; return (int) sprintf("%02d%02d%02d", $v[0], $v[1], $v[2]); @@ -139,12 +134,7 @@ function query($query) { if (!$query) return false; $time = microtime(true) - $start; - $debug['sql'][] = array( - 'query' => $query->queryString, - 'rows' => $query->rowCount(), - 'explain' => isset($explain) ? $explain->fetchAll(PDO::FETCH_ASSOC) : null, - 'time' => '~' . round($time * 1000, 2) . 'ms' - ); + $debug['sql'][] = ['query' => $query->queryString, 'rows' => $query->rowCount(), 'explain' => isset($explain) ? $explain->fetchAll(PDO::FETCH_ASSOC) : null, 'time' => '~' . round($time * 1000, 2) . 'ms']; $debug['time']['db_queries'] += $time; return $query; } diff --git a/inc/display.php b/inc/display.php index f702d7f8..cbe2fb0e 100644 --- a/inc/display.php +++ b/inc/display.php @@ -14,7 +14,7 @@ if (realpath($_SERVER['SCRIPT_FILENAME']) == str_replace('\\', '/', __FILE__)) { http://www.php.net/manual/en/function.filesize.php#100097 */ function format_bytes($size) { - $units = array(' B', ' KB', ' MB', ' GB', ' TB'); + $units = [' B', ' KB', ' MB', ' GB', ' TB']; for ($i = 0; $size >= 1024 && $i < 4; $i++) $size /= 1024; return round($size, 2).$units[$i]; } @@ -58,46 +58,33 @@ function doBoardListPart($list, $root, &$boards) { function createBoardlist($mod=false) { global $config; - if (!isset($config['boards'])) return array('top'=>'','bottom'=>''); + if (!isset($config['boards'])) return ['top'=>'', 'bottom'=>'']; $xboards = listBoards(); - $boards = array(); + $boards = []; foreach ($xboards as $val) { $boards[$val['uri']] = $val['title']; } $body = doBoardListPart($config['boards'], $mod?'?/':$config['root'], $boards); - if ($config['boardlist_wrap_bracket'] && !preg_match('/\] $/', $body)) + if ($config['boardlist_wrap_bracket'] && !preg_match('/\] $/', (string) $body)) $body = '[' . $body . ']'; - $body = trim($body); + $body = trim((string) $body); // Message compact-boardlist.js faster, so that page looks less ugly during loading $top = "<script type='text/javascript'>if (typeof do_boardlist != 'undefined') do_boardlist();</script>"; - return array( - 'top' => '<div class="boardlist">' . $body . '</div>' . $top, - 'bottom' => '<div class="boardlist bottom">' . $body . '</div>' - ); + return ['top' => '<div class="boardlist">' . $body . '</div>' . $top, 'bottom' => '<div class="boardlist bottom">' . $body . '</div>']; } -function loginForm($error=false, $username=false, $redirect=false) { +function loginForm($error=false, $username=false, $redirect=false): never { global $config; - die(Element('page.html', array( - 'index' => $config['root'], - 'title' => _('Login'), - 'config' => $config, - 'body' => Element('login.html', array( - 'config'=>$config, - 'error'=>$error, - 'username'=>utf8tohtml($username), - 'redirect'=>$redirect - ) - ) - ))); + die(Element('page.html', ['index' => $config['root'], 'title' => _('Login'), 'config' => $config, 'body' => Element('login.html', ['config'=>$config, 'error'=>$error, 'username'=>utf8tohtml($username), 'redirect'=>$redirect] + )])); } function pm_snippet($body, $len=null) { @@ -143,7 +130,7 @@ function capcode($cap) { if (!$cap) return false; - $capcode = array(); + $capcode = []; if (isset($config['custom_capcode'][$cap])) { if (is_array($config['custom_capcode'][$cap])) { $capcode['cap'] = sprintf($config['custom_capcode'][$cap][0], $cap); @@ -183,7 +170,7 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { $body = $m[0]; } - $body = mb_substr($body, 0, $max_chars); + $body = mb_substr((string) $body, 0, $max_chars); if ($body != $original_body) { // Remove any corrupt tags at the end @@ -192,15 +179,15 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { // Open tags if (preg_match_all('/<([\w]+)[^>]*>/', $body, $open_tags)) { - $tags = array(); - for ($x=0;$x<count($open_tags[0]);$x++) { - if (!preg_match('/\/(\s+)?>$/', $open_tags[0][$x])) + $tags = []; + for ($x=0;$x<(is_countable($open_tags[0]) ? count($open_tags[0]) : 0);$x++) { + if (!preg_match('/\/(\s+)?>$/', (string) $open_tags[0][$x])) $tags[] = $open_tags[1][$x]; } // List successfully closed tags if (preg_match_all('/(<\/([\w]+))>/', $body, $closed_tags)) { - for ($x=0;$x<count($closed_tags[0]);$x++) { + for ($x=0;$x<(is_countable($closed_tags[0]) ? count($closed_tags[0]) : 0);$x++) { unset($tags[array_search($closed_tags[2][$x], $tags)]); } } @@ -208,7 +195,7 @@ function truncate($body, $url, $max_lines = false, $max_chars = false) { // remove broken HTML entity at the end (if existent) $body = preg_replace('/&[^;]+$/', '', $body); - $tags_no_close_needed = array("colgroup", "dd", "dt", "li", "optgroup", "option", "p", "tbody", "td", "tfoot", "th", "thead", "tr", "br", "img"); + $tags_no_close_needed = ["colgroup", "dd", "dt", "li", "optgroup", "option", "p", "tbody", "td", "tfoot", "th", "thead", "tr", "br", "img"]; // Close any open tags foreach ($tags as &$tag) { @@ -233,12 +220,12 @@ function bidi_cleanup($data) { $explicits = '\xE2\x80\xAA|\xE2\x80\xAB|\xE2\x80\xAD|\xE2\x80\xAE'; $pdf = '\xE2\x80\xAC'; - preg_match_all("!$explicits!", $data, $m1, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); - preg_match_all("!$pdf!", $data, $m2, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + preg_match_all("!$explicits!", (string) $data, $m1, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); + preg_match_all("!$pdf!", (string) $data, $m2, PREG_OFFSET_CAPTURE | PREG_SET_ORDER); if (count($m1) || count($m2)){ - $p = array(); + $p = []; foreach ($m1 as $m){ $p[$m[0][1]] = 'push'; } foreach ($m2 as $m){ $p[$m[0][1]] = 'pop'; } ksort($p); @@ -254,8 +241,8 @@ function bidi_cleanup($data) { $stack--; }else{ # we have a pop without a push - remove it - $data = substr($data, 0, $pos-$offset) - .substr($data, $pos+3-$offset); + $data = substr((string) $data, 0, $pos-$offset) + .substr((string) $data, $pos+3-$offset); $offset += 3; } } @@ -275,7 +262,7 @@ function bidi_cleanup($data) { function secure_link_confirm($text, $title, $confirm_message, $href) { global $config; - return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes($confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>'; + return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes((string) $confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities((string) $title) . '" href="?/' . $href . '">' . $text . '</a>'; } function secure_link($href) { return $href . '/' . make_secure_link_token($href); @@ -315,7 +302,7 @@ class Post { } if (isset($this->files) && $this->files) - $this->files = @json_decode($this->files); + $this->files = @json_decode((string) $this->files, null, 512, JSON_THROW_ON_ERROR); $this->subject = utf8tohtml($this->subject); $this->name = utf8tohtml($this->name); @@ -336,7 +323,7 @@ class Post { // Fix internal links // Very complicated regex $this->body = preg_replace( - '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), $config['board_regex']) . ')/u', + '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote((string) $config['root'], '/') . '(' . sprintf(preg_quote((string) $config['board_path'], '/'), $config['board_regex']) . ')/u', '<a $1href="?/$4', $this->body ); @@ -350,7 +337,7 @@ class Post { public function build($index=false) { global $board, $config; - return Element('post_reply.html', array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'mod' => $this->mod)); + return Element('post_reply.html', ['config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'mod' => $this->mod]); } }; @@ -365,7 +352,7 @@ class Thread { } if (isset($this->files)) - $this->files = @json_decode($this->files); + $this->files = @json_decode((string) $this->files, null, 512, JSON_THROW_ON_ERROR); $this->subject = utf8tohtml($this->subject ?? ""); $this->name = utf8tohtml($this->name ?? ""); @@ -373,7 +360,7 @@ class Thread { $this->root = $root; $this->hr = $hr; - $this->posts = array(); + $this->posts = []; $this->omitted = 0; $this->omitted_images = 0; @@ -391,7 +378,7 @@ class Thread { // Fix internal links // Very complicated regex $this->body = preg_replace( - '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote($config['root'], '/') . '(' . sprintf(preg_quote($config['board_path'], '/'), $config['board_regex']) . ')/u', + '/<a((([a-zA-Z]+="[^"]+")|[a-zA-Z]+=[a-zA-Z]+|\s)*)href="' . preg_quote((string) $config['root'], '/') . '(' . sprintf(preg_quote((string) $config['board_path'], '/'), $config['board_regex']) . ')/u', '<a $1href="?/$4', $this->body ); @@ -405,7 +392,7 @@ class Thread { $this->posts[] = $post; } public function postCount() { - return count($this->posts) + $this->omitted; + return (is_countable($this->posts) ? count($this->posts) : 0) + $this->omitted; } public function build($index=false, $isnoko50=false) { global $board, $config, $debug; @@ -415,7 +402,7 @@ class Thread { event('show-thread', $this); $file = ($index && $config['file_board']) ? 'post_thread_fileboard.html' : 'post_thread.html'; - $built = Element($file, array('config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod)); + $built = Element($file, ['config' => $config, 'board' => $board, 'post' => &$this, 'index' => $index, 'hasnoko50' => $hasnoko50, 'isnoko50' => $isnoko50, 'mod' => $this->mod]); return $built; } diff --git a/inc/error.php b/inc/error.php index 37defe32..51054b7b 100644 --- a/inc/error.php +++ b/inc/error.php @@ -1,7 +1,8 @@ <?PHP function error_handler($errno,$errstr,$errfile, $errline){ - if(error_reporting() & $errno){ + $config = []; + if(error_reporting() & $errno){ $config['debug']=true; error($errstr . ' in ' . $errfile . ' at line ' . $errline); } @@ -49,9 +50,9 @@ function error($message, $priority = true, $debug_stuff = true) { } if ($config['debug']) { - $debug_stuff=array(); + $debug_stuff=[]; if(isset($db_error)){ - $debug_stuff = array_combine(array('SQLSTATE', 'Error code', 'Error message'), $db_error); + $debug_stuff = array_combine(['SQLSTATE', 'Error code', 'Error message'], $db_error); } $debug_stuff['backtrace'] = debug_backtrace(); $pw = $config['db']['password']; @@ -67,26 +68,15 @@ function error($message, $priority = true, $debug_stuff = true) { if (isset($_POST['json_response'])) { header('Content-Type: text/json; charset=utf-8'); - $data=array('error'=>$message); + $data=['error'=>$message]; if(!empty($config) && $config['debug']){ $data['debug']=$debug_stuff; } - print json_encode($data); + print json_encode($data, JSON_THROW_ON_ERROR); exit(); } header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error'); - die(Element('page.html', array( - 'config' => $config, - 'title' => _('Error'), - 'subtitle' => _('An error has occured.'), - 'body' => Element('error.html', array( - 'config' => $config, - 'message' => $message, - 'mod' => $mod, - 'board' => isset($board) ? $board : false, - 'debug' => str_replace("\n", ' ', utf8tohtml(print_r($debug_stuff, true))) - )) - ))); + die(Element('page.html', ['config' => $config, 'title' => _('Error'), 'subtitle' => _('An error has occured.'), 'body' => Element('error.html', ['config' => $config, 'message' => $message, 'mod' => $mod, 'board' => $board ?? false, 'debug' => str_replace("\n", ' ', (string) utf8tohtml(print_r($debug_stuff, true)))])])); } diff --git a/inc/events.php b/inc/events.php index e5a1e036..34c37920 100644 --- a/inc/events.php +++ b/inc/events.php @@ -32,7 +32,7 @@ function event_handler($event, $callback) { global $events; if (!isset($events[$event])) - $events[$event] = array(); + $events[$event] = []; $events[$event][] = $callback; } @@ -40,6 +40,6 @@ function event_handler($event, $callback) { function reset_events() { global $events; - $events = array(); + $events = []; } diff --git a/inc/filters.php b/inc/filters.php index b4781958..b63eb0f8 100644 --- a/inc/filters.php +++ b/inc/filters.php @@ -17,7 +17,7 @@ class Filter { } public function match($condition, $match) { - $condition = strtolower($condition); + $condition = strtolower((string) $condition); $post = &$this->post; @@ -32,7 +32,7 @@ class Filter { // Filter out "flood" table entries which do not match this filter. - $flood_check_matched = array(); + $flood_check_matched = []; foreach ($this->flood_check as $flood_post) { foreach ($match as $flood_match_arg) { @@ -85,15 +85,15 @@ class Filter { } return $count >= $match; case 'name': - return preg_match($match, $post['name']); + return preg_match($match, (string) $post['name']); case 'trip': return $match === $post['trip']; case 'email': - return preg_match($match, $post['email']); + return preg_match($match, (string) $post['email']); case 'subject': - return preg_match($match, $post['subject']); + return preg_match($match, (string) $post['subject']); case 'body': - return preg_match($match, $post['body_nomarkup']); + return preg_match($match, (string) $post['body_nomarkup']); case 'filehash': return $match === $post['filehash']; case 'filename': @@ -101,7 +101,7 @@ class Filter { return false; foreach ($post['files'] as $file) { - if (preg_match($match, $file['filename'])) { + if (preg_match($match, (string) $file['filename'])) { return true; } } @@ -111,13 +111,13 @@ class Filter { return false; foreach ($post['files'] as $file) { - if (preg_match($match, $file['extension'])) { + if (preg_match($match, (string) $file['extension'])) { return true; } } return false; case 'ip': - return preg_match($match, $_SERVER['REMOTE_ADDR']); + return preg_match($match, (string) $_SERVER['REMOTE_ADDR']); case 'op': return $post['op'] == $match; case 'has_file': @@ -132,9 +132,10 @@ class Filter { } public function action() { - global $board; + $message = null; + global $board; - $this->add_note = isset($this->add_note) ? $this->add_note : false; + $this->add_note ??= false; if ($this->add_note) { $query = prepare('INSERT INTO ``ip_notes`` VALUES (NULL, :ip, :mod, :time, :body)'); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); @@ -145,14 +146,14 @@ class Filter { } if (isset ($this->action)) switch($this->action) { case 'reject': - error(isset($this->message) ? $this->message : 'Posting blocked by filter.'); + error($this->message ?? 'Posting blocked by filter.'); case 'ban': if (!isset($this->reason)) error('The ban action requires a reason.'); - $this->expires = isset($this->expires) ? $this->expires : false; - $this->reject = isset($this->reject) ? $this->reject : true; - $this->all_boards = isset($this->all_boards) ? $this->all_boards : false; + $this->expires ??= false; + $this->reject ??= true; + $this->all_boards ??= false; Bans::new_ban($_SERVER['REMOTE_ADDR'], $this->reason, $this->expires, $this->all_boards ? false : $board['uri'], -1); @@ -175,7 +176,7 @@ class Filter { foreach ($this->condition as $condition => $value) { if ($condition[0] == '!') { $NOT = true; - $condition = substr($condition, 1); + $condition = substr((string) $condition, 1); } else $NOT = false; if ($this->match($condition, $value) == $NOT) diff --git a/inc/functions.php b/inc/functions.php index b4f07bcb..07cbd329 100755 --- a/inc/functions.php +++ b/inc/functions.php @@ -50,7 +50,7 @@ function init_locale($locale) { function loadConfig() { global $board, $config, $__ip, $debug, $__version, $microtime_start, $current_locale, $events; - $boardsuffix = isset($board['uri']) ? $board['uri'] : ''; + $boardsuffix = $board['uri'] ?? ''; if (!isset($_SERVER['REMOTE_ADDR'])) $_SERVER['REMOTE_ADDR'] = '0.0.0.0'; @@ -76,42 +76,14 @@ function loadConfig() { } } else { - $config = array(); + $config = []; reset_events(); - $arrays = array( - 'db', - 'api', - 'cache', - 'lock', - 'queue', - 'cookies', - 'error', - 'dir', - 'mod', - 'spam', - 'filters', - 'wordfilters', - 'custom_capcode', - 'custom_tripcode', - 'dnsbl', - 'dnsbl_exceptions', - 'remote', - 'allowed_ext', - 'allowed_ext_files', - 'file_icons', - 'footer', - 'stylesheets', - 'code_stylesheets', - 'additional_javascript', - 'markup', - 'custom_pages', - 'dashboard_links' - ); + $arrays = ['db', 'api', 'cache', 'lock', 'queue', 'cookies', 'error', 'dir', 'mod', 'spam', 'filters', 'wordfilters', 'custom_capcode', 'custom_tripcode', 'dnsbl', 'dnsbl_exceptions', 'remote', 'allowed_ext', 'allowed_ext_files', 'file_icons', 'footer', 'stylesheets', 'code_stylesheets', 'additional_javascript', 'markup', 'custom_pages', 'dashboard_links']; foreach ($arrays as $key) { - $config[$key] = array(); + $config[$key] = []; } if (!file_exists('inc/instance-config.php')) @@ -133,7 +105,7 @@ function loadConfig() { if (isset($board['dir']) && file_exists($board['dir'] . '/config.php')) { $configstr .= file_get_contents($board['dir'] . '/config.php'); } - $matches = array(); + $matches = []; preg_match_all('/[^\/#*]\$config\s*\[\s*[\'"]locale[\'"]\s*\]\s*=\s*([\'"])(.*?)\1/', $configstr, $matches); if ($matches && isset ($matches[2]) && $matches[2]) { $matches = $matches[2]; @@ -171,26 +143,26 @@ function loadConfig() { if (!isset($config['referer_match'])) if (isset($_SERVER['HTTP_HOST'])) { $config['referer_match'] = '/^' . - (preg_match('@^https?://@', $config['root']) ? '' : + (preg_match('@^https?://@', (string) $config['root']) ? '' : 'https?:\/\/' . $_SERVER['HTTP_HOST']) . - preg_quote($config['root'], '/') . + preg_quote((string) $config['root'], '/') . '(' . - str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) . + str_replace('%s', $config['board_regex'], preg_quote((string) $config['board_path'], '/')) . '(' . - preg_quote($config['file_index'], '/') . '|' . - str_replace('%d', '\d+', preg_quote($config['file_page'])) . + preg_quote((string) $config['file_index'], '/') . '|' . + str_replace('%d', '\d+', preg_quote((string) $config['file_page'])) . ')?' . '|' . - str_replace('%s', $config['board_regex'], preg_quote($config['board_path'], '/')) . - preg_quote($config['dir']['res'], '/') . + str_replace('%s', $config['board_regex'], preg_quote((string) $config['board_path'], '/')) . + preg_quote((string) $config['dir']['res'], '/') . '(' . - str_replace('%d', '\d+', preg_quote($config['file_page'], '/')) . '|' . - str_replace('%d', '\d+', preg_quote($config['file_page50'], '/')) . '|' . - str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '/')) . '|' . - str_replace(array('%d', '%s'), array('\d+', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) . + str_replace('%d', '\d+', preg_quote((string) $config['file_page'], '/')) . '|' . + str_replace('%d', '\d+', preg_quote((string) $config['file_page50'], '/')) . '|' . + str_replace(['%d', '%s'], ['\d+', '[a-z0-9-]+'], preg_quote((string) $config['file_page_slug'], '/')) . '|' . + str_replace(['%d', '%s'], ['\d+', '[a-z0-9-]+'], preg_quote((string) $config['file_page50_slug'], '/')) . ')' . '|' . - preg_quote($config['file_mod'], '/') . '\?\/.+' . + preg_quote((string) $config['file_mod'], '/') . '\?\/.+' . ')([#?](.+)?)?$/ui'; } else { // CLI mode @@ -240,7 +212,7 @@ function loadConfig() { if (!isset($config['user_flag'])) $config['user_flag'] = false; if (!isset($config['user_flags'])) - $config['user_flags'] = array(); + $config['user_flags'] = []; if (!isset($__version)) $__version = file_exists('.installed') ? trim(file_get_contents('.installed')) : false; @@ -266,7 +238,7 @@ function loadConfig() { $__ip = $_SERVER['REMOTE_ADDR']; // ::ffff:0.0.0.0 - if (preg_match('/^\:\:(ffff\:)?(\d+\.\d+\.\d+\.\d+)$/', $__ip, $m)) + if (preg_match('/^\:\:(ffff\:)?(\d+\.\d+\.\d+\.\d+)$/', (string) $__ip, $m)) $_SERVER['REMOTE_ADDR'] = $m[2]; if ($config['verbose_errors']) { @@ -314,19 +286,7 @@ function loadConfig() { if ($config['debug']) { if (!isset($debug)) { - $debug = array( - 'sql' => array(), - 'exec' => array(), - 'purge' => array(), - 'cached' => array(), - 'write' => array(), - 'time' => array( - 'db_queries' => 0, - 'exec' => 0, - ), - 'start' => $microtime_start, - 'start_debug' => microtime(true) - ); + $debug = ['sql' => [], 'exec' => [], 'purge' => [], 'cached' => [], 'write' => [], 'time' => ['db_queries' => 0, 'exec' => 0], 'start' => $microtime_start, 'start_debug' => microtime(true)]; $debug['start'] = $microtime_start; } } @@ -347,7 +307,7 @@ function define_groups() { global $config; foreach ($config['mod']['groups'] as $group_value => $group_name) { - $group_name = strtoupper($group_name); + $group_name = strtoupper((string) $group_name); if(!defined($group_name)) { define($group_name, $group_value); } @@ -357,7 +317,7 @@ function define_groups() { } function create_antibot($board, $thread = null) { - require_once dirname(__FILE__) . '/anti-bot.php'; + require_once __DIR__ . '/anti-bot.php'; return _create_antibot($board, $thread); } @@ -376,7 +336,7 @@ function rebuildThemes($action, $boardname = false) { else { $query = query("SELECT `theme` FROM ``theme_settings`` WHERE `name` IS NULL AND `value` IS NULL") or error(db_error()); - $themes = array(); + $themes = []; while ($theme = $query->fetch(PDO::FETCH_ASSOC)) { $themes[] = $theme; @@ -420,7 +380,8 @@ function rebuildThemes($action, $boardname = false) { function loadThemeConfig($_theme) { - global $config; + $theme = null; + global $config; if (!file_exists($config['dir']['themes'] . '/' . $_theme . '/info.php')) return false; @@ -454,7 +415,7 @@ function themeSettings($theme) { $query->bindValue(':theme', $theme); $query->execute() or error(db_error($query)); - $settings = array(); + $settings = []; while ($s = $query->fetch(PDO::FETCH_ASSOC)) { $settings[$s['name']] = $s['value']; } @@ -465,27 +426,22 @@ function themeSettings($theme) { } function sprintf3($str, $vars, $delim = '%') { - $replaces = array(); + $replaces = []; foreach ($vars as $k => $v) { $replaces[$delim . $k . $delim] = $v; } return str_replace(array_keys($replaces), - array_values($replaces), $str); + array_values($replaces), (string) $str); } function mb_substr_replace($string, $replacement, $start, $length) { - return mb_substr($string, 0, $start) . $replacement . mb_substr($string, $start + $length); + return mb_substr((string) $string, 0, $start) . $replacement . mb_substr((string) $string, $start + $length); } function setupBoard($array) { global $board, $config; - $board = array( - 'uri' => $array['uri'], - 'title' => $array['title'], - 'subtitle' => $array['subtitle'], - #'indexed' => $array['indexed'], - ); + $board = ['uri' => $array['uri'], 'title' => $array['title'], 'subtitle' => $array['subtitle']]; // older versions $board['name'] = &$board['title']; @@ -512,7 +468,7 @@ function openBoard($uri) { global $config, $build_pages, $board; if ($config['try_smarter']) - $build_pages = array(); + $build_pages = []; // And what if we don't really need to change a board we have opened? if (isset ($board) && isset ($board['uri']) && $board['uri'] == $uri) { @@ -563,15 +519,15 @@ function purge($uri) { global $config, $debug; // Fix for Unicode - $uri = rawurlencode($uri); + $uri = rawurlencode((string) $uri); $noescape = "/!~*()+:"; $noescape = preg_split('//', $noescape); $noescape_url = array_map("rawurlencode", $noescape); $uri = str_replace($noescape_url, $noescape, $uri); - if (preg_match($config['referer_match'], $config['root']) && isset($_SERVER['REQUEST_URI'])) { - $uri = (str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname($_SERVER['REQUEST_URI'])) . '/') . $uri; + if (preg_match($config['referer_match'], (string) $config['root']) && isset($_SERVER['REQUEST_URI'])) { + $uri = (str_replace('\\', '/', dirname((string) $_SERVER['REQUEST_URI'])) == '/' ? '/' : str_replace('\\', '/', dirname((string) $_SERVER['REQUEST_URI'])) . '/') . $uri; } else { $uri = $config['root'] . $uri; } @@ -583,7 +539,7 @@ function purge($uri) { foreach ($config['purge'] as &$purge) { $host = &$purge[0]; $port = &$purge[1]; - $http_host = isset($purge[2]) ? $purge[2] : (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : 'localhost'); + $http_host = $purge[2] ?? $_SERVER['HTTP_HOST'] ?? 'localhost'; $request = "PURGE {$uri} HTTP/1.1\r\nHost: {$http_host}\r\nUser-Agent: Tinyboard\r\nConnection: Close\r\n\r\n"; if ($fp = fsockopen($host, $port, $errno, $errstr, $config['purge_timeout'])) { fwrite($fp, $request); @@ -597,7 +553,7 @@ function purge($uri) { function file_write($path, $data, $simple = false, $skip_purge = false) { global $config, $debug; - if (preg_match('/^remote:\/\/(.+)\:(.+)$/', $path, $m)) { + if (preg_match('/^remote:\/\/(.+)\:(.+)$/', (string) $path, $m)) { if (isset($config['remote'][$m[1]])) { require_once 'inc/remote.php'; @@ -622,7 +578,7 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { error('Unable to truncate file: ' . $path); // Write data - if (($bytes = fwrite($fp, $data)) === false) + if (($bytes = fwrite($fp, (string) $data)) === false) error('Unable to write to file: ' . $path); // Unlock @@ -645,7 +601,7 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { $gzpath = "$path.gz"; if ($bytes & ~0x3ff) { // if ($bytes >= 1024) - if (file_put_contents($gzpath, gzencode($data), $simple ? 0 : LOCK_EX) === false) + if (file_put_contents($gzpath, gzencode((string) $data), $simple ? 0 : LOCK_EX) === false) error("Unable to write to file: $gzpath"); //if (!touch($gzpath, filemtime($path), fileatime($path))) // error("Unable to touch file: $gzpath"); @@ -657,9 +613,9 @@ function file_write($path, $data, $simple = false, $skip_purge = false) { if (!$skip_purge && isset($config['purge'])) { // Purge cache - if (basename($path) == $config['file_index']) { + if (basename((string) $path) == $config['file_index']) { // Index file (/index.html); purge "/" as well - $uri = dirname($path); + $uri = dirname((string) $path); // root if ($uri == '.') $uri = ''; @@ -682,7 +638,7 @@ function file_unlink($path) { if ($config['debug']) { if (!isset($debug['unlink'])) - $debug['unlink'] = array(); + $debug['unlink'] = []; $debug['unlink'][] = $path; } @@ -696,9 +652,9 @@ function file_unlink($path) { if (isset($config['purge']) && $path[0] != '/' && isset($_SERVER['HTTP_HOST'])) { // Purge cache - if (basename($path) == $config['file_index']) { + if (basename((string) $path) == $config['file_index']) { // Index file (/index.html); purge "/" as well - $uri = dirname($path); + $uri = dirname((string) $path); // root if ($uri == '.') $uri = ''; @@ -752,7 +708,7 @@ function listBoards($just_uri = false) { $query = query("SELECT * FROM ``boards`` ORDER BY `uri`") or error(db_error()); $boards = $query->fetchAll(); } else { - $boards = array(); + $boards = []; $query = query("SELECT `uri` FROM ``boards``") or error(db_error()); while ($board = $query->fetchColumn()) { $boards[] = $board; @@ -767,38 +723,26 @@ function listBoards($just_uri = false) { function until($timestamp) { $difference = $timestamp - time(); - switch(TRUE){ - case ($difference < 60): - return $difference . ' ' . ngettext('second', 'seconds', $difference); - case ($difference < 3600): //60*60 = 3600 - return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); - case ($difference < 86400): //60*60*24 = 86400 - return ($num = round($difference/(3600))) . ' ' . ngettext('hour', 'hours', $num); - case ($difference < 604800): //60*60*24*7 = 604800 - return ($num = round($difference/(86400))) . ' ' . ngettext('day', 'days', $num); - case ($difference < 31536000): //60*60*24*365 = 31536000 - return ($num = round($difference/(604800))) . ' ' . ngettext('week', 'weeks', $num); - default: - return ($num = round($difference/(31536000))) . ' ' . ngettext('year', 'years', $num); - } + return match (TRUE) { + $difference < 60 => $difference . ' ' . ngettext('second', 'seconds', $difference), + $difference < 3600 => ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num), + $difference < 86400 => ($num = round($difference/(3600))) . ' ' . ngettext('hour', 'hours', $num), + $difference < 604800 => ($num = round($difference/(86400))) . ' ' . ngettext('day', 'days', $num), + $difference < 31_536_000 => ($num = round($difference/(604800))) . ' ' . ngettext('week', 'weeks', $num), + default => ($num = round($difference/(31_536_000))) . ' ' . ngettext('year', 'years', $num), + }; } function ago($timestamp) { $difference = time() - $timestamp; - switch(TRUE){ - case ($difference < 60) : - return $difference . ' ' . ngettext('second', 'seconds', $difference); - case ($difference < 3600): //60*60 = 3600 - return ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num); - case ($difference < 86400): //60*60*24 = 86400 - return ($num = round($difference/(3600))) . ' ' . ngettext('hour', 'hours', $num); - case ($difference < 604800): //60*60*24*7 = 604800 - return ($num = round($difference/(86400))) . ' ' . ngettext('day', 'days', $num); - case ($difference < 31536000): //60*60*24*365 = 31536000 - return ($num = round($difference/(604800))) . ' ' . ngettext('week', 'weeks', $num); - default: - return ($num = round($difference/(31536000))) . ' ' . ngettext('year', 'years', $num); - } + return match (TRUE) { + $difference < 60 => $difference . ' ' . ngettext('second', 'seconds', $difference), + $difference < 3600 => ($num = round($difference/(60))) . ' ' . ngettext('minute', 'minutes', $num), + $difference < 86400 => ($num = round($difference/(3600))) . ' ' . ngettext('hour', 'hours', $num), + $difference < 604800 => ($num = round($difference/(86400))) . ' ' . ngettext('day', 'days', $num), + $difference < 31_536_000 => ($num = round($difference/(604800))) . ' ' . ngettext('week', 'weeks', $num), + default => ($num = round($difference/(31_536_000))) . ' ' . ngettext('year', 'years', $num), + }; } function displayBan($ban) { @@ -825,7 +769,7 @@ function displayBan($ban) { } } - $denied_appeals = array(); + $denied_appeals = []; $pending_appeal = false; if ($config['ban_appeals']) { @@ -841,19 +785,8 @@ function displayBan($ban) { // Show banned page and exit die( - Element('page.html', array( - 'title' => _('Banned!'), - 'config' => $config, - 'boardlist' => createBoardlist(isset($mod) ? $mod : false), - 'body' => Element('banned.html', array( - 'config' => $config, - 'ban' => $ban, - 'board' => $board, - 'post' => isset($post) ? $post->build(true) : false, - 'denied_appeals' => $denied_appeals, - 'pending_appeal' => $pending_appeal - ) - )) + Element('page.html', ['title' => _('Banned!'), 'config' => $config, 'boardlist' => createBoardlist($mod ?? false), 'body' => Element('banned.html', ['config' => $config, 'ban' => $ban, 'board' => $board, 'post' => isset($post) ? $post->build(true) : false, 'denied_appeals' => $denied_appeals, 'pending_appeal' => $pending_appeal] + )] )); } @@ -868,12 +801,12 @@ function checkBan($board = false) { if (event('check-ban', $board)) return true; - $ips = array(); + $ips = []; $ips[] = $_SERVER['REMOTE_ADDR']; if ($config['proxy_check'] && isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { - $ips = array_merge($ips, explode(", ", $_SERVER['HTTP_X_FORWARDED_FOR'])); + $ips = array_merge($ips, explode(", ", (string) $_SERVER['HTTP_X_FORWARDED_FOR'])); } foreach ($ips as $ip) { @@ -887,7 +820,7 @@ function checkBan($board = false) { displayBan($ban); } else { header('Content-Type: text/json'); - die(json_encode(array('error' => true, 'banned' => true))); + die(json_encode(['error' => true, 'banned' => true])); } } } else { @@ -895,7 +828,7 @@ function checkBan($board = false) { displayBan($ban); } else { header('Content-Type: text/json'); - die(json_encode(array('error' => true, 'banned' => true))); + die(json_encode(['error' => true, 'banned' => true])); } } } @@ -1006,9 +939,9 @@ function post(array $post) { $query->bindValue(':name', $post['name']); $query->bindValue(':body', $post['body']); $query->bindValue(':body_nomarkup', $post['body_nomarkup']); - $query->bindValue(':time', isset($post['time']) ? $post['time'] : time(), PDO::PARAM_INT); + $query->bindValue(':time', $post['time'] ?? time(), PDO::PARAM_INT); $query->bindValue(':password', $post['password']); - $query->bindValue(':ip', isset($post['ip']) ? $post['ip'] : $_SERVER['REMOTE_ADDR']); + $query->bindValue(':ip', $post['ip'] ?? $_SERVER['REMOTE_ADDR']); if ($post['op'] && $post['mod'] && isset($post['sticky']) && $post['sticky']) { $query->bindValue(':sticky', true, PDO::PARAM_INT); @@ -1053,7 +986,7 @@ function post(array $post) { } if ($post['has_file']) { - $query->bindValue(':files', json_encode($post['files'])); + $query->bindValue(':files', json_encode($post['files'], JSON_THROW_ON_ERROR)); $query->bindValue(':num_files', $post['num_files']); $query->bindValue(':filehash', $post['filehash']); } else { @@ -1102,8 +1035,8 @@ function deleteFile($id, $remove_entirely_if_already=true, $file=null) { $query->execute() or error(db_error($query)); if (!$post = $query->fetch(PDO::FETCH_ASSOC)) error($config['error']['invalidpost']); - $files = json_decode($post['files']); - $file_to_delete = $file !== false ? $files[(int)$file] : (object)array('file' => false); + $files = json_decode((string) $post['files'], null, 512, JSON_THROW_ON_ERROR); + $file_to_delete = $file !== false ? $files[(int)$file] : (object)['file' => false]; if (!$files[0]) error(_('That post has no files.')); @@ -1130,7 +1063,7 @@ function deleteFile($id, $remove_entirely_if_already=true, $file=null) { } } - $query->bindValue(':file', json_encode($files), PDO::PARAM_STR); + $query->bindValue(':file', json_encode($files, JSON_THROW_ON_ERROR), PDO::PARAM_STR); $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -1151,8 +1084,9 @@ function rebuildPost($id) { if ((!$post = $query->fetch(PDO::FETCH_ASSOC)) || !$post['body_nomarkup']) return false; + $post['body'] = &$post['body_nomarkup']; - markup($post['body'] = &$post['body_nomarkup']); + markup($post['body']); $post = (object)$post; event('rebuildpost', $post); $post = (array)$post; @@ -1162,14 +1096,15 @@ function rebuildPost($id) { $query->bindValue(':id', $id, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - buildThread($post['thread'] ? $post['thread'] : $id); + buildThread($post['thread'] ?: $id); return true; } // Delete a post (reply or thread) function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { - global $board, $config; + $thread_id = null; + global $board, $config; // Select post and replies (if thread) in one query $query = prepare(sprintf("SELECT `id`,`thread`,`files`,`slug` FROM ``posts_%s`` WHERE `id` = :id OR `thread` = :id", $board['uri'])); @@ -1182,7 +1117,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { else return false; } - $ids = array(); + $ids = []; // Delete posts and maybe replies while ($post = $query->fetch(PDO::FETCH_ASSOC)) { @@ -1205,7 +1140,7 @@ function deletePost($id, $error_if_doesnt_exist=true, $rebuild_after=true) { } if ($post['files']) { // Delete file - foreach (json_decode($post['files']) as $i => $f) { + foreach (json_decode((string) $post['files'], null, 512, JSON_THROW_ON_ERROR) as $i => $f) { if ($f->file !== 'deleted') { file_unlink($board['dir'] . $config['dir']['img'] . $f->file); file_unlink($board['dir'] . $config['dir']['thumb'] . $f->thumb); @@ -1301,7 +1236,8 @@ function thread_find_page($thread) { // $brief means that we won't need to generate anything yet function index($page, $mod=false, $brief = false) { - global $board, $config, $debug; + $omitted = []; + global $board, $config, $debug; $body = ''; $offset = round($page*$config['threads_per_page']-$config['threads_per_page']); @@ -1317,7 +1253,7 @@ function index($page, $mod=false, $brief = false) { if ($query->rowCount() < 1 && $page > 1) return false; - $threads = array(); + $threads = []; while ($th = $query->fetch(PDO::FETCH_ASSOC)) { $thread = new Thread($th, $mod ? '?/' : $config['root'], $mod); @@ -1342,16 +1278,13 @@ function index($page, $mod=false, $brief = false) { if (count($replies) == ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview'])) { $count = numPosts($th['id']); - $omitted = array('post_count' => $count['replies'], 'image_count' => $count['images']); + $omitted = ['post_count' => $count['replies'], 'image_count' => $count['images']]; } else { $omitted = false; } if ($config['cache']['enabled']) - cache::set("thread_index_{$board['uri']}_{$th['id']}", array( - 'replies' => $replies, - 'omitted' => $omitted, - )); + cache::set("thread_index_{$board['uri']}_{$th['id']}", ['replies' => $replies, 'omitted' => $omitted]); } $num_images = 0; @@ -1363,7 +1296,7 @@ function index($page, $mod=false, $brief = false) { } $thread->images = $num_images; - $thread->replies = isset($omitted['post_count']) ? $omitted['post_count'] : count($replies); + $thread->replies = $omitted['post_count'] ?? count($replies); if ($omitted) { $thread->omitted = $omitted['post_count'] - ($th['sticky'] ? $config['threads_preview_sticky'] : $config['threads_preview']); @@ -1378,22 +1311,15 @@ function index($page, $mod=false, $brief = false) { } if ($config['file_board']) { - $body = Element('fileboard.html', array('body' => $body, 'mod' => $mod)); + $body = Element('fileboard.html', ['body' => $body, 'mod' => $mod]); } - return array( - 'board' => $board, - 'body' => $body, - 'post_url' => $config['post_url'], - 'config' => $config, - 'boardlist' => createBoardlist($mod), - 'threads' => $threads, - ); + return ['board' => $board, 'body' => $body, 'post_url' => $config['post_url'], 'config' => $config, 'boardlist' => createBoardlist($mod), 'threads' => $threads]; } function getPageButtons($pages, $mod=false) { global $config, $board; - $btn = array(); + $btn = []; $root = ($mod ? '?/' : $config['root']) . $board['dir']; foreach ($pages as $num => $page) { @@ -1418,7 +1344,7 @@ function getPageButtons($pages, $mod=false) { '<input type="submit" value="' . _('Previous') . '" /></form>'; } - if ($num == count($pages) - 1) { + if ($num == (is_countable($pages) ? count($pages) : 0) - 1) { // There is no next page. $btn['next'] = _('Next'); } else { @@ -1451,12 +1377,9 @@ function getPages($mod=false) { if ($count < 1) $count = 1; - $pages = array(); + $pages = []; for ($x=0;$x<$count && $x<$config['max_pages'];$x++) { - $pages[] = array( - 'num' => $x+1, - 'link' => $x==0 ? ($mod ? '?/' : $config['root']) . $board['dir'] . $config['file_index'] : ($mod ? '?/' : $config['root']) . $board['dir'] . sprintf($config['file_page'], $x+1) - ); + $pages[] = ['num' => $x+1, 'link' => $x==0 ? ($mod ? '?/' : $config['root']) . $board['dir'] . $config['file_index'] : ($mod ? '?/' : $config['root']) . $board['dir'] . sprintf($config['file_page'], $x+1)]; } return $pages; @@ -1486,7 +1409,7 @@ function make_comment_hex($str) { function makerobot($body) { global $config; - $body = strtolower($body); + $body = strtolower((string) $body); // Leave only letters $body = preg_replace('/[^a-z]/i', '', $body); @@ -1542,7 +1465,7 @@ function muteTime() { if (!$result = $query->fetchColumn()) return 0; - return pow($config['robot_mute_multiplier'], $result); + return $config['robot_mute_multiplier'] ** $result; } function mute() { @@ -1592,16 +1515,19 @@ function checkMute() { } function buildIndex($global_api = "yes") { - global $board, $config, $build_pages; + $api = null; + $catalog = []; + $action = null; + global $board, $config, $build_pages; - $catalog_api_action = generation_strategy('sb_api', array($board['uri'])); + $catalog_api_action = generation_strategy('sb_api', [$board['uri']]); $pages = null; $antibot = null; if ($config['api']['enabled']) { $api = new Api(); - $catalog = array(); + $catalog = []; } for ($page = 1; $page <= $config['max_pages']; $page++) { @@ -1613,7 +1539,7 @@ function buildIndex($global_api = "yes") { if ((!$config['api']['enabled'] || $global_api == "skip") && $wont_build_this_page) continue; - $action = generation_strategy('sb_board', array($board['uri'], $page)); + $action = generation_strategy('sb_board', [$board['uri'], $page]); if ($action == 'rebuild' || $catalog_api_action == 'rebuild') { $content = index($page, false, $wont_build_this_page); if (!$content) @@ -1622,7 +1548,7 @@ function buildIndex($global_api = "yes") { // json api if ($config['api']['enabled']) { $threads = $content['threads']; - $json = json_encode($api->translatePage($threads)); + $json = json_encode($api->translatePage($threads), JSON_THROW_ON_ERROR); file_write($jsonFilename, $json); $catalog[$page-1] = $threads; @@ -1675,45 +1601,37 @@ function buildIndex($global_api = "yes") { file_unlink($jsonFilename); } elseif ($catalog_api_action == 'rebuild') { - $json = json_encode($api->translateCatalog($catalog)); + $json = json_encode($api->translateCatalog($catalog), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'catalog.json'; file_write($jsonFilename, $json); - $json = json_encode($api->translateCatalog($catalog, true)); + $json = json_encode($api->translateCatalog($catalog, true), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'threads.json'; file_write($jsonFilename, $json); } } if ($config['try_smarter']) - $build_pages = array(); + $build_pages = []; } function buildJavascript() { global $config; - $stylesheets = array(); + $stylesheets = []; foreach ($config['stylesheets'] as $name => $uri) { - $stylesheets[] = array( - 'name' => addslashes($name), - 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)); + $stylesheets[] = ['name' => addslashes((string) $name), 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)]; } - $code_stylesheets = array(); + $code_stylesheets = []; foreach ($config['code_stylesheets'] as $name => $uri) { - $code_stylesheets[] = array( - 'name' => addslashes($name), - 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)); + $code_stylesheets[] = ['name' => addslashes((string) $name), 'uri' => addslashes((!empty($uri) ? $config['uri_stylesheets'] : '') . $uri)]; } - $script = Element('main.js', array( - 'config' => $config, - 'stylesheets' => $stylesheets, - 'code_stylesheets' => $code_stylesheets - )); + $script = Element('main.js', ['config' => $config, 'stylesheets' => $stylesheets, 'code_stylesheets' => $code_stylesheets]); // Check if we have translation for the javascripts; if yes, we add it to additional javascripts - list($pure_locale) = explode(".", $config['locale']); + [$pure_locale] = explode(".", (string) $config['locale']); if (file_exists ($jsloc = "inc/locale/$pure_locale/LC_MESSAGES/javascript.js")) { $script = file_get_contents($jsloc) . "\n\n" . $script; } @@ -1740,7 +1658,7 @@ function checkDNSBL() { if (!isset($_SERVER['REMOTE_ADDR'])) return; // Fix your web server configuration - if (preg_match("/^(::(ffff:)?)?(127\.|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|0\.|255\.)/", $_SERVER['REMOTE_ADDR'])) + if (preg_match("/^(::(ffff:)?)?(127\.|192\.168\.|10\.|172\.(1[6-9]|2[0-9]|3[0-1])\.|0\.|255\.)/", (string) $_SERVER['REMOTE_ADDR'])) return; // It's pointless to check for local IP addresses in dnsbls, isn't it? if (in_array($_SERVER['REMOTE_ADDR'], $config['dnsbl_exceptions'])) @@ -1750,15 +1668,15 @@ function checkDNSBL() { foreach ($config['dnsbl'] as $blacklist) { if (!is_array($blacklist)) - $blacklist = array($blacklist); + $blacklist = [$blacklist]; - if (($lookup = str_replace('%', $ipaddr, $blacklist[0])) == $blacklist[0]) + if (($lookup = str_replace('%', $ipaddr, (string) $blacklist[0])) == $blacklist[0]) $lookup = $ipaddr . '.' . $blacklist[0]; if (!$ip = DNS($lookup)) continue; // not in list - $blacklist_name = isset($blacklist[2]) ? $blacklist[2] : $blacklist[0]; + $blacklist_name = $blacklist[2] ?? $blacklist[0]; if (!isset($blacklist[1])) { // If you're listed at all, you're blocked. @@ -1779,11 +1697,11 @@ function checkDNSBL() { } function isIPv6() { - return strstr($_SERVER['REMOTE_ADDR'], ':') !== false; + return str_contains((string) $_SERVER['REMOTE_ADDR'], ':'); } function ReverseIPOctets($ip) { - return implode('.', array_reverse(explode('.', $ip))); + return implode('.', array_reverse(explode('.', (string) $ip))); } function wordfilters(&$body) { @@ -1792,7 +1710,7 @@ function wordfilters(&$body) { foreach ($config['wordfilters'] as $filter) { if (isset($filter[3]) && $filter[3]) { $refilter = $filter[0]; - if (strncmp($filter[0], "/", 1) !== 0) + if (!str_starts_with((string) $filter[0], "/")) { $refilter = "/.*" . $filter[0] . "/"; } @@ -1804,7 +1722,7 @@ function wordfilters(&$body) { } else { if (isset($filter[2]) && $filter[2]) { $refilter = $filter[0]; - if (strncmp($filter[0], "/", 1) !== 0) + if (!str_starts_with((string) $filter[0], "/")) { $refilter = "/.*" . $filter[0] . "/"; } @@ -1838,7 +1756,7 @@ function wordfilters(&$body) { function quote($body, $quote=true) { global $config; - $body = str_replace('<br/>', "\n", $body); + $body = str_replace('<br/>', "\n", (string) $body); $body = strip_tags($body); @@ -1860,17 +1778,12 @@ function markup_url($matches) { $markup_urls[] = $url; - $link = (object) array( - 'href' => $config['link_prefix'] . $url, - 'text' => $url, - 'rel' => 'nofollow', - 'target' => '_blank', - ); + $link = (object) ['href' => $config['link_prefix'] . $url, 'text' => $url, 'rel' => 'nofollow', 'target' => '_blank']; event('markup-url', $link); $link = (array)$link; - $parts = array(); + $parts = []; foreach ($link as $attr => $value) { if ($attr == 'text' || $attr == 'after') continue; @@ -1882,7 +1795,7 @@ function markup_url($matches) { } function unicodify($body) { - $body = str_replace('...', '…', $body); + $body = str_replace('...', '…', (string) $body); $body = str_replace('<--', '←', $body); $body = str_replace('-->', '→', $body); @@ -1896,13 +1809,13 @@ function unicodify($body) { } function extract_modifiers($body) { - $modifiers = array(); + $modifiers = []; - if (preg_match_all('@<tinyboard ([\w\s]+)>(.*?)</tinyboard>@us', $body, $matches, PREG_SET_ORDER)) { + if (preg_match_all('@<tinyboard ([\w\s]+)>(.*?)</tinyboard>@us', (string) $body, $matches, PREG_SET_ORDER)) { foreach ($matches as $match) { - if (preg_match('/^escape /', $match[1])) + if (preg_match('/^escape /', (string) $match[1])) continue; - $modifiers[$match[1]] = html_entity_decode($match[2]); + $modifiers[$match[1]] = html_entity_decode((string) $match[2]); } } @@ -1922,17 +1835,17 @@ function markup(&$body, $track_cites = false, $op = false) { $body = preg_replace('@<(tinyboard) escape ([\w\s]+)>@i', '<$1 $2>', $body); if (isset($modifiers['raw html']) && $modifiers['raw html'] == '1') { - return array(); + return []; } $body = str_replace("\r", '', $body); $body = utf8tohtml($body); if (mysql_version() < 50503) - $body = mb_encode_numericentity($body, array(0x010000, 0xffffff, 0, 0xffffff), 'UTF-8'); + $body = mb_encode_numericentity((string) $body, [0x010000, 0xffffff, 0, 0xffffff], 'UTF-8'); if ($config['markup_code']) { - $code_markup = array(); + $code_markup = []; $body = preg_replace_callback($config['markup_code'], function($matches) use (&$code_markup) { $d = count($code_markup); $code_markup[] = $matches; @@ -1949,7 +1862,7 @@ function markup(&$body, $track_cites = false, $op = false) { } if ($config['markup_urls']) { - $markup_urls = array(); + $markup_urls = []; $body = preg_replace_callback( '/((?:https?:\/\/|ftp:\/\/|irc:\/\/|gopher:\/\/)[^\s<>()"]+?(?:\([^\s<>()"]*?\)[^\s<>()"]*?)*)((?:\s|<|>|"|\.||\]|!|\?|,|,|")*(?:[\s<>()"]|$))/', @@ -1963,30 +1876,30 @@ function markup(&$body, $track_cites = false, $op = false) { } if ($config['markup_repair_tidy']) - $body = str_replace(' ', ' ', $body); + $body = str_replace(' ', ' ', (string) $body); if ($config['auto_unicode']) { $body = unicodify($body); if ($config['markup_urls']) { foreach ($markup_urls as &$url) { - $body = str_replace(unicodify($url), $url, $body); + $body = str_replace(unicodify($url), $url, (string) $body); } } } - $tracked_cites = array(); + $tracked_cites = []; // Cites - if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - if (count($cites[0]) > $config['max_cites']) { + if (isset($board) && preg_match_all('/(^|\s)>>(\d+?)([\s,.)?]|$)/m', (string) $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + if ((is_countable($cites[0]) ? count($cites[0]) : 0) > $config['max_cites']) { error($config['error']['toomanycites']); } $skip_chars = 0; $body_tmp = $body; - $search_cites = array(); + $search_cites = []; foreach ($cites as $matches) { $search_cites[] = '`id` = ' . $matches[2][0]; } @@ -1995,9 +1908,9 @@ function markup(&$body, $track_cites = false, $op = false) { $query = query(sprintf('SELECT `thread`, `id` FROM ``posts_%s`` WHERE ' . implode(' OR ', $search_cites), $board['uri'])) or error(db_error()); - $cited_posts = array(); + $cited_posts = []; while ($cited = $query->fetch(PDO::FETCH_ASSOC)) { - $cited_posts[$cited['id']] = $cited['thread'] ? $cited['thread'] : false; + $cited_posts[$cited['id']] = $cited['thread'] ?: false; } foreach ($cites as $matches) { @@ -2005,28 +1918,28 @@ function markup(&$body, $track_cites = false, $op = false) { // preg_match_all is not multibyte-safe foreach ($matches as &$match) { - $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + $match[1] = mb_strlen(substr((string) $body_tmp, 0, $match[1])); } if (isset($cited_posts[$cite])) { $replacement = '<a onclick="highlightReply(\''.$cite.'\', event);" href="' . $config['root'] . $board['dir'] . $config['dir']['res'] . - link_for(array('id' => $cite, 'thread' => $cited_posts[$cite])) . '#' . $cite . '">' . + link_for(['id' => $cite, 'thread' => $cited_posts[$cite]]) . '#' . $cite . '">' . '>>' . $cite . '</a>'; - $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); - $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen($matches[0][0]); + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[3][0], $matches[0][1] + $skip_chars, mb_strlen((string) $matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[3][0]) - mb_strlen((string) $matches[0][0]); if ($track_cites && $config['track_cites']) - $tracked_cites[] = array($board['uri'], $cite); + $tracked_cites[] = [$board['uri'], $cite]; } } } // Cross-board linking - if (preg_match_all('/(^|\s)>>>\/(' . $config['board_regex'] . 'f?)\/(\d+)?([\s,.)?]|$)/um', $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { - if (count($cites[0]) > $config['max_cites']) { + if (preg_match_all('/(^|\s)>>>\/(' . $config['board_regex'] . 'f?)\/(\d+)?([\s,.)?]|$)/um', (string) $body, $cites, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) { + if ((is_countable($cites[0]) ? count($cites[0]) : 0) > $config['max_cites']) { error($config['error']['toomanycross']); } @@ -2037,31 +1950,29 @@ function markup(&$body, $track_cites = false, $op = false) { // Carry found posts from local board >>X links foreach ($cited_posts as $cite => $thread) { $cited_posts[$cite] = $config['root'] . $board['dir'] . $config['dir']['res'] . - ($thread ? $thread : $cite) . '.html#' . $cite; + ($thread ?: $cite) . '.html#' . $cite; } - $cited_posts = array( - $board['uri'] => $cited_posts - ); + $cited_posts = [$board['uri'] => $cited_posts]; } else - $cited_posts = array(); + $cited_posts = []; - $crossboard_indexes = array(); - $search_cites_boards = array(); + $crossboard_indexes = []; + $search_cites_boards = []; foreach ($cites as $matches) { $_board = $matches[2][0]; $cite = @$matches[3][0]; if (!isset($search_cites_boards[$_board])) - $search_cites_boards[$_board] = array(); + $search_cites_boards[$_board] = []; $search_cites_boards[$_board][] = $cite; } $tmp_board = $board['uri']; foreach ($search_cites_boards as $_board => $search_cites) { - $clauses = array(); + $clauses = []; foreach ($search_cites as $cite) { if (!$cite || isset($cited_posts[$_board][$cite])) continue; @@ -2088,7 +1999,7 @@ function markup(&$body, $track_cites = false, $op = false) { } if (!empty($clauses)) { - $cited_posts[$_board] = array(); + $cited_posts[$_board] = []; $query = query(sprintf('SELECT `thread`, `id`, `slug` FROM ``posts_%s`` WHERE ' . implode(' OR ', $clauses), $board['uri'])) or error(db_error()); @@ -2118,7 +2029,7 @@ function markup(&$body, $track_cites = false, $op = false) { // preg_match_all is not multibyte-safe foreach ($matches as &$match) { - $match[1] = mb_strlen(substr($body_tmp, 0, $match[1])); + $match[1] = mb_strlen(substr((string) $body_tmp, 0, $match[1])); } if ($cite) { @@ -2143,18 +2054,18 @@ function markup(&$body, $track_cites = false, $op = false) { } - $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); - $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen((string) $matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen((string) $matches[0][0]); if ($track_cites && $config['track_cites']) - $tracked_cites[] = array($_board, $cite); + $tracked_cites[] = [$_board, $cite]; } } elseif(isset($crossboard_indexes[$_board])) { $replacement = '<a href="' . $crossboard_indexes[$_board] . '">' . '>>>/' . $_board . '/' . '</a>'; - $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen($matches[0][0])); - $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen($matches[0][0]); + $body = mb_substr_replace($body, $matches[1][0] . $replacement . $matches[4][0], $matches[0][1] + $skip_chars, mb_strlen((string) $matches[0][0])); + $skip_chars += mb_strlen($matches[1][0] . $replacement . $matches[4][0]) - mb_strlen((string) $matches[0][0]); } } } @@ -2171,12 +2082,12 @@ function markup(&$body, $track_cites = false, $op = false) { // Fix code markup if ($config['markup_code']) { foreach ($code_markup as $id => $val) { - $code = isset($val[2]) ? $val[2] : $val[1]; + $code = $val[2] ?? $val[1]; $code_lang = isset($val[2]) ? $val[1] : ""; $code = rtrim(ltrim($code, "\r\n")); - $code = "<pre class='code lang-$code_lang'>".str_replace(array("\n","\t"), array(" ","	"), htmlspecialchars($code))."</pre>"; + $code = "<pre class='code lang-$code_lang'>".str_replace(["\n", "\t"], [" ", "	"], htmlspecialchars($code))."</pre>"; $body = str_replace("<code $id>", $code, $body); } @@ -2185,18 +2096,7 @@ function markup(&$body, $track_cites = false, $op = false) { if ($config['markup_repair_tidy']) { $tidy = new tidy(); $body = str_replace("\t", '	', $body); - $body = $tidy->repairString($body, array( - 'doctype' => 'omit', - 'bare' => true, - 'literal-attributes' => true, - 'indent' => false, - 'show-body-only' => true, - 'wrap' => 0, - 'output-bom' => false, - 'output-html' => true, - 'newline' => 'LF', - 'quiet' => true, - ), 'utf8'); + $body = $tidy->repairString($body, ['doctype' => 'omit', 'bare' => true, 'literal-attributes' => true, 'indent' => false, 'show-body-only' => true, 'wrap' => 0, 'output-bom' => false, 'output-html' => true, 'newline' => 'LF', 'quiet' => true], 'utf8'); $body = str_replace("\n", '', $body); } @@ -2232,7 +2132,8 @@ function utf8tohtml($utf8) { } function ordutf8($string, &$offset) { - $code = ord(substr($string, $offset,1)); + $bytesnumber = null; + $code = ord(substr((string) $string, $offset,1)); if ($code >= 128) { // otherwise 0xxxxxxx if ($code < 224) $bytesnumber = 2; // 110xxxxx @@ -2243,19 +2144,19 @@ function ordutf8($string, &$offset) { $codetemp = $code - 192 - ($bytesnumber > 2 ? 32 : 0) - ($bytesnumber > 3 ? 16 : 0); for ($i = 2; $i <= $bytesnumber; $i++) { $offset ++; - $code2 = ord(substr($string, $offset, 1)) - 128; //10xxxxxx + $code2 = ord(substr((string) $string, $offset, 1)) - 128; //10xxxxxx $codetemp = $codetemp*64 + $code2; } $code = $codetemp; } $offset += 1; - if ($offset >= strlen($string)) + if ($offset >= strlen((string) $string)) $offset = -1; return $code; } function strip_combining_chars($str) { - $chars = preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY); + $chars = preg_split('//u', (string) $str, -1, PREG_SPLIT_NO_EMPTY); $str = ''; foreach ($chars as $char) { $o = 0; @@ -2270,7 +2171,10 @@ function strip_combining_chars($str) { } function buildThread($id, $return = false, $mod = false) { - global $board, $config, $build_pages; + $body = null; + $hasnoko50 = null; + $antibot = null; + global $board, $config, $build_pages; $id = round($id); if (event('build-thread', $id)) @@ -2285,7 +2189,7 @@ function buildThread($id, $return = false, $mod = false) { if ($config['try_smarter'] && !$mod) $build_pages[] = thread_find_page($id); - $action = generation_strategy('sb_thread', array($board['uri'], $id)); + $action = generation_strategy('sb_thread', [$board['uri'], $id]); if ($action == 'rebuild' || $return || $mod) { $query = prepare(sprintf("SELECT * FROM ``posts_%s`` WHERE (`thread` IS NULL AND `id` = :id) OR `thread` = :id ORDER BY `thread`,`id`", $board['uri'])); @@ -2307,24 +2211,12 @@ function buildThread($id, $return = false, $mod = false) { $hasnoko50 = $thread->postCount() >= $config['noko50_min']; $antibot = $mod || $return ? false : create_antibot($board['uri'], $id); - $body = Element('thread.html', array( - 'board' => $board, - 'thread' => $thread, - 'body' => $thread->build(), - 'config' => $config, - 'id' => $id, - 'mod' => $mod, - 'hasnoko50' => $hasnoko50, - 'isnoko50' => false, - 'antibot' => $antibot, - 'boardlist' => createBoardlist($mod), - 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index']) - )); + $body = Element('thread.html', ['board' => $board, 'thread' => $thread, 'body' => $thread->build(), 'config' => $config, 'id' => $id, 'mod' => $mod, 'hasnoko50' => $hasnoko50, 'isnoko50' => false, 'antibot' => $antibot, 'boardlist' => createBoardlist($mod), 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index'])]); // json api if ($config['api']['enabled'] && !$mod) { $api = new Api(); - $json = json_encode($api->translateThread($thread)); + $json = json_encode($api->translateThread($thread), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . $config['dir']['res'] . $id . '.json'; file_write($jsonFilename, $json); } @@ -2335,10 +2227,10 @@ function buildThread($id, $return = false, $mod = false) { } if ($action == 'delete' && !$return && !$mod) { - $noko50fn = $board['dir'] . $config['dir']['res'] . link_for(array('id' => $id), true); + $noko50fn = $board['dir'] . $config['dir']['res'] . link_for(['id' => $id], true); file_unlink($noko50fn); - file_unlink($board['dir'] . $config['dir']['res'] . link_for(array('id' => $id))); + file_unlink($board['dir'] . $config['dir']['res'] . link_for(['id' => $id])); } elseif ($return) { return $body; } elseif ($action == 'rebuild') { @@ -2399,9 +2291,9 @@ function buildThread50($id, $return = false, $mod = false, $thread = null, $anti $allPosts = $thread->posts; $thread->posts = array_slice($allPosts, -$config['noko50_count']); - $thread->omitted += count($allPosts) - count($thread->posts); + $thread->omitted += (is_countable($allPosts) ? count($allPosts) : 0) - count($thread->posts); foreach ($allPosts as $index => $post) { - if ($index == count($allPosts)-count($thread->posts)) + if ($index == (is_countable($allPosts) ? count($allPosts) : 0)-count($thread->posts)) break; if ($post->files) $thread->omitted_images += $post->num_files; @@ -2410,19 +2302,7 @@ function buildThread50($id, $return = false, $mod = false, $thread = null, $anti $hasnoko50 = $thread->postCount() >= $config['noko50_min']; - $body = Element('thread.html', array( - 'board' => $board, - 'thread' => $thread, - 'body' => $thread->build(false, true), - 'config' => $config, - 'id' => $id, - 'mod' => $mod, - 'hasnoko50' => $hasnoko50, - 'isnoko50' => true, - 'antibot' => $mod ? false : ($antibot ? $antibot : create_antibot($board['uri'], $id)), - 'boardlist' => createBoardlist($mod), - 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index']) - )); + $body = Element('thread.html', ['board' => $board, 'thread' => $thread, 'body' => $thread->build(false, true), 'config' => $config, 'id' => $id, 'mod' => $mod, 'hasnoko50' => $hasnoko50, 'isnoko50' => true, 'antibot' => $mod ? false : ($antibot ?: create_antibot($board['uri'], $id)), 'boardlist' => createBoardlist($mod), 'return' => ($mod ? '?' . $board['url'] . $config['file_index'] : $config['root'] . $board['dir'] . $config['file_index'])]); if ($return) { return $body; @@ -2463,8 +2343,8 @@ function generate_tripcode($name) { if ($trip = event('tripcode', $name)) return $trip; - if (!preg_match('/^([^#]+)?(##|#)(.+)$/', $name, $match)) - return array($name); + if (!preg_match('/^([^#]+)?(##|#)(.+)$/', (string) $name, $match)) + return [$name]; $name = $match[1]; $secure = $match[2] == '##'; @@ -2474,7 +2354,7 @@ function generate_tripcode($name) { $trip = mb_convert_encoding($trip, 'Shift_JIS', 'UTF-8'); // generate salt - $salt = substr($trip . 'H..', 1, 2); + $salt = substr((string) ($trip . 'H..'), 1, 2); $salt = preg_replace('/[^.-z]/', '.', $salt); $salt = strtr($salt, ':;<=>?@[\]^_`', 'ABCDEFGabcdef'); @@ -2482,7 +2362,7 @@ function generate_tripcode($name) { if (isset($config['custom_tripcode']["##{$trip}"])) $trip = $config['custom_tripcode']["##{$trip}"]; else - $trip = '!!' . substr(crypt($trip, str_replace('+', '.', '_..A.' . substr(base64_encode(sha1($trip . $config['secure_trip_salt'], true)), 0, 4))), -10); + $trip = '!!' . substr(crypt($trip, str_replace('+', '.', '_..A.' . substr(base64_encode(sha1((string) ($trip . $config['secure_trip_salt']), true)), 0, 4))), -10); } else { if (isset($config['custom_tripcode']["#{$trip}"])) $trip = $config['custom_tripcode']["#{$trip}"]; @@ -2490,7 +2370,7 @@ function generate_tripcode($name) { $trip = '!' . substr(crypt($trip, $salt), -10); } - return array($name, $trip); + return [$name, $trip]; } // Highest common factor @@ -2572,7 +2452,7 @@ function rDNS($ip_addr) { $host = gethostbyaddr($ip_addr); } else { $resp = shell_exec_error('host -W 3 ' . $ip_addr); - if (preg_match('/domain name pointer ([^\s]+)$/', $resp, $m)) + if (preg_match('/domain name pointer ([^\s]+)$/', (string) $resp, $m)) $host = $m[1]; else $host = $ip_addr; @@ -2603,7 +2483,7 @@ function DNS($host) { $ip_addr = false; } else { $resp = shell_exec_error('host -W 1 ' . $host); - if (preg_match('/has address ([^\s]+)$/', $resp, $m)) + if (preg_match('/has address ([^\s]+)$/', (string) $resp, $m)) $ip_addr = $m[1]; else $ip_addr = false; @@ -2616,7 +2496,8 @@ function DNS($host) { } function shell_exec_error($command, $suppress_stdout = false) { - global $config, $debug; + $start = null; + global $config, $debug; if ($config['debug']) $start = microtime(true); @@ -2627,11 +2508,7 @@ function shell_exec_error($command, $suppress_stdout = false) { if ($config['debug']) { $time = microtime(true) - $start; - $debug['exec'][] = array( - 'command' => $command, - 'time' => '~' . round($time * 1000, 2) . 'ms', - 'response' => $return ? $return : null - ); + $debug['exec'][] = ['command' => $command, 'time' => '~' . round($time * 1000, 2) . 'ms', 'response' => $return ?: null]; $debug['time']['exec'] += $time; } @@ -2645,8 +2522,8 @@ function shell_exec_error($command, $suppress_stdout = false) { */ function diceRoller($post) { global $config; - if(strpos(strtolower($post->email), 'dice%20') === 0) { - $dicestr = str_split(substr($post->email, strlen('dice%20'))); + if(str_starts_with(strtolower((string) $post->email), 'dice%20')) { + $dicestr = str_split(substr((string) $post->email, strlen('dice%20'))); // Get params $diceX = ''; @@ -2656,12 +2533,12 @@ function diceRoller($post) { $curd = 'diceX'; for($i = 0; $i < count($dicestr); $i ++) { if(is_numeric($dicestr[$i])) { - $$curd .= $dicestr[$i]; + ${$curd} .= $dicestr[$i]; } else if($dicestr[$i] == 'd') { $curd = 'diceY'; } else if($dicestr[$i] == '-' || $dicestr[$i] == '+') { $curd = 'diceZ'; - $$curd = $dicestr[$i]; + ${$curd} = $dicestr[$i]; } } @@ -2681,10 +2558,10 @@ function diceRoller($post) { // Continue only if we have valid values if($diceX > 0 && $diceY > 0) { - $dicerolls = array(); + $dicerolls = []; $dicesum = $diceZ; for($i = 0; $i < $diceX; $i++) { - $roll = rand(1, $diceY); + $roll = random_int(1, $diceY); $dicerolls[] = $roll; $dicesum += $roll; } @@ -2707,7 +2584,7 @@ function slugify($post) { elseif (isset ($post['body_nomarkup']) && $post['body_nomarkup']) $slug = $post['body_nomarkup']; elseif (isset ($post['body']) && $post['body']) - $slug = strip_tags($post['body']); + $slug = strip_tags((string) $post['body']); // Fix UTF-8 first $slug = mb_convert_encoding($slug, "UTF-8", "UTF-8"); @@ -2738,12 +2615,13 @@ function slugify($post) { } function link_for($post, $page50 = false, $foreignlink = false, $thread = false) { - global $config, $board; + $tpl = null; + global $config, $board; $post = (array)$post; // Where do we need to look for OP? - $b = $foreignlink ? $foreignlink : (isset($post['board']) ? array('uri' => $post['board']) : $board); + $b = $foreignlink ?: (isset($post['board']) ? ['uri' => $post['board']] : $board); $id = (isset($post['thread']) && $post['thread']) ? $post['thread'] : $post['id']; @@ -2784,7 +2662,7 @@ function link_for($post, $page50 = false, $foreignlink = false, $thread = false) } function prettify_textarea($s){ - return str_replace("\t", '	', str_replace("\n", ' ', htmlentities($s))); + return str_replace("\t", '	', str_replace("\n", ' ', htmlentities((string) $s))); } /*class HTMLPurifier_URIFilter_NoExternalImages extends HTMLPurifier_URIFilter { @@ -2825,7 +2703,7 @@ function markdown($s) { return $pd->text($s); } -function generation_strategy($fun, $array=array()) { global $config; +function generation_strategy($fun, $array=[]) { global $config; $action = false; foreach ($config['generation_strategies'] as $s) { @@ -2839,7 +2717,7 @@ function generation_strategy($fun, $array=array()) { global $config; return 'rebuild'; case 'defer': // Ok, it gets interesting here :) - get_queue('generate')->push(serialize(array('build', $fun, $array, $action))); + get_queue('generate')->push(serialize(['build', $fun, $array, $action])); return 'ignore'; case 'build_on_load': return 'delete'; @@ -2847,18 +2725,18 @@ function generation_strategy($fun, $array=array()) { global $config; } function strategy_immediate($fun, $array) { - return array('immediate'); + return ['immediate']; } function strategy_smart_build($fun, $array) { - return array('build_on_load'); + return ['build_on_load']; } function strategy_sane($fun, $array) { global $config; if (php_sapi_name() == 'cli') return false; else if (isset($_POST['mod'])) return false; // Thread needs to be done instantly. Same with a board page, but only if posting a new thread. - else if ($fun == 'sb_thread' || ($fun == 'sb_board' && $array[1] == 1 && isset ($_POST['page']))) return array('immediate'); + else if ($fun == 'sb_thread' || ($fun == 'sb_board' && $array[1] == 1 && isset ($_POST['page']))) return ['immediate']; else return false; } @@ -2866,19 +2744,19 @@ function strategy_sane($fun, $array) { global $config; function strategy_first($fun, $array) { switch ($fun) { case 'sb_thread': - return array('defer'); + return ['defer']; case 'sb_board': - if ($array[1] > 8) return array('build_on_load'); - else return array('defer'); + if ($array[1] > 8) return ['build_on_load']; + else return ['defer']; case 'sb_api': - return array('defer'); + return ['defer']; case 'sb_catalog': - return array('defer'); + return ['defer']; case 'sb_recent': - return array('build_on_load'); + return ['build_on_load']; case 'sb_sitemap': - return array('build_on_load'); + return ['build_on_load']; case 'sb_ukko': - return array('defer'); + return ['defer']; } } diff --git a/inc/image.php b/inc/image.php index 34283b80..8e0f19a9 100644 --- a/inc/image.php +++ b/inc/image.php @@ -16,11 +16,11 @@ class Image { $this->format = $format; if ($config['thumb_method'] == 'imagick') { - $classname = 'ImageImagick'; - } elseif (in_array($config['thumb_method'], array('convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'))) { - $classname = 'ImageConvert'; + $classname = \ImageImagick::class; + } elseif (in_array($config['thumb_method'], ['convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'])) { + $classname = \ImageConvert::class; } else { - $classname = 'Image' . strtoupper($this->format); + $classname = \Image::class . strtoupper((string) $this->format); if (!class_exists($classname)) { error(_('Unsupported file format: ') . $this->format); } @@ -33,7 +33,7 @@ class Image { error($config['error']['invalidimg']); } - $this->size = (object)array('width' => $this->image->_width(), 'height' => $this->image->_height()); + $this->size = (object)['width' => $this->image->_width(), 'height' => $this->image->_height()]; if ($this->size->width < 1 || $this->size->height < 1) { $this->delete(); error($config['error']['invalidimg']); @@ -44,21 +44,21 @@ class Image { global $config; if ($config['thumb_method'] == 'imagick') { - $classname = 'ImageImagick'; + $classname = \ImageImagick::class; } elseif ($config['thumb_method'] == 'convert') { - $classname = 'ImageConvert'; + $classname = \ImageConvert::class; } elseif ($config['thumb_method'] == 'convert+gifsicle') { - $classname = 'ImageConvert'; + $classname = \ImageConvert::class; $gifsicle = true; } elseif ($config['thumb_method'] == 'gm') { - $classname = 'ImageConvert'; + $classname = \ImageConvert::class; $gm = true; } elseif ($config['thumb_method'] == 'gm+gifsicle') { - $classname = 'ImageConvert'; + $classname = \ImageConvert::class; $gm = true; $gifsicle = true; } else { - $classname = 'Image' . strtoupper($extension); + $classname = \Image::class . strtoupper((string) $extension); if (!class_exists($classname)) { error(_('Unsupported file format: ') . $extension); } @@ -174,7 +174,7 @@ class ImageImagick extends ImageBase { public function from() { try { $this->image->readImage($this->src); - } catch(ImagickException $e) { + } catch(ImagickException) { // invalid image $this->image = false; } @@ -184,7 +184,7 @@ class ImageImagick extends ImageBase { if ($config['strip_exif']) { $this->image->stripImage(); } - if (preg_match('/\.gif$/i', $src)) + if (preg_match('/\.gif$/i', (string) $src)) $this->image->writeImages($src, true); else $this->image->writeImage($src); @@ -205,7 +205,7 @@ class ImageImagick extends ImageBase { $this->image = new Imagick(); $this->image->setFormat('gif'); - $keep_frames = array(); + $keep_frames = []; for ($i = 0; $i < $this->original->getNumberImages(); $i += floor($this->original->getNumberImages() / $config['thumb_keep_animation_frames'])) $keep_frames[] = $i; @@ -252,8 +252,8 @@ class ImageConvert extends ImageBase { return $size; } $size = shell_exec_error(($this->gm ? 'gm ' : '') . 'identify -format "%w %h" ' . escapeshellarg($src . '[0]')); - if (preg_match('/^(\d+) (\d+)$/', $size, $m)) - return array($m[1], $m[2]); + if (preg_match('/^(\d+) (\d+)$/', (string) $size, $m)) + return [$m[1], $m[2]]; return false; } public function from() { @@ -278,13 +278,13 @@ class ImageConvert extends ImageBase { if (!$this->temp) { if ($config['strip_exif']) { if($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($this->src) . ' -auto-orient -strip ' . escapeshellarg($src))) { + escapeshellarg((string) $this->src) . ' -auto-orient -strip ' . escapeshellarg((string) $src))) { $this->destroy(); error(_('Failed to redraw image!'), null, $error); } } else { if($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($this->src) . ' -auto-orient ' . escapeshellarg($src))) { + escapeshellarg((string) $this->src) . ' -auto-orient ' . escapeshellarg((string) $src))) { $this->destroy(); error(_('Failed to redraw image!'), null, $error); } @@ -326,9 +326,9 @@ class ImageConvert extends ImageBase { } } else { if ($config['convert_manual_orient'] && ($this->format == 'jpg' || $this->format == 'jpeg')) - $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']); + $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), (string) $config['convert_args']); elseif ($config['convert_manual_orient']) - $convert_args = str_replace('-auto-orient', '', $config['convert_args']); + $convert_args = str_replace('-auto-orient', '', (string) $config['convert_args']); else $convert_args = &$config['convert_args']; @@ -336,7 +336,7 @@ class ImageConvert extends ImageBase { sprintf($convert_args, $this->width, $this->height, - escapeshellarg($this->src), + escapeshellarg((string) $this->src), $this->width, $this->height, escapeshellarg($this->temp)))) || !file_exists($this->temp)) { @@ -350,9 +350,9 @@ class ImageConvert extends ImageBase { } } else { if ($config['convert_manual_orient'] && ($this->format == 'jpg' || $this->format == 'jpeg')) - $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), $config['convert_args']); + $convert_args = str_replace('-auto-orient', ImageConvert::jpeg_exif_orientation($this->src), (string) $config['convert_args']); elseif ($config['convert_manual_orient']) - $convert_args = str_replace('-auto-orient', '', $config['convert_args']); + $convert_args = str_replace('-auto-orient', '', (string) $config['convert_args']); else $convert_args = &$config['convert_args']; if (($error = shell_exec_error(($this->gm ? 'gm ' : '') . 'convert ' . @@ -364,10 +364,10 @@ class ImageConvert extends ImageBase { $this->height, escapeshellarg($this->temp)))) || !file_exists($this->temp)) { - if (strpos($error, "known incorrect sRGB profile") === false && - strpos($error, "iCCP: Not recognizing known sRGB profile that has been edited") === false) { + if (!str_contains((string) $error, "known incorrect sRGB profile") && + !str_contains((string) $error, "iCCP: Not recognizing known sRGB profile that has been edited")) { $this->destroy(); - error(_('Failed to resize image!')." "._('Details: ').nl2br(htmlspecialchars($error)), null, array('convert_error' => $error)); + error(_('Failed to resize image!')." "._('Details: ').nl2br(htmlspecialchars((string) $error)), null, ['convert_error' => $error]); } if (!file_exists($this->temp)) { $this->destroy(); diff --git a/inc/lib/webm/ffmpeg.php b/inc/lib/webm/ffmpeg.php index 0747b420..56339cff 100644 --- a/inc/lib/webm/ffmpeg.php +++ b/inc/lib/webm/ffmpeg.php @@ -5,12 +5,12 @@ */ function get_webm_info($filename) { global $board, $config; - $filename = escapeshellarg($filename); + $filename = escapeshellarg((string) $filename); $ffprobe = $config['webm']['ffprobe_path']; - $ffprobe_out = array(); - $webminfo = array(); + $ffprobe_out = []; + $webminfo = []; exec("$ffprobe -v quiet -print_format json -show_format -show_streams $filename", $ffprobe_out); - $ffprobe_out = json_decode(implode("\n", $ffprobe_out), 1); + $ffprobe_out = json_decode(implode("\n", $ffprobe_out), 1, 512, JSON_THROW_ON_ERROR); $webminfo['error'] = is_valid_webm($ffprobe_out); if(empty($webminfo['error'])) { $webminfo['width'] = $ffprobe_out['streams'][0]['width']; @@ -22,34 +22,34 @@ function get_webm_info($filename) { function is_valid_webm($ffprobe_out) { global $board, $config; if (empty($ffprobe_out)) - return array('code' => 1, 'msg' => $config['error']['genwebmerror']); - $extension = pathinfo($ffprobe_out['format']['filename'], PATHINFO_EXTENSION); + return ['code' => 1, 'msg' => $config['error']['genwebmerror']]; + $extension = pathinfo((string) $ffprobe_out['format']['filename'], PATHINFO_EXTENSION); if ($extension === 'webm') { if ($ffprobe_out['format']['format_name'] != 'matroska,webm') - return array('code' => 2, 'msg' => $config['error']['invalidwebm']); + return ['code' => 2, 'msg' => $config['error']['invalidwebm']]; } elseif ($extension === 'mp4') { if ($ffprobe_out['streams'][0]['codec_name'] != 'h264' && $ffprobe_out['streams'][1]['codec_name'] != 'aac') - return array('code' => 2, 'msg' => $config['error']['invalidwebm']); + return ['code' => 2, 'msg' => $config['error']['invalidwebm']]; } else { - return array('code' => 1, 'msg' => $config['error']['genwebmerror']); + return ['code' => 1, 'msg' => $config['error']['genwebmerror']]; } - if ((count($ffprobe_out['streams']) > 1) && (!$config['webm']['allow_audio'])) - return array('code' => 3, 'msg' => $config['error']['webmhasaudio']); + if (((is_countable($ffprobe_out['streams']) ? count($ffprobe_out['streams']) : 0) > 1) && (!$config['webm']['allow_audio'])) + return ['code' => 3, 'msg' => $config['error']['webmhasaudio']]; if (empty($ffprobe_out['streams'][0]['width']) || (empty($ffprobe_out['streams'][0]['height']))) - return array('code' => 2, 'msg' => $config['error']['invalidwebm']); + return ['code' => 2, 'msg' => $config['error']['invalidwebm']]; if ($ffprobe_out['format']['duration'] > $config['webm']['max_length']) - return array('code' => 4, 'msg' => sprintf($config['error']['webmtoolong'], $config['webm']['max_length'])); + return ['code' => 4, 'msg' => sprintf($config['error']['webmtoolong'], $config['webm']['max_length'])]; } function make_webm_thumbnail($filename, $thumbnail, $width, $height, $duration) { global $board, $config; - $filename = escapeshellarg($filename); - $thumbnailfc = escapeshellarg($thumbnail); // Should be safe by default but you + $filename = escapeshellarg((string) $filename); + $thumbnailfc = escapeshellarg((string) $thumbnail); // Should be safe by default but you // can never be too safe. - $width = escapeshellarg($width); - $height = escapeshellarg($height); // Same as above. + $width = escapeshellarg((string) $width); + $height = escapeshellarg((string) $height); // Same as above. $ffmpeg = $config['webm']['ffmpeg_path']; $ret = 0; - $ffmpeg_out = array(); + $ffmpeg_out = []; exec("$ffmpeg -strict -2 -ss " . floor($duration / 2) . " -i $filename -v quiet -an -vframes 1 -f mjpeg -vf scale=$width:$height $thumbnailfc 2>&1", $ffmpeg_out, $ret); // Work around for https://trac.ffmpeg.org/ticket/4362 if (filesize($thumbnail) === 0) { diff --git a/inc/lib/webm/matroska.php b/inc/lib/webm/matroska.php index 5f1c38ee..baab054f 100644 --- a/inc/lib/webm/matroska.php +++ b/inc/lib/webm/matroska.php @@ -16,12 +16,12 @@ class EBMLElementTypeList { public function __construct($filename) { $lines = file($filename); foreach($lines as $line) { - $fields = explode(' ', trim($line)); + $fields = explode(' ', trim((string) $line)); $t = new EBMLElementType; $id = hexdec($fields[0]); $t->datatype = $fields[1]; $t->name = $fields[2]; - $t->validParents = array(); + $t->validParents = []; for ($i = 0; $i + 3 < count($fields); $i++) { if ($fields[$i+3] == '*' || $fields[$i+3] == 'root') { $t->validParents[$i] = $fields[$i+3]; @@ -44,7 +44,7 @@ class EBMLElementTypeList { } public function id($name) { - $name = strtoupper($name); + $name = strtoupper((string) $name); if (!isset($this->_ids[$name])) return NULL; return $this->_ids[$name]; } @@ -64,13 +64,13 @@ class EBMLElementTypeList { // Matroska element types global $EBML_ELEMENTS; -$EBML_ELEMENTS = new EBMLElementTypeList(dirname(__FILE__) . '/matroska-elements.txt'); +$EBML_ELEMENTS = new EBMLElementTypeList(__DIR__ . '/matroska-elements.txt'); // Decode big-endian integer function ebmlDecodeInt($data, $signed=FALSE, $carryIn=0) { $n = $carryIn; - if (strlen($data) > 8) throw new Exception('not supported: integer too long'); - for ($i = 0; $i < strlen($data); $i++) { + if (strlen((string) $data) > 8) throw new Exception('not supported: integer too long'); + for ($i = 0; $i < strlen((string) $data); $i++) { if ($n > (PHP_INT_MAX >> 8) || $n < ((-PHP_INT_MAX-1) >> 8)) { $n = floatval($n); } @@ -84,16 +84,16 @@ function ebmlDecodeInt($data, $signed=FALSE, $carryIn=0) { // Decode big-endian IEEE float function ebmlDecodeFloat($data) { - switch (strlen($data)) { + switch (strlen((string) $data)) { case 0: return 0; case 4: switch(pack('f', 1e9)) { case '(knN': - $arr = unpack('f', strrev($data)); + $arr = unpack('f', strrev((string) $data)); return $arr[1]; case 'Nnk(': - $arr = unpack('f', $data); + $arr = unpack('f', (string) $data); return $arr[1]; default: error_log('cannot decode floats'); @@ -102,10 +102,10 @@ function ebmlDecodeFloat($data) { case 8: switch(pack('d', 1e9)) { case "\x00\x00\x00\x00\x65\xcd\xcd\x41": - $arr = unpack('d', strrev($data)); + $arr = unpack('d', strrev((string) $data)); return $arr[1]; case "\x41\xcd\xcd\x65\x00\x00\x00\x00": - $arr = unpack('d', $data); + $arr = unpack('d', (string) $data); return $arr[1]; default: error_log('cannot decode floats'); @@ -120,33 +120,27 @@ function ebmlDecodeFloat($data) { // Decode big-endian signed offset from Jan 01, 2000 in nanoseconds // Convert to offset from Jan 01, 1970 in seconds function ebmlDecodeDate($data) { - return ebmlDecodeInt($data, TRUE) * 1e-9 + 946684800; + return ebmlDecodeInt($data, TRUE) * 1e-9 + 946_684_800; } // Decode data of specified datatype function ebmlDecode($data, $datatype) { - switch ($datatype) { - case 'int': return ebmlDecodeInt($data, TRUE); - case 'uint': return ebmlDecodeInt($data, FALSE); - case 'float': return ebmlDecodeFloat($data); - case 'string': return chop($data, "\0"); - case 'date': return ebmlDecodeDate($data); - case 'binary': return $data; - default: throw new Exception('unknown datatype'); - } + return match ($datatype) { + 'int' => ebmlDecodeInt($data, TRUE), + 'uint' => ebmlDecodeInt($data, FALSE), + 'float' => ebmlDecodeFloat($data), + 'string' => chop((string) $data, "\0"), + 'date' => ebmlDecodeDate($data), + 'binary' => $data, + default => throw new Exception('unknown datatype'), + }; } // Methods for reading data from section of EBML file class EBMLReader { - private $_fileHandle; - private $_offset; - private $_size; private $_position; - public function __construct($fileHandle, $offset=0, $size=NULL) { - $this->_fileHandle = $fileHandle; - $this->_offset = $offset; - $this->_size = $size; + public function __construct(private $_fileHandle, private $_offset=0, private $_size=NULL) { $this->_position = 0; } @@ -269,19 +263,13 @@ class EBMLReader { // EBML element class EBMLElement { - private $_id; private $_name; private $_datatype; - private $_content; - private $_headSize; - public function __construct($id, $content, $headSize) { + public function __construct(private $_id, private $_content, private $_headSize) { global $EBML_ELEMENTS; - $this->_id = $id; $this->_name = $EBML_ELEMENTS->name($this->_id); $this->_datatype = $EBML_ELEMENTS->datatype($this->_id); - $this->_content = $content; - $this->_headSize = $headSize; } public function id() {return $this->_id;} @@ -309,11 +297,11 @@ class EBMLElement { class EBMLElementList extends EBMLElement implements Iterator { private $_cache; private $_position; - private static $MAX_ELEMENTS = 10000; + private static int $MAX_ELEMENTS = 10000; public function __construct($id, $content, $headSize) { parent::__construct($id, $content, $headSize); - $this->_cache = array(); + $this->_cache = []; $this->_position = 0; } @@ -389,7 +377,7 @@ class EBMLElementList extends EBMLElement implements Iterator { foreach ($this as $element) { $iElement++; if ($iElement > self::$MAX_ELEMENTS) throw new Exception('not supported: too many elements'); - if (strtoupper($element->name()) == strtoupper($name)) { + if (strtoupper((string) $element->name()) == strtoupper((string) $name)) { return $element->value(); } } @@ -399,10 +387,10 @@ class EBMLElementList extends EBMLElement implements Iterator { // Parse block class MatroskaBlock { - const LACING_NONE = 0; - const LACING_XIPH = 1; - const LACING_EBML = 3; - const LACING_FIXED = 2; + final const LACING_NONE = 0; + final const LACING_XIPH = 1; + final const LACING_EBML = 3; + final const LACING_FIXED = 2; public $trackNumber; public $timecode; public $keyframe; @@ -430,7 +418,7 @@ class MatroskaBlock { } else { $nsizes = ord($reader->read(1)); } - $sizes = array(); + $sizes = []; switch ($this->lacing) { case self::LACING_XIPH: for ($i = 0; $i < $nsizes; $i++) { @@ -468,7 +456,7 @@ class MatroskaBlock { } # Frames - $this->frames = array(); + $this->frames = []; for ($i = 0; $i < $nsizes; $i++) { $this->frames[$i] = $reader->nextSlice($sizes[$i]); } @@ -520,5 +508,5 @@ function ebmlEncodeElementName($name) { } function ebmlEncodeElement($name, $content) { - return ebmlEncodeElementName($name) . ebmlEncodeVarInt(strlen($content)) . $content; + return ebmlEncodeElementName($name) . ebmlEncodeVarInt(strlen((string) $content)) . $content; } diff --git a/inc/lib/webm/posthandler.php b/inc/lib/webm/posthandler.php index 15c6600d..4cd26d6a 100644 --- a/inc/lib/webm/posthandler.php +++ b/inc/lib/webm/posthandler.php @@ -5,7 +5,7 @@ function postHandler($post) { global $board, $config; if ($post->has_file) foreach ($post->files as &$file) if ($file->extension == 'webm' || $file->extension == 'mp4') { if ($config['webm']['use_ffmpeg']) { - require_once dirname(__FILE__) . '/ffmpeg.php'; + require_once __DIR__ . '/ffmpeg.php'; $webminfo = get_webm_info($file->file_path); if (empty($webminfo['error'])) { $file->width = $webminfo['width']; @@ -29,7 +29,7 @@ function postHandler($post) { } } else { - require_once dirname(__FILE__) . '/videodata.php'; + require_once __DIR__ . '/videodata.php'; $videoDetails = videoData($file->file_path); if (!isset($videoDetails['container']) || $videoDetails['container'] != 'webm') return "not a WebM file"; // Set thumbnail @@ -39,7 +39,7 @@ function postHandler($post) { $file = webm_set_spoiler($file); } elseif (isset($videoDetails['frame']) && $thumbFile = fopen($thumbName, 'wb')) { // Use single frame from video as pseudo-thumbnail - fwrite($thumbFile, $videoDetails['frame']); + fwrite($thumbFile, (string) $videoDetails['frame']); fclose($thumbFile); $file->thumb = $file->file_id . '.webm'; } else { @@ -60,7 +60,7 @@ function postHandler($post) { } function set_thumbnail_dimensions($post,$file) { global $board, $config; - $tn_dimensions = array(); + $tn_dimensions = []; $tn_maxw = $post->op ? $config['thumb_op_width'] : $config['thumb_width']; $tn_maxh = $post->op ? $config['thumb_op_height'] : $config['thumb_height']; if ($file->width > $tn_maxw || $file->height > $tn_maxh) { diff --git a/inc/lib/webm/videodata.php b/inc/lib/webm/videodata.php index d54d484b..38fd4d00 100644 --- a/inc/lib/webm/videodata.php +++ b/inc/lib/webm/videodata.php @@ -1,6 +1,6 @@ <?php /* This file is dedicated to the public domain; you may do as you wish with it. */ -require dirname(__FILE__) . '/matroska.php'; +require __DIR__ . '/matroska.php'; function matroskaSeekElement($name, $pos) { return ebmlEncodeElement('Seek', @@ -46,11 +46,11 @@ function muxWebMFrame($videoTrack, $frame) { ebmlEncodeElement('CueTime', "\x00") . ebmlEncodeElement('CueTrackPositions', ebmlEncodeElement('CueTrack', pack('N', $videoTrack->get('TrackNumber'))) - . ebmlEncodeElement('CueClusterPosition', pack('N', $lenSeekHead + strlen($info) + strlen($tracks) + $lenCues)) + . ebmlEncodeElement('CueClusterPosition', pack('N', $lenSeekHead + strlen((string) $info) + strlen((string) $tracks) + $lenCues)) ) ) ); - if (strlen($cues) != $lenCues) throw new Exception('length of Cues element wrong'); + if (strlen((string) $cues) != $lenCues) throw new Exception('length of Cues element wrong'); $cluster = ebmlEncodeElement('Cluster', ebmlEncodeElement('Timecode', "\x00") . ebmlEncodeElement($frame->name(), $frame->content()->readAll()) @@ -58,11 +58,11 @@ function muxWebMFrame($videoTrack, $frame) { ); $seekHead = ebmlEncodeElement('SeekHead', matroskaSeekElement('Info', $lenSeekHead) - . matroskaSeekElement('Tracks', $lenSeekHead + strlen($info)) - . matroskaSeekElement('Cues', $lenSeekHead + strlen($info) + strlen($tracks)) - . matroskaSeekElement('Cluster', $lenSeekHead + strlen($info) + strlen($tracks) + $lenCues) + . matroskaSeekElement('Tracks', $lenSeekHead + strlen((string) $info)) + . matroskaSeekElement('Cues', $lenSeekHead + strlen((string) $info) + strlen((string) $tracks)) + . matroskaSeekElement('Cluster', $lenSeekHead + strlen((string) $info) + strlen((string) $tracks) + $lenCues) ); - if (strlen($seekHead) != $lenSeekHead) throw new Exception('length of SeekHead element wrong'); + if (strlen((string) $seekHead) != $lenSeekHead) throw new Exception('length of SeekHead element wrong'); $segment = ebmlEncodeElement('Segment', $seekHead . $info . $tracks . $cues . $cluster); return $ebml . $segment; @@ -93,11 +93,11 @@ function firstWebMFrame($segment, $trackNumber, $skip=0) { } } } - return isset($frame1) ? $frame1 : NULL; + return $frame1 ?? NULL; } function videoData($filename) { - $data = array(); + $data = []; // Open file $fileHandle = fopen($filename, 'rb'); diff --git a/inc/lock.php b/inc/lock.php index 4fb2f5df..0d05f52d 100644 --- a/inc/lock.php +++ b/inc/lock.php @@ -2,7 +2,7 @@ class Lock { function __construct($key) { global $config; if ($config['lock']['enabled'] == 'fs') { - $key = str_replace('/', '::', $key); + $key = str_replace('/', '::', (string) $key); $key = str_replace("\0", '', $key); $this->f = fopen("tmp/locks/$key", "w"); diff --git a/inc/mod/auth.php b/inc/mod/auth.php index 91a0dfe9..979fc77e 100644 --- a/inc/mod/auth.php +++ b/inc/mod/auth.php @@ -12,7 +12,7 @@ function mkhash($username, $password, $salt = false) { if (!$salt) { // create some sort of salt for the hash - $salt = substr(base64_encode(sha1(rand() . time(), true) . $config['cookies']['salt']), 0, 15); + $salt = substr(base64_encode(sha1(random_int(0, mt_getrandmax()) . time(), true) . $config['cookies']['salt']), 0, 15); $generated_salt = true; } @@ -25,31 +25,31 @@ function mkhash($username, $password, $salt = false) { $username . $password . $salt . ( $config['mod']['lock_ip'] ? $_SERVER['REMOTE_ADDR'] : '' ), true - ) . sha1($config['password_crypt_version']) // Log out users being logged in with older password encryption schema + ) . sha1((string) $config['password_crypt_version']) // Log out users being logged in with older password encryption schema , true ) ), 0, 20 ); if (isset($generated_salt)) - return array($hash, $salt); + return [$hash, $salt]; else return $hash; } function crypt_password_old($password) { $salt = generate_salt(); - $password = hash('sha256', $salt . sha1($password)); - return array($salt, $password); + $password = hash('sha256', $salt . sha1((string) $password)); + return [$salt, $password]; } function crypt_password($password) { global $config; // `salt` database field is reused as a version value. We don't want it to be 0. - $version = $config['password_crypt_version'] ? $config['password_crypt_version'] : 1; + $version = $config['password_crypt_version'] ?: 1; $new_salt = generate_salt(); - $password = crypt($password, $config['password_crypt'] . $new_salt . "$"); - return array($version, $password); + $password = crypt((string) $password, $config['password_crypt'] . $new_salt . "$"); + return [$version, $password]; } function test_password($password, $salt, $test) { @@ -57,22 +57,22 @@ function test_password($password, $salt, $test) { // Version = 0 denotes an old password hashing schema. In the same column, the // password hash was kept previously - $version = (strlen($salt) <= 8) ? (int) $salt : 0; + $version = (strlen((string) $salt) <= 8) ? (int) $salt : 0; if ($version == 0) { - $comp = hash('sha256', $salt . sha1($test)); + $comp = hash('sha256', $salt . sha1((string) $test)); } else { - $comp = crypt($test, $password); + $comp = crypt((string) $test, (string) $password); } - return array($version, hash_equals($password, $comp)); + return [$version, hash_equals($password, $comp)]; } function generate_salt() { // mcrypt_create_iv() was deprecated in PHP 7.1.0, only use it if we're below that version number. if (PHP_VERSION_ID < 70100) { // 128 bits of entropy - return strtr(base64_encode(mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.'); + return strtr(base64_encode((string) mcrypt_create_iv(16, MCRYPT_DEV_URANDOM)), '+', '.'); } // Otherwise, use random_bytes() return strtr(base64_encode(random_bytes(16)), '+', '.'); @@ -86,12 +86,12 @@ function login($username, $password) { $query->execute() or error(db_error($query)); if ($user = $query->fetch(PDO::FETCH_ASSOC)) { - list($version, $ok) = test_password($user['password'], $user['version'], $password); + [$version, $ok] = test_password($user['password'], $user['version'], $password); if ($ok) { if ($config['password_crypt_version'] > $version) { // It's time to upgrade the password hashing method! - list ($user['version'], $user['password']) = crypt_password($password); + [$user['version'], $user['password']] = crypt_password($password); $query = prepare("UPDATE ``mods`` SET `password` = :password, `version` = :version WHERE `id` = :id"); $query->bindValue(':password', $user['password']); $query->bindValue(':version', $user['version']); @@ -99,13 +99,7 @@ function login($username, $password) { $query->execute() or error(db_error($query)); } - return $mod = array( - 'id' => $user['id'], - 'type' => $user['type'], - 'username' => $username, - 'hash' => mkhash($username, $user['password']), - 'boards' => explode(',', $user['boards']) - ); + return $mod = ['id' => $user['id'], 'type' => $user['type'], 'username' => $username, 'hash' => mkhash($username, $user['password']), 'boards' => explode(',', (string) $user['boards'])]; } } @@ -122,20 +116,19 @@ function setCookies() { ':' . $mod['hash'][0] . // password ':' . - $mod['hash'][1], // salt - time() + $config['cookies']['expire'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', $config["domain"], !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', $config['cookies']['httponly']); + $mod['hash'][1], ['expires' => time() + $config['cookies']['expire'], 'path' => $config['cookies']['jail'] ? $config['cookies']['path'] : '/', 'domain' => $config["domain"], 'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', 'httponly' => $config['cookies']['httponly']]); } function destroyCookies() { global $config; // Delete the cookies - setcookie($config['cookies']['mod'], 'deleted', time() - $config['cookies']['expire'], $config['cookies']['jail']?$config['cookies']['path'] : '/', $config["domain"], !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true); + setcookie($config['cookies']['mod'], 'deleted', ['expires' => time() - $config['cookies']['expire'], 'path' => $config['cookies']['jail']?$config['cookies']['path'] : '/', 'domain' => $config["domain"], 'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', 'httponly' => true]); } function modLog($action, $_board=null) { global $mod, $board, $config; $query = prepare("INSERT INTO ``modlogs`` VALUES (:id, :ip, :board, :time, :text)"); - $query->bindValue(':id', (isset($mod['id']) ? $mod['id'] : -1), PDO::PARAM_INT); + $query->bindValue(':id', ($mod['id'] ?? -1), PDO::PARAM_INT); $query->bindValue(':ip', $_SERVER['REMOTE_ADDR']); $query->bindValue(':time', time(), PDO::PARAM_INT); $query->bindValue(':text', $action); @@ -166,7 +159,7 @@ function create_pm_header() { $query->execute() or error(db_error($query)); if ($pm = $query->fetch(PDO::FETCH_ASSOC)) - $header = array('id' => $pm['id'], 'waiting' => $query->rowCount() - 1); + $header = ['id' => $pm['id'], 'waiting' => $query->rowCount() - 1]; else $header = true; @@ -189,7 +182,7 @@ function check_login($prompt = false) { // Validate session if (isset($_COOKIE[$config['cookies']['mod']])) { // Should be username:hash:salt - $cookie = explode(':', $_COOKIE[$config['cookies']['mod']]); + $cookie = explode(':', (string) $_COOKIE[$config['cookies']['mod']]); if (count($cookie) != 3) { // Malformed cookies destroyCookies(); @@ -210,11 +203,6 @@ function check_login($prompt = false) { exit; } - $mod = array( - 'id' => (int)$user['id'], - 'type' => (int)$user['type'], - 'username' => $cookie[0], - 'boards' => explode(',', $user['boards']) - ); + $mod = ['id' => (int)$user['id'], 'type' => (int)$user['type'], 'username' => $cookie[0], 'boards' => explode(',', (string) $user['boards'])]; } } diff --git a/inc/mod/config-editor.php b/inc/mod/config-editor.php index 0f6dbc9a..28405bc2 100644 --- a/inc/mod/config-editor.php +++ b/inc/mod/config-editor.php @@ -11,7 +11,7 @@ function permission_to_edit_config_var($varname) { if (isset($config['mod']['config'][DISABLED])) { foreach ($config['mod']['config'][DISABLED] as $disabled_var_name) { - $disabled_var_name = explode('>', $disabled_var_name); + $disabled_var_name = explode('>', (string) $disabled_var_name); if (count($disabled_var_name) == 1) $disabled_var_name = $disabled_var_name[0]; if ($varname == $disabled_var_name) @@ -30,7 +30,7 @@ function permission_to_edit_config_var($varname) { $allow_only = true; continue; } - $perm_var_name = explode('>', $perm_var_name); + $perm_var_name = explode('>', (string) $perm_var_name); if ((count($perm_var_name) == 1 && $varname == $perm_var_name[0]) || (is_array($varname) && array_slice($varname, 0, count($perm_var_name)) == $perm_var_name)) { if ($allow_only) @@ -49,14 +49,9 @@ function config_vars() { global $config; $config_file = file('inc/config.php', FILE_IGNORE_NEW_LINES); - $conf = array(); + $conf = []; - $var = array( - 'name' => false, - 'comment' => array(), - 'default' => false, - 'default_temp' => false - ); + $var = ['name' => false, 'comment' => [], 'default' => false, 'default_temp' => false]; $temp_comment = false; $line_no = 0; foreach ($config_file as $line) { @@ -65,7 +60,7 @@ function config_vars() { $temp_comment = false; } - if (preg_match('!^\s*// ([^$].*)$!', $line, $matches)) { + if (preg_match('!^\s*// ([^$].*)$!', (string) $line, $matches)) { if ($var['default'] !== false) { $line = ''; $temp_comment = $matches[1]; @@ -74,11 +69,11 @@ function config_vars() { } } else if ($var['default_temp'] !== false) { $var['default_temp'] .= "\n" . $line; - } elseif (preg_match('!^[\s/]*\$config\[(.+?)\] = (.+?)(;( //.+)?)?$!', $line, $matches)) { - if (preg_match('!^\s*//\s*!', $line)) { + } elseif (preg_match('!^[\s/]*\$config\[(.+?)\] = (.+?)(;( //.+)?)?$!', (string) $line, $matches)) { + if (preg_match('!^\s*//\s*!', (string) $line)) { $var['commented'] = true; } - $var['name'] = explode('][', $matches[1]); + $var['name'] = explode('][', (string) $matches[1]); if (count($var['name']) == 1) { $var['name'] = preg_replace('/^\'(.*)\'$/', '$1', end($var['name'])); } else { @@ -97,7 +92,7 @@ function config_vars() { $var['default'] = $var['default_temp']; if ($var['default'][0] == '&') continue; // This is just an alias. - if (!preg_match('/^array|\[\]|function/', $var['default']) && !preg_match('/^Example: /', trim(implode(' ', $var['comment'])))) { + if (!preg_match('/^array|\[\]|function/', (string) $var['default']) && !preg_match('/^Example: /', trim(implode(' ', $var['comment'])))) { $syntax_error = true; $temp = eval('$syntax_error = false;return @' . $var['default'] . ';'); if ($syntax_error && $temp === false) { @@ -109,13 +104,13 @@ function config_vars() { } if ($var['type'] == 'integer' && $var['name'][0] == 'mod' && - (in_array($var['default'], array('JANITOR', 'MOD', 'ADMIN', 'DISABLED')) || mb_strpos($var['default'], "\$config['mod']") === 0)) { + (in_array($var['default'], ['JANITOR', 'MOD', 'ADMIN', 'DISABLED']) || mb_strpos((string) $var['default'], "\$config['mod']") === 0)) { // Permissions variable $var['permissions'] = true; } unset($var['default_temp']); - if (!is_array($var['name']) || (end($var['name']) != '' && !in_array(reset($var['name']), array('stylesheets')))) { + if (!is_array($var['name']) || (end($var['name']) != '' && !in_array(reset($var['name']), ['stylesheets']))) { $already_exists = false; foreach ($conf as $_var) { if ($var['name'] == $_var['name']) @@ -133,18 +128,11 @@ function config_vars() { } } - $var = array( - 'name' => false, - 'comment' => array(), - 'default' => false, - 'default_temp' => false, - 'commented' => false, - 'permissions' => false, - ); + $var = ['name' => false, 'comment' => [], 'default' => false, 'default_temp' => false, 'commented' => false, 'permissions' => false]; } - if (trim($line) === '') { - $var['comment'] = array(); + if (trim((string) $line) === '') { + $var['comment'] = []; } $line_no++; diff --git a/inc/mod/pages.php b/inc/mod/pages.php index 36a2c979..735acb57 100644 --- a/inc/mod/pages.php +++ b/inc/mod/pages.php @@ -9,27 +9,19 @@ defined('TINYBOARD') or exit; function mod_page($title, $template, $args, $subtitle = false) { global $config, $mod; - echo Element('page.html', array( - 'config' => $config, - 'mod' => $mod, - 'hide_dashboard_link' => $template == 'mod/dashboard.html', - 'title' => $title, - 'subtitle' => $subtitle, - 'boardlist' => createBoardlist($mod), - 'body' => Element($template, + echo Element('page.html', ['config' => $config, 'mod' => $mod, 'hide_dashboard_link' => $template == 'mod/dashboard.html', 'title' => $title, 'subtitle' => $subtitle, 'boardlist' => createBoardlist($mod), 'body' => Element($template, array_merge( - array('config' => $config, 'mod' => $mod), + ['config' => $config, 'mod' => $mod], $args ) - ) - ) + )] ); } function mod_login($redirect = false) { global $config; - $args = array(); + $args = []; if (isset($_POST['login'])) { // Check if inputs are set and not empty @@ -61,7 +53,7 @@ function mod_login($redirect = false) { } function mod_confirm($request) { - $args = array('request' => $request, 'token' => make_secure_link_token($request)); + $args = ['request' => $request, 'token' => make_secure_link_token($request)]; if(isset($_GET['thread'])) { $args['rest'] = 'thread=' . $_GET['thread']; } @@ -76,9 +68,10 @@ function mod_logout() { } function mod_dashboard() { - global $config, $mod; + $m = []; + global $config, $mod; - $args = array(); + $args = []; $args['boards'] = listBoards(); @@ -114,22 +107,14 @@ function mod_dashboard() { if (isset($_COOKIE['update'])) { $latest = unserialize($_COOKIE['update']); } else { - $ctx = stream_context_create(array('http' => array('timeout' => 5))); + $ctx = stream_context_create(['http' => ['timeout' => 5]]); if ($code = @file_get_contents('http://engine.vichan.net/version.txt', 0, $ctx)) { $ver = strtok($code, "\n"); if (preg_match('@^// v(\d+)\.(\d+)\.(\d+)\s*?$@', $ver, $matches)) { - $latest = array( - 'massive' => $matches[1], - 'major' => $matches[2], - 'minor' => $matches[3] - ); - if (preg_match('/(\d+)\.(\d)\.(\d+)(-dev.+)?$/', $config['version'], $matches)) { - $current = array( - 'massive' => (int) $matches[1], - 'major' => (int) $matches[2], - 'minor' => (int) $matches[3] - ); + $latest = ['massive' => $matches[1], 'major' => $matches[2], 'minor' => $matches[3]]; + if (preg_match('/(\d+)\.(\d)\.(\d+)(-dev.+)?$/', (string) $config['version'], $matches)) { + $current = ['massive' => (int) $matches[1], 'major' => (int) $matches[2], 'minor' => (int) $matches[3]]; if (isset($m[4])) { // Development versions are always ahead in the versioning numbers $current['minor'] --; @@ -154,7 +139,7 @@ function mod_dashboard() { $latest = false; } - setcookie('update', serialize($latest), time() + $config['check_updates_time'], $config['cookies']['jail'] ? $config['cookies']['path'] : '/', $config["domain"], !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', true); + setcookie('update', serialize($latest), ['expires' => time() + $config['check_updates_time'], 'path' => $config['cookies']['jail'] ? $config['cookies']['path'] : '/', 'domain' => $config["domain"], 'secure' => !empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] != 'off', 'httponly' => true]); } if ($latest) @@ -172,9 +157,9 @@ function mod_search_redirect() { if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); - if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], array('posts', 'IP_notes', 'bans', 'log'))) { + if (isset($_POST['query'], $_POST['type']) && in_array($_POST['type'], ['posts', 'IP_notes', 'bans', 'log'])) { $query = $_POST['query']; - $query = urlencode($query); + $query = urlencode((string) $query); $query = str_replace('_', '%5F', $query); $query = str_replace('+', '_', $query); @@ -190,13 +175,14 @@ function mod_search_redirect() { } function mod_search($type, $search_query_escaped, $page_no = 1) { - global $pdo, $config; + $sql_table = null; + global $pdo, $config; if (!hasPermission($config['mod']['search'])) error($config['error']['noaccess']); // Unescape query - $query = str_replace('_', ' ', $search_query_escaped); + $query = str_replace('_', ' ', (string) $search_query_escaped); $query = urldecode($query); $search_query = $query; @@ -215,7 +201,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { $query = str_replace('`', '!`', $query); // Array of phrases to match - $match = array(); + $match = []; // Exact phrases ("like this") if (preg_match_all('/"(.+?)"/', $query, $exact_phrases)) { @@ -236,7 +222,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // Which `field` to search? if ($type == 'posts') - $sql_field = array('body_nomarkup', 'files', 'subject', 'filehash', 'ip', 'name', 'trip'); + $sql_field = ['body_nomarkup', 'files', 'subject', 'filehash', 'ip', 'name', 'trip']; if ($type == 'IP_notes') $sql_field = 'body'; if ($type == 'bans') @@ -321,7 +307,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { if ($type == 'bans') { foreach ($results as &$ban) { - $ban['mask'] = Bans::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $ban['mask'] = Bans::range_to_string([$ban['ipstart'], $ban['ipend']]); if (filter_var($ban['mask'], FILTER_VALIDATE_IP) !== false) $ban['single_addr'] = true; } @@ -335,13 +321,7 @@ function mod_search($type, $search_query_escaped, $page_no = 1) { // $results now contains the search results - mod_page(_('Search results'), 'mod/search_results.html', array( - 'search_type' => $type, - 'search_query' => $search_query, - 'search_query_escaped' => $search_query_escaped, - 'result_count' => $result_count, - 'results' => $results - )); + mod_page(_('Search results'), 'mod/search_results.html', ['search_type' => $type, 'search_query' => $search_query, 'search_query_escaped' => $search_query_escaped, 'result_count' => $result_count, 'results' => $results]); } function mod_edit_board($boardName) { @@ -408,7 +388,7 @@ function mod_edit_board($boardName) { // Remove board from users/permissions table $query = query('SELECT `id`,`boards` FROM ``mods``') or error(db_error()); while ($user = $query->fetch(PDO::FETCH_ASSOC)) { - $user_boards = explode(',', $user['boards']); + $user_boards = explode(',', (string) $user['boards']); if (in_array($board['uri'], $user_boards)) { unset($user_boards[array_search($board['uri'], $user_boards)]); $_query = prepare('UPDATE ``mods`` SET `boards` = :boards WHERE `id` = :id'); @@ -439,10 +419,7 @@ function mod_edit_board($boardName) { header('Location: ?/', true, $config['redirect_http']); } else { - mod_page(sprintf('%s: ' . $config['board_abbreviation'], _('Edit board'), $board['uri']), 'mod/board.html', array( - 'board' => $board, - 'token' => make_secure_link_token('edit/' . $board['uri']) - )); + mod_page(sprintf('%s: ' . $config['board_abbreviation'], _('Edit board'), $board['uri']), 'mod/board.html', ['board' => $board, 'token' => make_secure_link_token('edit/' . $board['uri'])]); } } @@ -459,11 +436,11 @@ function mod_new_board() { if ($_POST['title'] == '') error(sprintf($config['error']['required'], 'title')); - if (!preg_match('/^' . $config['board_regex'] . '$/u', $_POST['uri'])) + if (!preg_match('/^' . $config['board_regex'] . '$/u', (string) $_POST['uri'])) error(sprintf($config['error']['invalidfield'], 'URI')); $bytes = 0; - $chars = preg_split('//u', $_POST['uri'], -1, PREG_SPLIT_NO_EMPTY); + $chars = preg_split('//u', (string) $_POST['uri'], -1, PREG_SPLIT_NO_EMPTY); foreach ($chars as $char) { $o = 0; $ord = ordutf8($char, $o); @@ -494,7 +471,7 @@ function mod_new_board() { if (!openBoard($_POST['uri'])) error(_("Couldn't open board after creation.")); - $query = Element('posts.sql', array('board' => $board['uri'])); + $query = Element('posts.sql', ['board' => $board['uri']]); if (mysql_version() < 50503) $query = preg_replace('/(CHARSET=|CHARACTER SET )utf8mb4/', '$1utf8', $query); @@ -512,7 +489,7 @@ function mod_new_board() { header('Location: ?/' . $board['uri'] . '/' . $config['file_index'], true, $config['redirect_http']); } - mod_page(_('New board'), 'mod/board.html', array('new' => true, 'token' => make_secure_link_token('new-board'))); + mod_page(_('New board'), 'mod/board.html', ['new' => true, 'token' => make_secure_link_token('new-board')]); } function mod_noticeboard($page_no = 1) { @@ -563,11 +540,7 @@ function mod_noticeboard($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('Noticeboard'), 'mod/noticeboard.html', array( - 'noticeboard' => $noticeboard, - 'count' => $count, - 'token' => make_secure_link_token('noticeboard') - )); + mod_page(_('Noticeboard'), 'mod/noticeboard.html', ['noticeboard' => $noticeboard, 'count' => $count, 'token' => make_secure_link_token('noticeboard')]); } function mod_noticeboard_delete($id) { @@ -632,7 +605,7 @@ function mod_news($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('News'), 'mod/news.html', array('news' => $news, 'count' => $count, 'token' => make_secure_link_token('edit_news'))); + mod_page(_('News'), 'mod/news.html', ['news' => $news, 'count' => $count, 'token' => make_secure_link_token('edit_news')]); } function mod_news_delete($id) { @@ -672,7 +645,7 @@ function mod_log($page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('Moderation log'), 'mod/log.html', array('logs' => $logs, 'count' => $count)); + mod_page(_('Moderation log'), 'mod/log.html', ['logs' => $logs, 'count' => $count]); } function mod_user_log($username, $page_no = 1) { @@ -699,7 +672,7 @@ function mod_user_log($username, $page_no = 1) { $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('Moderation log'), 'mod/log.html', array('logs' => $logs, 'count' => $count, 'username' => $username)); + mod_page(_('Moderation log'), 'mod/log.html', ['logs' => $logs, 'count' => $count, 'username' => $username]); } function mod_board_log($board, $page_no = 1, $hide_names = false, $public = false) { @@ -735,7 +708,7 @@ function mod_board_log($board, $page_no = 1, $hide_names = false, $public = fals $query->execute() or error(db_error($query)); $count = $query->fetchColumn(); - mod_page(_('Board log'), 'mod/log.html', array('logs' => $logs, 'count' => $count, 'board' => $board, 'hide_names' => $hide_names, 'public' => $public)); + mod_page(_('Board log'), 'mod/log.html', ['logs' => $logs, 'count' => $count, 'board' => $board, 'hide_names' => $hide_names, 'public' => $public]); } function mod_view_board($boardName, $page_no = 1) { @@ -748,7 +721,7 @@ function mod_view_board($boardName, $page_no = 1) { global $mod; $overboard = new $type(); - $overboard->settings = array(); + $overboard->settings = []; $overboard->settings['uri'] = $boardName; $overboard->settings['title'] = $config['overboards'][$boardName]['title']; $overboard->settings['subtitle'] = $config['overboards'][$boardName]['subtitle']; @@ -859,9 +832,9 @@ function mod_page_ip($ip) { return; } - $args = array(); + $args = []; $args['ip'] = $ip; - $args['posts'] = array(); + $args['posts'] = []; if ($config['mod']['dns_lookup']) $args['hostname'] = rDNS($ip); @@ -884,7 +857,7 @@ function mod_page_ip($ip) { } if (!isset($args['posts'][$board['uri']])) - $args['posts'][$board['uri']] = array('board' => $board, 'posts' => array()); + $args['posts'][$board['uri']] = ['board' => $board, 'posts' => []]; $args['posts'][$board['uri']]['posts'][] = $po->build(true); } } @@ -909,12 +882,12 @@ function mod_page_ip($ip) { $query->execute() or error(db_error($query)); $args['logs'] = $query->fetchAll(PDO::FETCH_ASSOC); } else { - $args['logs'] = array(); + $args['logs'] = []; } $args['security_token'] = make_secure_link_token('IP/' . $ip); - mod_page(sprintf('%s: %s', _('IP'), htmlspecialchars($ip)), 'mod/view_ip.html', $args, $args['hostname']); + mod_page(sprintf('%s: %s', _('IP'), htmlspecialchars((string) $ip)), 'mod/view_ip.html', $args, $args['hostname']); } function mod_ban() { @@ -924,7 +897,7 @@ function mod_ban() { error($config['error']['noaccess']); if (!isset($_POST['ip'], $_POST['reason'], $_POST['length'], $_POST['board'])) { - mod_page(_('New ban'), 'mod/ban_form.html', array('token' => make_secure_link_token('ban'))); + mod_page(_('New ban'), 'mod/ban_form.html', ['token' => make_secure_link_token('ban')]); return; } @@ -945,7 +918,7 @@ function mod_warning() { error($config['error']['noaccess']); if (!isset( $_POST['board'])) { - mod_page(_('New warning'), 'mod/warning_form.html', array('token' => make_secure_link_token('ban'))); + mod_page(_('New warning'), 'mod/warning_form.html', ['token' => make_secure_link_token('ban')]); return; } @@ -966,7 +939,7 @@ function mod_bans() { if (!hasPermission($config['mod']['unban'])) error($config['error']['noaccess']); - $unban = array(); + $unban = []; foreach ($_POST as $name => $unused) { if (preg_match('/^ban_(\d+)$/', $name, $match)) $unban[] = $match[1]; @@ -982,12 +955,7 @@ function mod_bans() { return; } - mod_page(_('Ban list'), 'mod/ban_list.html', array( - 'mod' => $mod, - 'boards' => json_encode($mod['boards']), - 'token' => make_secure_link_token('bans'), - 'token_json' => make_secure_link_token('bans.json') - )); + mod_page(_('Ban list'), 'mod/ban_list.html', ['mod' => $mod, 'boards' => json_encode($mod['boards'], JSON_THROW_ON_ERROR), 'token' => make_secure_link_token('bans'), 'token_json' => make_secure_link_token('bans.json')]); } function mod_bans_json() { @@ -997,7 +965,7 @@ function mod_bans_json() { error($config['error']['noaccess']); // Compress the json for faster loads - if (substr_count($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); + if (substr_count((string) $_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip')) ob_start("ob_gzhandler"); Bans::stream_json(false, false, !hasPermission($config['mod']['view_banstaff']), $mod['boards']); } @@ -1023,7 +991,7 @@ function mod_ban_appeals() { error(_('Ban appeal not found!')); } - $ban['mask'] = Bans::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $ban['mask'] = Bans::range_to_string([$ban['ipstart'], $ban['ipend']]); if (isset($_POST['unban'])) { modLog('Accepted ban appeal #' . $ban['id'] . ' for ' . $ban['mask']); @@ -1045,24 +1013,24 @@ function mod_ban_appeals() { $ban_appeals = $query->fetchAll(PDO::FETCH_ASSOC); foreach ($ban_appeals as &$ban) { if ($ban['post']) - $ban['post'] = json_decode($ban['post'], true); - $ban['mask'] = Bans::range_to_string(array($ban['ipstart'], $ban['ipend'])); + $ban['post'] = json_decode((string) $ban['post'], true, 512, JSON_THROW_ON_ERROR); + $ban['mask'] = Bans::range_to_string([$ban['ipstart'], $ban['ipend']]); if ($ban['post'] && isset($ban['post']['board'], $ban['post']['id'])) { if (openBoard($ban['post']['board'])) { $query = query(sprintf("SELECT `num_files`, `files` FROM ``posts_%s`` WHERE `id` = " . (int)$ban['post']['id'], $board['uri'])); if ($_post = $query->fetch(PDO::FETCH_ASSOC)) { - $_post['files'] = $_post['files'] ? json_decode($_post['files']) : array(); + $_post['files'] = $_post['files'] ? json_decode((string) $_post['files'], null, 512, JSON_THROW_ON_ERROR) : []; $ban['post'] = array_merge($ban['post'], $_post); } else { - $ban['post']['files'] = array(array()); + $ban['post']['files'] = [[]]; $ban['post']['files'][0]['file'] = 'deleted'; $ban['post']['files'][0]['thumb'] = false; $ban['post']['num_files'] = 1; } } else { - $ban['post']['files'] = array(array()); + $ban['post']['files'] = [[]]; $ban['post']['files'][0]['file'] = 'deleted'; $ban['post']['files'][0]['thumb'] = false; $ban['post']['num_files'] = 1; @@ -1076,10 +1044,7 @@ function mod_ban_appeals() { } } - mod_page(_('Ban appeals'), 'mod/ban_appeals.html', array( - 'ban_appeals' => $ban_appeals, - 'token' => make_secure_link_token('ban-appeals') - )); + mod_page(_('Ban appeals'), 'mod/ban_appeals.html', ['ban_appeals' => $ban_appeals, 'token' => make_secure_link_token('ban-appeals')]); } function mod_lock($board, $unlock, $post) { @@ -1216,7 +1181,7 @@ function mod_move_reply($originBoard, $postID) { } if ($post['files']) { - $post['files'] = json_decode($post['files'], TRUE); + $post['files'] = json_decode((string) $post['files'], TRUE, 512, JSON_THROW_ON_ERROR); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; @@ -1281,7 +1246,7 @@ function mod_move_reply($originBoard, $postID) { $security_token = make_secure_link_token($originBoard . '/move_reply/' . $postID); - mod_page(_('Move reply'), 'mod/move_reply.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); + mod_page(_('Move reply'), 'mod/move_reply.html', ['post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token]); } @@ -1316,7 +1281,7 @@ function mod_move($originBoard, $postID) { $post['op'] = true; if ($post['files']) { - $post['files'] = json_decode($post['files'], TRUE); + $post['files'] = json_decode((string) $post['files'], TRUE, 512, JSON_THROW_ON_ERROR); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { if ($file['file'] === 'deleted') @@ -1345,7 +1310,7 @@ function mod_move($originBoard, $postID) { foreach ($post['files'] as $i => &$file) { if ($file['file'] !== 'deleted') $clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); - if (isset($file['thumb']) && !in_array($file['thumb'], array('spoiler', 'deleted', 'file'))) + if (isset($file['thumb']) && !in_array($file['thumb'], ['spoiler', 'deleted', 'file'])) $clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } @@ -1357,14 +1322,14 @@ function mod_move($originBoard, $postID) { $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $replies = array(); + $replies = []; while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['mod'] = true; $post['thread'] = $newID; if ($post['files']) { - $post['files'] = json_decode($post['files'], TRUE); + $post['files'] = json_decode((string) $post['files'], TRUE, 512, JSON_THROW_ON_ERROR); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; @@ -1377,7 +1342,7 @@ function mod_move($originBoard, $postID) { $replies[] = $post; } - $newIDs = array($postID => $newID); + $newIDs = [$postID => $newID]; openBoard($targetBoard); @@ -1391,7 +1356,7 @@ function mod_move($originBoard, $postID) { while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if (isset($newIDs[$cite['target']])) { $post['body_nomarkup'] = preg_replace( - '/(>>(>\/' . preg_quote($originBoard, '/') . '\/)?)' . preg_quote($cite['target'], '/') . '/', + '/(>>(>\/' . preg_quote((string) $originBoard, '/') . '\/)?)' . preg_quote((string) $cite['target'], '/') . '/', '>>' . $newIDs[$cite['target']], $post['body_nomarkup']); @@ -1416,7 +1381,7 @@ function mod_move($originBoard, $postID) { if (!empty($post['tracked_cites'])) { - $insert_rows = array(); + $insert_rows = []; foreach ($post['tracked_cites'] as $cite) { $insert_rows[] = '(' . $pdo->quote($board['uri']) . ', ' . $newPostID . ', ' . @@ -1449,19 +1414,19 @@ function mod_move($originBoard, $postID) { $query->execute() or error(db_error($query)); // leave a reply, linking to the new thread - $spost = array( - 'mod' => true, - 'subject' => '', - 'email' => '', - 'name' => (!$config['mod']['shadow_name'] ? $config['anonymous'] : $config['mod']['shadow_name']), - 'capcode' => $config['mod']['shadow_capcode'], - 'trip' => '', - 'password' => '', - 'has_file' => false, - // attach to original thread - 'thread' => $postID, - 'op' => false - ); + $spost = [ + 'mod' => true, + 'subject' => '', + 'email' => '', + 'name' => (!$config['mod']['shadow_name'] ? $config['anonymous'] : $config['mod']['shadow_name']), + 'capcode' => $config['mod']['shadow_capcode'], + 'trip' => '', + 'password' => '', + 'has_file' => false, + // attach to original thread + 'thread' => $postID, + 'op' => false, + ]; $spost['body'] = $spost['body_nomarkup'] = sprintf($config['mod']['shadow_mesage'], '>>>/' . $targetBoard . '/' . $newID); @@ -1484,12 +1449,12 @@ function mod_move($originBoard, $postID) { } $boards = listBoards(); - if (count($boards) <= 1) + if ((is_countable($boards) ? count($boards) : 0) <= 1) error(_('Impossible to move thread; there is only one board.')); $security_token = make_secure_link_token($originBoard . '/move/' . $postID); - mod_page(_('Move thread'), 'mod/move.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); + mod_page(_('Move thread'), 'mod/move.html', ['post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token]); } function mod_merge($originBoard, $postID) { @@ -1566,12 +1531,12 @@ function mod_merge($originBoard, $postID) { else { // Move thread to new board without shadow thread and then update the thread id for all posts in that thread to new op // indicate that the post is a thread - if (count($boards) <= 1) + if ((is_countable($boards) ? count($boards) : 0) <= 1) error(_('Impossible to merge thread to different board; there is only one board.')); $post['op'] = true; if ($post['files']) { - $post['files'] = json_decode($post['files'], TRUE); + $post['files'] = json_decode((string) $post['files'], TRUE, 512, JSON_THROW_ON_ERROR); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { if ($file['file'] === 'deleted') @@ -1602,7 +1567,7 @@ function mod_merge($originBoard, $postID) { foreach ($post['files'] as $i => &$file) { if ($file['file'] !== 'deleted') $clone($file['file_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']); - if (isset($file['thumb']) && !in_array($file['thumb'], array('spoiler', 'deleted', 'file'))) + if (isset($file['thumb']) && !in_array($file['thumb'], ['spoiler', 'deleted', 'file'])) $clone($file['thumb_path'], sprintf($config['board_path'], $board['uri']) . $config['dir']['thumb'] . $file['thumb']); } } @@ -1614,14 +1579,14 @@ function mod_merge($originBoard, $postID) { $query->bindValue(':id', $postID, PDO::PARAM_INT); $query->execute() or error(db_error($query)); - $replies = array(); + $replies = []; while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $post['mod'] = true; $post['thread'] = $newID; if ($post['files']) { - $post['files'] = json_decode($post['files'], TRUE); + $post['files'] = json_decode((string) $post['files'], TRUE, 512, JSON_THROW_ON_ERROR); $post['has_file'] = true; foreach ($post['files'] as $i => &$file) { $file['file_path'] = sprintf($config['board_path'], $board['uri']) . $config['dir']['img'] . $file['file']; @@ -1634,7 +1599,7 @@ function mod_merge($originBoard, $postID) { $replies[] = $post; } - $newIDs = array($postID => $newID); + $newIDs = [$postID => $newID]; openBoard($targetBoard); @@ -1648,7 +1613,7 @@ function mod_merge($originBoard, $postID) { while ($cite = $query->fetch(PDO::FETCH_ASSOC)) { if (isset($newIDs[$cite['target']])) { $post['body_nomarkup'] = preg_replace( - '/(>>(>\/' . preg_quote($originBoard, '/') . '\/)?)' . preg_quote($cite['target'], '/') . '/', + '/(>>(>\/' . preg_quote((string) $originBoard, '/') . '\/)?)' . preg_quote((string) $cite['target'], '/') . '/', '>>' . $newIDs[$cite['target']], $post['body_nomarkup']); @@ -1673,7 +1638,7 @@ function mod_merge($originBoard, $postID) { if (!empty($post['tracked_cites'])) { - $insert_rows = array(); + $insert_rows = []; foreach ($post['tracked_cites'] as $cite) { $insert_rows[] = '(' . $pdo->quote($board['uri']) . ', ' . $newPostID . ', ' . @@ -1726,7 +1691,7 @@ function mod_merge($originBoard, $postID) { $security_token = make_secure_link_token($originBoard . '/merge/' . $postID); - mod_page(_('Merge thread'), 'mod/merge.html', array('post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token)); + mod_page(_('Merge thread'), 'mod/merge.html', ['post' => $postID, 'board' => $originBoard, 'boards' => $boards, 'token' => $security_token]); } function mod_ban_post($board, $delete, $post, $token = false) { @@ -1772,7 +1737,7 @@ function mod_ban_post($board, $delete, $post, $token = false) { rebuildPost($post); modLog("Attached a public ban message to post #{$post}: " . utf8tohtml($_POST['message'])); - buildThread($thread ? $thread : $post); + buildThread($thread ?: $post); buildIndex(); } elseif (isset($_POST['delete']) && (int) $_POST['delete']) { // Delete post @@ -1794,7 +1759,7 @@ function mod_ban_post($board, $delete, $post, $token = false) { $name = $mypost["name"]; $subject = $mypost["subject"]; $filehash = $mypost["filehash"]; - $mypost['files'] = $mypost['files'] ? json_decode($mypost['files']) : array(); + $mypost['files'] = $mypost['files'] ? json_decode((string) $mypost['files'], null, 512, JSON_THROW_ON_ERROR) : []; // For each file append file name for ($file_count = 0; $file_count < $mypost["num_files"];$file_count++){ $filename .= $mypost['files'][$file_count]->name . "\r\n"; @@ -1827,22 +1792,14 @@ function mod_ban_post($board, $delete, $post, $token = false) { if(isset($_POST['thread'])) { // Redirect to thread - header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], $config['file_page']), true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], (string) $config['file_page']), true, $config['redirect_http']); } else { // Redirect to board index. header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } } - $args = array( - 'ip' => $ip, - 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), - 'post' => $post, - 'board' => $board, - 'delete' => (bool)$delete, - 'boards' => listBoards(), - 'token' => $security_token - ); + $args = ['ip' => $ip, 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), 'post' => $post, 'board' => $board, 'delete' => (bool)$delete, 'boards' => listBoards(), 'token' => $security_token]; if(isset($_GET['thread'])) { $args['thread'] = $_GET['thread']; @@ -1883,7 +1840,7 @@ function mod_warning_post($board,$post, $token = false) { rebuildPost($post); modLog("Attached a public warning message to post #{$post}: " . utf8tohtml($_POST['message'])); - buildThread($thread ? $thread : $post); + buildThread($thread ?: $post); buildIndex(); if ($config['autotagging']){ @@ -1904,7 +1861,7 @@ function mod_warning_post($board,$post, $token = false) { $name = $mypost["name"]; $subject = $mypost["subject"]; $filehash = $mypost["filehash"]; - $mypost['files'] = $mypost['files'] ? json_decode($mypost['files']) : array(); + $mypost['files'] = $mypost['files'] ? json_decode((string) $mypost['files'], null, 512, JSON_THROW_ON_ERROR) : []; // For each file append file name for ($file_count = 0; $file_count < $mypost["num_files"];$file_count++){ $filename .= $mypost['files'][$file_count]->name . "\r\n"; @@ -1930,19 +1887,13 @@ function mod_warning_post($board,$post, $token = false) { } if(isset($_POST['thread'])) { // Redirect to thread - header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], $config['file_page']), true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_POST['thread'], (string) $config['file_page']), true, $config['redirect_http']); } else { // Redirect to board index. header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } } - $args = array( - 'ip' => $ip, - 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), - 'post' => $post, - 'board' => $board, - 'token' => $security_token - ); + $args = ['ip' => $ip, 'hide_ip' => !hasPermission($config['mod']['show_ip'], $board), 'post' => $post, 'board' => $board, 'token' => $security_token]; if(isset($_GET['thread'])) { $args['thread'] = $_GET['thread']; @@ -2016,15 +1967,15 @@ function mod_edit_post($board, $edit_raw_html, $postID) { $post['body_nomarkup'] = utf8tohtml($post['body_nomarkup']); $post['body'] = utf8tohtml($post['body']); if ($config['minify_html']) { - $post['body_nomarkup'] = str_replace("\n", '
', $post['body_nomarkup']); - $post['body'] = str_replace("\n", '
', $post['body']); - $post['body_nomarkup'] = str_replace("\r", '', $post['body_nomarkup']); - $post['body'] = str_replace("\r", '', $post['body']); - $post['body_nomarkup'] = str_replace("\t", '	', $post['body_nomarkup']); - $post['body'] = str_replace("\t", '	', $post['body']); + $post['body_nomarkup'] = str_replace("\n", '
', (string) $post['body_nomarkup']); + $post['body'] = str_replace("\n", '
', (string) $post['body']); + $post['body_nomarkup'] = str_replace("\r", '', (string) $post['body_nomarkup']); + $post['body'] = str_replace("\r", '', (string) $post['body']); + $post['body_nomarkup'] = str_replace("\t", '	', (string) $post['body_nomarkup']); + $post['body'] = str_replace("\t", '	', (string) $post['body']); } - mod_page(_('Edit post'), 'mod/edit_post_form.html', array('token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post)); + mod_page(_('Edit post'), 'mod/edit_post_form.html', ['token' => $security_token, 'board' => $board, 'raw' => $edit_raw_html, 'post' => $post]); } } @@ -2056,7 +2007,7 @@ function mod_delete($board, $post) { $name = $mypost["name"]; $subject = $mypost["subject"]; $filehash = $mypost["filehash"]; - $mypost['files'] = $mypost['files'] ? json_decode($mypost['files']) : array(); + $mypost['files'] = $mypost['files'] ? json_decode((string) $mypost['files'], null, 512, JSON_THROW_ON_ERROR) : []; // For each file append file name for ($file_count = 0; $file_count < $mypost["num_files"];$file_count++){ $filename .= $mypost['files'][$file_count]->name . "\r\n"; @@ -2088,7 +2039,7 @@ function mod_delete($board, $post) { rebuildThemes('post-delete', $board); // Redirect if(isset($_GET['thread'])) { - header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_GET['thread'], $config['file_page']), true, $config['redirect_http']); + header('Location: ?/' . sprintf($config['board_path'], $board) . $config['dir']['res'] . str_replace('%d', $_GET['thread'], (string) $config['file_page']), true, $config['redirect_http']); } else { header('Location: ?/' . sprintf($config['board_path'], $board) . $config['file_index'], true, $config['redirect_http']); } @@ -2131,7 +2082,7 @@ function mod_spoiler_image($board, $post, $file) { $query->bindValue(':id', $post, PDO::PARAM_INT); $query->execute() or error(db_error($query)); $result = $query->fetch(PDO::FETCH_ASSOC); - $files = json_decode($result['files']); + $files = json_decode((string) $result['files'], null, 512, JSON_THROW_ON_ERROR); $size_spoiler_image = @getimagesize($config['spoiler_image']); @@ -2142,7 +2093,7 @@ function mod_spoiler_image($board, $post, $file) { // Make thumbnail spoiler $query = prepare(sprintf("UPDATE ``posts_%s`` SET `files` = :files WHERE `id` = :id", $board)); - $query->bindValue(':files', json_encode($files)); + $query->bindValue(':files', json_encode($files, JSON_THROW_ON_ERROR)); $query->bindValue(':id', $post, PDO::PARAM_INT); $query->execute() or error(db_error($query)); @@ -2150,7 +2101,7 @@ function mod_spoiler_image($board, $post, $file) { modLog("Spoilered file from post #{$post}"); // Rebuild thread - buildThread($result['thread'] ? $result['thread'] : $post); + buildThread($result['thread'] ?: $post); // Rebuild board buildIndex(); @@ -2183,7 +2134,7 @@ function mod_deletebyip($boardName, $post, $global = false) { if (!$ip = $query->fetchColumn()) error($config['error']['invalidpost']); - $boards = $global ? listBoards() : array(array('uri' => $boardName)); + $boards = $global ? listBoards() : [['uri' => $boardName]]; $query = ''; foreach ($boards as $_board) { @@ -2200,8 +2151,8 @@ function mod_deletebyip($boardName, $post, $global = false) { @set_time_limit($config['mod']['rebuild_timelimit']); - $threads_to_rebuild = array(); - $threads_deleted = array(); + $threads_to_rebuild = []; + $threads_deleted = []; while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); if ($config['autotagging']){ @@ -2222,7 +2173,7 @@ function mod_deletebyip($boardName, $post, $global = false) { $name = $mypost["name"]; $subject = $mypost["subject"]; $filehash = $mypost["filehash"]; - $mypost['files'] = $mypost['files'] ? json_decode($mypost['files']) : array(); + $mypost['files'] = $mypost['files'] ? json_decode((string) $mypost['files'], null, 512, JSON_THROW_ON_ERROR) : []; // For each file append file name for ($file_count = 0; $file_count < $mypost["num_files"];$file_count++){ $filename .= $mypost['files'][$file_count]->name . "\r\n"; @@ -2292,14 +2243,14 @@ function mod_user($uid) { if (hasPermission($config['mod']['editusers']) && isset($_POST['username'], $_POST['password'])) { if (isset($_POST['allboards'])) { - $boards = array('*'); + $boards = ['*']; } else { $_boards = listBoards(); foreach ($_boards as &$board) { $board = $board['uri']; } - $boards = array(); + $boards = []; foreach ($_POST as $name => $value) { if (preg_match('/^board_(' . $config['board_regex'] . ')$/u', $name, $matches) && in_array($matches[1], $_boards)) $boards[] = $matches[1]; @@ -2336,7 +2287,7 @@ function mod_user($uid) { } if ($_POST['password'] != '') { - list($version, $password) = crypt_password($_POST['password']); + [$version, $password] = crypt_password($_POST['password']); $query = prepare('UPDATE ``mods`` SET `password` = :password, `version` = :version WHERE `id` = :id'); $query->bindValue(':id', $uid); @@ -2362,7 +2313,7 @@ function mod_user($uid) { if (hasPermission($config['mod']['change_password']) && $uid == $mod['id'] && isset($_POST['password'])) { if ($_POST['password'] != '') { - list($version, $password) = crypt_password($_POST['password']); + [$version, $password] = crypt_password($_POST['password']); $query = prepare('UPDATE ``mods`` SET `password` = :password, `version` = :version WHERE `id` = :id'); $query->bindValue(':id', $uid); @@ -2390,17 +2341,12 @@ function mod_user($uid) { $query->execute() or error(db_error($query)); $log = $query->fetchAll(PDO::FETCH_ASSOC); } else { - $log = array(); + $log = []; } - $user['boards'] = explode(',', $user['boards']); + $user['boards'] = explode(',', (string) $user['boards']); - mod_page(_('Edit user'), 'mod/user.html', array( - 'user' => $user, - 'logs' => $log, - 'boards' => listBoards(), - 'token' => make_secure_link_token('users/' . $user['id']) - )); + mod_page(_('Edit user'), 'mod/user.html', ['user' => $user, 'logs' => $log, 'boards' => listBoards(), 'token' => make_secure_link_token('users/' . $user['id'])]); } function mod_user_new() { @@ -2416,14 +2362,14 @@ function mod_user_new() { error(sprintf($config['error']['required'], 'password')); if (isset($_POST['allboards'])) { - $boards = array('*'); + $boards = ['*']; } else { $_boards = listBoards(); foreach ($_boards as &$board) { $board = $board['uri']; } - $boards = array(); + $boards = []; foreach ($_POST as $name => $value) { if (preg_match('/^board_(' . $config['board_regex'] . ')$/u', $name, $matches) && in_array($matches[1], $_boards)) $boards[] = $matches[1]; @@ -2434,7 +2380,7 @@ function mod_user_new() { if (!isset($config['mod']['groups'][$type]) || $type == DISABLED) error(sprintf($config['error']['invalidfield'], 'type')); - list($version, $password) = crypt_password($_POST['password']); + [$version, $password] = crypt_password($_POST['password']); $query = prepare('INSERT INTO ``mods`` VALUES (NULL, :username, :password, :version, :type, :boards)'); $query->bindValue(':username', $_POST['username']); @@ -2452,7 +2398,7 @@ function mod_user_new() { return; } - mod_page(_('New user'), 'mod/user.html', array('new' => true, 'boards' => listBoards(), 'token' => make_secure_link_token('users/new'))); + mod_page(_('New user'), 'mod/user.html', ['new' => true, 'boards' => listBoards(), 'token' => make_secure_link_token('users/new')]); } @@ -2474,7 +2420,7 @@ function mod_users() { $user['demote_token'] = make_secure_link_token("users/{$user['id']}/demote"); } - mod_page(sprintf('%s (%d)', _('Manage users'), count($users)), 'mod/users.html', array('users' => $users)); + mod_page(sprintf('%s (%d)', _('Manage users'), is_countable($users) ? count($users) : 0), 'mod/users.html', ['users' => $users]); } function mod_user_promote($uid, $action) { @@ -2564,12 +2510,7 @@ function mod_pm($id, $reply = false) { if (!$pm['to_username']) error($config['error']['404']); // deleted? - mod_page(sprintf('%s %s', _('New PM for'), $pm['to_username']), 'mod/new_pm.html', array( - 'username' => $pm['username'], - 'id' => $pm['sender'], - 'message' => quote($pm['message']), - 'token' => make_secure_link_token('new_PM/' . $pm['username']) - )); + mod_page(sprintf('%s %s', _('New PM for'), $pm['to_username']), 'mod/new_pm.html', ['username' => $pm['username'], 'id' => $pm['sender'], 'message' => quote($pm['message']), 'token' => make_secure_link_token('new_PM/' . $pm['username'])]); } else { mod_page(sprintf('%s – #%d', _('Private message'), $id), 'mod/pm.html', $pm); } @@ -2592,10 +2533,7 @@ function mod_inbox() { $message['snippet'] = pm_snippet($message['message']); } - mod_page(sprintf('%s (%s)', _('PM inbox'), count($messages) > 0 ? $unread . ' unread' : 'empty'), 'mod/inbox.html', array( - 'messages' => $messages, - 'unread' => $unread - )); + mod_page(sprintf('%s (%s)', _('PM inbox'), (is_countable($messages) ? count($messages) : 0) > 0 ? $unread . ' unread' : 'empty'), 'mod/inbox.html', ['messages' => $messages, 'unread' => $unread]); } @@ -2640,11 +2578,7 @@ function mod_new_pm($username) { header('Location: ?/', true, $config['redirect_http']); } - mod_page(sprintf('%s %s', _('New PM for'), $username), 'mod/new_pm.html', array( - 'username' => $username, - 'id' => $id, - 'token' => make_secure_link_token('new_PM/' . $username) - )); + mod_page(sprintf('%s %s', _('New PM for'), $username), 'mod/new_pm.html', ['username' => $username, 'id' => $id, 'token' => make_secure_link_token('new_PM/' . $username)]); } function deleteDirectory($dir) { @@ -2679,9 +2613,9 @@ function mod_rebuild() { if (isset($_POST['rebuild'])) { @set_time_limit($config['mod']['rebuild_timelimit']); - $log = array(); + $log = []; $boards = listBoards(); - $rebuilt_scripts = array(); + $rebuilt_scripts = []; if (isset($_POST['rebuild_cache'])) { if ($config['cache']['enabled']) { @@ -2731,14 +2665,11 @@ function mod_rebuild() { } } - mod_page(_('Rebuild'), 'mod/rebuilt.html', array('logs' => $log)); + mod_page(_('Rebuild'), 'mod/rebuilt.html', ['logs' => $log]); return; } - mod_page(_('Rebuild'), 'mod/rebuild.html', array( - 'boards' => listBoards(), - 'token' => make_secure_link_token('rebuild') - )); + mod_page(_('Rebuild'), 'mod/rebuild.html', ['boards' => listBoards(), 'token' => make_secure_link_token('rebuild')]); } function mod_reports() { @@ -2752,16 +2683,16 @@ function mod_reports() { $query->execute() or error(db_error($query)); $reports = $query->fetchAll(PDO::FETCH_ASSOC); - $report_queries = array(); + $report_queries = []; foreach ($reports as $report) { if (!isset($report_queries[$report['board']])) - $report_queries[$report['board']] = array(); + $report_queries[$report['board']] = []; $report_queries[$report['board']][] = $report['post']; } - $report_posts = array(); + $report_posts = []; foreach ($report_queries as $board => $posts) { - $report_posts[$board] = array(); + $report_posts[$board] = []; $query = query(sprintf('SELECT * FROM ``posts_%s`` WHERE `id` = ' . implode(' OR `id` = ', $posts), $board)) or error(db_error()); while ($post = $query->fetch(PDO::FETCH_ASSOC)) { @@ -2793,21 +2724,15 @@ function mod_reports() { } // a little messy and inefficient - $append_html = Element('mod/report.html', array( - 'report' => $report, - 'config' => $config, - 'mod' => $mod, - 'token' => make_secure_link_token('reports/' . $report['id'] . '/dismiss'), - 'token_all' => make_secure_link_token('reports/' . $report['id'] . '/dismissall') - )); + $append_html = Element('mod/report.html', ['report' => $report, 'config' => $config, 'mod' => $mod, 'token' => make_secure_link_token('reports/' . $report['id'] . '/dismiss'), 'token_all' => make_secure_link_token('reports/' . $report['id'] . '/dismissall')]); // Bug fix for https://github.com/savetheinternet/Tinyboard/issues/21 - $po->body = truncate($po->body, $po->link(), $config['body_truncate'] - substr_count($append_html, '<br>')); + $po->body = truncate($po->body, $po->link(), $config['body_truncate'] - substr_count((string) $append_html, '<br>')); - if (mb_strlen($po->body) + mb_strlen($append_html) > $config['body_truncate_char']) { + if (mb_strlen((string) $po->body) + mb_strlen((string) $append_html) > $config['body_truncate_char']) { // still too long; temporarily increase limit in the config $__old_body_truncate_char = $config['body_truncate_char']; - $config['body_truncate_char'] = mb_strlen($po->body) + mb_strlen($append_html); + $config['body_truncate_char'] = mb_strlen((string) $po->body) + mb_strlen((string) $append_html); } $po->body .= $append_html; @@ -2820,11 +2745,13 @@ function mod_reports() { $count++; } - mod_page(sprintf('%s (%d)', _('Report queue'), $count), 'mod/reports.html', array('reports' => $body, 'count' => $count)); + mod_page(sprintf('%s (%d)', _('Report queue'), $count), 'mod/reports.html', ['reports' => $body, 'count' => $count]); } function mod_report_dismiss($id, $all = false) { - global $config; + $board = null; + $ip = null; + global $config; $query = prepare("SELECT `post`, `board`, `ip` FROM ``reports`` WHERE `id` = :id"); $query->bindValue(':id', $id); @@ -2861,7 +2788,9 @@ function mod_report_dismiss($id, $all = false) { } function mod_recent_posts($lim,$board_list = false,$json=false) { - global $config, $mod, $pdo; + $apithreads = []; + $jsondata = null; + global $config, $mod, $pdo; if (!hasPermission($config['mod']['recent'])) error($config['error']['noaccess']); @@ -2869,7 +2798,7 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { $limit = (is_numeric($lim))? $lim : 25; $last_time = (isset($_GET['last']) && is_numeric($_GET['last'])) ? $_GET['last'] : 0; - $mod_boards = array(); + $mod_boards = []; $boards = listBoards(); //if not all boards @@ -2882,8 +2811,8 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { $mod_boards = $boards; } if ($board_list != false){ - $board_array = explode(",",$board_list); - $new_board_array = array(); + $board_array = explode(",",(string) $board_list); + $new_board_array = []; foreach ($board_array as $board) { if (array_key_exists($board,$config['boards_alias'])){ $newboard = $config['boards_alias'][$board]; @@ -2893,7 +2822,7 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { } $new_board_array[] = $newboard; } - $mod_boards = array(); + $mod_boards = []; foreach ($boards as $board) { if (in_array($board['uri'], $new_board_array)){ $mod_boards[] = $board; @@ -2914,7 +2843,7 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { $posts = $query->fetchAll(PDO::FETCH_ASSOC); if ($config['api']['enabled']) { - $apithreads = array(); + $apithreads = []; } foreach ($posts as &$post) { @@ -2942,18 +2871,14 @@ function mod_recent_posts($lim,$board_list = false,$json=false) { require_once __DIR__. '/../../inc/api.php'; $api = new Api(); $jsonFilename = 'mod/' . 'recent.json'; - $jsondata = json_encode($api->translatePage($apithreads)); + $jsondata = json_encode($api->translatePage($apithreads), JSON_THROW_ON_ERROR); } if ($json){ echo $jsondata; } else { - echo mod_page(_('Recent posts'), 'mod/recent_posts.html', array( - 'posts' => $posts, - 'limit' => $limit, - 'last_time' => $last_time - ) + echo mod_page(_('Recent posts'), 'mod/recent_posts.html', ['posts' => $posts, 'limit' => $limit, 'last_time' => $last_time] ); } } @@ -2978,7 +2903,7 @@ function mod_config($board_config = false) { $old_code = file_get_contents($config_file); file_put_contents($config_file, $code); $resp = shell_exec_error('php -l ' . $config_file); - if (preg_match('/No syntax errors detected/', $resp)) { + if (preg_match('/No syntax errors detected/', (string) $resp)) { header('Location: ?/config' . ($board_config ? '/' . $board_config : ''), true, $config['redirect_http']); return; } @@ -2992,16 +2917,9 @@ function mod_config($board_config = false) { if ($instance_config === false) { $instance_config = "<?php\n\n// This file does not exist yet. You are creating it."; } - $instance_config = str_replace("\n", '
', utf8tohtml($instance_config)); + $instance_config = str_replace("\n", '
', (string) utf8tohtml($instance_config)); - mod_page(_('Config editor'), 'mod/config-editor-php.html', array( - 'php' => $instance_config, - 'readonly' => $readonly, - 'boards' => listBoards(), - 'board' => $board_config, - 'file' => $config_file, - 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : '')) - )); + mod_page(_('Config editor'), 'mod/config-editor-php.html', ['php' => $instance_config, 'readonly' => $readonly, 'boards' => listBoards(), 'board' => $board_config, 'file' => $config_file, 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : ''))]); return; } @@ -3070,7 +2988,7 @@ function mod_config($board_config = false) { if ($config['minify_html']) $config_append = str_replace("\n", '
', $config_append); - $page = array(); + $page = []; $page['title'] = 'Cannot write to file!'; $page['config'] = $config; $page['body'] = ' @@ -3089,13 +3007,7 @@ function mod_config($board_config = false) { } mod_page(_('Config editor') . ($board_config ? ': ' . sprintf($config['board_abbreviation'], $board_config) : ''), - 'mod/config-editor.html', array( - 'boards' => listBoards(), - 'board' => $board_config, - 'conf' => $conf, - 'file' => $config_file, - 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : '')) - )); + 'mod/config-editor.html', ['boards' => listBoards(), 'board' => $board_config, 'conf' => $conf, 'file' => $config_file, 'token' => make_secure_link_token('config' . ($board_config ? '/' . $board_config : ''))]); } function mod_themes_list() { @@ -3113,7 +3025,7 @@ function mod_themes_list() { $themes_in_use = $query->fetchAll(PDO::FETCH_COLUMN); // Scan directory for themes - $themes = array(); + $themes = []; while ($file = readdir($dir)) { if ($file[0] != '.' && is_dir($config['dir']['themes'] . '/' . $file)) { $themes[$file] = loadThemeConfig($file); @@ -3126,10 +3038,7 @@ function mod_themes_list() { $theme['uninstall_token'] = make_secure_link_token('themes/' . $theme_name . '/uninstall'); } - mod_page(_('Manage themes'), 'mod/themes.html', array( - 'themes' => $themes, - 'themes_in_use' => $themes_in_use, - )); + mod_page(_('Manage themes'), 'mod/themes.html', ['themes' => $themes, 'themes_in_use' => $themes_in_use]); } function mod_theme_configure($theme_name) { @@ -3195,27 +3104,18 @@ function mod_theme_configure($theme_name) { // Build themes rebuildThemes('all'); - mod_page(sprintf(_($result ? 'Installed theme: %s' : 'Installation failed: %s'), $theme['name']), 'mod/theme_installed.html', array( - 'theme_name' => $theme_name, - 'theme' => $theme, - 'result' => $result, - 'message' => $message - )); + mod_page(sprintf(_($result ? 'Installed theme: %s' : 'Installation failed: %s'), $theme['name']), 'mod/theme_installed.html', ['theme_name' => $theme_name, 'theme' => $theme, 'result' => $result, 'message' => $message]); return; } $settings = themeSettings($theme_name); - mod_page(sprintf(_('Configuring theme: %s'), $theme['name']), 'mod/theme_config.html', array( - 'theme_name' => $theme_name, - 'theme' => $theme, - 'settings' => $settings, - 'token' => make_secure_link_token('themes/' . $theme_name) - )); + mod_page(sprintf(_('Configuring theme: %s'), $theme['name']), 'mod/theme_config.html', ['theme_name' => $theme_name, 'theme' => $theme, 'settings' => $settings, 'token' => make_secure_link_token('themes/' . $theme_name)]); } function mod_theme_uninstall($theme_name) { - global $config; + $theme = null; + global $config; if (!hasPermission($config['mod']['themes'])) error($config['error']['noaccess']); @@ -3239,9 +3139,7 @@ function mod_theme_rebuild($theme_name) { rebuildTheme($theme_name, 'all'); - mod_page(sprintf(_('Rebuilt theme: %s'), $theme_name), 'mod/theme_rebuilt.html', array( - 'theme_name' => $theme_name, - )); + mod_page(sprintf(_('Rebuilt theme: %s'), $theme_name), 'mod/theme_rebuilt.html', ['theme_name' => $theme_name]); } // This needs to be done for `secure` CSRF prevention compatibility, otherwise the $board will be read in as the token if editing global pages. @@ -3262,7 +3160,7 @@ function delete_page_base($page = '', $board = false) { if ($board) { $query = prepare('DELETE FROM ``pages`` WHERE `board` = :board AND `name` = :name'); - $query->bindValue(':board', ($board ? $board : NULL)); + $query->bindValue(':board', ($board ?: NULL)); } else { $query = prepare('DELETE FROM ``pages`` WHERE `board` IS NULL AND `name` = :name'); } @@ -3305,7 +3203,7 @@ function mod_edit_page($id) { $method = $_POST['method']; $page['type'] = $method; - if (!in_array($method, array('markdown', 'html', 'infinity'))) + if (!in_array($method, ['markdown', 'html', 'infinity'])) error(_('Unrecognized page markup method.')); switch ($method) { @@ -3337,7 +3235,7 @@ function mod_edit_page($id) { $fn = ($board['uri'] ? ($board['uri'] . '/') : '') . $page['name'] . '.html'; $body = "<div class='ban'>$write</div>"; - $html = Element('page.html', array('config' => $config, 'body' => $body, 'title' => utf8tohtml($page['title']))); + $html = Element('page.html', ['config' => $config, 'body' => $body, 'title' => utf8tohtml($page['title'])]); file_write($fn, $html); } @@ -3348,7 +3246,7 @@ function mod_edit_page($id) { $content = $query->fetchColumn(); } - mod_page(sprintf(_('Editing static page: %s'), $page['name']), 'mod/edit_page.html', array('page' => $page, 'token' => make_secure_link_token("edit_page/$id"), 'content' => prettify_textarea($content), 'board' => $board)); + mod_page(sprintf(_('Editing static page: %s'), $page['name']), 'mod/edit_page.html', ['page' => $page, 'token' => make_secure_link_token("edit_page/$id"), 'content' => prettify_textarea($content), 'board' => $board]); } function mod_pages($board = false) { @@ -3379,7 +3277,7 @@ function mod_pages($board = false) { if ($board and sizeof($pages) > $config['pages_max']) error(sprintf(_('Sorry, this site only allows %d pages per board.'), $config['pages_max'])); - if (!preg_match('/^[a-z0-9]{1,255}$/', $_POST['page'])) + if (!preg_match('/^[a-z0-9]{1,255}$/', (string) $_POST['page'])) error(_('Page names must be < 255 chars and may only contain lowercase letters A-Z and digits 1-9.')); foreach ($pages as $i => $p) { @@ -3387,28 +3285,28 @@ function mod_pages($board = false) { error(_('Refusing to create a new page with the same name as an existing one.')); } - $title = ($_POST['title'] ? $_POST['title'] : NULL); + $title = ($_POST['title'] ?: NULL); $query = prepare('INSERT INTO ``pages``(board, title, name) VALUES(:board, :title, :name)'); - $query->bindValue(':board', ($board ? $board : NULL)); + $query->bindValue(':board', ($board ?: NULL)); $query->bindValue(':title', $title); $query->bindValue(':name', $_POST['page']); $query->execute() or error(db_error($query)); - $pages[] = array('id' => $pdo->lastInsertId(), 'name' => $_POST['page'], 'board' => $board, 'title' => $title); + $pages[] = ['id' => $pdo->lastInsertId(), 'name' => $_POST['page'], 'board' => $board, 'title' => $title]; } foreach ($pages as $i => &$p) { $p['delete_token'] = make_secure_link_token('edit_pages/delete/' . $p['name'] . ($board ? ('/' . $board) : '')); } - mod_page(_('Pages'), 'mod/pages.html', array('pages' => $pages, 'token' => make_secure_link_token('edit_pages' . ($board ? ('/' . $board) : '')), 'board' => $board)); + mod_page(_('Pages'), 'mod/pages.html', ['pages' => $pages, 'token' => make_secure_link_token('edit_pages' . ($board ? ('/' . $board) : '')), 'board' => $board]); } function mod_debug_antispam() { global $pdo, $config; - $args = array(); + $args = []; if (isset($_POST['board'], $_POST['thread'])) { $where = '`board` = ' . $pdo->quote($_POST['board']); @@ -3473,11 +3371,12 @@ function mod_debug_recent_posts() { } } - mod_page(_('Debug: Recent posts'), 'mod/debug/recent_posts.html', array('posts' => $posts, 'flood_posts' => $flood_posts)); + mod_page(_('Debug: Recent posts'), 'mod/debug/recent_posts.html', ['posts' => $posts, 'flood_posts' => $flood_posts]); } function mod_debug_sql() { - global $config; + $args = []; + global $config; if (!hasPermission($config['mod']['debug_sql'])) error($config['error']['noaccess']); @@ -3512,13 +3411,13 @@ function mod_debug_apc() { $cache_info = apc_cache_info('user'); // $cached_vars = new APCIterator('user', '/^' . $config['cache']['prefix'] . '/'); - $cached_vars = array(); + $cached_vars = []; foreach ($cache_info['cache_list'] as $var) { - if ($config['cache']['prefix'] != '' && strpos(isset($var['key']) ? $var['key'] : $var['info'], $config['cache']['prefix']) !== 0) + if ($config['cache']['prefix'] != '' && !str_starts_with($var['key'] ?? $var['info'], (string) $config['cache']['prefix'])) continue; $cached_vars[] = $var; } - mod_page(_('Debug: APC'), 'mod/debug/apc.html', array('cached_vars' => $cached_vars)); + mod_page(_('Debug: APC'), 'mod/debug/apc.html', ['cached_vars' => $cached_vars]); } diff --git a/inc/nntpchan/nntpchan.php b/inc/nntpchan/nntpchan.php index de67a193..77ccb10d 100644 --- a/inc/nntpchan/nntpchan.php +++ b/inc/nntpchan/nntpchan.php @@ -18,14 +18,15 @@ function gen_msgid($board, $id) { function gen_nntp($headers, $files) { - if (count($files) == 0) { + $content = null; + if ((is_countable($files) ? count($files) : 0) == 0) { } - else if (count($files) == 1 && $files[0]['type'] == 'text/plain') { + else if ((is_countable($files) ? count($files) : 0) == 1 && $files[0]['type'] == 'text/plain') { $content = $files[0]['text'] . "\r\n"; $headers['Content-Type'] = "text/plain; charset=UTF-8"; } else { - $boundary = sha1($headers['Message-Id']); + $boundary = sha1((string) $headers['Message-Id']); $content = ""; $headers['Content-Type'] = "multipart/mixed; boundary=$boundary"; foreach ($files as $file) { @@ -34,13 +35,13 @@ function gen_nntp($headers, $files) { $file['name'] = preg_replace('/[\r\n\0"]/', '', $file['name']); $content .= "Content-Disposition: form-data; filename=\"$file[name]\"; name=\"attachment\"\r\n"; } - $type = explode('/', $file['type'])[0]; + $type = explode('/', (string) $file['type'])[0]; if ($type == 'text') { $file['type'] .= '; charset=UTF-8'; } $content .= "Content-Type: $file[type]\r\n"; if ($type != 'text' && $type != 'message') { - $file['text'] = base64_encode($file['text']); + $file['text'] = base64_encode((string) $file['text']); $content .= "Content-Transfer-Encoding: base64\r\n"; } $content .= "\r\n"; @@ -55,7 +56,7 @@ function gen_nntp($headers, $files) { $headers['Date'] = date('r', $headers['Date']); $out = ""; foreach ($headers as $id => $val) { - $val = str_replace("\n", "\n\t", $val); + $val = str_replace("\n", "\n\t", (string) $val); $out .= "$id: $val\r\n"; } $out .= "\r\n"; @@ -71,7 +72,7 @@ function nntp_publish($msg, $id) { fputs($s, "MODE STREAM\r\n"); fgets($s); fputs($s, "TAKETHIS $id\r\n"); - fputs($s, $msg); + fputs($s, (string) $msg); fputs($s, "\r\n.\r\n"); fgets($s); fputs($s, "QUIT\r\n"); @@ -81,13 +82,13 @@ function nntp_publish($msg, $id) { function post2nntp($post, $msgid) { global $config; - $headers = array(); - $files = array(); + $headers = []; + $files = []; $headers['Message-Id'] = $msgid; $headers['Newsgroups'] = $config['nntpchan']['group']; $headers['Date'] = time(); - $headers['Subject'] = $post['subject'] ? $post['subject'] : "None"; + $headers['Subject'] = $post['subject'] ?: "None"; $headers['From'] = $post['name'] . " <poster@" . $config['nntpchan']['domain'] . ">"; if ($post['email'] == 'sage') { @@ -110,7 +111,7 @@ function post2nntp($post, $msgid) { } // Let's parse the body a bit. - $body = trim($post['body_nomarkup']); + $body = trim((string) $post['body_nomarkup']); $body = preg_replace('/\r?\n/', "\r\n", $body); $body = preg_replace_callback('@>>(>/([a-zA-Z0-9_+-]+)/)?([0-9]+)@', function($o) use ($post) { if ($o[1]) { @@ -127,7 +128,7 @@ function post2nntp($post, $msgid) { $query->execute() or error(db_error($query)); if ($result = $query->fetch(PDO::FETCH_ASSOC)) { - return ">>".substr($result['message_id_digest'], 0, 18); + return ">>".substr((string) $result['message_id_digest'], 0, 18); } else { return $o[0]; // Should send URL imo @@ -136,10 +137,10 @@ function post2nntp($post, $msgid) { $body = preg_replace('/>>>>([0-9a-fA-F])+/', '>>\1', $body); - $files[] = array('type' => 'text/plain', 'text' => $body); + $files[] = ['type' => 'text/plain', 'text' => $body]; foreach ($post['files'] as $id => $file) { - $fc = array(); + $fc = []; $fc['type'] = $file['type']; $fc['text'] = file_get_contents($file['file_path']); @@ -148,5 +149,5 @@ function post2nntp($post, $msgid) { $files[] = $fc; } - return array($headers, $files); + return [$headers, $files]; } diff --git a/inc/polyfill.php b/inc/polyfill.php index 2b14c4dc..3de6f607 100644 --- a/inc/polyfill.php +++ b/inc/polyfill.php @@ -4,7 +4,8 @@ if (!function_exists('hex2bin')) { function hex2bin($data) { - return pack("H*" , $hex_string); + $hex_string = null; + return pack("H*" , $hex_string); } } @@ -42,7 +43,7 @@ if (!function_exists('imagecreatefrombmp')) { $BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'. '/Vcompression/Vsize_bitmap/Vhoriz_resolution'. '/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40)); - $BMP['colors'] = pow(2,$BMP['bits_per_pixel']); + $BMP['colors'] = 2 ** $BMP['bits_per_pixel']; if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset']; $BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8; $BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']); @@ -50,8 +51,8 @@ if (!function_exists('imagecreatefrombmp')) { $BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4); $BMP['decal'] = 4-(4*$BMP['decal']); if ($BMP['decal'] == 4) $BMP['decal'] = 0; - $PALETTE = array(); - if ($BMP['colors'] < 16777216) + $PALETTE = []; + if ($BMP['colors'] < 16_777_216) { $PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4)); } @@ -135,12 +136,12 @@ if (!function_exists('imagebmp')) { $result .= int_to_dword(0); // Number of palettes used (4b) $result .= int_to_dword(0); // Number of important colour (4b) // is faster than chr() - $arrChr = array(); + $arrChr = []; for ($i=0; $i<256; $i++){ $arrChr[$i] = chr($i); } // creates image data - $bgfillcolor = array('red'=>0, 'green'=>0, 'blue'=>0); + $bgfillcolor = ['red'=>0, 'green'=>0, 'blue'=>0]; // bottom to top - left to right - attention blue green red !!! $y=$height-1; for ($y2=0; $y2<$height; $y2++) { diff --git a/inc/queue.php b/inc/queue.php index 66305b3b..0113fe86 100644 --- a/inc/queue.php +++ b/inc/queue.php @@ -4,7 +4,7 @@ class Queue { function __construct($key) { global $config; if ($config['queue']['enabled'] == 'fs') { $this->lock = new Lock($key); - $key = str_replace('/', '::', $key); + $key = str_replace('/', '::', (string) $key); $key = str_replace("\0", '', $key); $this->key = "tmp/queue/$key/"; } @@ -23,14 +23,14 @@ class Queue { if ($config['queue']['enabled'] == 'fs') { $this->lock->get_ex(); $dir = opendir($this->key); - $paths = array(); + $paths = []; while ($n > 0) { $path = readdir($dir); if ($path === FALSE) break; elseif ($path == '.' || $path == '..') continue; else { $paths[] = $path; $n--; } } - $out = array(); + $out = []; foreach ($paths as $v) { $out []= file_get_contents($this->key.$v); unlink($this->key.$v); @@ -42,8 +42,8 @@ class Queue { } // Don't use the constructor. Use the get_queue function. -$queues = array(); +$queues = []; function get_queue($name) { global $queues; - return $queues[$name] = isset ($queues[$name]) ? $queues[$name] : new Queue($name); + return $queues[$name] ??= new Queue($name); } diff --git a/inc/remote.php b/inc/remote.php index 6a685e82..3bc0ab2a 100644 --- a/inc/remote.php +++ b/inc/remote.php @@ -12,13 +12,13 @@ class Remote { $this->{$name} = $value; } - $methods = array(); + $methods = []; if (!isset($this->auth['method'])) error('Unspecified authentication method.'); // Connect - $this->connection = ssh2_connect($this->host, isset($this->port) ? $this->port : 22, $methods); + $this->connection = ssh2_connect($this->host, $this->port ?? 22, $methods); switch ($this->auth['method']) { case 'pubkey': @@ -28,7 +28,7 @@ class Remote { if (!isset($this->auth['private'])) error('Private key filename not specified.'); - if (!ssh2_auth_pubkey_file($this->connection, $this->auth['username'], $this->auth['public'], $this->auth['private'], isset($this->auth['passphrase']) ? $this->auth['passphrase']: null)) + if (!ssh2_auth_pubkey_file($this->connection, $this->auth['username'], $this->auth['public'], $this->auth['private'], $this->auth['passphrase'] ?? null)) error('Public key authentication failed.'); break; case 'plain': diff --git a/inc/route.php b/inc/route.php index 2a5c1732..d056d180 100644 --- a/inc/route.php +++ b/inc/route.php @@ -8,7 +8,7 @@ defined('TINYBOARD') or exit; function route($path) { global $config; - $entrypoints = array(); + $entrypoints = []; $entrypoints['/%b/'] = 'sb_board'; $entrypoints['/%b/'.$config['file_index']] = 'sb_board'; @@ -40,7 +40,7 @@ function route($path) { global $config; $reached = false; - list($request) = explode('?', $path); + [$request] = explode('?', (string) $path); foreach ($entrypoints as $id => $fun) { $id = '@^' . preg_quote($id, '@') . '$@u'; @@ -54,7 +54,7 @@ function route($path) { global $config; if (preg_match ($id, $request, $matches)) { array_shift($matches); - $reached = array($fun, $matches); + $reached = [$fun, $matches]; break; } diff --git a/inc/template.php b/inc/template.php index a74cc0ec..742c1125 100644 --- a/inc/template.php +++ b/inc/template.php @@ -14,12 +14,8 @@ function load_twig() { $loader = new Twig_Loader_Filesystem($config['dir']['template']); $loader->setPaths($config['dir']['template']); - $twig = new Twig_Environment($loader, array( - 'autoescape' => false, - 'cache' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')) ? - "{$config['dir']['template']}/cache" : false, - 'debug' => $config['debug'], - )); + $twig = new Twig_Environment($loader, ['autoescape' => false, 'cache' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')) ? + "{$config['dir']['template']}/cache" : false, 'debug' => $config['debug']]); $twig->addExtension(new Twig_Extensions_Extension_Tinyboard()); $twig->addExtension(new Twig_Extensions_Extension_I18n()); } @@ -31,7 +27,7 @@ function Element($templateFile, array $options) { if (!$twig) load_twig(); - if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', $templateFile)) { + if (function_exists('create_pm_header') && ((isset($options['mod']) && $options['mod']) || isset($options['__mod'])) && !preg_match('!^mod/!', (string) $templateFile)) { $options['pm'] = create_pm_header(); } @@ -52,13 +48,13 @@ function Element($templateFile, array $options) { $_debug['time']['exec'] = '~' . round($_debug['time']['exec'] * 1000, 2) . 'ms'; $options['body'] .= '<h3>Debug</h3><pre style="white-space: pre-wrap;font-size: 10px;">' . - str_replace("\n", '<br/>', utf8tohtml(print_r($_debug, true))) . + str_replace("\n", '<br/>', (string) utf8tohtml(print_r($_debug, true))) . '</pre>'; } // Read the template file if (@file_get_contents("{$config['dir']['template']}/${templateFile}")) { $body = $twig->render($templateFile, $options); - if ($config['minify_html'] && preg_match('/\.html$/', $templateFile)) { + if ($config['minify_html'] && preg_match('/\.html$/', (string) $templateFile)) { $body = trim(preg_replace("/[\t\r\n]/", '', $body)); } return $body; @@ -207,13 +203,9 @@ function custom_strftime(string $format, $timestamp = null, ?string $locale = nu '%a' => $intl_formatter, '%A' => $intl_formatter, '%d' => 'd', - '%e' => function ($timestamp) { - return sprintf('% 2u', $timestamp->format('j')); - }, - '%j' => function ($timestamp) { - // Day number in year, 001 to 366 - return sprintf('%03d', $timestamp->format('z')+1); - }, + '%e' => fn($timestamp) => sprintf('% 2u', $timestamp->format('j')), + '%j' => fn($timestamp) => // Day number in year, 001 to 366 +sprintf('%03d', $timestamp->format('z')+1), '%u' => 'N', '%w' => 'w', @@ -237,26 +229,18 @@ function custom_strftime(string $format, $timestamp = null, ?string $locale = nu '%m' => 'm', // Year - '%C' => function ($timestamp) { - // Century (-1): 19 for 20th century - return floor($timestamp->format('Y') / 100); - }, - '%g' => function ($timestamp) { - return substr($timestamp->format('o'), -2); - }, + '%C' => fn($timestamp) => // Century (-1): 19 for 20th century +floor($timestamp->format('Y') / 100), + '%g' => fn($timestamp) => substr((string) $timestamp->format('o'), -2), '%G' => 'o', '%y' => 'y', '%Y' => 'Y', // Time '%H' => 'H', - '%k' => function ($timestamp) { - return sprintf('% 2u', $timestamp->format('G')); - }, + '%k' => fn($timestamp) => sprintf('% 2u', $timestamp->format('G')), '%I' => 'h', - '%l' => function ($timestamp) { - return sprintf('% 2u', $timestamp->format('g')); - }, + '%l' => fn($timestamp) => sprintf('% 2u', $timestamp->format('g')), '%M' => 'i', '%p' => 'A', // AM PM (this is reversed on purpose!) '%P' => 'a', // am pm @@ -313,7 +297,7 @@ function twig_hasPermission_filter($mod, $permission, $board = null) { } function twig_extension_filter($value, $case_insensitive = true) { - $ext = mb_substr($value, mb_strrpos($value, '.') + 1); + $ext = mb_substr((string) $value, mb_strrpos((string) $value, '.') + 1); if($case_insensitive) $ext = mb_strtolower($ext); return $ext; @@ -324,25 +308,25 @@ function twig_sprintf_filter( $value, $var) { } function twig_truncate_filter($value, $length = 30, $preserve = false, $separator = '…') { - if (mb_strlen($value) > $length) { + if (mb_strlen((string) $value) > $length) { if ($preserve) { - if (false !== ($breakpoint = mb_strpos($value, ' ', $length))) { + if (false !== ($breakpoint = mb_strpos((string) $value, ' ', $length))) { $length = $breakpoint; } } - return mb_substr($value, 0, $length) . $separator; + return mb_substr((string) $value, 0, $length) . $separator; } return $value; } function twig_filename_truncate_filter($value, $length = 30, $separator = '…') { - if (mb_strlen($value) > $length) { - $value = strrev($value); + if (mb_strlen((string) $value) > $length) { + $value = strrev((string) $value); $array = array_reverse(explode(".", $value, 2)); $array = array_map("strrev", $array); $filename = &$array[0]; - $extension = isset($array[1]) ? $array[1] : false; + $extension = $array[1] ?? false; $filename = mb_substr($filename, 0, $length - ($extension ? mb_strlen($extension) + 1 : 0)) . $separator; @@ -357,7 +341,7 @@ function twig_ratio_function($w, $h) { function twig_secure_link_confirm($text, $title, $confirm_message, $href) { global $config; - return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes($confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities($title) . '" href="?/' . $href . '">' . $text . '</a>'; + return '<a onclick="if (event.which==2) return true;if (confirm(\'' . htmlentities(addslashes((string) $confirm_message)) . '\')) document.location=\'?/' . htmlspecialchars(addslashes($href . '/' . make_secure_link_token($href))) . '\';return false;" title="' . htmlentities((string) $title) . '" href="?/' . $href . '">' . $text . '</a>'; } function twig_secure_link($href) { return $href . '/' . make_secure_link_token($href); diff --git a/install.php b/install.php index 272da715..307dfe6d 100644 --- a/install.php +++ b/install.php @@ -13,12 +13,7 @@ if (fopen('inc/instance-config.php' , 'a') === false) { loadConfig(); $step = isset($_GET['step']) ? round($_GET['step']) : 0; -$page = array( - 'config' => $config, - 'title' => 'Install', - 'body' => '', - 'nojavascript' => true -); +$page = ['config' => $config, 'title' => 'Install', 'body' => '', 'nojavascript' => true]; // this breaks the display of licenses if enabled $config['minify_html'] = false; @@ -36,7 +31,7 @@ if (file_exists($config['has_installed'])) { if (mysql_version() >= 50503) return query($sql); else - return query(str_replace('utf8mb4', 'utf8', $sql)); + return query(str_replace('utf8mb4', 'utf8', (string) $sql)); } $boards = listBoards(); @@ -108,9 +103,7 @@ if (file_exists($config['has_installed'])) { } case 'v0.9.3-dev-6': // change to MyISAM - $tables = array( - 'bans', 'boards', 'ip_notes', 'modlogs', 'mods', 'mutes', 'noticeboard', 'pms', 'reports', 'robot', 'theme_settings', 'news' - ); + $tables = ['bans', 'boards', 'ip_notes', 'modlogs', 'mods', 'mutes', 'noticeboard', 'pms', 'reports', 'robot', 'theme_settings', 'news']; foreach ($boards as &$board) { $tables[] = "posts_{$board['uri']}"; } @@ -253,9 +246,9 @@ if (file_exists($config['has_installed'])) { query("ALTER TABLE `mods` ADD `salt` CHAR( 32 ) NOT NULL AFTER `password`") or error(db_error()); $query = query("SELECT `id`,`password` FROM `mods`") or error(db_error()); while ($user = $query->fetch(PDO::FETCH_ASSOC)) { - if (strlen($user['password']) == 40) { + if (strlen((string) $user['password']) == 40) { mt_srand(microtime(true) * 100000 + memory_get_usage(true)); - $salt = md5(uniqid(mt_rand(), true)); + $salt = md5(uniqid(random_int(0, mt_getrandmax()), true)); $user['salt'] = $salt; $user['password'] = hash('sha256', $user['salt'] . $user['password']); @@ -620,15 +613,15 @@ function create_config_from_array(&$instance_config, &$array, $prefix = '') { foreach ($array as $name => $value) { if (is_array($value)) { $instance_config .= "\n"; - create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes($name) . '\']'); + create_config_from_array($instance_config, $value, $prefix . '[\'' . addslashes((string) $name) . '\']'); $instance_config .= "\n"; } else { - $instance_config .= ' $config' . $prefix . '[\'' . addslashes($name) . '\'] = '; + $instance_config .= ' $config' . $prefix . '[\'' . addslashes((string) $name) . '\'] = '; if (is_numeric($value)) $instance_config .= $value; else - $instance_config .= "'" . addslashes($value) . "'"; + $instance_config .= "'" . addslashes((string) $value) . "'"; $instance_config .= ";\n"; } @@ -665,182 +658,15 @@ if ($step == 0) { } // Required extensions - $extensions = array( - 'PDO' => array( - 'installed' => extension_loaded('pdo'), - 'required' => true - ), - 'GD' => array( - 'installed' => extension_loaded('gd'), - 'required' => true - ), - 'Imagick' => array( - 'installed' => extension_loaded('imagick'), - 'required' => false - ) - ); + $extensions = [\PDO::class => ['installed' => extension_loaded('pdo'), 'required' => true], 'GD' => ['installed' => extension_loaded('gd'), 'required' => true], \Imagick::class => ['installed' => extension_loaded('imagick'), 'required' => false]]; - $tests = array( - array( - 'category' => 'PHP', - 'name' => 'PHP ≥ 5.4', - 'result' => PHP_VERSION_ID >= 50400, - 'required' => true, - 'message' => 'vichan requires PHP 5.4 or better.', - ), - array( - 'category' => 'PHP', - 'name' => 'PHP ≥ 5.6', - 'result' => PHP_VERSION_ID >= 50600, - 'required' => false, - 'message' => 'vichan works best on PHP 5.6 or better.', - ), - array( - 'category' => 'PHP', - 'name' => 'mbstring extension installed', - 'result' => extension_loaded('mbstring'), - 'required' => true, - 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/mbstring.installation.php">mbstring</a> extension.', - ), - array( - 'category' => 'Database', - 'name' => 'PDO extension installed', - 'result' => extension_loaded('pdo'), - 'required' => true, - 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/intro.pdo.php">PDO</a> extension.', - ), - array( - 'category' => 'Database', - 'name' => 'MySQL PDO driver installed', - 'result' => extension_loaded('pdo') && in_array('mysql', PDO::getAvailableDrivers()), - 'required' => true, - 'message' => 'The required <a href="http://www.php.net/manual/en/ref.pdo-mysql.php">PDO MySQL driver</a> is not installed.', - ), - array( - 'category' => 'Image processing', - 'name' => 'GD extension installed', - 'result' => extension_loaded('gd'), - 'required' => true, - 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/intro.image.php">GD</a> extension. GD is a requirement even if you have chosen another image processor for thumbnailing.', - ), - array( - 'category' => 'Image processing', - 'name' => 'GD: JPEG', - 'result' => function_exists('imagecreatefromjpeg'), - 'required' => true, - 'message' => 'imagecreatefromjpeg() does not exist. This is a problem.', - ), - array( - 'category' => 'Image processing', - 'name' => 'GD: PNG', - 'result' => function_exists('imagecreatefrompng'), - 'required' => true, - 'message' => 'imagecreatefrompng() does not exist. This is a problem.', - ), - array( - 'category' => 'Image processing', - 'name' => 'GD: GIF', - 'result' => function_exists('imagecreatefromgif'), - 'required' => true, - 'message' => 'imagecreatefromgif() does not exist. This is a problem.', - ), - array( - 'category' => 'Image processing', - 'name' => '`convert` (command-line ImageMagick)', - 'result' => $can_exec && shell_exec('which convert'), - 'required' => false, - 'message' => '(Optional) `convert` was not found or executable; command-line ImageMagick image processing cannot be enabled.', - 'effect' => function (&$config) { $config['thumb_method'] = 'convert'; }, - ), - array( - 'category' => 'Image processing', - 'name' => '`identify` (command-line ImageMagick)', - 'result' => $can_exec && shell_exec('which identify'), - 'required' => false, - 'message' => '(Optional) `identify` was not found or executable; command-line ImageMagick image processing cannot be enabled.', - ), - array( - 'category' => 'Image processing', - 'name' => '`gm` (command-line GraphicsMagick)', - 'result' => $can_exec && shell_exec('which gm'), - 'required' => false, - 'message' => '(Optional) `gm` was not found or executable; command-line GraphicsMagick (faster than ImageMagick) cannot be enabled.', - 'effect' => function (&$config) { $config['thumb_method'] = 'gm'; }, - ), - array( - 'category' => 'Image processing', - 'name' => '`gifsicle` (command-line animted GIF thumbnailing)', - 'result' => $can_exec && shell_exec('which gifsicle'), - 'required' => false, - 'message' => '(Optional) `gifsicle` was not found or executable; you may not use `convert+gifsicle` for better animated GIF thumbnailing.', - 'effect' => function (&$config) { if ($config['thumb_method'] == 'gm') $config['thumb_method'] = 'gm+gifsicle'; - if ($config['thumb_method'] == 'convert') $config['thumb_method'] = 'convert+gifsicle'; }, - ), - array( - 'category' => 'Image processing', - 'name' => '`md5sum` (quick file hashing on GNU/Linux)', - 'prereq' => '', - 'result' => $can_exec && shell_exec('echo "vichan" | md5sum') == "141225c362da02b5c359c45b665168de -\n", - 'required' => false, - 'message' => '(Optional) `md5sum` was not found or executable; file hashing for multiple images will be slower. Ignore if not using Linux.', - 'effect' => function (&$config) { $config['gnu_md5'] = true; }, - ), - array( - 'category' => 'Image processing', - 'name' => '`/sbin/md5` (quick file hashing on BSDs)', - 'result' => $can_exec && shell_exec('echo "vichan" | /sbin/md5 -r') == "141225c362da02b5c359c45b665168de\n", - 'required' => false, - 'message' => '(Optional) `/sbin/md5` was not found or executable; file hashing for multiple images will be slower. Ignore if not using BSD.', - 'effect' => function (&$config) { $config['bsd_md5'] = true; }, - ), - array( - 'category' => 'File permissions', - 'name' => getcwd(), - 'result' => is_writable('.'), - 'required' => true, - 'message' => 'vichan does not have permission to create directories (boards) here. You will need to <code>chmod</code> (or operating system equivalent) appropriately.' - ), - array( - 'category' => 'File permissions', - 'name' => getcwd() . '/templates/cache', - 'result' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')), - 'required' => true, - 'message' => 'You must give vichan permission to create (and write to) the <code>templates/cache</code> directory or performance will be drastically reduced.' - ), - array( - 'category' => 'File permissions', - 'name' => getcwd() . '/tmp/cache', - 'result' => is_dir('tmp/cache') && is_writable('tmp/cache'), - 'required' => true, - 'message' => 'You must give vichan permission to write to the <code>tmp/cache</code> directory.' - ), - array( - 'category' => 'File permissions', - 'name' => getcwd() . '/inc/instance-config.php', - 'result' => is_writable('inc/instance-config.php'), - 'required' => false, - 'message' => 'vichan does not have permission to make changes to <code>inc/instance-config.php</code>. To complete the installation, you will be asked to manually copy and paste code into the file instead.' - ), - array( - 'category' => 'Misc', - 'name' => 'Caching available (APC, XCache, Memcached or Redis)', - 'result' => extension_loaded('apc') || extension_loaded('xcache') - || extension_loaded('memcached') || extension_loaded('redis'), - 'required' => false, - 'message' => 'You will not be able to enable the additional caching system, designed to minimize SQL queries and significantly improve performance. <a href="http://php.net/manual/en/book.apc.php">APC</a> is the recommended method of caching, but <a href="http://xcache.lighttpd.net/">XCache</a>, <a href="http://www.php.net/manual/en/intro.memcached.php">Memcached</a> and <a href="http://pecl.php.net/package/redis">Redis</a> are also supported.' - ), - array( - 'category' => 'Misc', - 'name' => 'vichan installed using git', - 'result' => is_dir('.git'), - 'required' => false, - 'message' => 'vichan is still beta software and it\'s not going to come out of beta any time soon. As there are often many months between releases yet changes and bug fixes are very frequent, it\'s recommended to use the git repository to maintain your vichan installation. Using git makes upgrading much easier.' - ) - ); + $tests = [['category' => 'PHP', 'name' => 'PHP ≥ 5.4', 'result' => PHP_VERSION_ID >= 50400, 'required' => true, 'message' => 'vichan requires PHP 5.4 or better.'], ['category' => 'PHP', 'name' => 'PHP ≥ 5.6', 'result' => PHP_VERSION_ID >= 50600, 'required' => false, 'message' => 'vichan works best on PHP 5.6 or better.'], ['category' => 'PHP', 'name' => 'mbstring extension installed', 'result' => extension_loaded('mbstring'), 'required' => true, 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/mbstring.installation.php">mbstring</a> extension.'], ['category' => 'Database', 'name' => 'PDO extension installed', 'result' => extension_loaded('pdo'), 'required' => true, 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/intro.pdo.php">PDO</a> extension.'], ['category' => 'Database', 'name' => 'MySQL PDO driver installed', 'result' => extension_loaded('pdo') && in_array('mysql', PDO::getAvailableDrivers()), 'required' => true, 'message' => 'The required <a href="http://www.php.net/manual/en/ref.pdo-mysql.php">PDO MySQL driver</a> is not installed.'], ['category' => 'Image processing', 'name' => 'GD extension installed', 'result' => extension_loaded('gd'), 'required' => true, 'message' => 'You must install the PHP <a href="http://www.php.net/manual/en/intro.image.php">GD</a> extension. GD is a requirement even if you have chosen another image processor for thumbnailing.'], ['category' => 'Image processing', 'name' => 'GD: JPEG', 'result' => function_exists('imagecreatefromjpeg'), 'required' => true, 'message' => 'imagecreatefromjpeg() does not exist. This is a problem.'], ['category' => 'Image processing', 'name' => 'GD: PNG', 'result' => function_exists('imagecreatefrompng'), 'required' => true, 'message' => 'imagecreatefrompng() does not exist. This is a problem.'], ['category' => 'Image processing', 'name' => 'GD: GIF', 'result' => function_exists('imagecreatefromgif'), 'required' => true, 'message' => 'imagecreatefromgif() does not exist. This is a problem.'], ['category' => 'Image processing', 'name' => '`convert` (command-line ImageMagick)', 'result' => $can_exec && shell_exec('which convert'), 'required' => false, 'message' => '(Optional) `convert` was not found or executable; command-line ImageMagick image processing cannot be enabled.', 'effect' => function (&$config) { $config['thumb_method'] = 'convert'; }], ['category' => 'Image processing', 'name' => '`identify` (command-line ImageMagick)', 'result' => $can_exec && shell_exec('which identify'), 'required' => false, 'message' => '(Optional) `identify` was not found or executable; command-line ImageMagick image processing cannot be enabled.'], ['category' => 'Image processing', 'name' => '`gm` (command-line GraphicsMagick)', 'result' => $can_exec && shell_exec('which gm'), 'required' => false, 'message' => '(Optional) `gm` was not found or executable; command-line GraphicsMagick (faster than ImageMagick) cannot be enabled.', 'effect' => function (&$config) { $config['thumb_method'] = 'gm'; }], ['category' => 'Image processing', 'name' => '`gifsicle` (command-line animted GIF thumbnailing)', 'result' => $can_exec && shell_exec('which gifsicle'), 'required' => false, 'message' => '(Optional) `gifsicle` was not found or executable; you may not use `convert+gifsicle` for better animated GIF thumbnailing.', 'effect' => function (&$config) { if ($config['thumb_method'] == 'gm') $config['thumb_method'] = 'gm+gifsicle'; + if ($config['thumb_method'] == 'convert') $config['thumb_method'] = 'convert+gifsicle'; }], ['category' => 'Image processing', 'name' => '`md5sum` (quick file hashing on GNU/Linux)', 'prereq' => '', 'result' => $can_exec && shell_exec('echo "vichan" | md5sum') == "141225c362da02b5c359c45b665168de -\n", 'required' => false, 'message' => '(Optional) `md5sum` was not found or executable; file hashing for multiple images will be slower. Ignore if not using Linux.', 'effect' => function (&$config) { $config['gnu_md5'] = true; }], ['category' => 'Image processing', 'name' => '`/sbin/md5` (quick file hashing on BSDs)', 'result' => $can_exec && shell_exec('echo "vichan" | /sbin/md5 -r') == "141225c362da02b5c359c45b665168de\n", 'required' => false, 'message' => '(Optional) `/sbin/md5` was not found or executable; file hashing for multiple images will be slower. Ignore if not using BSD.', 'effect' => function (&$config) { $config['bsd_md5'] = true; }], ['category' => 'File permissions', 'name' => getcwd(), 'result' => is_writable('.'), 'required' => true, 'message' => 'vichan does not have permission to create directories (boards) here. You will need to <code>chmod</code> (or operating system equivalent) appropriately.'], ['category' => 'File permissions', 'name' => getcwd() . '/templates/cache', 'result' => is_writable('templates') || (is_dir('templates/cache') && is_writable('templates/cache')), 'required' => true, 'message' => 'You must give vichan permission to create (and write to) the <code>templates/cache</code> directory or performance will be drastically reduced.'], ['category' => 'File permissions', 'name' => getcwd() . '/tmp/cache', 'result' => is_dir('tmp/cache') && is_writable('tmp/cache'), 'required' => true, 'message' => 'You must give vichan permission to write to the <code>tmp/cache</code> directory.'], ['category' => 'File permissions', 'name' => getcwd() . '/inc/instance-config.php', 'result' => is_writable('inc/instance-config.php'), 'required' => false, 'message' => 'vichan does not have permission to make changes to <code>inc/instance-config.php</code>. To complete the installation, you will be asked to manually copy and paste code into the file instead.'], ['category' => 'Misc', 'name' => 'Caching available (APC, XCache, Memcached or Redis)', 'result' => extension_loaded('apc') || extension_loaded('xcache') + || extension_loaded('memcached') || extension_loaded('redis'), 'required' => false, 'message' => 'You will not be able to enable the additional caching system, designed to minimize SQL queries and significantly improve performance. <a href="http://php.net/manual/en/book.apc.php">APC</a> is the recommended method of caching, but <a href="http://xcache.lighttpd.net/">XCache</a>, <a href="http://www.php.net/manual/en/intro.memcached.php">Memcached</a> and <a href="http://pecl.php.net/package/redis">Redis</a> are also supported.'], ['category' => 'Misc', 'name' => 'vichan installed using git', 'result' => is_dir('.git'), 'required' => false, 'message' => 'vichan is still beta software and it\'s not going to come out of beta any time soon. As there are often many months between releases yet changes and bug fixes are very frequent, it\'s recommended to use the git repository to maintain your vichan installation. Using git makes upgrading much easier.']]; $config['font_awesome'] = true; - $additional_config = array(); + $additional_config = []; foreach ($tests as $test) { if ($test['result'] && isset($test['effect'])) { $test['effect']($additional_config); @@ -850,30 +676,15 @@ if ($step == 0) { create_config_from_array($more, $additional_config); $_SESSION['more'] = $more; - echo Element('page.html', array( - 'body' => Element('installer/check-requirements.html', array( - 'extensions' => $extensions, - 'tests' => $tests, - 'config' => $config, - )), - 'title' => 'Checking environment', - 'config' => $config, - )); + echo Element('page.html', ['body' => Element('installer/check-requirements.html', ['extensions' => $extensions, 'tests' => $tests, 'config' => $config]), 'title' => 'Checking environment', 'config' => $config]); } elseif ($step == 2) { // Basic config $page['title'] = 'Configuration'; - $config['cookies']['salt'] = substr(base64_encode(sha1(rand())), 0, 30); - $config['secure_trip_salt'] = substr(base64_encode(sha1(rand())), 0, 30); + $config['cookies']['salt'] = substr(base64_encode(sha1(random_int(0, mt_getrandmax()))), 0, 30); + $config['secure_trip_salt'] = substr(base64_encode(sha1(random_int(0, mt_getrandmax()))), 0, 30); - echo Element('page.html', array( - 'body' => Element('installer/config.html', array( - 'config' => $config, - 'more' => $_SESSION['more'], - )), - 'title' => 'Configuration', - 'config' => $config - )); + echo Element('page.html', ['body' => Element('installer/config.html', ['config' => $config, 'more' => $_SESSION['more']]), 'title' => 'Configuration', 'config' => $config]); } elseif ($step == 3) { $more = $_POST['more']; unset($_POST['more']); @@ -927,7 +738,7 @@ if ($step == 0) { preg_match_all("/(^|\n)((SET|CREATE|INSERT).+)\n\n/msU", $sql, $queries); $queries = $queries[2]; - $queries[] = Element('posts.sql', array('board' => 'b')); + $queries[] = Element('posts.sql', ['board' => 'b']); $sql_errors = ''; foreach ($queries as $query) { @@ -949,7 +760,7 @@ if ($step == 0) { setupBoard($_board); buildIndex(); } - + file_write($config['has_installed'], VERSION); /*if (!file_unlink(__FILE__)) { $page['body'] .= '<div class="ban"><h2>Delete install.php!</h2><p>I couldn\'t remove <strong>install.php</strong>. You will have to remove it manually.</p></div>'; @@ -2,7 +2,7 @@ include 'inc/bootstrap.php'; include 'inc/mod/pages.php'; -if (!isset($_GET['board']) || !preg_match("/{$config['board_regex']}/u", $_GET['board'])) { +if (!isset($_GET['board']) || !preg_match("/{$config['board_regex']}/u", (string) $_GET['board'])) { http_response_code(400); error('Bad board.'); } @@ -14,7 +14,7 @@ require_once 'inc/mod/pages.php'; check_login(true); -$query = isset($_SERVER['QUERY_STRING']) ? rawurldecode($_SERVER['QUERY_STRING']) : ''; +$query = isset($_SERVER['QUERY_STRING']) ? rawurldecode((string) $_SERVER['QUERY_STRING']) : ''; // If there's a thread parameter (eg, for returning to after enacting a ban) // drop it from the $query. @@ -22,111 +22,153 @@ if(isset($_GET['thread'])) { $query = explode("&thread=", $query)[0]; } -$pages = array( - '' => ':?/', // redirect to dashboard - '/' => 'dashboard', // dashboard - '/confirm/(.+)' => 'confirm', // confirm action (if javascript didn't work) - '/logout' => 'secure logout', // logout - - '/users' => 'users', // manage users - '/users/(\d+)/(promote|demote)' => 'secure user_promote', // prmote/demote user - '/users/(\d+)' => 'secure_POST user', // edit user - '/users/new' => 'secure_POST user_new', // create a new user - - '/new_PM/([^/]+)' => 'secure_POST new_pm', // create a new pm - '/PM/(\d+)(/reply)?' => 'pm', // read a pm - '/inbox' => 'inbox', // pm inbox - - '/log' => 'log', // modlog - '/log/(\d+)' => 'log', // modlog - '/log:([^/:]+)' => 'user_log', // modlog - '/log:([^/:]+)/(\d+)' => 'user_log', // modlog - '/log:b:([^/]+)' => 'board_log', // modlog - '/log:b:([^/]+)/(\d+)' => 'board_log', // modlog - - '/edit_news' => 'secure_POST news', // view news - '/edit_news/(\d+)' => 'secure_POST news', // view news - '/edit_news/delete/(\d+)' => 'secure news_delete', // delete from news - - '/edit_pages(?:/?(\%b)?)' => 'secure_POST pages', - '/edit_page/(\d+)' => 'secure_POST edit_page', - '/edit_pages/delete/([a-z0-9]+)' => 'secure delete_page', - '/edit_pages/delete/([a-z0-9]+)/(\%b)' => 'secure delete_page_board', - - '/noticeboard' => 'secure_POST noticeboard', // view noticeboard - '/noticeboard/(\d+)' => 'secure_POST noticeboard', // view noticeboard - '/noticeboard/delete/(\d+)' => 'secure noticeboard_delete', // delete from noticeboard - - '/edit/(\%b)' => 'secure_POST edit_board', // edit board details - '/new-board' => 'secure_POST new_board', // create a new board - - '/rebuild' => 'secure_POST rebuild', // rebuild static files - '/reports' => 'reports', // report queue - '/reports/(\d+)/dismiss(all)?' => 'secure report_dismiss', // dismiss a report - - '/IP/([\w.:]+)' => 'secure_POST ip', // view ip address - '/IP/([\w.:]+)/remove_note/(\d+)' => 'secure ip_remove_note', // remove note from ip address - - '/ban' => 'secure_POST ban', // new ban - '/bans' => 'secure_POST bans', // ban list - '/bans.json' => 'secure bans_json', // ban list JSON - '/ban-appeals' => 'secure_POST ban_appeals', // view ban appeals - - '/recent/(\d+)' => 'recent_posts', // view recent posts - '/recent/(\d+)/([\w,]+?)' => 'recent_posts', // view recent posts - '/recent/(\d+)/([\w,]+?)/(json)?' => 'recent_posts', // view recent posts JSON - - '/search' => 'search_redirect', // search - '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', // search - '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', // search - - '/(\%b)/warning/(\d+)' => 'secure_POST warning_post', // warn poster - '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', // ban poster - '/(\%b)/move/(\d+)' => 'secure_POST move', // move thread - '/(\%b)/move_reply/(\d+)' => 'secure_POST move_reply', // move reply - '/(\%b)/merge/(\d+)' => 'secure_POST merge', // merge thread - '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', // edit post - '/(\%b)/delete/(\d+)' => 'secure delete', // delete post - '/(\%b)/deletefile/(\d+)/(\d+)' => 'secure deletefile', // delete file from post - '/(\%b+)/spoiler/(\d+)/(\d+)' => 'secure spoiler_image', // spoiler file - '/(\%b)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', // delete all posts by IP address - '/(\%b)/(un)?lock/(\d+)' => 'secure lock', // lock thread - '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', // sticky thread - '/(\%b)/(un)?cycle/(\d+)' => 'secure cycle', // cycle thread - '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', // "bumplock" thread - - '/themes' => 'themes_list', // manage themes - '/themes/(\w+)' => 'secure_POST theme_configure', // configure/reconfigure theme - '/themes/(\w+)/rebuild' => 'secure theme_rebuild', // rebuild theme - '/themes/(\w+)/uninstall' => 'secure theme_uninstall', // uninstall theme - - '/config' => 'secure_POST config', // config editor - '/config/(\%b)' => 'secure_POST config', // config editor - - // these pages aren't listed in the dashboard without $config['debug'] - '/debug/antispam' => 'debug_antispam', - '/debug/recent' => 'debug_recent_posts', - '/debug/apc' => 'debug_apc', - '/debug/sql' => 'secure_POST debug_sql', - - // This should always be at the end: - '/(\%b)/' => 'view_board', - '/(\%b)/' . preg_quote($config['file_index'], '!') => 'view_board', - '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_board', - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '!')) => 'view_thread50', - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace('%d', '(\d+)', preg_quote($config['file_page'], '!')) => 'view_thread', - - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '!')) => 'view_thread50', - '/(\%b)/' . preg_quote($config['dir']['res'], '!') . - str_replace(array('%d','%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page_slug'], '!')) => 'view_thread', -); +$pages = [ + '' => ':?/', + // redirect to dashboard + '/' => 'dashboard', + // dashboard + '/confirm/(.+)' => 'confirm', + // confirm action (if javascript didn't work) + '/logout' => 'secure logout', + // logout + '/users' => 'users', + // manage users + '/users/(\d+)/(promote|demote)' => 'secure user_promote', + // prmote/demote user + '/users/(\d+)' => 'secure_POST user', + // edit user + '/users/new' => 'secure_POST user_new', + // create a new user + '/new_PM/([^/]+)' => 'secure_POST new_pm', + // create a new pm + '/PM/(\d+)(/reply)?' => 'pm', + // read a pm + '/inbox' => 'inbox', + // pm inbox + '/log' => 'log', + // modlog + '/log/(\d+)' => 'log', + // modlog + '/log:([^/:]+)' => 'user_log', + // modlog + '/log:([^/:]+)/(\d+)' => 'user_log', + // modlog + '/log:b:([^/]+)' => 'board_log', + // modlog + '/log:b:([^/]+)/(\d+)' => 'board_log', + // modlog + '/edit_news' => 'secure_POST news', + // view news + '/edit_news/(\d+)' => 'secure_POST news', + // view news + '/edit_news/delete/(\d+)' => 'secure news_delete', + // delete from news + '/edit_pages(?:/?(\%b)?)' => 'secure_POST pages', + '/edit_page/(\d+)' => 'secure_POST edit_page', + '/edit_pages/delete/([a-z0-9]+)' => 'secure delete_page', + '/edit_pages/delete/([a-z0-9]+)/(\%b)' => 'secure delete_page_board', + '/noticeboard' => 'secure_POST noticeboard', + // view noticeboard + '/noticeboard/(\d+)' => 'secure_POST noticeboard', + // view noticeboard + '/noticeboard/delete/(\d+)' => 'secure noticeboard_delete', + // delete from noticeboard + '/edit/(\%b)' => 'secure_POST edit_board', + // edit board details + '/new-board' => 'secure_POST new_board', + // create a new board + '/rebuild' => 'secure_POST rebuild', + // rebuild static files + '/reports' => 'reports', + // report queue + '/reports/(\d+)/dismiss(all)?' => 'secure report_dismiss', + // dismiss a report + '/IP/([\w.:]+)' => 'secure_POST ip', + // view ip address + '/IP/([\w.:]+)/remove_note/(\d+)' => 'secure ip_remove_note', + // remove note from ip address + '/ban' => 'secure_POST ban', + // new ban + '/bans' => 'secure_POST bans', + // ban list + '/bans.json' => 'secure bans_json', + // ban list JSON + '/ban-appeals' => 'secure_POST ban_appeals', + // view ban appeals + '/recent/(\d+)' => 'recent_posts', + // view recent posts + '/recent/(\d+)/([\w,]+?)' => 'recent_posts', + // view recent posts + '/recent/(\d+)/([\w,]+?)/(json)?' => 'recent_posts', + // view recent posts JSON + '/search' => 'search_redirect', + // search + '/search/(posts|IP_notes|bans|log)/(.+)/(\d+)' => 'search', + // search + '/search/(posts|IP_notes|bans|log)/(.+)' => 'search', + // search + '/(\%b)/warning/(\d+)' => 'secure_POST warning_post', + // warn poster + '/(\%b)/ban(&delete)?/(\d+)' => 'secure_POST ban_post', + // ban poster + '/(\%b)/move/(\d+)' => 'secure_POST move', + // move thread + '/(\%b)/move_reply/(\d+)' => 'secure_POST move_reply', + // move reply + '/(\%b)/merge/(\d+)' => 'secure_POST merge', + // merge thread + '/(\%b)/edit(_raw)?/(\d+)' => 'secure_POST edit_post', + // edit post + '/(\%b)/delete/(\d+)' => 'secure delete', + // delete post + '/(\%b)/deletefile/(\d+)/(\d+)' => 'secure deletefile', + // delete file from post + '/(\%b+)/spoiler/(\d+)/(\d+)' => 'secure spoiler_image', + // spoiler file + '/(\%b)/deletebyip/(\d+)(/global)?' => 'secure deletebyip', + // delete all posts by IP address + '/(\%b)/(un)?lock/(\d+)' => 'secure lock', + // lock thread + '/(\%b)/(un)?sticky/(\d+)' => 'secure sticky', + // sticky thread + '/(\%b)/(un)?cycle/(\d+)' => 'secure cycle', + // cycle thread + '/(\%b)/bump(un)?lock/(\d+)' => 'secure bumplock', + // "bumplock" thread + '/themes' => 'themes_list', + // manage themes + '/themes/(\w+)' => 'secure_POST theme_configure', + // configure/reconfigure theme + '/themes/(\w+)/rebuild' => 'secure theme_rebuild', + // rebuild theme + '/themes/(\w+)/uninstall' => 'secure theme_uninstall', + // uninstall theme + '/config' => 'secure_POST config', + // config editor + '/config/(\%b)' => 'secure_POST config', + // config editor + // these pages aren't listed in the dashboard without $config['debug'] + '/debug/antispam' => 'debug_antispam', + '/debug/recent' => 'debug_recent_posts', + '/debug/apc' => 'debug_apc', + '/debug/sql' => 'secure_POST debug_sql', + // This should always be at the end: + '/(\%b)/' => 'view_board', + '/(\%b)/' . preg_quote((string) $config['file_index'], '!') => 'view_board', + '/(\%b)/' . str_replace('%d', '(\d+)', preg_quote((string) $config['file_page'], '!')) => 'view_board', + '/(\%b)/' . preg_quote((string) $config['dir']['res'], '!') . + str_replace('%d', '(\d+)', preg_quote((string) $config['file_page50'], '!')) => 'view_thread50', + '/(\%b)/' . preg_quote((string) $config['dir']['res'], '!') . + str_replace('%d', '(\d+)', preg_quote((string) $config['file_page'], '!')) => 'view_thread', + '/(\%b)/' . preg_quote((string) $config['dir']['res'], '!') . + str_replace(['%d', '%s'], ['(\d+)', '[a-z0-9-]+'], preg_quote((string) $config['file_page50_slug'], '!')) => 'view_thread50', + '/(\%b)/' . preg_quote((string) $config['dir']['res'], '!') . + str_replace(['%d', '%s'], ['(\d+)', '[a-z0-9-]+'], preg_quote((string) $config['file_page_slug'], '!')) => 'view_thread', +]; if (!$mod) { - $pages = array('!^(.+)?$!' => 'login'); + $pages = ['!^(.+)?$!' => 'login']; } elseif (isset($_GET['status'], $_GET['r'])) { header('Location: ' . $_GET['r'], true, (int)$_GET['status']); exit; @@ -136,11 +178,11 @@ if (isset($config['mod']['custom_pages'])) { $pages = array_merge($pages, $config['mod']['custom_pages']); } -$new_pages = array(); +$new_pages = []; foreach ($pages as $key => $callback) { if (is_string($callback) && preg_match('/^secure /', $callback)) $key .= '(/(?P<token>[a-f0-9]{8}))?'; - $key = str_replace('\%b', '?P<board>' . sprintf(substr($config['board_path'], 0, -1), $config['board_regex']), $key); + $key = str_replace('\%b', '?P<board>' . sprintf(substr((string) $config['board_path'], 0, -1), $config['board_regex']), $key); $new_pages[@$key[0] == '!' ? $key : '!^' . $key . '(?:&[^&=]+=[^&]*)*$!u'] = $callback; } $pages = $new_pages; @@ -153,7 +195,7 @@ foreach ($pages as $uri => $handler) { $board_match = $matches['board']; unset($matches['board']); $key = array_search($board_match, $matches); - if (preg_match('/^' . sprintf(substr($config['board_path'], 0, -1), '(' . $config['board_regex'] . ')') . '$/u', $matches[$key], $board_match)) { + if (preg_match('/^' . sprintf(substr((string) $config['board_path'], 0, -1), '(' . $config['board_regex'] . ')') . '$/u', (string) $matches[$key], $board_match)) { $matches[$key] = $board_match[1]; } } @@ -161,7 +203,7 @@ foreach ($pages as $uri => $handler) { if (is_string($handler) && preg_match('/^secure(_POST)? /', $handler, $m)) { $secure_post_only = isset($m[1]); if (!$secure_post_only || $_SERVER['REQUEST_METHOD'] == 'POST') { - $token = isset($matches['token']) ? $matches['token'] : (isset($_POST['token']) ? $_POST['token'] : false); + $token = $matches['token'] ?? $_POST['token'] ?? false; if ($token === false) { if ($secure_post_only) @@ -182,11 +224,7 @@ foreach ($pages as $uri => $handler) { } if ($config['debug']) { - $debug['mod_page'] = array( - 'req' => $query, - 'match' => $uri, - 'handler' => $handler, - ); + $debug['mod_page'] = ['req' => $query, 'match' => $uri, 'handler' => $handler]; $debug['time']['parse_mod_req'] = '~' . round((microtime(true) - $parse_start_time) * 1000, 2) . 'ms'; } @@ -9,15 +9,16 @@ require_once 'inc/bans.php'; $dropped_post = false; function handle_nntpchan() { - global $config; + $msgid = null; + global $config; if ($_SERVER['REMOTE_ADDR'] != $config['nntpchan']['trusted_peer']) { error("NNTPChan: Forbidden. $_SERVER[REMOTE_ADDR] is not a trusted peer"); } - $_POST = array(); + $_POST = []; $_POST['json_response'] = true; - $headers = json_encode($_GET); + $headers = json_encode($_GET, JSON_THROW_ON_ERROR); if (!isset ($_GET['Message-Id'])) { if (!isset ($_GET['Message-ID'])) { @@ -27,8 +28,8 @@ function handle_nntpchan() { } else $msgid = $_GET['Message-Id']; - $groups = preg_split("/,\s*/", $_GET['Newsgroups']); - if (count($groups) != 1) { + $groups = preg_split("/,\s*/", (string) $_GET['Newsgroups']); + if ((is_countable($groups) ? count($groups) : 0) != 1) { error("NNTPChan: Messages can go to only one newsgroup"); } $group = $groups[0]; @@ -40,9 +41,9 @@ function handle_nntpchan() { $ref = null; if (isset ($_GET['References'])) { - $refs = preg_split("/,\s*/", $_GET['References']); + $refs = preg_split("/,\s*/", (string) $_GET['References']); - if (count($refs) > 1) { + if ((is_countable($refs) ? count($refs) : 0) > 1) { error("NNTPChan: We don't support multiple references"); } @@ -54,7 +55,7 @@ function handle_nntpchan() { $ary = $query->fetchAll(PDO::FETCH_ASSOC); - if (count($ary) == 0) { + if ((is_countable($ary) ? count($ary) : 0) == 0) { error("NNTPChan: We don't have $ref that $msgid references"); } @@ -68,9 +69,9 @@ function handle_nntpchan() { $_POST['thread'] = $p_id; } - $date = isset($_GET['Date']) ? strtotime($_GET['Date']) : time(); + $date = isset($_GET['Date']) ? strtotime((string) $_GET['Date']) : time(); - list($ct) = explode('; ', $_GET['Content-Type']); + [$ct] = explode('; ', (string) $_GET['Content-Type']); $query = prepare("SELECT COUNT(*) AS `c` FROM ``nntp_references`` WHERE `message_id` = :msgid"); $query->bindValue(":msgid", $msgid); @@ -89,7 +90,7 @@ function handle_nntpchan() { $content = ''; - $newfiles = array(); + $newfiles = []; foreach ($_FILES['attachment']['error'] as $id => $error) { if ($_FILES['attachment']['type'][$id] == 'text/plain') { $content .= file_get_contents($_FILES['attachment']['tmp_name'][$id]); @@ -97,7 +98,7 @@ function handle_nntpchan() { elseif ($_FILES['attachment']['type'][$id] == 'message/rfc822') { // Signed message, ignore for now } else { // A real attachment :^) - $file = array(); + $file = []; $file['name'] = $_FILES['attachment']['name'][$id]; $file['type'] = $_FILES['attachment']['type'][$id]; $file['size'] = $_FILES['attachment']['size'][$id]; @@ -118,7 +119,7 @@ function handle_nntpchan() { $_POST['board'] = $xboard; if (isset ($_GET['From'])) { - list($name, $mail) = explode(" <", $_GET['From'], 2); + [$name, $mail] = explode(" <", (string) $_GET['From'], 2); $mail = preg_replace('/>\s+$/', '', $mail); $_POST['name'] = $name; @@ -139,11 +140,11 @@ function handle_nntpchan() { $query->execute() or error(db_error($query)); $ary = $query->fetchAll(PDO::FETCH_ASSOC); - if (count($ary) == 0) { + if ((is_countable($ary) ? count($ary) : 0) == 0) { return ">>>>$id"; } else { - $ret = array(); + $ret = []; foreach ($ary as $v) { if ($v['board'] != $xboard) { $ret[] = ">>>/".$v['board']."/".$v['id']; @@ -158,13 +159,7 @@ function handle_nntpchan() { $_POST['body'] = $content; - $dropped_post = array( - 'date' => $date, - 'board' => $xboard, - 'msgid' => $msgid, - 'headers' => $headers, - 'from_nntp' => true, - ); + $dropped_post = ['date' => $date, 'board' => $xboard, 'msgid' => $msgid, 'headers' => $headers, 'from_nntp' => true]; } @@ -180,7 +175,7 @@ function handle_delete(){ if ($password == '') error($config['error']['invalidpassword']); - $delete = array(); + $delete = []; foreach ($_POST as $post => $value) { if (preg_match('/^delete_(\d+)$/', $post, $m)) { $delete[] = (int)$m[1]; @@ -236,7 +231,7 @@ function handle_delete(){ } _syslog(LOG_INFO, 'Deleted post: ' . - '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ? $post['thread'] : $id) . ($post['thread'] ? '#' . $id : '') + '/' . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], $post['thread'] ?: $id) . ($post['thread'] ? '#' . $id : '') ); } } @@ -250,7 +245,7 @@ function handle_delete(){ header('Location: ' . $root . $board['dir'] . $config['file_index'], true, $config['redirect_http']); } else { header('Content-Type: text/json'); - echo json_encode(array('success' => true)); + echo json_encode(['success' => true]); } // We are already done, let's continue our heavy-lifting work in the background (if we run off FastCGI) @@ -262,11 +257,13 @@ function handle_delete(){ } function handle_report(){ - global $config,$board; + $thread = []; + $id = null; + global $config,$board; if (!isset($_POST['board'], $_POST['reason'])) error($config['error']['bot']); - $report = array(); + $report = []; foreach ($_POST as $post => $value) { if (preg_match('/^delete_(\d+)$/', $post, $m)) { $report[] = (int)$m[1]; @@ -315,7 +312,7 @@ function handle_report(){ $thread = $query->fetch(PDO::FETCH_ASSOC); - $error = event('report', array('ip' => $_SERVER['REMOTE_ADDR'], 'board' => $board['uri'], 'post' => $post, 'reason' => $reason, 'link' => link_for($post))); + $error = event('report', ['ip' => $_SERVER['REMOTE_ADDR'], 'board' => $board['uri'], 'post' => $post, 'reason' => $reason, 'link' => link_for($post)]); if ($error) { error($error); } @@ -338,12 +335,9 @@ function handle_report(){ function slack($message, $room = "reports", $icon = ":no_entry_sign:") { - $room = ($room) ? $room : "reports"; - $data = "payload=" . json_encode(array( - "channel" => "#{$room}", - "text" => urlencode($message), - "icon_emoji" => $icon - )); + $config = []; + $room = $room ?: "reports"; + $data = "payload=" . json_encode(["channel" => "#{$room}", "text" => urlencode((string) $message), "icon_emoji" => $icon], JSON_THROW_ON_ERROR); // You can get your webhook endpoint from your Slack settings // For some reason using the configuration key doesn't work @@ -358,8 +352,8 @@ function handle_report(){ return $result; } - $postcontent = mb_substr($thread['body_nomarkup'], 0, 120) . '... _*(POST TRIMMED)*_'; - $slackmessage = '<' .$config['domain'] . "/mod.php?/" . $board['dir'] . $config['dir']['res'] . ( $thread['thread'] ? $thread['thread'] : $id ) . ".html" . ($thread['thread'] ? '#' . $id : '') . '> \n ' . $reason . '\n ' . $postcontent . '\n'; + $postcontent = mb_substr((string) $thread['body_nomarkup'], 0, 120) . '... _*(POST TRIMMED)*_'; + $slackmessage = '<' .$config['domain'] . "/mod.php?/" . $board['dir'] . $config['dir']['res'] . ( $thread['thread'] ?: $id ) . ".html" . ($thread['thread'] ? '#' . $id : '') . '> \n ' . $reason . '\n ' . $postcontent . '\n'; $slackresult = slack($slackmessage, $config['slack_channel']); @@ -373,13 +367,13 @@ function handle_report(){ if (!isset($_POST['json_response'])) { $index = $root . $board['dir'] . $config['file_index']; - $reported_post = $root . $board['dir'] . $config['dir']['res'] . ( $thread['thread'] ? $thread['thread'] : $id ) . ".html" . ($thread['thread'] ? '#' . $id : '') ; + $reported_post = $root . $board['dir'] . $config['dir']['res'] . ( $thread['thread'] ?: $id ) . ".html" . ($thread['thread'] ? '#' . $id : '') ; //header('Location: ' . $reported_post); - echo Element('page.html', array('config' => $config, 'body' => '<div style="text-align:center"><a href="javascript:window.close()">[ ' . _('Close window') ." ]</a> <a href='$index'>[ " . _('Return') . ' ]</a></div>', 'title' => _('Report submitted!'))); + echo Element('page.html', ['config' => $config, 'body' => '<div style="text-align:center"><a href="javascript:window.close()">[ ' . _('Close window') ." ]</a> <a href='$index'>[ " . _('Return') . ' ]</a></div>', 'title' => _('Report submitted!')]); } else { header('Content-Type: text/json'); - echo json_encode(array('success' => true)); + echo json_encode(['success' => true]); } } @@ -389,7 +383,7 @@ function handle_post(){ if (!isset($_POST['body'], $_POST['board']) && !$dropped_post) error($config['error']['bot']); - $post = array('board' => $_POST['board'], 'files' => array()); + $post = ['board' => $_POST['board'], 'files' => []]; // Check if board exists if (!openBoard($post['board'])) @@ -397,7 +391,7 @@ function handle_post(){ $board_locked_check = (!isset($_POST['mod']) || !$_POST['mod']) && ($config['board_locked']===true - || (is_array($config['board_locked']) && in_array(strtolower($_POST['board']), $config['board_locked']))); + || (is_array($config['board_locked']) && in_array(strtolower((string) $_POST['board']), $config['board_locked']))); if ($board_locked_check){ error("Board is locked"); @@ -430,8 +424,8 @@ function handle_post(){ // Check what reCAPTCHA has to say... $resp = json_decode(file_get_contents(sprintf('https://www.google.com/recaptcha/api/siteverify?secret=%s&response=%s&remoteip=%s', $config['recaptcha_private'], - urlencode($_POST['g-recaptcha-response']), - $_SERVER['REMOTE_ADDR'])), true); + urlencode((string) $_POST['g-recaptcha-response']), + $_SERVER['REMOTE_ADDR'])), true, 512, JSON_THROW_ON_ERROR); if (!$resp['success']) { error($config['error']['captcha']); @@ -460,7 +454,7 @@ function handle_post(){ // Check the referrer if ($config['referer_match'] !== false && - (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], rawurldecode($_SERVER['HTTP_REFERER'])))) + (!isset($_SERVER['HTTP_REFERER']) || !preg_match($config['referer_match'], rawurldecode((string) $_SERVER['HTTP_REFERER'])))) error($config['error']['referer']); checkDNSBL(); @@ -488,7 +482,7 @@ function handle_post(){ } if (!$post['mod']) { - $post['antispam_hash'] = checkSpam(array($board['uri'], isset($post['thread']) ? $post['thread'] : ($config['try_smarter'] && isset($_POST['page']) ? 0 - (int)$_POST['page'] : null))); + $post['antispam_hash'] = checkSpam([$board['uri'], $post['thread'] ?? ($config['try_smarter'] && isset($_POST['page']) ? 0 - (int)$_POST['page'] : null)]); if ($post['antispam_hash'] === true) error($config['error']['spam']); } @@ -522,7 +516,7 @@ function handle_post(){ // yep; validate it $value = $_POST['embed']; foreach ($config['embedding'] as &$embed) { - if (preg_match($embed[0], $value)) { + if (preg_match($embed[0], (string) $value)) { // Valid link $post['embed'] = $value; // This is bad, lol. @@ -557,15 +551,15 @@ function handle_post(){ function upload_by_url($config,$post,$url) { $post['file_url'] = $url; - if (!preg_match('@^https?://@', $post['file_url'])) + if (!preg_match('@^https?://@', (string) $post['file_url'])) error($config['error']['invalidimg']); - if (mb_strpos($post['file_url'], '?') !== false) - $url_without_params = mb_substr($post['file_url'], 0, mb_strpos($post['file_url'], '?')); + if (mb_strpos((string) $post['file_url'], '?') !== false) + $url_without_params = mb_substr((string) $post['file_url'], 0, mb_strpos((string) $post['file_url'], '?')); else $url_without_params = $post['file_url']; - $post['extension'] = strtolower(mb_substr($url_without_params, mb_strrpos($url_without_params, '.') + 1)); + $post['extension'] = strtolower(mb_substr((string) $url_without_params, mb_strrpos((string) $url_without_params, '.') + 1)); if ($post['op'] && $config['allowed_ext_op']) { if (!in_array($post['extension'], $config['allowed_ext_op'])) @@ -598,13 +592,7 @@ function handle_post(){ fclose($fp); - $_FILES[$post['file_tmp']] = array( - 'name' => basename($url_without_params), - 'tmp_name' => $post['file_tmp'], - 'file_tmp' => true, - 'error' => 0, - 'size' => filesize($post['file_tmp']) - ); + $_FILES[$post['file_tmp']] = ['name' => basename((string) $url_without_params), 'tmp_name' => $post['file_tmp'], 'file_tmp' => true, 'error' => 0, 'size' => filesize($post['file_tmp'])]; } for( $counter = 1; $counter <= $config['max_images']; $counter++ ) { @@ -618,7 +606,7 @@ function handle_post(){ $post['name'] = $_POST['name'] != '' ? $_POST['name'] : $config['anonymous']; $post['subject'] = $_POST['subject']; - $post['email'] = str_replace(' ', '%20', htmlspecialchars($_POST['email'])); + $post['email'] = str_replace(' ', '%20', htmlspecialchars((string) $_POST['email'])); $post['body'] = $_POST['body']; $post['password'] = $_POST['password']; $post['has_file'] = (!isset($post['embed']) && (($post['op'] && !isset($post['no_longer_require_an_image_for_op']) && $config['force_image_op']) || count($_FILES) > 0)); @@ -683,18 +671,14 @@ function handle_post(){ } if ($size > $max_size) - error(sprintf3($config['error']['filesize'], array( - 'sz' => number_format($size), - 'filesz' => number_format($size), - 'maxsz' => number_format($config['max_filesize']) - ))); + error(sprintf3($config['error']['filesize'], ['sz' => number_format($size), 'filesz' => number_format($size), 'maxsz' => number_format($config['max_filesize'])])); $post['filesize'] = $size; } $post['capcode'] = false; - if ($mod && preg_match('/^((.+) )?## (.+)$/', $post['name'], $matches)) { + if ($mod && preg_match('/^((.+) )?## (.+)$/', (string) $post['name'], $matches)) { $name = $matches[2] != '' ? $matches[2] : $config['anonymous']; $cap = $matches[3]; @@ -724,7 +708,7 @@ function handle_post(){ $trip = generate_tripcode($post['name']); $post['name'] = $trip[0]; - $post['trip'] = isset($trip[1]) ? $trip[1] : ''; // XX: Dropped posts and tripcodes + $post['trip'] = $trip[1] ?? ''; // XX: Dropped posts and tripcodes $noko = false; if (strtolower($post['email']) == 'noko') { @@ -739,7 +723,7 @@ function handle_post(){ $i = 0; foreach ($_FILES as $key => $file) { if ($file['size'] && $file['tmp_name']) { - $file['filename'] = urldecode($file['name']); + $file['filename'] = urldecode((string) $file['name']); $file['extension'] = strtolower(mb_substr($file['filename'], mb_strrpos($file['filename'], '.') + 1)); if (isset($config['filename_func'])) $file['file_id'] = $config['filename_func']($file); @@ -750,7 +734,7 @@ function handle_post(){ $file['file_id'] .= "-$i"; $file['file'] = $board['dir'] . $config['dir']['img'] . $file['file_id'] . '.' . $file['extension']; - $file['thumb'] = $board['dir'] . $config['dir']['thumb'] . $file['file_id'] . '.' . ($config['thumb_ext'] ? $config['thumb_ext'] : $file['extension']); + $file['thumb'] = $board['dir'] . $config['dir']['thumb'] . $file['file_id'] . '.' . ($config['thumb_ext'] ?: $file['extension']); $post['files'][] = $file; $i++; } @@ -780,17 +764,17 @@ function handle_post(){ if (!$dropped_post) { // Check string lengths - if (mb_strlen($post['name']) > 35) + if (mb_strlen((string) $post['name']) > 35) error(sprintf($config['error']['toolong'], 'name')); - if (mb_strlen($post['email']) > 40) + if (mb_strlen((string) $post['email']) > 40) error(sprintf($config['error']['toolong'], 'email')); - if (mb_strlen($post['subject']) > 100) + if (mb_strlen((string) $post['subject']) > 100) error(sprintf($config['error']['toolong'], 'subject')); - if (!$mod && mb_strlen($post['body']) > $config['max_body']) + if (!$mod && mb_strlen((string) $post['body']) > $config['max_body']) error($config['error']['toolong_body']); - if (!$mod && mb_strlen($post['body']) > 0 && (mb_strlen($post['body']) < $config['min_body'])) + if (!$mod && mb_strlen((string) $post['body']) > 0 && (mb_strlen((string) $post['body']) < $config['min_body'])) error($config['error']['tooshort_body']); - if (mb_strlen($post['password']) > 20) + if (mb_strlen((string) $post['password']) > 20) error(sprintf($config['error']['toolong'], 'password')); } wordfilters($post['body']); @@ -806,20 +790,20 @@ function handle_post(){ $gi=geoip_open('inc/lib/geoip/GeoIPv6.dat', GEOIP_STANDARD); function ipv4to6($ip) { - if (strpos($ip, ':') !== false) { - if (strpos($ip, '.') > 0) - $ip = substr($ip, strrpos($ip, ':')+1); + if (str_contains((string) $ip, ':')) { + if (strpos((string) $ip, '.') > 0) + $ip = substr((string) $ip, strrpos((string) $ip, ':')+1); else return $ip; //native ipv6 } - $iparr = array_pad(explode('.', $ip), 4, 0); + $iparr = array_pad(explode('.', (string) $ip), 4, 0); $part7 = base_convert(($iparr[0] * 256) + $iparr[1], 10, 16); $part8 = base_convert(($iparr[2] * 256) + $iparr[3], 10, 16); return '::ffff:'.$part7.':'.$part8; } if ($country_code = geoip_country_code_by_addr_v6($gi, ipv4to6($_SERVER['REMOTE_ADDR']))) { - if (!in_array(strtolower($country_code), array('eu', 'ap', 'o1', 'a1', 'a2'))) - $post['body'] .= "\n<tinyboard flag>".strtolower($country_code)."</tinyboard>". + if (!in_array(strtolower((string) $country_code), ['eu', 'ap', 'o1', 'a1', 'a2'])) + $post['body'] .= "\n<tinyboard flag>".strtolower((string) $country_code)."</tinyboard>". "\n<tinyboard flag alt>".geoip\geoip_country_name_by_addr_v6($gi, ipv4to6($_SERVER['REMOTE_ADDR']))."</tinyboard>"; } } @@ -832,9 +816,9 @@ function handle_post(){ if (!isset($config['user_flags'][$user_flag])) error(_('Invalid flag selection!')); - $flag_alt = isset($user_flag_alt) ? $user_flag_alt : $config['user_flags'][$user_flag]; + $flag_alt = $user_flag_alt ?? $config['user_flags'][$user_flag]; - $post['body'] .= "\n<tinyboard flag>" . strtolower($user_flag) . "</tinyboard>" . + $post['body'] .= "\n<tinyboard flag>" . strtolower((string) $user_flag) . "</tinyboard>" . "\n<tinyboard flag alt>" . $flag_alt . "</tinyboard>"; } @@ -854,7 +838,7 @@ function handle_post(){ // MySQL's `utf8` charset only supports up to 3-byte symbols // Remove anything >= 0x010000 - $chars = preg_split('//u', $post['body'], -1, PREG_SPLIT_NO_EMPTY); + $chars = preg_split('//u', (string) $post['body'], -1, PREG_SPLIT_NO_EMPTY); $post['body_nomarkup'] = ''; foreach ($chars as $char) { $o = 0; @@ -887,7 +871,7 @@ function handle_post(){ $file['is_an_image'] = !in_array($file['extension'], $config['allowed_ext_files']); // Truncate filename if it is too long - $file['filename'] = mb_substr($file['filename'], 0, $config['max_filename_len']); + $file['filename'] = mb_substr((string) $file['filename'], 0, $config['max_filename_len']); $upload = $file['tmp_name']; @@ -895,8 +879,8 @@ function handle_post(){ error($config['error']['nomove']); if ($md5cmd) { - $output = shell_exec_error($md5cmd . " " . escapeshellarg($upload)); - $output = explode(' ', $output); + $output = shell_exec_error($md5cmd . " " . escapeshellarg((string) $upload)); + $output = explode(' ', (string) $output); $hash = $output[0]; } else { @@ -939,7 +923,7 @@ function handle_post(){ if (!$size = @getimagesize($file['tmp_name'])) { error($config['error']['invalidimg']); } - if (!in_array($size[2], array(IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_BMP))) { + if (!in_array($size[2], [IMAGETYPE_PNG, IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_BMP])) { error($config['error']['invalidimg']); } if ($size[0] > $config['max_width'] || $size[1] > $config['max_height']) { @@ -951,22 +935,22 @@ function handle_post(){ // The following code corrects the image orientation. // Currently only works with the 'convert' option selected but it could easily be expanded to work with the rest if you can be bothered. if (!($config['redraw_image'] || (($config['strip_exif'] && !$config['use_exiftool']) && ($file['extension'] == 'jpg' || $file['extension'] == 'jpeg')))) { - if (in_array($config['thumb_method'], array('convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'))) { + if (in_array($config['thumb_method'], ['convert', 'convert+gifsicle', 'gm', 'gm+gifsicle'])) { $exif = @exif_read_data($file['tmp_name']); - $gm = in_array($config['thumb_method'], array('gm', 'gm+gifsicle')); + $gm = in_array($config['thumb_method'], ['gm', 'gm+gifsicle']); if (isset($exif['Orientation']) && $exif['Orientation'] != 1) { if ($config['convert_manual_orient']) { $error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($file['tmp_name']) . ' ' . + escapeshellarg((string) $file['tmp_name']) . ' ' . ImageConvert::jpeg_exif_orientation(false, $exif) . ' ' . ($config['strip_exif'] ? '+profile "*"' : ($config['use_exiftool'] ? '' : '+profile "*"') ) . ' ' . - escapeshellarg($file['tmp_name'])); + escapeshellarg((string) $file['tmp_name'])); if ($config['use_exiftool'] && !$config['strip_exif']) { if ($exiftool_error = shell_exec_error( 'exiftool -overwrite_original -q -q -orientation=1 -n ' . - escapeshellarg($file['tmp_name']))) + escapeshellarg((string) $file['tmp_name']))) error(_('exiftool failed!'), null, $exiftool_error); } else { // TODO: Find another way to remove the Orientation tag from the EXIF profile @@ -974,7 +958,7 @@ function handle_post(){ } } else { $error = shell_exec_error(($gm ? 'gm ' : '') . 'convert ' . - escapeshellarg($file['tmp_name']) . ' -auto-orient ' . escapeshellarg($upload)); + escapeshellarg((string) $file['tmp_name']) . ' -auto-orient ' . escapeshellarg((string) $upload)); } if ($error) error(_('Could not auto-orient image!'), null, $error); @@ -1005,7 +989,7 @@ function handle_post(){ } elseif ($config['minimum_copy_resize'] && $image->size->width <= $config['thumb_width'] && $image->size->height <= $config['thumb_height'] && - $file['extension'] == ($config['thumb_ext'] ? $config['thumb_ext'] : $file['extension'])) { + $file['extension'] == ($config['thumb_ext'] ?: $file['extension'])) { // Copy, because there's nothing to resize copy($file['tmp_name'], $file['thumb']); @@ -1014,7 +998,7 @@ function handle_post(){ $file['thumbheight'] = $image->size->height; } else { $thumb = $image->resize( - $config['thumb_ext'] ? $config['thumb_ext'] : $file['extension'], + $config['thumb_ext'] ?: $file['extension'], $post['op'] ? $config['thumb_op_width'] : $config['thumb_width'], $post['op'] ? $config['thumb_op_height'] : $config['thumb_height'] ); @@ -1030,7 +1014,7 @@ function handle_post(){ if ($config['redraw_image'] || (!@$file['exif_stripped'] && $config['strip_exif'] && ($file['extension'] == 'jpg' || $file['extension'] == 'jpeg'))) { if (!$config['redraw_image'] && $config['use_exiftool']) { if($error = shell_exec_error('exiftool -overwrite_original -ignoreMinorErrors -q -q -all= ' . - escapeshellarg($file['tmp_name']))) + escapeshellarg((string) $file['tmp_name']))) error(_('Could not strip EXIF metadata!'), null, $error); } else { $image->to($file['file']); @@ -1044,13 +1028,13 @@ function handle_post(){ $path = $file['thumb']; $error = shell_exec_error( 'convert -thumbnail x300 -background white -alpha remove ' . escapeshellarg($file['tmp_name']. '[0]') . ' ' . - escapeshellarg($file['thumb'])); + escapeshellarg((string) $file['thumb'])); if ($error){ - $path = sprintf($config['file_thumb'],isset($config['file_icons'][$file['extension']]) ? $config['file_icons'][$file['extension']] : $config['file_icons']['default']); + $path = sprintf($config['file_thumb'],$config['file_icons'][$file['extension']] ?? $config['file_icons']['default']); } - $file['thumb'] = basename($file['thumb']); + $file['thumb'] = basename((string) $file['thumb']); $size = @getimagesize($path); $file['thumbwidth'] = $size[0]; $file['thumbheight'] = $size[1]; @@ -1106,13 +1090,13 @@ function handle_post(){ $path = $file['thumb']; $error = shell_exec_error( 'convert -thumbnail x300 xc:white -pointsize 12 -fill black -annotate +15+15 ' . escapeshellarg( '@' . $file['tmp_name']) . ' ' . - escapeshellarg($file['thumb'])); + escapeshellarg((string) $file['thumb'])); if ($error){ - $path = sprintf($config['file_thumb'],isset($config['file_icons'][$file['extension']]) ? $config['file_icons'][$file['extension']] : $config['file_icons']['default']); + $path = sprintf($config['file_thumb'],$config['file_icons'][$file['extension']] ?? $config['file_icons']['default']); } - $file['thumb'] = basename($file['thumb']); + $file['thumb'] = basename((string) $file['thumb']); $size = @getimagesize($path); $file['thumbwidth'] = $size[0]; $file['thumbheight'] = $size[1]; @@ -1121,11 +1105,11 @@ function handle_post(){ } else if ($file['extension'] == "svg"){ // Copy, because there's nothing to resize - $file['thumb'] = substr_replace($file['thumb'] , $file['extension'], strrpos($file['thumb'] , '.') +1); + $file['thumb'] = substr_replace($file['thumb'] , $file['extension'], strrpos((string) $file['thumb'] , '.') +1); copy($file['tmp_name'], $file['thumb']); $file['thumbwidth'] = $config['thumb_width']; $file['thumbheight'] = $config['thumb_height']; - $file['thumb'] = basename($file['thumb']); + $file['thumb'] = basename((string) $file['thumb']); } else { @@ -1134,8 +1118,7 @@ function handle_post(){ $file['thumb'] = 'file'; $size = @getimagesize(sprintf($config['file_thumb'], - isset($config['file_icons'][$file['extension']]) ? - $config['file_icons'][$file['extension']] : $config['file_icons']['default'])); + $config['file_icons'][$file['extension']] ?? $config['file_icons']['default'])); $file['thumbwidth'] = $size[0]; $file['thumbheight'] = $size[1]; } @@ -1151,10 +1134,10 @@ function handle_post(){ if ($fname == 'spoiler') { // We don't have that much CPU time, do we? } else { - $tmpname = __DIR__ . "/tmp/tesseract/".rand(0,10000000); + $tmpname = __DIR__ . "/tmp/tesseract/".random_int(0,10_000_000); // Preprocess command is an ImageMagick b/w quantization - $error = shell_exec_error(sprintf($config['tesseract_preprocess_command'], escapeshellarg($fname)) . " | " . + $error = shell_exec_error(sprintf($config['tesseract_preprocess_command'], escapeshellarg((string) $fname)) . " | " . 'tesseract stdin '.escapeshellarg($tmpname).' '.$config['tesseract_params']); $tmpname .= ".txt"; @@ -1227,17 +1210,17 @@ function handle_post(){ foreach ($post['files'] as $key => &$file) { $file['file_path'] = $file['file']; $file['thumb_path'] = $file['thumb']; - $file['file'] = mb_substr($file['file'], mb_strlen($board['dir'] . $config['dir']['img'])); + $file['file'] = mb_substr((string) $file['file'], mb_strlen($board['dir'] . $config['dir']['img'])); if ($file['is_an_image'] && $file['thumb'] != 'spoiler') - $file['thumb'] = mb_substr($file['thumb'], mb_strlen($board['dir'] . $config['dir']['thumb'])); + $file['thumb'] = mb_substr((string) $file['thumb'], mb_strlen($board['dir'] . $config['dir']['thumb'])); } } $post = (object)$post; - $post->files = array_map(function($a) { return (object)$a; }, $post->files); + $post->files = array_map(fn($a) => (object)$a, $post->files); $error = event('post', $post); - $post->files = array_map(function($a) { return (array)$a; }, $post->files); + $post->files = array_map(fn($a) => (array)$a, $post->files); if ($error) { undoImage((array)$post); @@ -1260,7 +1243,7 @@ function handle_post(){ $query->bindValue(':board', $dropped_post['board']); $query->bindValue(':id', $id); $query->bindValue(':message_id', $dropped_post['msgid']); - $query->bindValue(':message_id_digest', sha1($dropped_post['msgid'])); + $query->bindValue(':message_id_digest', sha1((string) $dropped_post['msgid'])); $query->bindValue(':headers', $dropped_post['headers']); $query->execute() or error(db_error($query)); } // ^^^^^ For inbound posts ^^^^^ @@ -1270,7 +1253,7 @@ function handle_post(){ require_once('inc/nntpchan/nntpchan.php'); $msgid = gen_msgid($post['board'], $post['id']); - list($headers, $files) = post2nntp($post, $msgid); + [$headers, $files] = post2nntp($post, $msgid); $message = gen_nntp($headers, $files); @@ -1280,8 +1263,8 @@ function handle_post(){ $query->bindValue(':board', $post['board']); $query->bindValue(':id', $post['id']); $query->bindValue(':message_id', $msgid); - $query->bindValue(':message_id_digest', sha1($msgid)); - $query->bindValue(':headers', json_encode($headers)); + $query->bindValue(':message_id_digest', sha1((string) $msgid)); + $query->bindValue(':headers', json_encode($headers, JSON_THROW_ON_ERROR)); $query->execute() or error(db_error($query)); // Let's broadcast it! @@ -1304,7 +1287,7 @@ function handle_post(){ } if (isset($post['tracked_cites']) && !empty($post['tracked_cites'])) { - $insert_rows = array(); + $insert_rows = []; foreach ($post['tracked_cites'] as $cite) { $insert_rows[] = '(' . $pdo->quote($board['uri']) . ', ' . (int)$id . ', ' . @@ -1313,20 +1296,20 @@ function handle_post(){ query('INSERT INTO ``cites`` VALUES ' . implode(', ', $insert_rows)) or error(db_error()); } - if (!$post['op'] && strtolower($post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || $numposts['replies']+1 < $config['reply_limit'])) { + if (!$post['op'] && strtolower((string) $post['email']) != 'sage' && !$thread['sage'] && ($config['reply_limit'] == 0 || $numposts['replies']+1 < $config['reply_limit'])) { bumpThread($post['thread']); } if (isset($_SERVER['HTTP_REFERER'])) { // Tell Javascript that we posted successfully if (isset($_COOKIE[$config['cookies']['js']])) - $js = json_decode($_COOKIE[$config['cookies']['js']]); + $js = json_decode((string) $_COOKIE[$config['cookies']['js']], null, 512, JSON_THROW_ON_ERROR); else - $js = (object) array(); + $js = (object) []; // Tell it to delete the cached post for referer $js->{$_SERVER['HTTP_REFERER']} = true; // Encode and set cookie - setcookie($config['cookies']['js'], json_encode($js), 0, $config['cookies']['jail'] ? $config['cookies']['path'] : '/', $config['domain'], false, false); + setcookie($config['cookies']['js'], json_encode($js, JSON_THROW_ON_ERROR), ['expires' => 0, 'path' => $config['cookies']['jail'] ? $config['cookies']['path'] : '/', 'domain' => $config['domain'], 'secure' => false, 'httponly' => false]); } $root = $post['mod'] ? $config['root'] . $config['file_mod'] . '?/' : $config['root']; @@ -1336,15 +1319,10 @@ function handle_post(){ link_for($post, false, false, $thread) . (!$post['op'] ? '#' . $id : ''); if (!$post['op'] && isset($_SERVER['HTTP_REFERER'])) { - $regex = array( - 'board' => str_replace('%s', '(\w{1,8})', preg_quote($config['board_path'], '/')), - 'page' => str_replace('%d', '(\d+)', preg_quote($config['file_page'], '/')), - 'page50' => '(' . str_replace('%d', '(\d+)', preg_quote($config['file_page50'], '/')) . '|' . - str_replace(array('%d', '%s'), array('(\d+)', '[a-z0-9-]+'), preg_quote($config['file_page50_slug'], '/')) . ')', - 'res' => preg_quote($config['dir']['res'], '/'), - ); + $regex = ['board' => str_replace('%s', '(\w{1,8})', preg_quote((string) $config['board_path'], '/')), 'page' => str_replace('%d', '(\d+)', preg_quote((string) $config['file_page'], '/')), 'page50' => '(' . str_replace('%d', '(\d+)', preg_quote((string) $config['file_page50'], '/')) . '|' . + str_replace(['%d', '%s'], ['(\d+)', '[a-z0-9-]+'], preg_quote((string) $config['file_page50_slug'], '/')) . ')', 'res' => preg_quote((string) $config['dir']['res'], '/')]; - if (preg_match('/\/' . $regex['board'] . $regex['res'] . $regex['page50'] . '([?&].*)?$/', $_SERVER['HTTP_REFERER'])) { + if (preg_match('/\/' . $regex['board'] . $regex['res'] . $regex['page50'] . '([?&].*)?$/', (string) $_SERVER['HTTP_REFERER'])) { $redirect = $root . $board['dir'] . $config['dir']['res'] . link_for($post, true, false, $thread) . (!$post['op'] ? '#' . $id : ''); } @@ -1366,11 +1344,7 @@ function handle_post(){ header('Location: ' . $redirect, true, $config['redirect_http']); } else { header('Content-Type: text/json; charset=utf-8'); - echo json_encode(array( - 'redirect' => $redirect, - 'noko' => $noko, - 'id' => $id - )); + echo json_encode(['redirect' => $redirect, 'noko' => $noko, 'id' => $id], JSON_THROW_ON_ERROR); } if ($config['try_smarter'] && $post['op']) @@ -1421,7 +1395,7 @@ function handle_appeal(){ $query = query("SELECT `denied` FROM ``ban_appeals`` WHERE `ban_id` = $ban_id") or error(db_error()); $ban_appeals = $query->fetchAll(PDO::FETCH_COLUMN); - if (count($ban_appeals) >= $config['ban_appeals_max']) { + if ((is_countable($ban_appeals) ? count($ban_appeals) : 0) >= $config['ban_appeals_max']) { error(_("You cannot appeal this ban again.")); } @@ -1,10 +1,10 @@ <?php include 'inc/functions.php'; $global = isset($_GET['global']); -$post = (isset($_GET['post']) ? $_GET['post'] : false); -$board = (isset($_GET['board']) ? $_GET['board'] : false); +$post = ($_GET['post'] ?? false); +$board = ($_GET['board'] ?? false); -if (!$post || !preg_match('/^delete_\d+$/', $post) || !$board || !openBoard($board)) { +if (!$post || !preg_match('/^delete_\d+$/', (string) $post) || !$board || !openBoard($board)) { header('HTTP/1.1 400 Bad Request'); error(_('Bad request.')); } @@ -15,7 +15,7 @@ $boards = listBoards(TRUE); } - $body = Element('search_form.html', Array('boards' => $boards, 'board' => isset($_GET['board']) ? $_GET['board'] : false, 'search' => isset($_GET['search']) ? str_replace('"', '"', utf8tohtml($_GET['search'])) : false)); + $body = Element('search_form.html', ['boards' => $boards, 'board' => $_GET['board'] ?? false, 'search' => isset($_GET['search']) ? str_replace('"', '"', (string) utf8tohtml($_GET['search'])) : false]); if(isset($_GET['search']) && !empty($_GET['search']) && isset($_GET['board']) && in_array($_GET['board'], $boards)) { $phrase = $_GET['search']; @@ -50,14 +50,14 @@ openBoard($_GET['board']); - $filters = Array(); + $filters = []; function search_filters($m) { global $filters; $name = $m[2]; - $value = isset($m[4]) ? $m[4] : $m[3]; + $value = $m[4] ?? $m[3]; - if(!in_array($name, array('id', 'thread', 'subject', 'name'))) { + if(!in_array($name, ['id', 'thread', 'subject', 'name'])) { // unknown filter return $m[0]; } @@ -72,11 +72,7 @@ if(!preg_match('/[^*^\s]/', $phrase) && empty($filters)) { _syslog(LOG_WARNING, 'Query too broad.'); $body .= '<p class="unimportant" style="text-align:center">(Query too broad.)</p>'; - echo Element('page.html', Array( - 'config'=>$config, - 'title'=>'Search', - 'body'=>$body, - )); + echo Element('page.html', ['config'=>$config, 'title'=>'Search', 'body'=>$body]); exit; } @@ -93,7 +89,7 @@ $phrase = str_replace('`', '!`', $phrase); $like = ''; - $match = Array(); + $match = []; // Find exact phrases if(preg_match_all('/"(.+?)"/', $phrase, $m)) { @@ -133,11 +129,7 @@ if($query->rowCount() == $search_limit) { _syslog(LOG_WARNING, 'Query too broad.'); $body .= '<p class="unimportant" style="text-align:center">('._('Query too broad.').')</p>'; - echo Element('page.html', Array( - 'config'=>$config, - 'title'=>'Search', - 'body'=>$body, - )); + echo Element('page.html', ['config'=>$config, 'title'=>'Search', 'body'=>$body]); exit; } @@ -167,8 +159,4 @@ $body .= '<p style="text-align:center" class="unimportant">('._('No results.').')</p>'; } - echo Element('page.html', Array( - 'config'=>$config, - 'title'=>_('Search'), - 'body'=>'' . $body - )); + echo Element('page.html', ['config'=>$config, 'title'=>_('Search'), 'body'=>'' . $body]); diff --git a/smart_build.php b/smart_build.php index cfac446a..242767be 100644 --- a/smart_build.php +++ b/smart_build.php @@ -8,11 +8,11 @@ if (!$config["smart_build_helper"]) { } $config['smart_build'] = false; // Let's disable it, so we can build the page for real -$config['generation_strategies'] = array('strategy_immediate'); +$config['generation_strategies'] = ['strategy_immediate']; function after_open_board() { global $config; $config['smart_build'] = false; - $config['generation_strategies'] = array('strategy_immediate'); + $config['generation_strategies'] = ['strategy_immediate']; }; $request = $_SERVER['REQUEST_URI']; @@ -23,7 +23,7 @@ if (!$route) { $reached = false; } else { - list ($fun, $args) = $route; + [$fun, $args] = $route; $reached = call_user_func_array($fun, $args); } @@ -41,7 +41,7 @@ function die_404() { global $config; } if ($reached) { - if ($request[strlen($request)-1] == '/') { + if ($request[strlen((string) $request)-1] == '/') { $request .= 'index.html'; } $request = '.'.$request; diff --git a/templates/themes/basic/info.php b/templates/themes/basic/info.php index 0b8ba98b..982010ef 100644 --- a/templates/themes/basic/info.php +++ b/templates/themes/basic/info.php @@ -1,44 +1,22 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'Basic'; + $theme['name'] = \Basic::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Extremely basic news listing for the homepage. Enabling boardlinks is recommended for this theme.'; $theme['version'] = 'v0.9.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => $config['file_index'], - 'comment' => '(eg. "index.html")' - ); + $theme['config'][] = ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => $config['file_index'], 'comment' => '(eg. "index.html")']; - $theme['config'][] = Array( - 'title' => '# of recent entries', - 'name' => 'no_recent', - 'type' => 'text', - 'default' => 0, - 'size' => 3, - 'comment' => '(number of recent news entries to display; "0" is infinite)' - ); + $theme['config'][] = ['title' => '# of recent entries', 'name' => 'no_recent', 'type' => 'text', 'default' => 0, 'size' => 3, 'comment' => '(number of recent news entries to display; "0" is infinite)']; // Unique function name for building everything $theme['build_function'] = 'basic_build'; @@ -47,7 +25,7 @@ if (!function_exists('build_install')) { function build_install($settings) { if (!is_numeric($settings['no_recent']) || $settings['no_recent'] < 0) - return Array(false, '<strong>' . utf8tohtml($settings['no_recent']) . '</strong> is not a non-negative integer.'); + return [false, '<strong>' . utf8tohtml($settings['no_recent']) . '</strong> is not a non-negative integer.']; } } diff --git a/templates/themes/basic/theme.php b/templates/themes/basic/theme.php index 6ba09ce6..4d79d73f 100644 --- a/templates/themes/basic/theme.php +++ b/templates/themes/basic/theme.php @@ -28,12 +28,7 @@ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC" . ($settings['no_recent'] ? ' LIMIT ' . $settings['no_recent'] : '')) or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); - return Element('themes/basic/index.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist(), - 'news' => $news - )); + return Element('themes/basic/index.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'news' => $news]); } }; diff --git a/templates/themes/calendar/calendarpost.php b/templates/themes/calendar/calendarpost.php index 5293a881..ac2c1a72 100644 --- a/templates/themes/calendar/calendarpost.php +++ b/templates/themes/calendar/calendarpost.php @@ -51,7 +51,7 @@ $method = $_SERVER['REQUEST_METHOD']; } elseif ($method == 'GET') { // Method is GET $query = query("SELECT * FROM calendar_events ORDER BY id") or error(db_error()); - echo json_encode($query->fetchAll(PDO::FETCH_ASSOC)); + echo json_encode($query->fetchAll(PDO::FETCH_ASSOC), JSON_THROW_ON_ERROR); } ?> diff --git a/templates/themes/calendar/info.php b/templates/themes/calendar/info.php index 0687a26d..6d770601 100644 --- a/templates/themes/calendar/info.php +++ b/templates/themes/calendar/info.php @@ -1,35 +1,20 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'Calendar'; + $theme['name'] = \Calendar::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Calendar theme.'; $theme['version'] = 'v0.0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => $config['file_index'], - 'comment' => '(eg. "index.html")' - ); + $theme['config'][] = ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => $config['file_index'], 'comment' => '(eg. "index.html")']; // Unique function name for building everything $theme['build_function'] = 'calendar_build'; diff --git a/templates/themes/calendar/theme.php b/templates/themes/calendar/theme.php index 8e9d32db..b39729ed 100644 --- a/templates/themes/calendar/theme.php +++ b/templates/themes/calendar/theme.php @@ -24,11 +24,7 @@ public static function htmlpage($settings) { global $config; - return Element('themes/calendar/calendar.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist() - )); + return Element('themes/calendar/calendar.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } public static function phppage($settings) { global $config; diff --git a/templates/themes/catalog/info.php b/templates/themes/catalog/info.php index bc0e7eb5..cf0d42ab 100644 --- a/templates/themes/catalog/info.php +++ b/templates/themes/catalog/info.php @@ -1,96 +1,37 @@ <?php - $theme = array(); + $theme = []; // Theme name - $theme['name'] = 'Catalog'; + $theme['name'] = \Catalog::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Show a post catalog.'; $theme['version'] = 'v0.2.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Title', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Catalog' - ); + $theme['config'][] = ['title' => 'Title', 'name' => 'title', 'type' => 'text', 'default' => \Catalog::class]; $__boards = listBoards(); - $__default_boards = Array(); + $__default_boards = []; foreach ($__boards as $__board) $__default_boards[] = $__board['uri']; - $theme['config'][] = Array( - 'title' => 'Included boards', - 'name' => 'boards', - 'type' => 'text', - 'comment' => '(space seperated)', - 'default' => implode(' ', $__default_boards) - ); + $theme['config'][] = ['title' => 'Included boards', 'name' => 'boards', 'type' => 'text', 'comment' => '(space seperated)', 'default' => implode(' ', $__default_boards)]; - $theme['config'][] = Array( - 'title' => 'Update on new posts', - 'name' => 'update_on_posts', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Without this checked, the catalog only updates on new threads.' - ); + $theme['config'][] = ['title' => 'Update on new posts', 'name' => 'update_on_posts', 'type' => 'checkbox', 'default' => false, 'comment' => 'Without this checked, the catalog only updates on new threads.']; - $theme['config'][] = Array( - 'title' => 'Enable Ukko catalog', - 'name' => 'enable_ukko', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko theme to be enabled.' - ); + $theme['config'][] = ['title' => 'Enable Ukko catalog', 'name' => 'enable_ukko', 'type' => 'checkbox', 'default' => false, 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko theme to be enabled.']; - $theme['config'][] = Array( - 'title' => 'Enable Ukko2 catalog', - 'name' => 'enable_ukko2', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Enable catalog for the Ukko2 theme. This requires the Ukko2 theme to be enabled.' - ); + $theme['config'][] = ['title' => 'Enable Ukko2 catalog', 'name' => 'enable_ukko2', 'type' => 'checkbox', 'default' => false, 'comment' => 'Enable catalog for the Ukko2 theme. This requires the Ukko2 theme to be enabled.']; - $theme['config'][] = Array( - 'title' => 'Enable Ukko3 catalog', - 'name' => 'enable_ukko3', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko3 theme to be enabled.' - ); - $theme['config'][] = Array( - 'title' => 'Enable Ukko4 catalog', - 'name' => 'enable_ukko4', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko4 theme to be enabled.' - ); + $theme['config'][] = ['title' => 'Enable Ukko3 catalog', 'name' => 'enable_ukko3', 'type' => 'checkbox', 'default' => false, 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko3 theme to be enabled.']; + $theme['config'][] = ['title' => 'Enable Ukko4 catalog', 'name' => 'enable_ukko4', 'type' => 'checkbox', 'default' => false, 'comment' => 'Enable catalog for the Ukko theme. This requires the Ukko4 theme to be enabled.']; - $theme['config'][] = Array( - 'title' => 'Enable Rand catalog', - 'name' => 'enable_rand', - 'type' => 'checkbox', - 'default' => false, - 'comment' => 'Enable catalog for the Rand theme. This requires the Rand theme to be enabled.' - ); - $theme['config'][] = Array( - 'title' => 'Use tooltipster', - 'name' => 'use_tooltipster', - 'type' => 'checkbox', - 'default' => true, - 'comment' => 'Check this if you wish to show a nice tooltip with info about the thread on mouse over.' - ); + $theme['config'][] = ['title' => 'Enable Rand catalog', 'name' => 'enable_rand', 'type' => 'checkbox', 'default' => false, 'comment' => 'Enable catalog for the Rand theme. This requires the Rand theme to be enabled.']; + $theme['config'][] = ['title' => 'Use tooltipster', 'name' => 'use_tooltipster', 'type' => 'checkbox', 'default' => true, 'comment' => 'Check this if you wish to show a nice tooltip with info about the thread on mouse over.']; - $theme['config'][] = Array( - 'title' => 'Base URL', - 'name' => 'base_url', - 'type' => 'text', - 'default' => 'http://test.com', - 'comment' => '(eg. "http://test.com")' - ); + $theme['config'][] = ['title' => 'Base URL', 'name' => 'base_url', 'type' => 'text', 'default' => 'http://test.com', 'comment' => '(eg. "http://test.com")']; // Unique function name for building everything $theme['build_function'] = 'catalog_build'; diff --git a/templates/themes/catalog/theme.php b/templates/themes/catalog/theme.php index 1b55d56e..f4c59681 100644 --- a/templates/themes/catalog/theme.php +++ b/templates/themes/catalog/theme.php @@ -5,7 +5,7 @@ global $config; $b = new Catalog($settings); - $boards = explode(' ', $settings['boards']); + $boards = explode(' ', (string) $settings['boards']); // Possible values for $action: // - all (rebuild everything, initialization) @@ -17,7 +17,7 @@ foreach ($boards as $board) { $b = new Catalog($settings); - $action = generation_strategy("sb_catalog", array($board)); + $action = generation_strategy("sb_catalog", [$board]); if ($action == 'delete') { file_unlink($config['dir']['home'] . $board . '/catalog.html'); file_unlink($config['dir']['home'] . $board . '/index.rss'); @@ -30,7 +30,7 @@ || $action == 'sticky' || ($action == 'lock' && in_array($board, $boards))) { $b = new Catalog($settings); - $action = generation_strategy("sb_catalog", array($board)); + $action = generation_strategy("sb_catalog", [$board]); if ($action == 'delete') { file_unlink($config['dir']['home'] . $board . '/catalog.html'); file_unlink($config['dir']['home'] . $board . '/index.rss'); @@ -82,13 +82,12 @@ // Wrap functions in a class so they don't interfere with normal Tinyboard operations class Catalog { - private $settings; // Cache for threads from boards that have already been processed - private $threadsCache = array(); + private array $threadsCache = []; - public function __construct($settings) { - $this->settings = $settings; - } + public function __construct(private $settings) + { + } /** * Build and save the HTML of the catalog for the Ukko theme @@ -97,10 +96,10 @@ global $config; $ukkoSettings = themeSettings('ukko'); - $queries = array(); - $threads = array(); + $queries = []; + $threads = []; - $exclusions = explode(' ', $ukkoSettings['exclude']); + $exclusions = explode(' ', (string) $ukkoSettings['exclude']); $boards = array_diff(listBoards(true), $exclusions); foreach ($boards as $b) { @@ -119,9 +118,7 @@ } // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + usort($threads, fn($a, $b) => strcmp((string) $b['bump'], (string) $a['bump'])); // Generate data for the template $recent_posts = $this->generateRecentPosts($threads); @@ -134,10 +131,10 @@ public function buildUkko2() { global $config; $ukkoSettings = themeSettings('ukko2'); - $queries = array(); - $threads = array(); + $queries = []; + $threads = []; - $inclusions = explode(' ', $ukkoSettings['include']); + $inclusions = explode(' ', (string) $ukkoSettings['include']); $boards = array_intersect(listBoards(true), $inclusions); foreach ($boards as $b) { @@ -156,9 +153,7 @@ } // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + usort($threads, fn($a, $b) => strcmp((string) $b['bump'], (string) $a['bump'])); // Generate data for the template $recent_posts = $this->generateRecentPosts($threads); @@ -173,10 +168,10 @@ global $config; $ukkoSettings = themeSettings('ukko3'); - $queries = array(); - $threads = array(); + $queries = []; + $threads = []; - $inclusions = explode(' ', $ukkoSettings['include']); + $inclusions = explode(' ', (string) $ukkoSettings['include']); $boards = array_intersect(listBoards(true), $inclusions); foreach ($boards as $b) { @@ -195,9 +190,7 @@ } // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + usort($threads, fn($a, $b) => strcmp((string) $b['bump'], (string) $a['bump'])); // Generate data for the template $recent_posts = $this->generateRecentPosts($threads); @@ -212,10 +205,10 @@ global $config; $ukkoSettings = themeSettings('ukko4'); - $queries = array(); - $threads = array(); + $queries = []; + $threads = []; - $exclusions = explode(' ', $ukkoSettings['exclude']); + $exclusions = explode(' ', (string) $ukkoSettings['exclude']); $boards = array_diff(listBoards(true), $exclusions); foreach ($boards as $b) { @@ -234,9 +227,7 @@ } // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + usort($threads, fn($a, $b) => strcmp((string) $b['bump'], (string) $a['bump'])); // Generate data for the template $recent_posts = $this->generateRecentPosts($threads); @@ -250,10 +241,10 @@ global $config; $randSettings = themeSettings('rand'); - $queries = array(); - $threads = array(); + $queries = []; + $threads = []; - $exclusions = explode(' ', $randSettings['exclude']); + $exclusions = explode(' ', (string) $randSettings['exclude']); $boards = array_diff(listBoards(true), $exclusions); foreach ($boards as $b) { @@ -272,9 +263,7 @@ } // Sort in bump order - usort($threads, function($a, $b) { - return strcmp($b['bump'], $a['bump']); - }); + usort($threads, fn($a, $b) => strcmp((string) $b['bump'], (string) $a['bump'])); // Generate data for the template $recent_posts = $this->generateRecentPosts($threads); @@ -321,7 +310,7 @@ private function generateRecentPosts($threads) { global $config, $board; - $posts = array(); + $posts = []; foreach ($threads as $post) { if ($board['uri'] !== $post['board']) { openBoard($post['board']); @@ -330,16 +319,16 @@ $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . link_for($post); $post['board_name'] = $board['name']; - if ($post['embed'] && preg_match('/^https?:\/\/(\w+\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', $post['embed'], $matches)) { + if ($post['embed'] && preg_match('/^https?:\/\/(\w+\.)?(?:youtube\.com\/watch\?v=|youtu\.be\/)([a-zA-Z0-9\-_]{10,11})(&.+)?$/i', (string) $post['embed'], $matches)) { $post['youtube'] = $matches[2]; } if (isset($post['files']) && $post['files']) { - $files = json_decode($post['files']); + $files = json_decode((string) $post['files'], null, 512, JSON_THROW_ON_ERROR); if ($files[0]) { if ($files[0]->file == 'deleted') { - if (count($files) > 1) { + if ((is_countable($files) ? count($files) : 0) > 1) { foreach ($files as $file) { if (($file == $files[0]) || ($file->file == 'deleted')) continue; @@ -378,8 +367,7 @@ $board_link = $config['root'] . $board['dir']; } - $required_scripts = array('js/jquery.min.js', 'js/jquery.mixitup.min.js', - 'js/catalog.js'); + $required_scripts = ['js/jquery.min.js', 'js/jquery.mixitup.min.js', 'js/catalog.js']; // Include scripts that haven't been yet included foreach($required_scripts as $i => $s) { @@ -387,22 +375,8 @@ $config['additional_javascript'][] = $s; } - file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', Array( - 'settings' => $this->settings, - 'config' => $config, - 'boardlist' => createBoardlist(), - 'recent_images' => array(), - 'recent_posts' => $recent_posts, - 'stats' => array(), - 'board' => $board_name, - 'link' => $board_link - ))); + file_write($config['dir']['home'] . $board_name . '/catalog.html', Element('themes/catalog/catalog.html', ['settings' => $this->settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => [], 'recent_posts' => $recent_posts, 'stats' => [], 'board' => $board_name, 'link' => $board_link])); - file_write($config['dir']['home'] . $board_name . '/index.rss', Element('themes/catalog/index.rss', Array( - 'settings' => $this->settings, - 'config' => $config, - 'recent_posts' => $recent_posts, - 'board' => $board - ))); + file_write($config['dir']['home'] . $board_name . '/index.rss', Element('themes/catalog/index.rss', ['settings' => $this->settings, 'config' => $config, 'recent_posts' => $recent_posts, 'board' => $board])); } } diff --git a/templates/themes/categories-uboachan/info.php b/templates/themes/categories-uboachan/info.php index 3ef9871f..99177e8f 100644 --- a/templates/themes/categories-uboachan/info.php +++ b/templates/themes/categories-uboachan/info.php @@ -1,5 +1,5 @@ <?php - $theme = Array(); + $theme = []; // Theme name $theme['name'] = 'Categories-Uboachan'; @@ -11,19 +11,11 @@ Requires $config[\'boards\'] and $config[\'categories\'].'; $theme['version'] = 'v0.2.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text']; // Unique function name for building everything $theme['build_function'] = 'categories_build'; @@ -34,8 +26,8 @@ Requires $config[\'boards\'] and $config[\'categories\'].'; global $config; if(!isset($config['boards']) || !isset($config['categories'])) { - return Array(false, '<h2>Prerequisites not met!</h2>' . - 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.'); + return [false, '<h2>Prerequisites not met!</h2>' . + 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.']; } } } diff --git a/templates/themes/categories-uboachan/theme.php b/templates/themes/categories-uboachan/theme.php index 296e0d06..3c735ec4 100644 --- a/templates/themes/categories-uboachan/theme.php +++ b/templates/themes/categories-uboachan/theme.php @@ -105,7 +105,7 @@ openBoard($post['board']); $body .= '<strong>' . $board['name'] . '</strong>: <a href="' . - $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread']?$post['thread']:$post['id']) . '.html#' . $post['id'] . + $config['root'] . $board['dir'] . $config['dir']['res'] . ($post['thread'] ?: $post['id']) . '.html#' . $post['id'] . '">'; $snip = pm_snippet($post['body'], 95); if($snip === "<em></em>") @@ -136,10 +136,7 @@ : '' ) . - ($news['subject'] ? - $news['subject'] - : - '<em>no subject</em>' + ($news['subject'] ?: '<em>no subject</em>' ) . ' — by ' . $news['name'] . @@ -190,7 +187,7 @@ '<li><a href="javascript:changeStyleForAll(\'YB\');">[YB]</a> <a href="javascript:changeStyleForAll(\'Y\');">[Y]</a> <a href="javascript:changeStyleForAll(\'U\');">[U]</a> <a href="javascript:changeStyleForAll(\'UG\');">[UG]</a> <a href="javascript:changeStyleForAll(\'RZ\');">[RZ]</a></li>'. '</ul></fieldset>'; - for($cat = 0; $cat < count($config['categories']); $cat++) { + for($cat = 0; $cat < (is_countable($config['categories']) ? count($config['categories']) : 0); $cat++) { $body .= '<fieldset><legend class="category">' . $config['categories'][$cat] . '</legend><ul>'; foreach($config['boards'][$cat] as &$board) { diff --git a/templates/themes/categories/info.php b/templates/themes/categories/info.php index 62d8f6bb..003d30a5 100644 --- a/templates/themes/categories/info.php +++ b/templates/themes/categories/info.php @@ -1,8 +1,8 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'Categories'; + $theme['name'] = \Categories::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Group-ordered, category-aware modification of the Frameset theme, with removable sidebar frame. @@ -11,44 +11,17 @@ Requires $config[\'categories\'].'; $theme['version'] = 'v0.3'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'Main HTML file', - 'name' => 'file_main', - 'type' => 'text', - 'default' => $config['file_index'], - 'comment' => '(eg. "index.html")' - ); + $theme['config'][] = ['title' => 'Main HTML file', 'name' => 'file_main', 'type' => 'text', 'default' => $config['file_index'], 'comment' => '(eg. "index.html")']; - $theme['config'][] = Array( - 'title' => 'Sidebar file', - 'name' => 'file_sidebar', - 'type' => 'text', - 'default' => 'sidebar.html', - 'comment' => '(eg. "sidebar.html")' - ); + $theme['config'][] = ['title' => 'Sidebar file', 'name' => 'file_sidebar', 'type' => 'text', 'default' => 'sidebar.html', 'comment' => '(eg. "sidebar.html")']; - $theme['config'][] = Array( - 'title' => 'News file', - 'name' => 'file_news', - 'type' => 'text', - 'default' => 'news.html', - 'comment' => '(eg. "news.html")' - ); + $theme['config'][] = ['title' => 'News file', 'name' => 'file_news', 'type' => 'text', 'default' => 'news.html', 'comment' => '(eg. "news.html")']; // Unique function name for building everything $theme['build_function'] = 'categories_build'; @@ -59,8 +32,8 @@ Requires $config[\'categories\'].'; global $config; if (!isset($config['categories'])) { - return Array(false, '<h2>Prerequisites not met!</h2>' . - 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.'); + return [false, '<h2>Prerequisites not met!</h2>' . + 'This theme requires $config[\'boards\'] and $config[\'categories\'] to be set.']; } } } diff --git a/templates/themes/categories/theme.php b/templates/themes/categories/theme.php index 1ccfe451..d76fd7fc 100644 --- a/templates/themes/categories/theme.php +++ b/templates/themes/categories/theme.php @@ -29,7 +29,7 @@ public static function homepage($settings) { global $config; - return Element('themes/categories/frames.html', Array('config' => $config, 'settings' => $settings)); + return Element('themes/categories/frames.html', ['config' => $config, 'settings' => $settings]); } // Build news page @@ -39,12 +39,7 @@ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); - return Element('themes/categories/news.html', Array( - 'settings' => $settings, - 'config' => $config, - 'news' => $news, - 'boardlist' => createBoardlist(false) - )); + return Element('themes/categories/news.html', ['settings' => $settings, 'config' => $config, 'news' => $news, 'boardlist' => createBoardlist(false)]); } // Build sidebar @@ -58,15 +53,11 @@ $title = boardTitle($board); if (!$title) $title = $board; // board doesn't exist, but for some reason you want to display it anyway - $board = Array('title' => $title, 'uri' => sprintf($config['board_path'], $board)); + $board = ['title' => $title, 'uri' => sprintf($config['board_path'], $board)]; } } - return Element('themes/categories/sidebar.html', Array( - 'settings' => $settings, - 'config' => $config, - 'categories' => $categories - )); + return Element('themes/categories/sidebar.html', ['settings' => $settings, 'config' => $config, 'categories' => $categories]); } }; diff --git a/templates/themes/donate/donate.html b/templates/themes/donate/donate.html index 955beaab..592b5a64 100644 --- a/templates/themes/donate/donate.html +++ b/templates/themes/donate/donate.html @@ -25,7 +25,7 @@ <h2>Thanks for donating</h2> <p>The server costs {{ settings.monthlyamount }} per month. If you buy stickers we get about 45-55% of whatever you spend. Historical donation records to the former owner are ForeverN2Dust is the top donator, giving about $3000. FOOFDOOF is #2 with $1000 and lots of cheap Chinese shit. Please specify what you'd like your money to go towards. If you don't want to buy stickers, but want to donate something else please either ask in /q/ or contact the Lainchan administration on IRC at #lainchan on Lainchan IRC at irc.lainchan.org or Freenode. </p> - <p>Stickermule shutdown their stickermarket place ages ago. So stickers are no longer avaliable for purchase. Lainstore is being slowly worked on but isn't finished yet. + <p>Stickermule shutdown their stickermarket place ages ago. So stickers are no longer avaliable for purcahse. Lainstore is being slowly worked on but isn't finished yet. </p> <p> <a href="/stickers.html">To view the sticker gallery click here </a> diff --git a/templates/themes/donate/info.php b/templates/themes/donate/info.php index ecb53154..6f5b725e 100644 --- a/templates/themes/donate/info.php +++ b/templates/themes/donate/info.php @@ -1,81 +1,4 @@ <?php -$theme = array( - 'name' => 'Donate', - 'description' => 'le wales face', - 'version' => 'v9001', - - 'config' => array( - array('title' => 'Page title', - 'name' => 'title', - 'type' => 'text'), - - array('title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)'), - - array('title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'donate.html'), - - array('title' => 'Monthly Amount', - 'name' => 'monthlyamount', - 'type' => 'text', - 'default' => '$0'), - - - array('title' => 'Current Sticker Amount', - 'name' => 'stickeramount', - 'type' => 'text', - 'default' => '$0'), - - array('title' => 'Current Other Donations Amount', - 'name' => 'otheramount', - 'type' => 'text', - 'default' => '$0'), - - array('title' => 'Current Bitcoin Amount', - 'name' => 'bitcoinamount', - 'type' => 'text', - 'default' => '0 BTC'), - - array('title' => 'Current Progress', - 'name' => 'currentprogress', - 'type' => 'text', - 'default' => '$0'), - - array('title' => 'Progress Bar CSS class', - 'name' => 'progressbarcssclass', - 'type' => 'text', - 'default' => 'progress-bar green glow'), - - - array('title' => 'Progress Bar CSS width', - 'name' => 'progressbarcsswidth', - 'type' => 'text', - 'default' => '15%'), - - array('title' => 'Progress Bar CSS left', - 'name' => 'progressbarcssleft', - 'type' => 'text', - 'default' => '51'), - - array('title' => 'Progress Bar Text CSS left', - 'name' => 'progressbartextcssleft', - 'type' => 'text', - 'default' => '195'), - - array('title' => 'Bitcoin receiving address', - 'name' => 'bitcoinreceivingaddress', - 'type' => 'text', - 'default' => 'nothing'), - - array('title' => 'Bitcoin receiving QR code ', - 'name' => 'bitcoinreceivingqrcode', - 'type' => 'text', - 'default' => 'nothing'), - ), - 'build_function' => 'donate_build'); +$theme = ['name' => 'Donate', 'description' => 'le wales face', 'version' => 'v9001', 'config' => [['title' => 'Page title', 'name' => 'title', 'type' => 'text'], ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)'], ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'donate.html'], ['title' => 'Monthly Amount', 'name' => 'monthlyamount', 'type' => 'text', 'default' => '$0'], ['title' => 'Current Sticker Amount', 'name' => 'stickeramount', 'type' => 'text', 'default' => '$0'], ['title' => 'Current Other Donations Amount', 'name' => 'otheramount', 'type' => 'text', 'default' => '$0'], ['title' => 'Current Bitcoin Amount', 'name' => 'bitcoinamount', 'type' => 'text', 'default' => '0 BTC'], ['title' => 'Current Progress', 'name' => 'currentprogress', 'type' => 'text', 'default' => '$0'], ['title' => 'Progress Bar CSS class', 'name' => 'progressbarcssclass', 'type' => 'text', 'default' => 'progress-bar green glow'], ['title' => 'Progress Bar CSS width', 'name' => 'progressbarcsswidth', 'type' => 'text', 'default' => '15%'], ['title' => 'Progress Bar CSS left', 'name' => 'progressbarcssleft', 'type' => 'text', 'default' => '51'], ['title' => 'Progress Bar Text CSS left', 'name' => 'progressbartextcssleft', 'type' => 'text', 'default' => '195'], ['title' => 'Bitcoin receiving address', 'name' => 'bitcoinreceivingaddress', 'type' => 'text', 'default' => 'nothing'], ['title' => 'Bitcoin receiving QR code ', 'name' => 'bitcoinreceivingqrcode', 'type' => 'text', 'default' => 'nothing']], 'build_function' => 'donate_build']; ?> diff --git a/templates/themes/donate/theme.php b/templates/themes/donate/theme.php index 736519a8..23acdb81 100644 --- a/templates/themes/donate/theme.php +++ b/templates/themes/donate/theme.php @@ -19,9 +19,7 @@ class donate { global $config; return Element('themes/donate/donate.html', - array('settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist())); + ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } } diff --git a/templates/themes/faq/info.php b/templates/themes/faq/info.php index c81d52ab..019eff88 100644 --- a/templates/themes/faq/info.php +++ b/templates/themes/faq/info.php @@ -1,35 +1,20 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'FAQ'; + $theme['name'] = \FAQ::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'FAQ because Lainons have questions'; $theme['version'] = 'v0.0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => "faq.html", - 'comment' => '(eg. "faq.html")' - ); + $theme['config'][] = ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => "faq.html", 'comment' => '(eg. "faq.html")']; // Unique function name for building everything diff --git a/templates/themes/faq/theme.php b/templates/themes/faq/theme.php index 28db35a2..18421482 100644 --- a/templates/themes/faq/theme.php +++ b/templates/themes/faq/theme.php @@ -22,11 +22,7 @@ // Build FAQ page public static function homepage($settings) { global $config; - return Element('themes/faq/index.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist(), - )); + return Element('themes/faq/index.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } }; diff --git a/templates/themes/frameset/info.php b/templates/themes/frameset/info.php index 8cff78a9..f19ea010 100644 --- a/templates/themes/frameset/info.php +++ b/templates/themes/frameset/info.php @@ -1,8 +1,8 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'Frameset'; + $theme['name'] = \Frameset::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Use a basic frameset layout, with a list of boards and pages on a sidebar to the left of the page. @@ -11,44 +11,17 @@ Users never have to leave the homepage; they can do all their browsing from the $theme['version'] = 'v0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'Main HTML file', - 'name' => 'file_main', - 'type' => 'text', - 'default' => $config['file_index'], - 'comment' => '(eg. "index.html")' - ); + $theme['config'][] = ['title' => 'Main HTML file', 'name' => 'file_main', 'type' => 'text', 'default' => $config['file_index'], 'comment' => '(eg. "index.html")']; - $theme['config'][] = Array( - 'title' => 'Sidebar file', - 'name' => 'file_sidebar', - 'type' => 'text', - 'default' => 'sidebar.html', - 'comment' => '(eg. "sidebar.html")' - ); + $theme['config'][] = ['title' => 'Sidebar file', 'name' => 'file_sidebar', 'type' => 'text', 'default' => 'sidebar.html', 'comment' => '(eg. "sidebar.html")']; - $theme['config'][] = Array( - 'title' => 'News file', - 'name' => 'file_news', - 'type' => 'text', - 'default' => 'news.html', - 'comment' => '(eg. "news.html")' - ); + $theme['config'][] = ['title' => 'News file', 'name' => 'file_news', 'type' => 'text', 'default' => 'news.html', 'comment' => '(eg. "news.html")']; // Unique function name for building everything $theme['build_function'] = 'frameset_build'; diff --git a/templates/themes/frameset/theme.php b/templates/themes/frameset/theme.php index ffab0538..996ee64e 100644 --- a/templates/themes/frameset/theme.php +++ b/templates/themes/frameset/theme.php @@ -29,7 +29,7 @@ public static function homepage($settings) { global $config; - return Element('themes/frameset/frames.html', Array('config' => $config, 'settings' => $settings)); + return Element('themes/frameset/frames.html', ['config' => $config, 'settings' => $settings]); } // Build news page @@ -39,22 +39,14 @@ $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC") or error(db_error()); $news = $query->fetchAll(PDO::FETCH_ASSOC); - return Element('themes/frameset/news.html', Array( - 'settings' => $settings, - 'config' => $config, - 'news' => $news - )); + return Element('themes/frameset/news.html', ['settings' => $settings, 'config' => $config, 'news' => $news]); } // Build sidebar public static function sidebar($settings) { global $config, $board; - return Element('themes/frameset/sidebar.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boards' => listBoards() - )); + return Element('themes/frameset/sidebar.html', ['settings' => $settings, 'config' => $config, 'boards' => listBoards()]); } }; diff --git a/templates/themes/irc/info.php b/templates/themes/irc/info.php index 8ca3be0a..2c46f3c0 100644 --- a/templates/themes/irc/info.php +++ b/templates/themes/irc/info.php @@ -1,38 +1,3 @@ <?php -$theme = array( - 'name' => 'IRC', - 'description' => 'Display a link to the lainchan irc', - 'version' => 'v1', - - 'config' => array( - array('title' => 'Page title', - 'name' => 'title', - 'type' => 'text'), - - array('title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)'), - - array('title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'irc.html'), - - array('title' => 'Channel', - 'name' => 'channel', - 'type' => 'text', - 'default' => 'general'), - - array('title' => 'Server', - 'name' => 'server', - 'type' => 'text', - 'default' => 'irc.lainchan.org'), - - array('title' => 'Port', - 'name' => 'port', - 'type' => 'text', - 'default' => '6697')), - - 'build_function' => 'irc_build'); +$theme = ['name' => 'IRC', 'description' => 'Display a link to the lainchan irc', 'version' => 'v1', 'config' => [['title' => 'Page title', 'name' => 'title', 'type' => 'text'], ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)'], ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'irc.html'], ['title' => 'Channel', 'name' => 'channel', 'type' => 'text', 'default' => 'general'], ['title' => 'Server', 'name' => 'server', 'type' => 'text', 'default' => 'irc.lainchan.org'], ['title' => 'Port', 'name' => 'port', 'type' => 'text', 'default' => '6697']], 'build_function' => 'irc_build']; ?> diff --git a/templates/themes/irc/theme.php b/templates/themes/irc/theme.php index c9b45c33..fd98a122 100644 --- a/templates/themes/irc/theme.php +++ b/templates/themes/irc/theme.php @@ -18,9 +18,7 @@ class irc { global $config; return Element('themes/irc/irc.html', - array('settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist())); + ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } } diff --git a/templates/themes/public_banlist/info.php b/templates/themes/public_banlist/info.php index 006ac38e..6f928d9a 100644 --- a/templates/themes/public_banlist/info.php +++ b/templates/themes/public_banlist/info.php @@ -1,5 +1,5 @@ <?php - $theme = Array(); + $theme = []; // Theme name $theme['name'] = 'Public Banlist'; @@ -10,23 +10,11 @@ copies the banlist interface from moderation panel.'; $theme['version'] = 'v0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'JSON feed file', - 'name' => 'file_json', - 'type' => 'text', - 'default' => 'bans.json', - 'comment' => '(eg. "bans.json")' - ); + $theme['config'][] = ['title' => 'JSON feed file', 'name' => 'file_json', 'type' => 'text', 'default' => 'bans.json', 'comment' => '(eg. "bans.json")']; - $theme['config'][] = Array( - 'title' => 'Main HTML file', - 'name' => 'file_bans', - 'type' => 'text', - 'default' => 'bans.html', - 'comment' => '(eg. "bans.html")' - ); + $theme['config'][] = ['title' => 'Main HTML file', 'name' => 'file_bans', 'type' => 'text', 'default' => 'bans.html', 'comment' => '(eg. "bans.html")']; // Unique function name for building everything $theme['build_function'] = 'pbanlist_build'; diff --git a/templates/themes/public_banlist/theme.php b/templates/themes/public_banlist/theme.php index d56a6481..3b27d764 100644 --- a/templates/themes/public_banlist/theme.php +++ b/templates/themes/public_banlist/theme.php @@ -25,7 +25,7 @@ public static function gen_json($settings) { ob_start(); - Bans::stream_json(false, true, true, array(), array("/\bcp\b/i", "/porn/i")); + Bans::stream_json(false, true, true, [], ["/\bcp\b/i", "/porn/i"]); $out = ob_get_contents(); ob_end_clean(); return $out; @@ -35,22 +35,16 @@ public static function homepage($settings) { global $config; - return Element('page.html', array( - 'config' => $config, - 'mod' => false, - #'hide_dashboard_link' => true, - 'title' => _("Ban list"), - 'subtitle' => "", - 'boardlist' => createBoardlist(), - #'nojavascript' => true, - 'body' => Element('mod/ban_list.html', array( - 'mod' => false, - 'boards' => "[]", - 'token' => false, - 'token_json' => false, - 'uri_json' => $config['dir']['home'] . $settings['file_json'], - )) - )); + return Element('page.html', [ + 'config' => $config, + 'mod' => false, + #'hide_dashboard_link' => true, + 'title' => _("Ban list"), + 'subtitle' => "", + 'boardlist' => createBoardlist(), + #'nojavascript' => true, + 'body' => Element('mod/ban_list.html', ['mod' => false, 'boards' => "[]", 'token' => false, 'token_json' => false, 'uri_json' => $config['dir']['home'] . $settings['file_json']]), + ]); } }; diff --git a/templates/themes/radio/info.php b/templates/themes/radio/info.php index 70be5c59..3432616d 100644 --- a/templates/themes/radio/info.php +++ b/templates/themes/radio/info.php @@ -1,58 +1,3 @@ <?php -$theme = array( - 'name' => 'Radio', - 'description' => 'Display a link to the lainchan radio', - 'version' => 'v1', - - 'config' => array( - array('title' => 'Page title', - 'name' => 'title', - 'type' => 'text'), - - array('title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)'), - - array('title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'radio.html'), - - array('title' => 'HTTP Prefix', - 'name' => 'httpprefix', - 'type' => 'text', - 'default' => ''), - - array('title' => 'Radio Status URL', - 'name' => 'radiostatus', - 'type' => 'text', - 'default' => '/radio_assets/status.xsl'), - - array('title' => 'Radio Prefix', - 'name' => 'radioprefix', - 'type' => 'text', - 'default' => ''), - - array('title' => 'Filelist Prefix', - 'name' => 'filelistprefix', - 'type' => 'text', - 'default' => ''), - - array('title' => 'Channels', - 'name' => 'channels', - 'type' => 'text', - 'default' => 'everything cyberia swing'), - - array('title' => 'Default Channel', - 'name' => 'defaultchannel', - 'type' => 'text', - 'default' => 'everything'), - - array('title' => 'formats', - 'name' => 'formats', - 'type' => 'text', - 'default' => 'mp3 ogg'), - ), - 'build_function' => 'radio_build'); +$theme = ['name' => 'Radio', 'description' => 'Display a link to the lainchan radio', 'version' => 'v1', 'config' => [['title' => 'Page title', 'name' => 'title', 'type' => 'text'], ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)'], ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'radio.html'], ['title' => 'HTTP Prefix', 'name' => 'httpprefix', 'type' => 'text', 'default' => ''], ['title' => 'Radio Status URL', 'name' => 'radiostatus', 'type' => 'text', 'default' => '/radio_assets/status.xsl'], ['title' => 'Radio Prefix', 'name' => 'radioprefix', 'type' => 'text', 'default' => ''], ['title' => 'Filelist Prefix', 'name' => 'filelistprefix', 'type' => 'text', 'default' => ''], ['title' => 'Channels', 'name' => 'channels', 'type' => 'text', 'default' => 'everything cyberia swing'], ['title' => 'Default Channel', 'name' => 'defaultchannel', 'type' => 'text', 'default' => 'everything'], ['title' => 'formats', 'name' => 'formats', 'type' => 'text', 'default' => 'mp3 ogg']], 'build_function' => 'radio_build']; ?> diff --git a/templates/themes/radio/theme.php b/templates/themes/radio/theme.php index e1244e6f..fafb51a0 100644 --- a/templates/themes/radio/theme.php +++ b/templates/themes/radio/theme.php @@ -18,9 +18,7 @@ class radio { global $config; return Element('themes/radio/radio.html', - array('settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist())); + ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } } diff --git a/templates/themes/rand/info.php b/templates/themes/rand/info.php index c226e2e4..833c0c78 100644 --- a/templates/themes/rand/info.php +++ b/templates/themes/rand/info.php @@ -1,5 +1,5 @@ <?php - $theme = array(); + $theme = []; // Theme name $theme['name'] = 'Random Overboard'; @@ -8,39 +8,13 @@ $theme['version'] = 'v0.2'; // Theme configuration - $theme['config'] = array(); + $theme['config'] = []; - $theme['config'][] = array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Random' - ); - $theme['config'][] = array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '.', - 'comment' => '(rand for example)' - ); - $theme['config'][] = array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' - ); - $theme['config'][] = array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)' - ); - $theme['config'][] = array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ); + $theme['config'][] = ['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Random']; + $theme['config'][] = ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '.', 'comment' => '(rand for example)']; + $theme['config'][] = ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")']; + $theme['config'][] = ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)']; + $theme['config'][] = ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15']; // Unique function name for building everything $theme['build_function'] = 'rand_build'; $theme['install_callback'] = 'rand_install'; diff --git a/templates/themes/rand/theme.php b/templates/themes/rand/theme.php index e3814c4e..14a78b59 100644 --- a/templates/themes/rand/theme.php +++ b/templates/themes/rand/theme.php @@ -6,7 +6,7 @@ $rand->settings = $settings; file_write($settings['uri'] . '/index.html', $rand->build()); - file_write($settings['uri'] . '/rand.js', Element('themes/rand/rand.js', array())); + file_write($settings['uri'] . '/rand.js', Element('themes/rand/rand.js', [])); } class rand { @@ -16,17 +16,12 @@ $boards = listBoards(); $body = ''; - $overflow = array(); - $board = array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'name' => $this->settings['title'], - 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) - ); + $overflow = []; + $board = ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])]; $query = ''; foreach($boards as &$_board) { - if(in_array($_board['uri'], explode(' ', $this->settings['exclude']))) + if(in_array($_board['uri'], explode(' ', (string) $this->settings['exclude']))) continue; $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); } @@ -34,7 +29,7 @@ $query = query($query) or error(db_error()); $count = 0; - $threads = array(); + $threads = []; while($post = $query->fetch()) { if(!isset($threads[$post['board']])) { @@ -81,23 +76,16 @@ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; } - $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } $count += 1; } - $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script> var overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/rand.js"></script>'; - return Element('index.html', array( - 'config' => $config, - 'board' => $board, - 'no_post_form' => true, - 'body' => $body, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - )); + return Element('index.html', ['config' => $config, 'board' => $board, 'no_post_form' => true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod)]); } }; diff --git a/templates/themes/recent/info.php b/templates/themes/recent/info.php index bea3513c..188f9dfe 100644 --- a/templates/themes/recent/info.php +++ b/templates/themes/recent/info.php @@ -1,76 +1,30 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'RecentPosts'; + $theme['name'] = \RecentPosts::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Show recent posts and images, like 4chan.'; $theme['version'] = 'v1.0'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Title', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Recent Posts' - ); + $theme['config'][] = ['title' => 'Title', 'name' => 'title', 'type' => 'text', 'default' => 'Recent Posts']; - $theme['config'][] = Array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)' - ); + $theme['config'][] = ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)']; - $theme['config'][] = Array( - 'title' => '# of recent images', - 'name' => 'limit_images', - 'type' => 'text', - 'default' => '3', - 'comment' => '(maximum images to display)' - ); + $theme['config'][] = ['title' => '# of recent images', 'name' => 'limit_images', 'type' => 'text', 'default' => '3', 'comment' => '(maximum images to display)']; - $theme['config'][] = Array( - 'title' => '# of recent posts', - 'name' => 'limit_posts', - 'type' => 'text', - 'default' => '30', - 'comment' => '(maximum posts to display)' - ); + $theme['config'][] = ['title' => '# of recent posts', 'name' => 'limit_posts', 'type' => 'text', 'default' => '30', 'comment' => '(maximum posts to display)']; - $theme['config'][] = Array( - 'title' => 'HTML file', - 'name' => 'html', - 'type' => 'text', - 'default' => 'recent.html', - 'comment' => '(eg. "recent.html")' - ); + $theme['config'][] = ['title' => 'HTML file', 'name' => 'html', 'type' => 'text', 'default' => 'recent.html', 'comment' => '(eg. "recent.html")']; - $theme['config'][] = Array( - 'title' => 'CSS file', - 'name' => 'css', - 'type' => 'text', - 'default' => 'recent.css', - 'comment' => '(eg. "recent.css")' - ); + $theme['config'][] = ['title' => 'CSS file', 'name' => 'css', 'type' => 'text', 'default' => 'recent.css', 'comment' => '(eg. "recent.css")']; - $theme['config'][] = Array( - 'title' => 'CSS stylesheet name', - 'name' => 'basecss', - 'type' => 'text', - 'default' => 'recent.css', - 'comment' => '(eg. "recent.css" - see templates/themes/recent for details)' - ); + $theme['config'][] = ['title' => 'CSS stylesheet name', 'name' => 'basecss', 'type' => 'text', 'default' => 'recent.css', 'comment' => '(eg. "recent.css" - see templates/themes/recent for details)']; - $theme['config'][] = Array( - 'title' => '# of recent news', - 'name' => 'limit_news', - 'type' => 'text', - 'default' => '1', - 'comment' => '(maximum news to display)' - ); + $theme['config'][] = ['title' => '# of recent news', 'name' => 'limit_news', 'type' => 'text', 'default' => '1', 'comment' => '(maximum news to display)']; // Unique function name for building everything $theme['build_function'] = 'recentposts_build'; $theme['install_callback'] = 'recentposts_install'; @@ -78,11 +32,11 @@ if (!function_exists('recentposts_install')) { function recentposts_install($settings) { if (!is_numeric($settings['limit_news']) || $settings['limit_news'] < 0) - return Array(false, '<strong>' . utf8tohtml($settings['limit_news']) . '</strong> is not a non-negative integer.'); + return [false, '<strong>' . utf8tohtml($settings['limit_news']) . '</strong> is not a non-negative integer.']; if (!is_numeric($settings['limit_images']) || $settings['limit_images'] < 0) - return Array(false, '<strong>' . utf8tohtml($settings['limit_images']) . '</strong> is not a non-negative integer.'); + return [false, '<strong>' . utf8tohtml($settings['limit_images']) . '</strong> is not a non-negative integer.']; if (!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) - return Array(false, '<strong>' . utf8tohtml($settings['limit_posts']) . '</strong> is not a non-negative integer.'); + return [false, '<strong>' . utf8tohtml($settings['limit_posts']) . '</strong> is not a non-negative integer.']; } } diff --git a/templates/themes/recent/theme.php b/templates/themes/recent/theme.php index ecc3adfb..e51061db 100644 --- a/templates/themes/recent/theme.php +++ b/templates/themes/recent/theme.php @@ -22,10 +22,10 @@ copy('templates/themes/recent/' . $settings['basecss'], $config['dir']['home'] . "stylesheets/" . $settings['css']); } - $this->excluded = explode(' ', $settings['exclude']); + $this->excluded = explode(' ', (string) $settings['exclude']); if ($action == 'all' || $action == 'post' || $action == 'post-thread' || $action == 'post-delete') { - $action = generation_strategy('sb_recent', array()); + $action = generation_strategy('sb_recent', []); if ($action == 'delete') { file_unlink($config['dir']['home'] . $settings['html']); } @@ -37,11 +37,12 @@ // Build news page public function homepage($settings) { - global $config, $board; + $files = []; + global $config, $board; - $recent_images = Array(); - $recent_posts = Array(); - $stats = Array(); + $recent_images = []; + $recent_posts = []; + $stats = []; $boards = listBoards(); @@ -63,7 +64,7 @@ openBoard($post['board']); if (isset($post['files'])) - $files = json_decode($post['files']); + $files = json_decode((string) $post['files'], null, 512, JSON_THROW_ON_ERROR); if ($files[0]->file == 'deleted' || $files[0]->thumb == 'file') continue; @@ -145,22 +146,14 @@ $files = $query->fetchAll(); $stats['active_content'] = 0; foreach ($files as &$file) { - preg_match_all('/"size":([0-9]*)/', $file[0], $matches); + preg_match_all('/"size":([0-9]*)/', (string) $file[0], $matches); $stats['active_content'] += array_sum($matches[1]); } $query = query("SELECT * FROM ``news`` ORDER BY `time` DESC" . ($settings['limit_news'] ? ' LIMIT ' . $settings['limit_news'] : '')) or error(db_error()); $recent_news = $query->fetchAll(PDO::FETCH_ASSOC); - return Element('themes/recent/recent.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist(), - 'recent_images' => $recent_images, - 'recent_posts' => $recent_posts, - 'stats' => $stats, - 'recent_news' => $recent_news, - )); + return Element('themes/recent/recent.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist(), 'recent_images' => $recent_images, 'recent_posts' => $recent_posts, 'stats' => $stats, 'recent_news' => $recent_news]); } }; diff --git a/templates/themes/rss/info.php b/templates/themes/rss/info.php index 4da43bf0..62832341 100755 --- a/templates/themes/rss/info.php +++ b/templates/themes/rss/info.php @@ -1,5 +1,5 @@ <?php - $theme = Array(); + $theme = []; // Theme name $theme['name'] = 'RSS'; @@ -8,59 +8,21 @@ $theme['version'] = 'v0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Title', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Recent Posts RSS' - ); + $theme['config'][] = ['title' => 'Title', 'name' => 'title', 'type' => 'text', 'default' => 'Recent Posts RSS']; - $theme['config'][] = Array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)' - ); + $theme['config'][] = ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)']; - $theme['config'][] = Array( - 'title' => '# of recent posts', - 'name' => 'limit_posts', - 'type' => 'text', - 'default' => '30', - 'comment' => '(maximum posts to display)' - ); + $theme['config'][] = ['title' => '# of recent posts', 'name' => 'limit_posts', 'type' => 'text', 'default' => '30', 'comment' => '(maximum posts to display)']; - $theme['config'][] = Array( - 'title' => 'XML file', - 'name' => 'xml', - 'type' => 'text', - 'default' => 'recent.xml', - 'comment' => '(eg. "recent.xml")' - ); + $theme['config'][] = ['title' => 'XML file', 'name' => 'xml', 'type' => 'text', 'default' => 'recent.xml', 'comment' => '(eg. "recent.xml")']; - $theme['config'][] = Array( - 'title' => 'Base URL', - 'name' => 'base_url', - 'type' => 'text', - 'default' => 'http://test.com', - 'comment' => '(eg. "http://test.com")' - ); + $theme['config'][] = ['title' => 'Base URL', 'name' => 'base_url', 'type' => 'text', 'default' => 'http://test.com', 'comment' => '(eg. "http://test.com")']; - $theme['config'][] = Array( - 'title' => 'Show Threads Only', - 'name' => 'show_threads_only', - 'type' => 'text', - 'default' => 'false', - ); + $theme['config'][] = ['title' => 'Show Threads Only', 'name' => 'show_threads_only', 'type' => 'text', 'default' => 'false']; - $theme['config'][] = Array( - 'title' => 'Enable Per Board', - 'name' => 'enable_per_board', - 'type' => 'text', - 'default' => 'false', - ); + $theme['config'][] = ['title' => 'Enable Per Board', 'name' => 'enable_per_board', 'type' => 'text', 'default' => 'false']; // Unique function name for building everything $theme['build_function'] = 'rss_recentposts_build'; @@ -69,7 +31,7 @@ if (!function_exists('rss_recentposts_install')) { function rss_recentposts_install($settings) { if (!is_numeric($settings['limit_posts']) || $settings['limit_posts'] < 0) - return Array(false, '<strong>' . utf8tohtml($settings['limit_posts']) . '</strong> is not a non-negative integer.'); + return [false, '<strong>' . utf8tohtml($settings['limit_posts']) . '</strong> is not a non-negative integer.']; } } diff --git a/templates/themes/rss/theme.php b/templates/themes/rss/theme.php index 4b0c86a5..9549559d 100755 --- a/templates/themes/rss/theme.php +++ b/templates/themes/rss/theme.php @@ -19,7 +19,7 @@ global $config, $_theme,$board; - $this->excluded = explode(' ', $settings['exclude']); + $this->excluded = explode(' ', (string) $settings['exclude']); if ($settings['show_threads_only'] == 'true'){ if ($action == 'all' || $action == 'post-thread' || $action == 'post-delete') file_write($config['dir']['home'] . $settings['xml'], $this->site_rsspage($settings)); @@ -68,7 +68,7 @@ public function site_rsspage($settings) { global $config, $board; - $recent_posts = Array(); + $recent_posts = []; $boards = listBoards(); @@ -89,7 +89,7 @@ while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); - $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; + $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ?: $post['id'])) . '#' . $post['id']; $post['snippet'] = pm_snippet($post['body'], 30); $post['board_name'] = $board['name']; @@ -97,18 +97,14 @@ } - return Element('themes/rss/rss.xml', Array( - 'settings' => $settings, - 'config' => $config, - 'recent_posts' => $recent_posts, - )); + return Element('themes/rss/rss.xml', ['settings' => $settings, 'config' => $config, 'recent_posts' => $recent_posts]); } // Build news page public function board_rsspage($settings,$_board) { global $config, $board; - $recent_posts = Array(); + $recent_posts = []; $query = ''; if ($settings['show_threads_only'] == 'true'){ @@ -123,7 +119,7 @@ while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); - $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; + $post['link'] = $config['root'] . $board['dir'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ?: $post['id'])) . '#' . $post['id']; $post['snippet'] = pm_snippet($post['body'], 30); $post['board_name'] = $board['name']; @@ -131,18 +127,14 @@ } - return Element('themes/rss/rss.xml', Array( - 'settings' => $settings, - 'config' => $config, - 'recent_posts' => $recent_posts, - )); + return Element('themes/rss/rss.xml', ['settings' => $settings, 'config' => $config, 'recent_posts' => $recent_posts]); } // Build news page public function overboard_rsspage($settings,$overboard) { global $config, $board; - $recent_posts = Array(); + $recent_posts = []; $boards = listBoards(); @@ -178,7 +170,7 @@ while ($post = $query->fetch(PDO::FETCH_ASSOC)) { openBoard($post['board']); - $post['link'] = $config['root'] . $post['board'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ? $post['thread'] : $post['id'])) . '#' . $post['id']; + $post['link'] = $config['root'] . $post['board'] . $config['dir']['res'] . sprintf($config['file_page'], ($post['thread'] ?: $post['id'])) . '#' . $post['id']; $post['snippet'] = pm_snippet($post['body'], 30); $post['board_name'] = $post['board']; @@ -186,11 +178,7 @@ } - return Element('themes/rss/rss.xml', Array( - 'settings' => $settings, - 'config' => $config, - 'recent_posts' => $recent_posts, - )); + return Element('themes/rss/rss.xml', ['settings' => $settings, 'config' => $config, 'recent_posts' => $recent_posts]); } }; diff --git a/templates/themes/rules/info.php b/templates/themes/rules/info.php index 7faaedc6..31f42d79 100755 --- a/templates/themes/rules/info.php +++ b/templates/themes/rules/info.php @@ -1,23 +1,3 @@ <?php -$theme = array( - 'name' => 'Rules', - 'description' => 'Display the lainchan rules', - 'version' => 'v1', - - 'config' => array( - array('title' => 'Page title', - 'name' => 'title', - 'type' => 'text'), - - array('title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)'), - - array('title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'rules.html')), - - 'build_function' => 'rules_build'); +$theme = ['name' => 'Rules', 'description' => 'Display the lainchan rules', 'version' => 'v1', 'config' => [['title' => 'Page title', 'name' => 'title', 'type' => 'text'], ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)'], ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'rules.html']], 'build_function' => 'rules_build']; ?>
\ No newline at end of file diff --git a/templates/themes/rules/theme.php b/templates/themes/rules/theme.php index fc50437f..457f4067 100755 --- a/templates/themes/rules/theme.php +++ b/templates/themes/rules/theme.php @@ -19,10 +19,8 @@ class rules { global $config; return Element('themes/rules/rules.html', - array('settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist())); + ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } } -?>
\ No newline at end of file +?> diff --git a/templates/themes/semirand/info.php b/templates/themes/semirand/info.php index 8590a205..ddf4c08d 100644 --- a/templates/themes/semirand/info.php +++ b/templates/themes/semirand/info.php @@ -1,64 +1,18 @@ <?php // Basic theme properties - $theme = array( - 'name' => 'Mixed All/Random Overboard', - // Description (you can use Tinyboard markup here) - 'description' => 'Board with threads from all boards with most recently bumped and random ones intermixed', - 'version' => 'v0.1', - // Unique function name for building and installing whatever's necessary - 'build_function' => 'semirand_build', - 'install_callback' => 'semirand_install', - ); + $theme = [ + 'name' => 'Mixed All/Random Overboard', + // Description (you can use Tinyboard markup here) + 'description' => 'Board with threads from all boards with most recently bumped and random ones intermixed', + 'version' => 'v0.1', + // Unique function name for building and installing whatever's necessary + 'build_function' => 'semirand_build', + 'install_callback' => 'semirand_install', + ]; // Theme configuration - $theme['config'] = array( - array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Semirandom', - ), - array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '.', - 'comment' => '("mixed", for example)', - ), - array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit, for example "%s coolest threads")', - ), - array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)', - ), - array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ), - array( - 'title' => 'Random threads', - 'name' => 'random_count', - 'comment' => '(number of consecutive random threads)', - 'type' => 'text', - 'default' => '1', - ), - array( - 'title' => 'Bumped threads', - 'name' => 'recent_count', - 'comment' => '(number of consecutive recent threads)', - 'type' => 'text', - 'default' => '1', - ), - ); + $theme['config'] = [['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Semirandom'], ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '.', 'comment' => '("mixed", for example)'], ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit, for example "%s coolest threads")'], ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)'], ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15'], ['title' => 'Random threads', 'name' => 'random_count', 'comment' => '(number of consecutive random threads)', 'type' => 'text', 'default' => '1'], ['title' => 'Bumped threads', 'name' => 'recent_count', 'comment' => '(number of consecutive recent threads)', 'type' => 'text', 'default' => '1']]; if (!function_exists('semirand_install')) { function semirand_install($settings) { diff --git a/templates/themes/semirand/theme.php b/templates/themes/semirand/theme.php index e8d3e56c..ba93f87a 100644 --- a/templates/themes/semirand/theme.php +++ b/templates/themes/semirand/theme.php @@ -23,7 +23,7 @@ // Copy the generated board HTML to its place file_write($settings['uri'] . '/index.html', $semirand->build()); file_write($settings['uri'] . '/semirand.js', - Element('themes/semirand/semirand.js', array())); + Element('themes/semirand/semirand.js', [])); } } @@ -48,7 +48,7 @@ error('Invalid configuration parameters.', true); } - $settings['exclude'] = explode(' ', $settings['exclude']); + $settings['exclude'] = explode(' ', (string) $settings['exclude']); $settings['thread_limit'] = intval($settings['thread_limit']); $settings['random_count'] = intval($settings['random_count']); $settings['recent_count'] = intval($settings['recent_count']); @@ -101,10 +101,10 @@ private function shuffleThreads($threads) { $random_count = $this->settings['random_count']; $recent_count = $this->settings['recent_count']; - $total = count($threads); + $total = is_countable($threads) ? count($threads) : 0; // Storage for threads that will be randomly interspersed - $shuffled = array(); + $shuffled = []; // Ratio of bumped / all threads $topRatio = $recent_count / ($recent_count + $random_count); @@ -148,9 +148,7 @@ } // Count the number of omitted image replies - $omitted_img_count = count(array_filter($replies, function($p) { - return $p['files'] !== ''; - })); + $omitted_img_count = count(array_filter($replies, fn($p) => $p['files'] !== '')); // Set the corresponding omitted numbers on the thread if (!empty($replies)) { @@ -178,16 +176,16 @@ global $config; $html = ''; - $overflow = array(); + $overflow = []; // Fetch threads from all boards and chomp the first 'n' posts, depending // on the setting $threads = $this->shuffleThreads($this->fetchThreads()); - $total_count = count($threads); + $total_count = is_countable($threads) ? count($threads) : 0; // Top threads displayed on load $top_threads = array_splice($threads, 0, $this->settings['thread_limit']); // Number of processed threads by board - $counts = array(); + $counts = []; // Output threads up to the specified limit foreach ($top_threads as $post) { @@ -212,30 +210,14 @@ if ($board_page > 0) { $page = $board_page + 1; } - $overflow[] = array( - 'id' => $post['id'], - 'board' => $post['board'], - 'page' => $page . '.html' - ); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } - $html .= '<script>var ukko_overflow = ' . json_encode($overflow) . '</script>'; + $html .= '<script>var ukko_overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $html .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/semirand.js"></script>'; - return Element('index.html', array( - 'config' => $config, - 'board' => array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'title' => $this->settings['title'], - 'subtitle' => str_replace('%s', $this->settings['thread_limit'], - strval(min($this->settings['subtitle'], $total_count))), - ), - 'no_post_form' => true, - 'body' => $html, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - )); + return Element('index.html', ['config' => $config, 'board' => ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'title' => $this->settings['title'], 'subtitle' => str_replace('%s', $this->settings['thread_limit'], + strval(min($this->settings['subtitle'], $total_count)))], 'no_post_form' => true, 'body' => $html, 'mod' => $mod, 'boardlist' => createBoardlist($mod)]); } }; diff --git a/templates/themes/sitemap/info.php b/templates/themes/sitemap/info.php index 0ea2ba9d..058bed4d 100644 --- a/templates/themes/sitemap/info.php +++ b/templates/themes/sitemap/info.php @@ -1,5 +1,5 @@ <?php - $theme = Array(); + $theme = []; // Theme name $theme['name'] = 'Sitemap Generator'; @@ -8,55 +8,21 @@ $theme['version'] = 'v1.0'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Sitemap Path', - 'name' => 'path', - 'type' => 'text', - 'default' => 'sitemap.xml', - 'size' => '20' - ); + $theme['config'][] = ['title' => 'Sitemap Path', 'name' => 'path', 'type' => 'text', 'default' => 'sitemap.xml', 'size' => '20']; - $theme['config'][] = Array( - 'title' => 'URL prefix', - 'name' => 'url', - 'type' => 'text', - 'comment' => '(with trailing slash)', - 'default' => (isset($_SERVER['HTTP_HOST']) ? 'http://' . $_SERVER['HTTP_HOST'] . $config['root'] : ''), - 'size' => '20' - ); + $theme['config'][] = ['title' => 'URL prefix', 'name' => 'url', 'type' => 'text', 'comment' => '(with trailing slash)', 'default' => (isset($_SERVER['HTTP_HOST']) ? 'http://' . $_SERVER['HTTP_HOST'] . $config['root'] : ''), 'size' => '20']; - $theme['config'][] = Array( - 'title' => 'Thread change frequency', - 'name' => 'changefreq', - 'type' => 'text', - 'comment' => '(eg. "hourly", "daily", etc.)', - 'default' => 'hourly', - 'size' => '20' - ); + $theme['config'][] = ['title' => 'Thread change frequency', 'name' => 'changefreq', 'type' => 'text', 'comment' => '(eg. "hourly", "daily", etc.)', 'default' => 'hourly', 'size' => '20']; - $theme['config'][] = Array( - 'title' => 'Minimum time between regenerating', - 'name' => 'regen_time', - 'type' => 'text', - 'comment' => '(in seconds)', - 'default' => '0', - 'size' => '8' - ); + $theme['config'][] = ['title' => 'Minimum time between regenerating', 'name' => 'regen_time', 'type' => 'text', 'comment' => '(in seconds)', 'default' => '0', 'size' => '8']; $__boards = listBoards(); - $__default_boards = Array(); + $__default_boards = []; foreach ($__boards as $__board) $__default_boards[] = $__board['uri']; - $theme['config'][] = Array( - 'title' => 'Boards', - 'name' => 'boards', - 'type' => 'text', - 'comment' => '(boards to include; space seperated)', - 'size' => 24, - 'default' => implode(' ', $__default_boards) - ); + $theme['config'][] = ['title' => 'Boards', 'name' => 'boards', 'type' => 'text', 'comment' => '(boards to include; space seperated)', 'size' => 24, 'default' => implode(' ', $__default_boards)]; $theme['build_function'] = 'sitemap_build'; diff --git a/templates/themes/sitemap/theme.php b/templates/themes/sitemap/theme.php index 6bc035bb..a04b9f7c 100644 --- a/templates/themes/sitemap/theme.php +++ b/templates/themes/sitemap/theme.php @@ -23,26 +23,21 @@ } } - $action = generation_strategy('sb_sitemap', array()); + $action = generation_strategy('sb_sitemap', []); if ($action == 'delete') { file_unlink($settings['path']); } elseif ($action == 'rebuild') { - $boards = explode(' ', $settings['boards']); + $boards = explode(' ', (string) $settings['boards']); - $threads = array(); + $threads = []; foreach ($boards as $board) { $query = query(sprintf("SELECT `id`, `id` AS `thread_id`, `slug`, (SELECT `time` FROM ``posts_%s`` WHERE `thread` = `thread_id` OR `id` = `thread_id` ORDER BY `time` DESC LIMIT 1) AS `lastmod` FROM ``posts_%s`` WHERE `thread` IS NULL", $board, $board)) or error(db_error()); $threads[$board] = $query->fetchAll(PDO::FETCH_ASSOC); } - file_write($settings['path'], Element('themes/sitemap/sitemap.xml', Array( - 'settings' => $settings, - 'config' => $config, - 'threads' => $threads, - 'boards' => $boards, - ))); + file_write($settings['path'], Element('themes/sitemap/sitemap.xml', ['settings' => $settings, 'config' => $config, 'threads' => $threads, 'boards' => $boards])); } } diff --git a/templates/themes/staffapplication/info.php b/templates/themes/staffapplication/info.php index a8093093..64915b38 100644 --- a/templates/themes/staffapplication/info.php +++ b/templates/themes/staffapplication/info.php @@ -1,35 +1,20 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'StaffApplication'; + $theme['name'] = \StaffApplication::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Staff Application theme.'; $theme['version'] = 'v0.0.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => $config['file_index'], - 'comment' => '(eg. "index.html")' - ); + $theme['config'][] = ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => $config['file_index'], 'comment' => '(eg. "index.html")']; // Unique function name for building everything $theme['build_function'] = 'staffapplication_build'; diff --git a/templates/themes/staffapplication/staffapplicationpost.php b/templates/themes/staffapplication/staffapplicationpost.php index 0e1b14ca..4d850cc2 100644 --- a/templates/themes/staffapplication/staffapplicationpost.php +++ b/templates/themes/staffapplication/staffapplicationpost.php @@ -43,12 +43,6 @@ $displaymessage = "<p style=\"text-align:center;\">ANTISPAM NOT SET</p>\r\n"; } $displaymessage .= '<span style="text-align:center; display: block;" >[ <a href="https://lainchan.org/"> Return Home </a> ]</span>'; -echo Element('page.html', array( - 'index' => $config['root'], - 'title' => _('Staff Application'), - 'config' => $config, - 'boardlist' => createBoardlist(isset($mod) ? $mod : false), - 'body' => $displaymessage, - ) +echo Element('page.html', ['index' => $config['root'], 'title' => _('Staff Application'), 'config' => $config, 'boardlist' => createBoardlist($mod ?? false), 'body' => $displaymessage] ); ?> diff --git a/templates/themes/staffapplication/theme.php b/templates/themes/staffapplication/theme.php index a827a7f8..e94e09b7 100644 --- a/templates/themes/staffapplication/theme.php +++ b/templates/themes/staffapplication/theme.php @@ -24,11 +24,7 @@ public static function htmlpage($settings) { global $config; - return Element('themes/staffapplication/staffapplication.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist() - )); + return Element('themes/staffapplication/staffapplication.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } public static function phppage($settings) { global $config; diff --git a/templates/themes/stream/info.php b/templates/themes/stream/info.php index d522032d..b0f67492 100644 --- a/templates/themes/stream/info.php +++ b/templates/themes/stream/info.php @@ -1,92 +1,32 @@ <?php - $theme = Array(); + $theme = []; // Theme name - $theme['name'] = 'Stream'; + $theme['name'] = \Stream::class; // Description (you can use Tinyboard markup here) $theme['description'] = 'Stream page'; $theme['version'] = 'v0.9.1'; // Theme configuration - $theme['config'] = Array(); + $theme['config'] = []; - $theme['config'][] = Array( - 'title' => 'Site title', - 'name' => 'title', - 'type' => 'text' - ); + $theme['config'][] = ['title' => 'Site title', 'name' => 'title', 'type' => 'text']; - $theme['config'][] = Array( - 'title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)' - ); + $theme['config'][] = ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)']; - $theme['config'][] = Array( - 'title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'stream.html', - 'comment' => '(eg. "stream.html")' - ); - $theme['config'][] = Array( - 'title' => 'OGV stream URL', - 'name' => 'ogvurl', - 'type' => 'text', - 'default' => 'https://lainchan.org/icecast/lainstream.ogg' - ); - $theme['config'][] = Array( - 'title' => 'RTMP stream URL', - 'name' => 'rtmpurl', - 'type' => 'text', - 'default' => 'rtmp://lainchan.org/show/stream' - ); - $theme['config'][] = Array( - 'title' => 'RTMP Video.JS stream URL', - 'name' => 'rtmpvideojsurl', - 'type' => 'text', - 'default' => 'rtmp://lainchan.org/show/&stream' - ); + $theme['config'][] = ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'stream.html', 'comment' => '(eg. "stream.html")']; + $theme['config'][] = ['title' => 'OGV stream URL', 'name' => 'ogvurl', 'type' => 'text', 'default' => 'https://lainchan.org/icecast/lainstream.ogg']; + $theme['config'][] = ['title' => 'RTMP stream URL', 'name' => 'rtmpurl', 'type' => 'text', 'default' => 'rtmp://lainchan.org/show/stream']; + $theme['config'][] = ['title' => 'RTMP Video.JS stream URL', 'name' => 'rtmpvideojsurl', 'type' => 'text', 'default' => 'rtmp://lainchan.org/show/&stream']; - $theme['config'][] = Array( - 'title' => 'RTMP HLS stream URL', - 'name' => 'hlsurl', - 'type' => 'text', - 'default' => 'https://lainchan.org:8080/hls/stream.m3u8' - ); + $theme['config'][] = ['title' => 'RTMP HLS stream URL', 'name' => 'hlsurl', 'type' => 'text', 'default' => 'https://lainchan.org:8080/hls/stream.m3u8']; - $theme['config'][] = Array( - 'title' => 'OGV Status URL', - 'name' => 'ogvstatus', - 'type' => 'text', - 'default' => '/radio_assets/status.xsl' - ); + $theme['config'][] = ['title' => 'OGV Status URL', 'name' => 'ogvstatus', 'type' => 'text', 'default' => '/radio_assets/status.xsl']; - $theme['config'][] = Array( - 'title' => 'RTMP Status URL', - 'name' => 'rtmpstatus', - 'type' => 'text', - 'default' => '/live/status?app=live&name=stream' - ); - $theme['config'][] = Array( - 'title' => 'RTMP Viewers URL', - 'name' => 'rtmpviewers', - 'type' => 'text', - 'default' => '/live/subs?app=live&name=stream' - ); - $theme['config'][] = Array( - 'title' => 'Formats', - 'name' => 'formats', - 'type' => 'text', - 'default' => 'hls ogg rtmp' - ); - $theme['config'][] = Array( - 'title' => 'Default Format', - 'name' => 'defaultformat', - 'type' => 'text', - 'default' => 'hls ogg rtmp' - ); + $theme['config'][] = ['title' => 'RTMP Status URL', 'name' => 'rtmpstatus', 'type' => 'text', 'default' => '/live/status?app=live&name=stream']; + $theme['config'][] = ['title' => 'RTMP Viewers URL', 'name' => 'rtmpviewers', 'type' => 'text', 'default' => '/live/subs?app=live&name=stream']; + $theme['config'][] = ['title' => 'Formats', 'name' => 'formats', 'type' => 'text', 'default' => 'hls ogg rtmp']; + $theme['config'][] = ['title' => 'Default Format', 'name' => 'defaultformat', 'type' => 'text', 'default' => 'hls ogg rtmp']; // Unique function name for building everything diff --git a/templates/themes/stream/theme.php b/templates/themes/stream/theme.php index 6d11a0dc..d37ceca9 100644 --- a/templates/themes/stream/theme.php +++ b/templates/themes/stream/theme.php @@ -23,11 +23,7 @@ global $config; - return Element('themes/stream/stream.html', Array( - 'settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist(), - )); + return Element('themes/stream/stream.html', ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } }; diff --git a/templates/themes/ukko/info.php b/templates/themes/ukko/info.php index 9a0a53e6..f9b27520 100644 --- a/templates/themes/ukko/info.php +++ b/templates/themes/ukko/info.php @@ -1,5 +1,5 @@ <?php - $theme = array(); + $theme = []; // Theme name $theme['name'] = 'Overboard (Ukko)'; @@ -8,39 +8,13 @@ $theme['version'] = 'v0.2'; // Theme configuration - $theme['config'] = array(); + $theme['config'] = []; - $theme['config'][] = array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Ukko' - ); - $theme['config'][] = array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '*', - 'comment' => '(ukko for example)' - ); - $theme['config'][] = array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' - ); - $theme['config'][] = array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)' - ); - $theme['config'][] = array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ); + $theme['config'][] = ['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Ukko']; + $theme['config'][] = ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '*', 'comment' => '(ukko for example)']; + $theme['config'][] = ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")']; + $theme['config'][] = ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)']; + $theme['config'][] = ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15']; // Unique function name for building everything $theme['build_function'] = 'ukko_build'; $theme['install_callback'] = 'ukko_install'; @@ -49,7 +23,7 @@ function ukko_install($settings) { if (!file_exists($settings['uri'])) @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true); - file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array())); + file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', [])); } } diff --git a/templates/themes/ukko/theme.php b/templates/themes/ukko/theme.php index d08b6769..4b729514 100644 --- a/templates/themes/ukko/theme.php +++ b/templates/themes/ukko/theme.php @@ -11,7 +11,7 @@ return; } - $action = generation_strategy('sb_ukko', array()); + $action = generation_strategy('sb_ukko', []); if ($action == 'delete') { file_unlink($settings['uri'] . '/index.html'); @@ -32,23 +32,18 @@ class ukko { public $settings; public function build($mod = false) { - global $config; + $apithreads = null; + global $config; $boards = listBoards(); $body = ''; - $overflow = array(); - $board = array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'uri' => $this->settings['uri'], - 'name' => $this->settings['title'], - 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) - ); + $overflow = []; + $board = ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'uri' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])]; - $boardsforukko = array(); + $boardsforukko = []; $query = ''; foreach($boards as &$_board) { - if(in_array($_board['uri'], explode(' ', $this->settings['exclude']))) + if(in_array($_board['uri'], explode(' ', (string) $this->settings['exclude']))) continue; $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); array_push($boardsforukko,$_board); @@ -57,9 +52,9 @@ $query = query($query) or error(db_error()); $count = 0; - $threads = array(); + $threads = []; if ($config['api']['enabled']) { - $apithreads = array(); + $apithreads = []; } while($post = $query->fetch()) { @@ -110,13 +105,13 @@ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; } - $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } $count += 1; } - $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script> var overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/ukko.js"></script>'; // json api @@ -124,18 +119,18 @@ require_once __DIR__. '/../../../inc/api.php'; $api = new Api(); $jsonFilename = $board['dir'] . '0.json'; - $json = json_encode($api->translatePage($apithreads)); + $json = json_encode($api->translatePage($apithreads), JSON_THROW_ON_ERROR); file_write($jsonFilename, $json); - $catalog = array(); + $catalog = []; $catalog[0] = $apithreads; - $json = json_encode($api->translateCatalog($catalog)); + $json = json_encode($api->translateCatalog($catalog), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'catalog.json'; file_write($jsonFilename, $json); - $json = json_encode($api->translateCatalog($catalog, true)); + $json = json_encode($api->translateCatalog($catalog, true), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'threads.json'; file_write($jsonFilename, $json); } @@ -145,15 +140,7 @@ } $antibot->reset(); - return Element('index.html', array( - 'config' => $config, - 'board' => $board, - 'no_post_form' => $config['overboard_post_form'] ? false : true, - 'body' => $body, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - 'boards' => $boardsforukko, - 'antibot' => $antibot ) + return Element('index.html', ['config' => $config, 'board' => $board, 'no_post_form' => $config['overboard_post_form'] ? false : true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod), 'boards' => $boardsforukko, 'antibot' => $antibot] ); } diff --git a/templates/themes/ukko2/info.php b/templates/themes/ukko2/info.php index f7094697..24904c91 100644 --- a/templates/themes/ukko2/info.php +++ b/templates/themes/ukko2/info.php @@ -1,5 +1,5 @@ <?php - $theme = array(); + $theme = []; // Theme name $theme['name'] = 'Overboard (Ukko2)'; @@ -8,39 +8,13 @@ $theme['version'] = 'v0.2'; // Theme configuration - $theme['config'] = array(); + $theme['config'] = []; - $theme['config'][] = array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Ukko' - ); - $theme['config'][] = array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '*', - 'comment' => '(ukko for example)' - ); - $theme['config'][] = array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' - ); - $theme['config'][] = array( - 'title' => 'included boards', - 'name' => 'include', - 'type' => 'text', - 'comment' => '(space seperated)' - ); - $theme['config'][] = array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ); + $theme['config'][] = ['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Ukko']; + $theme['config'][] = ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '*', 'comment' => '(ukko for example)']; + $theme['config'][] = ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")']; + $theme['config'][] = ['title' => 'included boards', 'name' => 'include', 'type' => 'text', 'comment' => '(space seperated)']; + $theme['config'][] = ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15']; // Unique function name for building everything $theme['build_function'] = 'ukko2_build'; $theme['install_callback'] = 'ukko2_install'; @@ -49,7 +23,7 @@ function ukko2_install($settings) { if (!file_exists($settings['uri'])) @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true); - file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array())); + file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', [])); } } diff --git a/templates/themes/ukko2/theme.php b/templates/themes/ukko2/theme.php index c34b5b89..629ab4e1 100644 --- a/templates/themes/ukko2/theme.php +++ b/templates/themes/ukko2/theme.php @@ -11,7 +11,7 @@ return; } - $action = generation_strategy('sb_ukko', array()); + $action = generation_strategy('sb_ukko', []); if ($action == 'delete') { file_unlink($settings['uri'] . '/index.html'); @@ -32,22 +32,17 @@ class ukko2 { public $settings; public function build($mod = false) { - global $config; + $apithreads = null; + global $config; $boards = listBoards(); $body = ''; - $overflow = array(); - $board = array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'uri' => $this->settings['uri'], - 'name' => $this->settings['title'], - 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) - ); - $boardsforukko2 = array(); + $overflow = []; + $board = ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'uri' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])]; + $boardsforukko2 = []; $query = ''; foreach($boards as &$_board) { - if(in_array($_board['uri'], explode(' ', $this->settings['include']))){ + if(in_array($_board['uri'], explode(' ', (string) $this->settings['include']))){ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); array_push($boardsforukko2,$_board); } @@ -56,9 +51,9 @@ $query = query($query) or error(db_error()); $count = 0; - $threads = array(); + $threads = []; if ($config['api']['enabled']) { - $apithreads = array(); + $apithreads = []; } while($post = $query->fetch()) { @@ -109,13 +104,13 @@ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; } - $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } $count += 1; } - $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script> var overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/ukko.js"></script>'; // json api @@ -123,18 +118,18 @@ require_once __DIR__. '/../../../inc/api.php'; $api = new Api(); $jsonFilename = $board['dir'] . '0.json'; - $json = json_encode($api->translatePage($apithreads)); + $json = json_encode($api->translatePage($apithreads), JSON_THROW_ON_ERROR); file_write($jsonFilename, $json); - $catalog = array(); + $catalog = []; $catalog[0] = $apithreads; - $json = json_encode($api->translateCatalog($catalog)); + $json = json_encode($api->translateCatalog($catalog), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'catalog.json'; file_write($jsonFilename, $json); - $json = json_encode($api->translateCatalog($catalog, true)); + $json = json_encode($api->translateCatalog($catalog, true), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'threads.json'; file_write($jsonFilename, $json); } @@ -144,15 +139,7 @@ } $antibot->reset(); - return Element('index.html', array( - 'config' => $config, - 'board' => $board, - 'no_post_form' => $config['overboard_post_form'] ? false : true, - 'body' => $body, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - 'boards' => $boardsforukko2, - 'antibot' => $antibot ) + return Element('index.html', ['config' => $config, 'board' => $board, 'no_post_form' => $config['overboard_post_form'] ? false : true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod), 'boards' => $boardsforukko2, 'antibot' => $antibot] ); } diff --git a/templates/themes/ukko3/info.php b/templates/themes/ukko3/info.php index 375995f4..463331f9 100644 --- a/templates/themes/ukko3/info.php +++ b/templates/themes/ukko3/info.php @@ -1,5 +1,5 @@ <?php - $theme = array(); + $theme = []; // Theme name $theme['name'] = 'Overboard (Ukko3)'; @@ -8,39 +8,13 @@ $theme['version'] = 'v0.2'; // Theme configuration - $theme['config'] = array(); + $theme['config'] = []; - $theme['config'][] = array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Ukko' - ); - $theme['config'][] = array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '*', - 'comment' => '(ukko for example)' - ); - $theme['config'][] = array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' - ); - $theme['config'][] = array( - 'title' => 'included boards', - 'name' => 'include', - 'type' => 'text', - 'comment' => '(space seperated)' - ); - $theme['config'][] = array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ); + $theme['config'][] = ['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Ukko']; + $theme['config'][] = ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '*', 'comment' => '(ukko for example)']; + $theme['config'][] = ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")']; + $theme['config'][] = ['title' => 'included boards', 'name' => 'include', 'type' => 'text', 'comment' => '(space seperated)']; + $theme['config'][] = ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15']; // Unique function name for building everything $theme['build_function'] = 'ukko3_build'; $theme['install_callback'] = 'ukko3_install'; @@ -49,7 +23,7 @@ function ukko3_install($settings) { if (!file_exists($settings['uri'])) @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true); - file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array())); + file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', [])); } } diff --git a/templates/themes/ukko3/theme.php b/templates/themes/ukko3/theme.php index c33b8521..eabe3998 100644 --- a/templates/themes/ukko3/theme.php +++ b/templates/themes/ukko3/theme.php @@ -11,7 +11,7 @@ return; } - $action = generation_strategy('sb_ukko', array()); + $action = generation_strategy('sb_ukko', []); if ($action == 'delete') { file_unlink($settings['uri'] . '/index.html'); @@ -32,23 +32,18 @@ class ukko3 { public $settings; public function build($mod = false) { - global $config; + $apithreads = null; + global $config; $boards = listBoards(); $body = ''; - $overflow = array(); - $board = array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'uri' => $this->settings['uri'], - 'name' => $this->settings['title'], - 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) - ); + $overflow = []; + $board = ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'uri' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])]; - $boardsforukko3 = array(); + $boardsforukko3 = []; $query = ''; foreach($boards as &$_board) { - if(in_array($_board['uri'], explode(' ', $this->settings['include']))){ + if(in_array($_board['uri'], explode(' ', (string) $this->settings['include']))){ $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); array_push($boardsforukko3,$_board); } @@ -57,9 +52,9 @@ $query = query($query) or error(db_error()); $count = 0; - $threads = array(); + $threads = []; if ($config['api']['enabled']) { - $apithreads = array(); + $apithreads = []; } while($post = $query->fetch()) { @@ -110,13 +105,13 @@ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; } - $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } $count += 1; } - $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script> var overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/ukko.js"></script>'; // json api @@ -124,18 +119,18 @@ require_once __DIR__. '/../../../inc/api.php'; $api = new Api(); $jsonFilename = $board['dir'] . '0.json'; - $json = json_encode($api->translatePage($apithreads)); + $json = json_encode($api->translatePage($apithreads), JSON_THROW_ON_ERROR); file_write($jsonFilename, $json); - $catalog = array(); + $catalog = []; $catalog[0] = $apithreads; - $json = json_encode($api->translateCatalog($catalog)); + $json = json_encode($api->translateCatalog($catalog), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'catalog.json'; file_write($jsonFilename, $json); - $json = json_encode($api->translateCatalog($catalog, true)); + $json = json_encode($api->translateCatalog($catalog, true), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'threads.json'; file_write($jsonFilename, $json); } @@ -145,15 +140,7 @@ } $antibot->reset(); - return Element('index.html', array( - 'config' => $config, - 'board' => $board, - 'no_post_form' => $config['overboard_post_form'] ? false : true, - 'body' => $body, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - 'boards' => $boardsforukko3, - 'antibot' => $antibot ) + return Element('index.html', ['config' => $config, 'board' => $board, 'no_post_form' => $config['overboard_post_form'] ? false : true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod), 'boards' => $boardsforukko3, 'antibot' => $antibot] ); } diff --git a/templates/themes/ukko4/info.php b/templates/themes/ukko4/info.php index dbbf6da8..0e797026 100644 --- a/templates/themes/ukko4/info.php +++ b/templates/themes/ukko4/info.php @@ -1,5 +1,5 @@ <?php - $theme = array(); + $theme = []; // Theme name $theme['name'] = 'Overboard (Ukko) 4'; @@ -8,39 +8,13 @@ $theme['version'] = 'v0.2'; // Theme configuration - $theme['config'] = array(); + $theme['config'] = []; - $theme['config'][] = array( - 'title' => 'Board name', - 'name' => 'title', - 'type' => 'text', - 'default' => 'Ukko' - ); - $theme['config'][] = array( - 'title' => 'Board URI', - 'name' => 'uri', - 'type' => 'text', - 'default' => '*', - 'comment' => '(ukko for example)' - ); - $theme['config'][] = array( - 'title' => 'Subtitle', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")' - ); - $theme['config'][] = array( - 'title' => 'Excluded boards', - 'name' => 'exclude', - 'type' => 'text', - 'comment' => '(space seperated)' - ); - $theme['config'][] = array( - 'title' => 'Number of threads', - 'name' => 'thread_limit', - 'type' => 'text', - 'default' => '15', - ); + $theme['config'][] = ['title' => 'Board name', 'name' => 'title', 'type' => 'text', 'default' => 'Ukko']; + $theme['config'][] = ['title' => 'Board URI', 'name' => 'uri', 'type' => 'text', 'default' => '*', 'comment' => '(ukko for example)']; + $theme['config'][] = ['title' => 'Subtitle', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(%s = thread limit. for example "%s freshly bumped threads")']; + $theme['config'][] = ['title' => 'Excluded boards', 'name' => 'exclude', 'type' => 'text', 'comment' => '(space seperated)']; + $theme['config'][] = ['title' => 'Number of threads', 'name' => 'thread_limit', 'type' => 'text', 'default' => '15']; // Unique function name for building everything $theme['build_function'] = 'ukko4_build'; $theme['install_callback'] = 'ukko4_install'; @@ -49,7 +23,7 @@ function ukko4_install($settings) { if (!file_exists($settings['uri'])) @mkdir($settings['uri'], 0777) or error("Couldn't create " . $settings['uri'] . ". Check permissions.", true); - file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', array())); + file_write($settings['uri'] . '/ukko.js', Element('themes/ukko/ukko.js', [])); } } diff --git a/templates/themes/ukko4/theme.php b/templates/themes/ukko4/theme.php index 4511483e..d58d8653 100644 --- a/templates/themes/ukko4/theme.php +++ b/templates/themes/ukko4/theme.php @@ -11,7 +11,7 @@ return; } - $action = generation_strategy('sb_ukko', array()); + $action = generation_strategy('sb_ukko', []); if ($action == 'delete') { file_unlink($settings['uri'] . '/index.html'); @@ -32,23 +32,18 @@ class ukko4 { public $settings; public function build($mod = false) { - global $config; + $apithreads = null; + global $config; $boards = listBoards(); $body = ''; - $overflow = array(); - $board = array( - 'dir' => $this->settings['uri'] . "/", - 'url' => $this->settings['uri'], - 'uri' => $this->settings['uri'], - 'name' => $this->settings['title'], - 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit']) - ); + $overflow = []; + $board = ['dir' => $this->settings['uri'] . "/", 'url' => $this->settings['uri'], 'uri' => $this->settings['uri'], 'name' => $this->settings['title'], 'title' => sprintf($this->settings['subtitle'], $this->settings['thread_limit'])]; - $boardsforukko = array(); + $boardsforukko = []; $query = ''; foreach($boards as &$_board) { - if(in_array($_board['uri'], explode(' ', $this->settings['exclude']))) + if(in_array($_board['uri'], explode(' ', (string) $this->settings['exclude']))) continue; $query .= sprintf("SELECT *, '%s' AS `board` FROM ``posts_%s`` WHERE `thread` IS NULL UNION ALL ", $_board['uri'], $_board['uri']); array_push($boardsforukko,$_board); @@ -57,9 +52,9 @@ $query = query($query) or error(db_error()); $count = 0; - $threads = array(); + $threads = []; if ($config['api']['enabled']) { - $apithreads = array(); + $apithreads = []; } while($post = $query->fetch()) { @@ -110,13 +105,13 @@ if(floor($threads[$post['board']] / $config['threads_per_page']) > 0) { $page = floor($threads[$post['board']] / $config['threads_per_page']) + 1; } - $overflow[] = array('id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html'); + $overflow[] = ['id' => $post['id'], 'board' => $post['board'], 'page' => $page . '.html']; } $count += 1; } - $body .= '<script> var overflow = ' . json_encode($overflow) . '</script>'; + $body .= '<script> var overflow = ' . json_encode($overflow, JSON_THROW_ON_ERROR) . '</script>'; $body .= '<script type="text/javascript" src="/'.$this->settings['uri'].'/ukko.js"></script>'; // json api @@ -124,18 +119,18 @@ require_once __DIR__. '/../../../inc/api.php'; $api = new Api(); $jsonFilename = $board['dir'] . '0.json'; - $json = json_encode($api->translatePage($apithreads)); + $json = json_encode($api->translatePage($apithreads), JSON_THROW_ON_ERROR); file_write($jsonFilename, $json); - $catalog = array(); + $catalog = []; $catalog[0] = $apithreads; - $json = json_encode($api->translateCatalog($catalog)); + $json = json_encode($api->translateCatalog($catalog), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'catalog.json'; file_write($jsonFilename, $json); - $json = json_encode($api->translateCatalog($catalog, true)); + $json = json_encode($api->translateCatalog($catalog, true), JSON_THROW_ON_ERROR); $jsonFilename = $board['dir'] . 'threads.json'; file_write($jsonFilename, $json); } @@ -145,15 +140,7 @@ } $antibot->reset(); - return Element('index.html', array( - 'config' => $config, - 'board' => $board, - 'no_post_form' => $config['overboard_post_form'] ? false : true, - 'body' => $body, - 'mod' => $mod, - 'boardlist' => createBoardlist($mod), - 'boards' => $boardsforukko, - 'antibot' => $antibot ) + return Element('index.html', ['config' => $config, 'board' => $board, 'no_post_form' => $config['overboard_post_form'] ? false : true, 'body' => $body, 'mod' => $mod, 'boardlist' => createBoardlist($mod), 'boards' => $boardsforukko, 'antibot' => $antibot] ); } diff --git a/templates/themes/zine/info.php b/templates/themes/zine/info.php index d7dabef5..a0fad880 100644 --- a/templates/themes/zine/info.php +++ b/templates/themes/zine/info.php @@ -1,23 +1,3 @@ <?php -$theme = array( - 'name' => 'Zine', - 'description' => 'sex on digital paper', - 'version' => 'v9001', - - 'config' => array( - array('title' => 'Page title', - 'name' => 'title', - 'type' => 'text'), - - array('title' => 'Slogan', - 'name' => 'subtitle', - 'type' => 'text', - 'comment' => '(optional)'), - - array('title' => 'File', - 'name' => 'file', - 'type' => 'text', - 'default' => 'zine/index.html')), - - 'build_function' => 'zine_build'); +$theme = ['name' => 'Zine', 'description' => 'sex on digital paper', 'version' => 'v9001', 'config' => [['title' => 'Page title', 'name' => 'title', 'type' => 'text'], ['title' => 'Slogan', 'name' => 'subtitle', 'type' => 'text', 'comment' => '(optional)'], ['title' => 'File', 'name' => 'file', 'type' => 'text', 'default' => 'zine/index.html']], 'build_function' => 'zine_build']; ?> diff --git a/templates/themes/zine/theme.php b/templates/themes/zine/theme.php index 78cb780c..fdeffc64 100644 --- a/templates/themes/zine/theme.php +++ b/templates/themes/zine/theme.php @@ -19,9 +19,7 @@ class zine { global $config; return Element('themes/zine/zine.html', - array('settings' => $settings, - 'config' => $config, - 'boardlist' => createBoardlist())); + ['settings' => $settings, 'config' => $config, 'boardlist' => createBoardlist()]); } } diff --git a/tools/benchmark.php b/tools/benchmark.php index ed7c200d..0bf38509 100755 --- a/tools/benchmark.php +++ b/tools/benchmark.php @@ -5,17 +5,17 @@ * */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; require 'inc/image.php'; // move back to this directory -chdir(dirname(__FILE__)); +chdir(__DIR__); -if(count($argv) != 2) +if((is_countable($argv) ? count($argv) : 0) != 2) die("Usage: {$argv[0]} [file]\n"); $file = $argv[1]; -$extension = strtolower(substr($file, strrpos($file, '.') + 1)); +$extension = strtolower(substr((string) $file, strrpos((string) $file, '.') + 1)); $out = tempnam($config['tmp'], 'thumb'); $count = 300; @@ -30,7 +30,7 @@ function benchmark($method) { for($i = 0; $i < $count; $i++) { $image = new Image($file, $extension); $thumb = $image->resize( - $config['thumb_ext'] ? $config['thumb_ext'] : $extension, + $config['thumb_ext'] ?: $extension, $config['thumb_width'], $config['thumb_height'] ); diff --git a/tools/delete-stray-images.php b/tools/delete-stray-images.php index cf94dfe5..06cf513b 100755 --- a/tools/delete-stray-images.php +++ b/tools/delete-stray-images.php @@ -9,7 +9,7 @@ * */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; $boards = listBoards(); @@ -19,8 +19,8 @@ foreach ($boards as $board) { openBoard($board['uri']); $query = query(sprintf("SELECT `file`, `thumb` FROM ``posts_%s`` WHERE `file` IS NOT NULL", $board['uri'])); - $valid_src = array(); - $valid_thumb = array(); + $valid_src = []; + $valid_thumb = []; while ($post = $query->fetch(PDO::FETCH_ASSOC)) { $valid_src[] = $post['file']; @@ -33,10 +33,7 @@ foreach ($boards as $board) { $stray_src = array_diff($files_src, $valid_src); $stray_thumb = array_diff($files_thumb, $valid_thumb); - $stats = array( - 'deleted' => 0, - 'size' => 0 - ); + $stats = ['deleted' => 0, 'size' => 0]; foreach ($stray_src as $src) { $stats['deleted']++; diff --git a/tools/i18n_compile.php b/tools/i18n_compile.php index ba193767..54827151 100755 --- a/tools/i18n_compile.php +++ b/tools/i18n_compile.php @@ -10,15 +10,15 @@ * */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; // parse command line -$opts = getopt('l:', Array('locale:')); -$options = Array(); +$opts = getopt('l:', ['locale:']); +$options = []; -$options['locale'] = isset($opts['l']) ? $opts['l'] : (isset($opts['locale']) ? $opts['locale'] : false); +$options['locale'] = $opts['l'] ?? $opts['locale'] ?? false; -if ($options['locale']) $locales = array($options['locale']); +if ($options['locale']) $locales = [$options['locale']]; else die("Error: no locales specified; use -l switch, eg. -l pl_PL\n"); foreach ($locales as $loc) { diff --git a/tools/i18n_extract.php b/tools/i18n_extract.php index fe501a37..66ccbc74 100755 --- a/tools/i18n_extract.php +++ b/tools/i18n_extract.php @@ -10,18 +10,18 @@ * */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; // parse command line -$opts = getopt('l:', Array('locale:')); -$options = Array(); +$opts = getopt('l:', ['locale:']); +$options = []; -$options['locale'] = isset($opts['l']) ? $opts['l'] : (isset($opts['locale']) ? $opts['locale'] : false); +$options['locale'] = $opts['l'] ?? $opts['locale'] ?? false; $locales = glob("inc/locale/*"); $locales = array_map("basename", $locales); -if ($options['locale']) $locales = array($options['locale']); +if ($options['locale']) $locales = [$options['locale']]; foreach ($locales as $loc) { diff --git a/tools/import_rules.php b/tools/import_rules.php index f583f035..167ecb2c 100644 --- a/tools/import_rules.php +++ b/tools/import_rules.php @@ -1,7 +1,7 @@ <?php // This script imports rules.txt files from the old system into the new ``pages`` table. -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; $boards = listBoards(TRUE); diff --git a/tools/inc/cli.php b/tools/inc/cli.php index b04d042a..4b8e3793 100644 --- a/tools/inc/cli.php +++ b/tools/inc/cli.php @@ -40,11 +40,6 @@ putenv('TINYBOARD_PATH=' . getcwd()); require 'inc/bootstrap.php'; -$mod = Array( - 'id' => -1, - 'type' => ADMIN, - 'username' => '?', - 'boards' => Array('*') -); +$mod = ['id' => -1, 'type' => ADMIN, 'username' => '?', 'boards' => ['*']]; diff --git a/tools/inc/lib/jsgettext/JSParser.php b/tools/inc/lib/jsgettext/JSParser.php index adba59bc..739d1195 100644 --- a/tools/inc/lib/jsgettext/JSParser.php +++ b/tools/inc/lib/jsgettext/JSParser.php @@ -4,9 +4,9 @@ class JSParser { protected $content; protected $keywords; - protected $regs = array(); + protected $regs = []; protected $regsCounter = 0; - protected $strings = array(); + protected $strings = []; protected $stringsCounter = 0; protected function _extractRegs($match) { @@ -23,16 +23,12 @@ class JSParser { } protected function importRegExps($input) { $regs = $this->regs; - return preg_replace_callback("#<<reg(\d+)>>#", function ($match) use($regs) { - return $regs[$match[1]]; - }, $input); + return preg_replace_callback("#<<reg(\d+)>>#", fn($match) => $regs[$match[1]], $input); } protected function importStrings($input) { $strings = $this->strings; - return preg_replace_callback("#<<s(\d+)>>#", function ($match) use($strings) { - return $strings[$match[1]]; - }, $input); + return preg_replace_callback("#<<s(\d+)>>#", fn($match) => $strings[$match[1]], $input); } public function __construct($file, $keywords = '_') { @@ -46,15 +42,12 @@ class JSParser { // extract reg exps $output = preg_replace_callback( '# ( / (?: (?>[^/\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\/ )+ (?<!\\\\)/ ) [a-z]* \b #ix', - array($this, '_extractRegs'), $output + $this->_extractRegs(...), $output ); // extract strings $output = preg_replace_callback( - array( - '# " ( (?: (?>[^"\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\" )* ) (?<!\\\\)" #ix', - "# ' ( (?: (?>[^'\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\' )* ) (?<!\\\\)' #ix" - ), array($this, '_extractStrings'), $output + ['# " ( (?: (?>[^"\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\" )* ) (?<!\\\\)" #ix', "# ' ( (?: (?>[^'\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\' )* ) (?<!\\\\)' #ix"], $this->_extractStrings(...), $output ); // delete line comments @@ -64,13 +57,11 @@ class JSParser { $output = preg_replace('#/\*(.*?)\*/#is', '', $output); $strings = $this->strings; - $output = preg_replace_callback("#<<s(\d+)>>#", function($match) use($strings) { - return $strings[$match[1]]; - }, $output); + $output = preg_replace_callback("#<<s(\d+)>>#", fn($match) => $strings[$match[1]], $output); $keywords = implode('|', $this->keywords); - $strings = array(); + $strings = []; // extract func calls preg_match_all( @@ -78,15 +69,15 @@ class JSParser { $output, $matches, PREG_SET_ORDER ); - foreach ($matches as $m) $strings[] = stripslashes($m[1]); + foreach ($matches as $m) $strings[] = stripslashes((string) $m[1]); - $matches = array(); + $matches = []; preg_match_all( "# (?:$keywords) \(\\ *' ( (?: (?>[^'\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\' )* ) (?<!\\\\)'\\ *\) #ix", $output, $matches, PREG_SET_ORDER ); - foreach ($matches as $m) $strings[] = stripslashes($m[1]); + foreach ($matches as $m) $strings[] = stripslashes((string) $m[1]); return $strings; } diff --git a/tools/inc/lib/jsgettext/PoeditParser.php b/tools/inc/lib/jsgettext/PoeditParser.php index eebd816e..0fbe04e6 100644 --- a/tools/inc/lib/jsgettext/PoeditParser.php +++ b/tools/inc/lib/jsgettext/PoeditParser.php @@ -4,17 +4,16 @@ require_once 'PoeditString.php'; class PoeditParser { - protected $file; protected $header = ''; - protected $strings = array(); + protected $strings = []; protected function _fixQuotes($str) { - return stripslashes($str); + return stripslashes((string) $str); } - public function __construct($file) { - $this->file = $file; - } + public function __construct(protected $file) + { + } public function parse() { $contents = file_get_contents($this->file); @@ -26,13 +25,13 @@ class PoeditParser { foreach ($parts as $part) { // parse comments - $comments = array(); - preg_match_all('#^\\#: (.*?)$#m', $part, $matches, PREG_SET_ORDER); + $comments = []; + preg_match_all('#^\\#: (.*?)$#m', (string) $part, $matches, PREG_SET_ORDER); foreach ($matches as $m) $comments[] = $m[1]; - $isFuzzy = preg_match('#^\\#, fuzzy$#im', $part) ? true : false; + $isFuzzy = preg_match('#^\\#, fuzzy$#im', (string) $part) ? true : false; - preg_match_all('# ^ (msgid|msgstr)\ " ( (?: (?>[^"\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\" )* ) (?<!\\\\)" $ #ixm', $part, $matches2, PREG_SET_ORDER); + preg_match_all('# ^ (msgid|msgstr)\ " ( (?: (?>[^"\\\\]++) | \\\\\\\\ | (?<!\\\\)\\\\(?!\\\\) | \\\\" )* ) (?<!\\\\)" $ #ixm', (string) $part, $matches2, PREG_SET_ORDER); $k = $this->_fixQuotes($matches2[0][2]); $v = !empty($matches2[1][2]) ? $this->_fixQuotes($matches2[1][2]) : ''; @@ -58,11 +57,11 @@ class PoeditParser { } public function getJSON() { - $str = array(); + $str = []; foreach ($this->strings as $s) { if ($s->value) $str[$s->key] = $s->value; } - return json_encode($str); + return json_encode($str, JSON_THROW_ON_ERROR); } public function toJSON($outputFilename, $varName = 'l10n') { @@ -75,7 +74,7 @@ class PoeditParser { foreach ($this->strings as $str) { $data .= $str; } - return file_put_contents($filename ? $filename : $this->file, $data) !== false; + return file_put_contents($filename ?: $this->file, $data) !== false; } } diff --git a/tools/inc/lib/jsgettext/PoeditString.php b/tools/inc/lib/jsgettext/PoeditString.php index 3d59d004..5bffeea0 100644 --- a/tools/inc/lib/jsgettext/PoeditString.php +++ b/tools/inc/lib/jsgettext/PoeditString.php @@ -1,26 +1,20 @@ <?php -class PoeditString { - public $key; - public $value; - public $fuzzy; +class PoeditString implements \Stringable { public $comments; - function __construct($key, $value = '', $fuzzy = false, $comments = array()) { - $this->key = $key; - $this->value = $value; - $this->fuzzy = $fuzzy; + function __construct(public $key, public $value = '', public $fuzzy = false, $comments = []) { $this->comments = (array)$comments; } - public function __toString() { + public function __toString(): string { $str =''; foreach ($this->comments as $c) { $str .= "#: $c\n"; } if ($this->fuzzy) $str .= "#, fuzzy\n"; - $str .= 'msgid "'.str_replace('"', '\\"', $this->key).'"' . "\n"; - $str .= 'msgstr "'.str_replace('"', '\\"', $this->value).'"' . "\n"; + $str .= 'msgid "'.str_replace('"', '\\"', (string) $this->key).'"' . "\n"; + $str .= 'msgstr "'.str_replace('"', '\\"', (string) $this->value).'"' . "\n"; $str .= "\n"; return $str; } diff --git a/tools/inc/lib/jsgettext/jsgettext.php b/tools/inc/lib/jsgettext/jsgettext.php index 6c70f0b4..75ea6566 100644 --- a/tools/inc/lib/jsgettext/jsgettext.php +++ b/tools/inc/lib/jsgettext/jsgettext.php @@ -4,16 +4,12 @@ require_once 'PoeditParser.php'; function buildOptions($args) { - $options = array( - 'files' => array(), - '-o' => null, - '-k' => '_' - ); - $len = count($args); + $options = ['files' => [], '-o' => null, '-k' => '_']; + $len = is_countable($args) ? count($args) : 0; $i = 1; while ($i < $len) { - if (preg_match('#^-[a-z]$#i', $args[$i])) { - $options[$args[$i]] = isset($args[$i+1]) ? trim($args[$i+1]) : true; + if (preg_match('#^-[a-z]$#i', (string) $args[$i])) { + $options[$args[$i]] = isset($args[$i+1]) ? trim((string) $args[$i+1]) : true; $i += 2; } else { @@ -43,14 +39,14 @@ $poeditParser = new PoeditParser($options['-o']); $poeditParser->parse(); - $errors = array(); + $errors = []; foreach ($inputFiles as $f) { - if (!is_readable($f) || !preg_match('#\.js$#', $f)) { + if (!is_readable($f) || !preg_match('#\.js$#', (string) $f)) { $errors[] = ("$f is not a valid javascript file."); continue; } - $jsparser = new JSParser($f, explode(' ', $options['-k'])); + $jsparser = new JSParser($f, explode(' ', (string) $options['-k'])); $jsStrings = $jsparser->parse(); $poeditParser->merge($jsStrings); } diff --git a/tools/inc/lib/jsgettext/po2json.php b/tools/inc/lib/jsgettext/po2json.php index 847b0899..8fb6f69f 100644 --- a/tools/inc/lib/jsgettext/po2json.php +++ b/tools/inc/lib/jsgettext/po2json.php @@ -3,16 +3,12 @@ require_once 'PoeditParser.php'; function buildOptions($args) { - $options = array( - '-o' => null, - '-i' => null, - '-n' => 'l10n' - ); - $len = count($args); + $options = ['-o' => null, '-i' => null, '-n' => 'l10n']; + $len = is_countable($args) ? count($args) : 0; $i = 0; while ($i < $len) { - if (preg_match('#^-[a-z]$#i', $args[$i])) { - $options[$args[$i]] = isset($args[$i+1]) ? trim($args[$i+1]) : true; + if (preg_match('#^-[a-z]$#i', (string) $args[$i])) { + $options[$args[$i]] = isset($args[$i+1]) ? trim((string) $args[$i+1]) : true; $i += 2; } else { @@ -33,8 +29,8 @@ $poeditParser->parse(); if ($poeditParser->toJSON($options['-o'], $options['-n'])) { - $strings = count($poeditParser->getStrings()); - echo "Successfully exported " . count($strings) . " strings.\n"; + $strings = is_countable($poeditParser->getStrings()) ? count($poeditParser->getStrings()) : 0; + echo "Successfully exported " . (is_countable($strings) ? count($strings) : 0) . " strings.\n"; } else { echo "Cannor write to file '{$options['-o']}'.\n"; diff --git a/tools/rebuild.php b/tools/rebuild.php index 289523a1..9adb183b 100755 --- a/tools/rebuild.php +++ b/tools/rebuild.php @@ -19,18 +19,18 @@ * */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; require_once("inc/bans.php"); $start = microtime(true); // parse command line -$opts = getopt('qfb:', Array('board:', 'quick', 'full', 'quiet')); -$options = Array(); +$opts = getopt('qfb:', ['board:', 'quick', 'full', 'quiet']); +$options = []; $global_locale = $config['locale']; -$options['board'] = isset($opts['board']) ? $opts['board'] : (isset($opts['b']) ? $opts['b'] : false); +$options['board'] = $opts['board'] ?? $opts['b'] ?? false; $options['quiet'] = isset($opts['q']) || isset($opts['quiet']); $options['quick'] = isset($opts['quick']); $options['full'] = isset($opts['full']) || isset($opts['f']); diff --git a/tools/rebuild2.php b/tools/rebuild2.php index 2945460c..82d0fef2 100755 --- a/tools/rebuild2.php +++ b/tools/rebuild2.php @@ -11,17 +11,17 @@ * I removed the quiet option, it's useless. Just use output redirection. */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; $start = microtime(true); // parse command line -$opts = getopt('', Array('board:', 'themes', 'js', 'indexes', 'threads', 'processes:', 'cache', 'postmarkup', 'api')); -$options = Array(); +$opts = getopt('', ['board:', 'themes', 'js', 'indexes', 'threads', 'processes:', 'cache', 'postmarkup', 'api']); +$options = []; $global_locale = $config['locale']; // Do only one board? -$options['board'] = isset($opts['board']) ? $opts['board'] : (isset($opts['b']) ? $opts['b'] : false); +$options['board'] = $opts['board'] ?? $opts['b'] ?? false; // Clear the cache? $options['cache'] = isset($opts['cache']); // Rebuild themes (catalogs)? @@ -37,7 +37,7 @@ $options['postmarkup'] = isset($opts['postmarkup']); // Rebuild API pages? (e.g. /b/res/1.json') $options['api'] = isset($opts['api']); // How many processes? -$options['processes'] = isset($opts['processes']) ? $opts['processes'] : 1; +$options['processes'] = $opts['processes'] ?? 1; echo "== Tinyboard + vichan {$config['version']} ==\n"; @@ -71,22 +71,22 @@ function doboard($board) { echo "Opening board /{$board['uri']}/...\n"; // Reset locale to global locale $config['locale'] = $global_locale; - init_locale($config['locale'], 'error'); + init_locale($config['locale']); openBoard($board['uri']); $config['try_smarter'] = false; - + if($config['file_script'] != $main_js && $options['js']) { // different javascript file echo "(/{$board['uri']}/) Generating Javascript file...\n"; buildJavascript(); } - - + + if ($options['indexes']) { echo "(/{$board['uri']}/) Creating index pages...\n"; buildIndex(); } - + if($options['postmarkup']) { $query = query(sprintf("SELECT `id` FROM ``posts_%s``", $board['uri'])) or error(db_error()); while($post = $query->fetch()) { @@ -94,7 +94,7 @@ function doboard($board) { rebuildPost($post['id']); } } - + if ($options['threads']) { $query = query(sprintf("SELECT `id` FROM ``posts_%s`` WHERE `thread` IS NULL", $board['uri'])) or error(db_error()); while($post = $query->fetch()) { @@ -104,7 +104,7 @@ function doboard($board) { } } -$children = array(); +$children = []; foreach ($boards_m as $i => $bb) { $pid = pcntl_fork(); diff --git a/tools/recount-bumps.php b/tools/recount-bumps.php index 06e8ca9f..5d1053ab 100644 --- a/tools/recount-bumps.php +++ b/tools/recount-bumps.php @@ -2,7 +2,7 @@ // A script to recount bumps to recover from a last-page-bump attack // or to be run after the KusabaX Migration. -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; if (!isset ($argv[1])) { die("Usage: tools/recount-bumps.php board_uri\n"); diff --git a/tools/stats.php b/tools/stats.php index 00214842..0729418f 100755 --- a/tools/stats.php +++ b/tools/stats.php @@ -1,14 +1,13 @@ #!/usr/bin/php <?php mb_internal_encoding('utf-8'); -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; -$variants = array(array("hour", 3600), array("day", 3600*24), array("3 days", 3600*24*3), - array("week", 3600*24*7), array("month", 3600*24*7*30)); +$variants = [["hour", 3600], ["day", 3600*24], ["3 days", 3600*24*3], ["week", 3600*24*7], ["month", 3600*24*7*30]]; printf(" || "); foreach ($variants as $iter) { - list($term, $time) = $iter; + [$term, $time] = $iter; printf("%8s | ", $term); } print("\n"); @@ -18,12 +17,12 @@ print("\n"); function mb_str_pad ($input, $pad_length, $pad_string, $pad_type, $encoding="UTF-8") { if (!$encoding) { - $diff = strlen($input) - mb_strlen($input); + $diff = strlen((string) $input) - mb_strlen((string) $input); } else { - $diff = strlen($input) - mb_strlen($input, $encoding); + $diff = strlen((string) $input) - mb_strlen((string) $input, $encoding); } - return str_pad($input, $pad_length + $diff, $pad_string, $pad_type); + return str_pad((string) $input, $pad_length + $diff, $pad_string, $pad_type); } @@ -33,7 +32,7 @@ while ($f = $q->fetch()) { $str = mb_str_pad($str,10," ", STR_PAD_LEFT, "UTF-8"); printf("%s || ", $str); foreach ($variants as $iter) { - list($term, $time) = $iter; + [$term, $time] = $iter; $qq = query(sprintf("SELECT COUNT(*) as count FROM ``posts_%s`` WHERE time > %d", $f['uri'], time()-$time)); $c = $qq->fetch()['count']; diff --git a/tools/worker.php b/tools/worker.php index e19fe1c6..d0623eb4 100755 --- a/tools/worker.php +++ b/tools/worker.php @@ -2,15 +2,15 @@ <?php /* worker.php - part of advanced build vichan feature */ -require dirname(__FILE__) . '/inc/cli.php'; +require __DIR__ . '/inc/cli.php'; require_once 'inc/controller.php'; $config['smart_build'] = false; // Let's disable it, so we can build the page for real -$config['generation_strategies'] = array('strategy_immediate'); +$config['generation_strategies'] = ['strategy_immediate']; function after_open_board() { global $config; $config['smart_build'] = false; - $config['generation_strategies'] = array('strategy_immediate'); + $config['generation_strategies'] = ['strategy_immediate']; }; echo "Hello world!\n"; @@ -20,7 +20,7 @@ $queue = get_queue('generate'); while (true) { $q = $queue->pop(2); foreach ($q as $v) { - list($__, $func, $ary, $action) = unserialize($v); + [$__, $func, $ary, $action] = unserialize($v); echo "Starting to generate $func ".implode(" ", $ary)."... "; call_user_func_array($func, $ary); |
