2017-12-16 08:19:56 +00:00
|
|
|
<?php
|
2019-12-04 18:23:00 +00:00
|
|
|
function array_test(array $array, callable $func): bool {
|
2020-05-18 21:27:34 +00:00
|
|
|
foreach($array as $value)
|
|
|
|
if(!$func($value))
|
2019-12-04 18:23:00 +00:00
|
|
|
return false;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_apply(array $array, callable $func): array {
|
2020-05-18 21:27:34 +00:00
|
|
|
for($i = 0; $i < count($array); ++$i)
|
2019-12-04 18:23:00 +00:00
|
|
|
$array[$i] = $func($array[$i]);
|
|
|
|
return $array;
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_bit_or(array $array1, array $array2): array {
|
2020-05-18 21:27:34 +00:00
|
|
|
foreach($array1 as $key => $value)
|
2019-12-04 18:23:00 +00:00
|
|
|
$array1[$key] |= $array2[$key] ?? 0;
|
|
|
|
return $array1;
|
|
|
|
}
|
|
|
|
|
2019-12-06 01:04:10 +00:00
|
|
|
function array_rand_value(array $array) {
|
2020-05-18 21:27:34 +00:00
|
|
|
return $array[mt_rand(0, count($array) - 1)];
|
|
|
|
}
|
|
|
|
|
|
|
|
function array_find(array $array, callable $callback) {
|
|
|
|
foreach($array as $item)
|
|
|
|
if($callback($item))
|
|
|
|
return $item;
|
|
|
|
return null;
|
2019-12-06 01:04:10 +00:00
|
|
|
}
|
|
|
|
|
2019-12-04 18:23:00 +00:00
|
|
|
function clamp($num, int $min, int $max): int {
|
|
|
|
return max($min, min($max, intval($num)));
|
|
|
|
}
|
|
|
|
|
2022-02-19 19:03:00 +00:00
|
|
|
function starts_with(string $string, string $text): bool {
|
|
|
|
return str_starts_with($string, $text);
|
2019-12-04 18:23:00 +00:00
|
|
|
}
|
|
|
|
|
2022-02-19 19:03:00 +00:00
|
|
|
function ends_with(string $string, string $text): bool {
|
|
|
|
return str_ends_with($string, $text);
|
2019-12-04 18:23:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function first_paragraph(string $text, string $delimiter = "\n"): string {
|
|
|
|
$index = mb_strpos($text, $delimiter);
|
|
|
|
return $index === false ? $text : mb_substr($text, 0, $index);
|
|
|
|
}
|
|
|
|
|
|
|
|
function unique_chars(string $input, bool $multibyte = true): int {
|
|
|
|
$chars = [];
|
|
|
|
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
|
|
|
|
$substr = $multibyte ? 'mb_substr' : 'substr';
|
|
|
|
$length = $strlen($input);
|
|
|
|
|
|
|
|
for($i = 0; $i < $length; $i++) {
|
|
|
|
$current = $substr($input, $i, 1);
|
|
|
|
|
|
|
|
if(!in_array($current, $chars, true)) {
|
|
|
|
$chars[] = $current;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return count($chars);
|
|
|
|
}
|
|
|
|
|
|
|
|
function byte_symbol(int $bytes, bool $decimal = false, array $symbols = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): string {
|
2020-05-18 21:27:34 +00:00
|
|
|
if($bytes < 1)
|
2019-12-04 18:23:00 +00:00
|
|
|
return '0 B';
|
|
|
|
|
|
|
|
$divider = $decimal ? 1000 : 1024;
|
|
|
|
$exp = floor(log($bytes) / log($divider));
|
2020-05-18 21:27:34 +00:00
|
|
|
$bytes = $bytes / pow($divider, $exp);
|
2019-12-04 18:23:00 +00:00
|
|
|
$symbol = $symbols[$exp];
|
|
|
|
|
|
|
|
return sprintf("%.2f %s%sB", $bytes, $symbol, $symbol !== '' && !$decimal ? 'i' : '');
|
|
|
|
}
|
|
|
|
|
2020-10-06 20:07:47 +00:00
|
|
|
function get_country_name(string $code, string $locale = 'en'): string {
|
|
|
|
$code = strtolower($code);
|
|
|
|
switch($code) {
|
2018-03-22 02:56:41 +00:00
|
|
|
case 'xx':
|
|
|
|
return 'Unknown';
|
|
|
|
case 'a1':
|
|
|
|
return 'Anonymous Proxy';
|
|
|
|
case 'a2':
|
|
|
|
return 'Satellite Provider';
|
2020-10-06 20:07:47 +00:00
|
|
|
case 'cn':
|
|
|
|
return 'West Taiwan';
|
|
|
|
case 'xm':
|
|
|
|
return 'The Moon';
|
2018-03-22 02:56:41 +00:00
|
|
|
default:
|
2020-10-06 20:07:47 +00:00
|
|
|
return \Locale::getDisplayRegion("-{$code}", $locale);
|
2018-03-22 02:56:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-05-05 15:46:57 +00:00
|
|
|
// render_error, render_info and render_info_or_json should be redone a bit better
|
|
|
|
// following a uniform format so there can be a global handler for em
|
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
function render_error(int $code, string $template = 'errors.%d'): string {
|
2018-08-06 22:19:35 +00:00
|
|
|
return render_info(null, $code, $template);
|
|
|
|
}
|
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
function render_info(?string $message, int $httpCode, string $template = 'errors.%d'): string {
|
2018-08-06 22:19:35 +00:00
|
|
|
http_response_code($httpCode);
|
2018-05-26 20:33:05 +00:00
|
|
|
|
|
|
|
try {
|
2019-12-04 18:16:22 +00:00
|
|
|
\Misuzu\Template::set('http_code', $httpCode);
|
2018-08-06 22:19:35 +00:00
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
if(mb_strlen($message)) {
|
2019-12-04 18:16:22 +00:00
|
|
|
\Misuzu\Template::set('message', $message);
|
2018-08-06 22:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$template = sprintf($template, $httpCode);
|
|
|
|
|
2019-12-04 18:16:22 +00:00
|
|
|
/*if(!tpl_exists($template)) {
|
2018-08-06 22:19:35 +00:00
|
|
|
$template = 'errors.master';
|
2019-12-04 18:16:22 +00:00
|
|
|
}*/
|
2018-08-06 22:19:35 +00:00
|
|
|
|
2019-12-06 01:04:10 +00:00
|
|
|
return \Misuzu\Template::renderRaw(sprintf($template, $httpCode));
|
2019-06-10 17:04:53 +00:00
|
|
|
} catch(Exception $ex) {
|
2018-08-06 22:19:35 +00:00
|
|
|
echo $ex->getMessage();
|
|
|
|
return $message ?? '';
|
2018-05-26 20:33:05 +00:00
|
|
|
}
|
|
|
|
}
|
2018-07-06 01:28:06 +00:00
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
function render_info_or_json(bool $json, string $message, int $httpCode = 200, string $template = 'errors.%d'): string {
|
2018-08-06 22:19:35 +00:00
|
|
|
$error = $httpCode >= 400;
|
|
|
|
http_response_code($httpCode);
|
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
if($json) {
|
2019-01-11 23:00:53 +00:00
|
|
|
return json_encode([($error ? 'error' : 'message') => $message, 'success' => $error]);
|
2018-08-06 22:19:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return render_info($message, $httpCode, $template);
|
|
|
|
}
|
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
function html_colour(?int $colour, $attribs = '--user-colour'): string {
|
2019-12-12 00:42:28 +00:00
|
|
|
$colour = $colour == null ? \Misuzu\Colour::none() : new \Misuzu\Colour($colour);
|
2018-07-23 13:31:36 +00:00
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
if(is_string($attribs)) {
|
2018-09-23 14:42:15 +00:00
|
|
|
$attribs = [
|
|
|
|
$attribs => '%s',
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
if(!$attribs) {
|
2018-09-23 14:42:15 +00:00
|
|
|
$attribs = [
|
|
|
|
'color' => '%s',
|
|
|
|
'--user-colour' => '%s',
|
|
|
|
];
|
2018-07-06 01:28:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
$css = '';
|
2019-12-12 00:42:28 +00:00
|
|
|
$value = $colour->getCSS();
|
2018-07-06 01:28:06 +00:00
|
|
|
|
2019-06-10 17:04:53 +00:00
|
|
|
foreach($attribs as $name => $format) {
|
2018-07-06 01:28:06 +00:00
|
|
|
$css .= $name . ':' . sprintf($format, $value) . ';';
|
|
|
|
}
|
|
|
|
|
|
|
|
return $css;
|
|
|
|
}
|
2019-09-28 19:21:23 +00:00
|
|
|
|
2020-05-18 21:27:34 +00:00
|
|
|
function html_avatar(?int $userId, int $resolution, string $altText = '', array $attributes = []): string {
|
|
|
|
$attributes['src'] = url('user-avatar', ['user' => $userId ?? 0, 'res' => $resolution * 2]);
|
2019-09-28 19:21:23 +00:00
|
|
|
$attributes['alt'] = $altText;
|
|
|
|
$attributes['class'] = trim('avatar ' . ($attributes['class'] ?? ''));
|
|
|
|
|
|
|
|
if(!isset($attributes['width']))
|
|
|
|
$attributes['width'] = $resolution;
|
|
|
|
if(!isset($attributes['height']))
|
|
|
|
$attributes['height'] = $resolution;
|
|
|
|
|
|
|
|
return html_tag('img', $attributes);
|
|
|
|
}
|
|
|
|
|
|
|
|
function html_tag(string $name, array $atrributes = [], ?bool $close = null, string $content = ''): string {
|
|
|
|
$html = '<' . $name;
|
|
|
|
|
|
|
|
foreach($atrributes as $key => $value) {
|
|
|
|
$html .= ' ' . $key;
|
|
|
|
|
|
|
|
if(!empty($value))
|
|
|
|
$html .= '="' . $value . '"';
|
|
|
|
}
|
|
|
|
|
|
|
|
if($close === false)
|
|
|
|
$html .= '/';
|
|
|
|
|
|
|
|
$html .= '>';
|
|
|
|
|
|
|
|
if($close === true)
|
|
|
|
$html .= $content . '</' . $name . '>';
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
}
|
2022-02-28 01:55:36 +00:00
|
|
|
|
|
|
|
function msz_server_timing(\Index\Performance\Timings $timings): string {
|
|
|
|
$laps = $timings->getLaps();
|
|
|
|
$timings = [];
|
|
|
|
|
|
|
|
foreach($laps as $lap) {
|
|
|
|
$timing = $lap->getName();
|
|
|
|
if($lap->hasComment())
|
|
|
|
$timing .= ';desc="' . strtr($lap->getComment(), ['"' => '\\"']) . '"';
|
|
|
|
|
|
|
|
$timing .= ';dur=' . round($lap->getDurationTime(), 5);
|
|
|
|
$timings[] = $timing;
|
|
|
|
}
|
|
|
|
|
|
|
|
return sprintf('Server-Timing: %s', implode(', ', $timings));
|
|
|
|
}
|