4in1_ws_web/src/functions.php
2025-04-28 14:47:25 +03:00

349 lines
9.5 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
function htmlescape(string|array $s): string|array {
if (is_array($s)) {
foreach ($s as $k => $v) {
$s[$k] = htmlescape($v);
}
return $s;
}
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}
function sizeString(int $size): string {
$ks = ['B', 'KiB', 'MiB', 'GiB'];
foreach ($ks as $i => $k) {
if ($size < pow(1024, $i + 1)) {
if ($i == 0)
return $size.' '.$k;
return round($size / pow(1024, $i), 2).' '.$k;
}
}
return $size;
}
function extension(string $name): string {
$expl = explode('.', $name);
return end($expl);
}
/**
* @param string $filename
* @return resource|bool
*/
function imageopen(string $filename) {
$size = getimagesize($filename);
$types = [
1 => 'gif',
2 => 'jpeg',
3 => 'png'
];
if (!$size || !isset($types[$size[2]]))
return null;
return call_user_func('imagecreatefrom'.$types[$size[2]], $filename);
}
function detectImageType(string $filename) {
$size = getimagesize($filename);
$types = [
1 => 'gif',
2 => 'jpg',
3 => 'png'
];
if (!$size || !isset($types[$size[2]]))
return false;
return $types[$size[2]];
}
function transliterate(string $string): string {
$roman = [
'Sch', 'sch', 'Yo', 'Zh', 'Kh', 'Ts', 'Ch', 'Sh', 'Yu', 'ya', 'yo',
'zh', 'kh', 'ts', 'ch', 'sh', 'yu', 'ya', 'A', 'B', 'V', 'G', 'D', 'E',
'Z', 'I', 'Y', 'K', 'L', 'M', 'N', 'O', 'P', 'R', 'S', 'T', 'U', 'F',
'', 'Y', '', 'E', 'a', 'b', 'v', 'g', 'd', 'e', 'z', 'i', 'y', 'k',
'l', 'm', 'n', 'o', 'p', 'r', 's', 't', 'u', 'f', '', 'y', '', 'e'
];
$cyrillic = [
'Щ', 'щ', 'Ё', 'Ж', 'Х', 'Ц', 'Ч', 'Ш', 'Ю', 'я', 'ё', 'ж', 'х', 'ц',
'ч', 'ш', 'ю', 'я', 'А', 'Б', 'В', 'Г', 'Д', 'Е', 'З', 'И', 'Й', 'К',
'Л', 'М', 'Н', 'О', 'П', 'Р', 'С', 'Т', 'У', 'Ф', 'Ь', 'Ы', 'Ъ', 'Э',
'а', 'б', 'в', 'г', 'д', 'е', 'з', 'и', 'й', 'к', 'л', 'м', 'н', 'о',
'п', 'р', 'с', 'т', 'у', 'ф', 'ь', 'ы', 'ъ', 'э'
];
return str_replace($cyrillic, $roman, $string);
}
/**
* @param resource $img
* @param ?int $w
* @param ?int $h
* @param ?int[] $transparent_color
*/
function imageresize(&$img, ?int $w = null, ?int $h = null, ?array $transparent_color = null) {
assert(is_int($w) || is_int($h));
$curw = imagesx($img);
$curh = imagesy($img);
if (!is_int($w) && is_int($h)) {
$w = round($curw / ($curw / $w));
} else if (is_int($w) && !is_int($h)) {
$h = round($curh / ($curh / $h));
}
$img2 = imagecreatetruecolor($w, $h);
if (is_array($transparent_color)) {
list($r, $g, $b) = $transparent_color;
$col = imagecolorallocate($img2, $r, $g, $b);
imagefilledrectangle($img2, 0, 0, $w, $h, $col);
} else {
imagealphablending($img2, false);
imagesavealpha($img2, true);
imagefilledrectangle($img2, 0, 0, $w, $h, imagecolorallocatealpha($img2, 255, 255, 255, 127));
}
imagecopyresampled($img2, $img, 0, 0, 0, 0, $w, $h, $curw, $curh);
imagedestroy($img);
$img = $img2;
}
function rrmdir(string $dir, bool $dont_delete_dir = false): bool {
if (!is_dir($dir)) {
logError('rrmdir: '.$dir.' is not a directory');
return false;
}
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != '.' && $object != '..') {
if (is_dir($dir.'/'.$object)) {
rrmdir($dir.'/'.$object);
} else {
unlink($dir.'/'.$object);
}
}
}
if (!$dont_delete_dir)
rmdir($dir);
return true;
}
function ip2ulong(string $ip): int {
return sprintf("%u", ip2long($ip));
}
function ulong2ip(int $ip): string {
$long = 4294967295 - ($ip - 1);
return long2ip(-$long);
}
function fromCamelCase(string $s): string {
$buf = '';
$len = strlen($s);
for ($i = 0; $i < $len; $i++) {
if (!ctype_upper($s[$i])) {
$buf .= $s[$i];
} else {
$buf .= '_'.strtolower($s[$i]);
}
}
return $buf;
}
function toCamelCase(string $input, string $separator = '_'): string {
return lcfirst(str_replace($separator, '', ucwords($input, $separator)));
}
function strReplaceOnce(string $needle, string $replace, string $haystack) {
$pos = strpos($haystack, $needle);
if ($pos !== false)
$haystack = substr_replace($haystack, $replace, $pos, strlen($needle));
return $haystack;
}
function strgen(int $len): string {
$buf = '';
for ($i = 0; $i < $len; $i++) {
$j = mt_rand(0, 61);
if ($j >= 36) {
$j += 13;
} else if ($j >= 10) {
$j += 7;
}
$buf .= chr(48 + $j);
}
return $buf;
}
function sanitizeFilename(string $name): string {
$name = mb_strtolower($name);
$name = transliterate($name);
$name = preg_replace('/[^\w\d\-_\s.]/', '', $name);
$name = preg_replace('/\s+/', '_', $name);
return $name;
}
function setperm(string $file): void {
global $config;
// chgrp
$gid = filegroup($file);
if ($gid != $config['group']) {
if (!chgrp($file, $config['group'])) {
logError(__FUNCTION__.": chgrp() failed on $file");
}
}
// chmod
$perms = fileperms($file);
$need_perms = is_dir($file) ? $config['dirs_mode'] : $config['files_mode'];
if (($perms & $need_perms) !== $need_perms) {
if (!chmod($file, $need_perms)) {
logError(__FUNCTION__.": chmod() failed on $file");
}
}
}
function saltPassword(string $pwd): string {
global $config;
return hash('sha256', "{$pwd}|{$config['password_salt']}");
}
function exectime(?string $format = null): string|float {
$time = round(microtime(true) - START_TIME, 4);
if (!is_null($format))
$time = sprintf($format, $time);
return $time;
}
function formatNumber(int|float $num, string $delim = ' ', bool $short = false): string {
if ($short) {
if ($num >= 1000000)
return floor($num / 1000000).'m';
if ($num >= 1000)
return floor($num / 1000).'k';
}
return number_format($num, 0, '.', $delim);
}
function jsonEncode($obj): ?string { return json_encode($obj, JSON_UNESCAPED_UNICODE) ?: null; }
function jsonDecode($json) { return json_decode($json, true); }
function pcreNoError(mixed &$result, bool $no_error = false): bool {
if ($result === null) {
if (preg_last_error() !== PREG_NO_ERROR) {
if (!$no_error)
logError('an error occurred while PCRE regex execution: '.preg_last_error_msg());
return false;
}
}
return true;
}
function highlightSubstring(string $s, string|array|null $keywords = []): string {
if (is_null($keywords))
return htmlescape($s);
if ($keywords instanceof Stringable)
$keywords = $keywords->__toString();
else if (is_array($keywords)) {
$keywords = array_map(function($s) {
if ($s instanceof Stringable)
return $s->__toString();
return $s;
}, $keywords);
}
if (is_string($keywords))
$keywords = preg_split('/\s+/', $keywords);
$charset = 'utf-8';
$s_len = mb_strlen($s, $charset);
usort($keywords, function($a, $b) use (&$charset) {
return mb_strlen($b, $charset) - mb_strlen($a, $charset);
});
$all = [];
foreach ($keywords as $kw) {
$kw_len = mb_strlen($kw, $charset);
$offset = 0;
while (($pos = mb_stripos($s, $kw, $offset, $charset)) !== false) {
$offset = $pos + 1;
$all[] = [$pos, $kw_len];
}
}
usort($all, function($a, $b) {
return $a[0] - $b[0];
});
$last_index = 0;
$buf = '';
foreach ($all as $range) {
list($start_pos, $len) = $range;
if ($start_pos < $last_index) {
continue;
}
if ($start_pos > $last_index) {
$buf .= htmlescape(mb_substr($s, $last_index, $start_pos - $last_index, $charset));
}
$buf .= '<span class="matched">'.htmlescape(mb_substr($s, $start_pos, $len, $charset)).'</span>';
$last_index = $start_pos + $len;
}
if ($last_index < $s_len) {
$buf .= htmlescape(mb_substr($s, $last_index, $s_len - $last_index, $charset));
}
return $buf;
}
function formatTime($ts, array $opts = []) {
$default_opts = [
'date_only' => false,
'day_of_week' => false,
'seconds' => false,
'short_months' => false,
'skip_today_date' => false,
'skip_old_time' => false,
'at' => null,
];
$opts = array_merge($default_opts, $opts);
$is_today = date('Ymd') == date('Ymd', $ts);
$date = '';
$skip_old_time = false;
if (!$is_today || !$opts['skip_today_date']) {
$y = (int)date('Y', $ts);
$date .= date('j '.(!$opts['short_months'] ? 'F' : 'M'), $ts);
if ($y != (int)date('Y')) {
$date .= ' ' . $y;
if ($opts['skip_old_time']) {
$skip_old_time = true;
}
}
if ($opts['day_of_week']) {
$date .= ', ' . date('l', $ts);
}
}
if (!$opts['date_only'] && !$skip_old_time) {
if ($date != '') {
$date .= $opts['at'] ?? ' at ';
}
$date .= date('H:i', $ts);
if ($opts['seconds'])
$date .= date(':s', $ts);
}
return $date;
}