misuzu/utility.php

306 lines
8.1 KiB
PHP
Raw Normal View History

<?php
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[array_rand($array)];
}
function clamp($num, int $min, int $max): int {
return max($min, min($max, intval($num)));
}
function starts_with(string $string, string $text, bool $multibyte = true): bool {
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
$substr = $multibyte ? 'mb_substr' : 'substr';
return $substr($string, 0, $strlen($text)) === $text;
}
function ends_with(string $string, string $text, bool $multibyte = true): bool {
$strlen = $multibyte ? 'mb_strlen' : 'strlen';
$substr = $multibyte ? 'mb_substr' : 'substr';
return $substr($string, 0 - $strlen($text)) === $text;
}
function first_paragraph(string $text, string $delimiter = "\n"): string {
$index = mb_strpos($text, $delimiter);
return $index === false ? $text : mb_substr($text, 0, $index);
}
function camel_to_snake(string $camel): string {
return trim(mb_strtolower(preg_replace('#([A-Z][a-z]+)#', '$1_', $camel)), '_');
}
function snake_to_camel(string $snake): string {
return str_replace('_', '', ucwords($snake, '_'));
}
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, floor($exp));
$symbol = $symbols[$exp];
return sprintf("%.2f %s%sB", $bytes, $symbol, $symbol !== '' && !$decimal ? 'i' : '');
}
2019-12-09 02:41:34 +00:00
// For chat emote list, nuke this when Sharp Chat comms are in this project
function emotes_list(int $hierarchy = PHP_INT_MAX, bool $unique = false, bool $order = true): array {
$getEmotes = \Misuzu\DB::prepare('
SELECT e.`emote_id`, e.`emote_order`, e.`emote_hierarchy`, e.`emote_url`,
s.`emote_string_order`, s.`emote_string`
FROM `msz_emoticons_strings` AS s
LEFT JOIN `msz_emoticons` AS e
ON e.`emote_id` = s.`emote_id`
WHERE `emote_hierarchy` <= :hierarchy
ORDER BY IF(:order, e.`emote_order`, e.`emote_id`), s.`emote_string_order`
');
$getEmotes->bind('hierarchy', $hierarchy);
$getEmotes->bind('order', $order);
$emotes = $getEmotes->fetchAll();
// Removes aliases, emote with lowest ordering is considered the main
if($unique) {
$existing = [];
for($i = 0; $i < count($emotes); $i++) {
if(in_array($emotes[$i]['emote_url'], $existing)) {
unset($emotes[$i]);
} else {
$existing[] = $emotes[$i]['emote_url'];
}
}
}
return $emotes;
}
2019-06-10 17:04:53 +00:00
function safe_delete(string $path): void {
$path = realpath($path);
2019-06-10 17:04:53 +00:00
if(empty($path)) {
return;
}
2019-06-10 17:04:53 +00:00
if(is_dir($path)) {
rmdir($path);
return;
}
2019-06-10 17:04:53 +00:00
if(is_file($path)) {
unlink($path);
}
}
2019-02-05 20:29:37 +00:00
// mkdir but it fails silently
2019-06-10 17:04:53 +00:00
function mkdirs(string $path, bool $recursive = false, int $mode = 0777): bool {
if(file_exists($path)) {
2019-02-05 20:29:37 +00:00
return true;
}
2019-02-05 20:29:37 +00:00
return mkdir($path, $mode, $recursive);
}
2019-06-10 17:04:53 +00:00
function get_country_name(string $code): string {
switch(strtolower($code)) {
2018-03-22 02:56:41 +00:00
case 'xx':
return 'Unknown';
case 'a1':
return 'Anonymous Proxy';
case 'a2':
return 'Satellite Provider';
default:
return locale_get_display_region("-{$code}", 'en');
}
}
2019-06-10 17:04:53 +00:00
function pdo_prepare_array_update(array $keys, bool $useKeys = false, string $format = '%s'): string {
2018-05-16 02:58:21 +00:00
return pdo_prepare_array($keys, $useKeys, sprintf($format, '`%1$s` = :%1$s'));
}
2019-06-10 17:04:53 +00:00
function pdo_prepare_array(array $keys, bool $useKeys = false, string $format = '`%s`'): string {
2018-05-16 02:58:21 +00:00
$parts = [];
2019-06-10 17:04:53 +00:00
if($useKeys) {
2018-05-16 02:58:21 +00:00
$keys = array_keys($keys);
}
2019-06-10 17:04:53 +00:00
foreach($keys as $key) {
2018-05-16 02:58:21 +00:00
$parts[] = sprintf($format, $key);
}
return implode(', ', $parts);
}
2018-05-24 19:31:48 +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);
try {
\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)) {
\Misuzu\Template::set('message', $message);
2018-08-06 22:19:35 +00:00
}
$template = sprintf($template, $httpCode);
/*if(!tpl_exists($template)) {
2018-08-06 22:19:35 +00:00
$template = 'errors.master';
}*/
2018-08-06 22:19:35 +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-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_link(string $url, ?string $content = null, $attributes = []): string {
2018-07-06 01:28:06 +00:00
$content = $content ?? $url;
$attributes = array_merge(
is_string($attributes) ? ['class' => $attributes] : $attributes,
['href' => $url]
);
2019-06-10 17:04:53 +00:00
if(mb_strpos($url, '://') !== false) {
2018-07-06 01:28:06 +00:00
$attributes['target'] = '_blank';
$attributes['rel'] = 'noreferrer noopener';
}
$html = '<a';
2019-06-10 17:04:53 +00:00
foreach($attributes as $name => $value) {
2018-07-06 01:28:06 +00:00
$value = str_replace('"', '\"', $value);
$html .= " {$name}=\"{$value}\"";
}
$html .= ">{$content}</a>";
return $html;
}
2019-06-10 17:04:53 +00:00
function html_colour(?int $colour, $attribs = '--user-colour'): string {
2018-07-23 13:31:36 +00:00
$colour = $colour ?? colour_none();
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 = '';
$value = colour_get_css($colour);
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
function html_avatar(int $userId, int $resolution, string $altText = '', array $attributes = []): string {
$attributes['src'] = url('user-avatar', ['user' => $userId, 'res' => $resolution * 2]);
$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;
}