misuzu/utility.php

155 lines
4.2 KiB
PHP

<?php
use Index\Colour\Colour;
function array_test(array $array, callable $func): bool {
foreach($array as $value)
if(!$func($value))
return false;
return true;
}
function array_apply(array $array, callable $func): array {
for($i = 0; $i < count($array); ++$i)
$array[$i] = $func($array[$i]);
return $array;
}
function array_bit_or(array $array1, array $array2): array {
foreach($array1 as $key => $value)
$array1[$key] |= $array2[$key] ?? 0;
return $array1;
}
function array_rand_value(array $array) {
return $array[mt_rand(0, count($array) - 1)];
}
function array_find(array $array, callable $callback) {
foreach($array as $item)
if($callback($item))
return $item;
return null;
}
function clamp($num, int $min, int $max): int {
return max($min, min($max, (int)$num));
}
function first_paragraph(string $text, string $delimiter = "\n"): string {
$index = mb_strpos($text, $delimiter);
return $index === false ? $text : mb_substr($text, 0, $index);
}
function unique_chars(string $input, bool $multibyte = true): int {
$chars = [];
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
$substr = $multibyte ? 'mb_substr' : 'substr';
$length = $strlen($input);
for($i = 0; $i < $length; $i++) {
$current = $substr($input, $i, 1);
if(!in_array($current, $chars, true)) {
$chars[] = $current;
}
}
return count($chars);
}
function byte_symbol(int $bytes, bool $decimal = false, array $symbols = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']): string {
if($bytes < 1)
return '0 B';
$divider = $decimal ? 1000 : 1024;
$exp = floor(log($bytes) / log($divider));
$bytes = $bytes / pow($divider, $exp);
$symbol = $symbols[$exp];
return sprintf("%.2f %s%sB", $bytes, $symbol, $symbol !== '' && !$decimal ? 'i' : '');
}
function get_country_name(string $code, string $locale = 'en'): string {
$code = strtolower($code);
switch($code) {
case 'xx':
return 'Unknown';
case 'a1':
return 'Anonymous Proxy';
case 'a2':
return 'Satellite Provider';
case 'cn':
return 'West Taiwan';
case 'xm':
return 'The Moon';
default:
return \Locale::getDisplayRegion("-{$code}", $locale);
}
}
// 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
function render_error(int $code, string $template = 'errors.%d'): string {
return render_info(null, $code, $template);
}
function render_info(?string $message, int $httpCode, string $template = 'errors.%d'): string {
http_response_code($httpCode);
\Misuzu\Template::set('http_code', $httpCode);
if(!empty($message))
\Misuzu\Template::set('message', $message);
$template = sprintf($template, $httpCode);
return \Misuzu\Template::renderRaw(sprintf($template, $httpCode));
}
function html_colour(int|null|Colour $colour, $attribs = '--user-colour'): string {
$colour = (string)($colour instanceof Colour ? $colour : Colour::fromMisuzu($colour ?? 0x40000000));
if(is_string($attribs))
$attribs = [ $attribs => '%s' ];
if(!$attribs)
$attribs = [
'color' => '%s',
'--user-colour' => '%s',
];
$css = '';
foreach($attribs as $name => $format)
$css .= $name . ':' . sprintf($format, $colour) . ';';
return $css;
}
function msz_server_timing(\Index\Performance\Timings $timings): string {
$laps = $timings->getLaps();
$timings = [];
foreach($laps as $lap) {
$timing = $lap->getName();
if($lap->hasComment())
$timing .= ';desc="' . strtr($lap->getComment(), ['"' => '\\"']) . '"';
$timing .= ';dur=' . round($lap->getDurationTime(), 5);
$timings[] = $timing;
}
return sprintf('Server-Timing: %s', implode(', ', $timings));
}
function msz_cookie_domain(bool $compatible = true): string {
$url = parse_url($_SERVER['HTTP_HOST'], PHP_URL_HOST);
if(empty($url))
$url = $_SERVER['HTTP_HOST'];
if(!filter_var($url, FILTER_VALIDATE_IP) && $compatible)
$url = '.' . $url;
return $url;
}