misuzu/utility.php

396 lines
9.1 KiB
PHP
Raw Normal View History

<?php
2018-07-15 02:15:12 +00:00
function starts_with(string $string, string $text): bool
{
return mb_substr($string, 0, mb_strlen($text)) === $text;
}
2018-07-15 02:15:12 +00:00
function ends_with(string $string, string $text): bool
{
return mb_substr($string, 0 - mb_strlen($text)) === $text;
}
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 set_cookie_m(string $name, string $value, int $expires): void
{
setcookie(
"msz_{$name}",
$value,
$expires,
'/',
'',
!empty($_SERVER['HTTPS']),
true
);
}
function password_entropy(string $password): int
{
2018-04-16 00:36:50 +00:00
return count(count_chars(utf8_decode($password), 1)) * 8;
}
function fix_path_separator(string $path, string $separator = DIRECTORY_SEPARATOR, array $separators = ['/', '\\']): string
{
return str_replace($separators, $separator, rtrim($path, implode($separators)));
}
function safe_delete(string $path): void
{
$path = realpath($path);
if (empty($path)) {
return;
}
if (is_dir($path)) {
rmdir($path);
return;
}
unlink($path);
}
// mkdir + recursion
function create_directory(string $path): string
{
if (is_file($path)) {
return '';
}
if (is_dir($path)) {
return realpath($path);
}
$on_windows = running_on_windows();
$path = fix_path_separator($path);
$split_path = explode(DIRECTORY_SEPARATOR, $path);
$existing_path = $on_windows ? '' : DIRECTORY_SEPARATOR;
foreach ($split_path as $path_part) {
$existing_path .= $path_part . DIRECTORY_SEPARATOR;
if ($on_windows && mb_substr($path_part, 1, 2) === ':\\') {
continue;
}
if (!file_exists($existing_path)) {
mkdir($existing_path);
}
}
return ($path = realpath($path)) === false ? '' : $path;
}
function build_path(string ...$path): string
{
for ($i = 0; $i < count($path); $i++) {
$path[$i] = fix_path_separator($path[$i]);
}
return implode(DIRECTORY_SEPARATOR, $path);
}
function check_mx_record(string $email): bool
{
$domain = mb_substr(mb_strstr($email, '@'), 1);
return checkdnsrr($domain, 'MX') || checkdnsrr($domain, 'A');
}
2018-07-21 16:01:36 +00:00
function asset_url(string $path): string
{
$realPath = realpath(__DIR__ . '/public/' . $path);
2018-08-12 14:01:26 +00:00
if ($realPath === false || !file_exists($realPath)) {
2018-07-21 16:01:36 +00:00
return $path;
}
return $path . '?' . filemtime($realPath);
}
2017-12-16 22:51:36 +00:00
function dechex_pad(int $value, int $padding = 2): string
{
return str_pad(dechex($value), $padding, '0', STR_PAD_LEFT);
}
2018-01-03 01:12:28 +00:00
function byte_symbol($bytes, $decimal = false)
{
if ($bytes < 1) {
return "0 B";
}
$divider = $decimal ? 1000 : 1024;
$symbols = ['', 'K', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'];
$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' : '');
}
2018-03-22 02:56:41 +00:00
function get_country_name(string $code): string
{
switch (strtolower($code)) {
case 'xx':
return 'Unknown';
case 'a1':
return 'Anonymous Proxy';
case 'a2':
return 'Satellite Provider';
default:
return locale_get_display_region("-{$code}", 'en');
}
}
2018-03-22 18:07:02 +00:00
// this is temporary, don't scream at me for using md5
// BIG TODO: make these functions not dependent on sessions so they can be used outside of those.
2018-05-16 02:58:21 +00:00
function tmp_csrf_verify(string $token): bool
2018-03-22 18:07:02 +00:00
{
2018-05-16 02:58:21 +00:00
return hash_equals(tmp_csrf_token(), $token);
2018-03-22 18:07:02 +00:00
}
2018-05-16 02:58:21 +00:00
function tmp_csrf_token(): string
2018-03-22 18:07:02 +00:00
{
2018-05-16 02:58:21 +00:00
return md5($_COOKIE['msz_sid'] ?? 'this is very insecure lmao');
2018-03-22 18:07:02 +00:00
}
2018-03-24 04:31:42 +00:00
function crop_image_centred_path(string $filename, int $target_width, int $target_height): \Imagick
{
return crop_image_centred(new \Imagick($filename), $target_width, $target_height);
}
function crop_image_centred(Imagick $image, int $target_width, int $target_height): Imagick
{
$image->setImageFormat($image->getNumberImages() > 1 ? 'gif' : 'png');
$image = $image->coalesceImages();
$width = $image->getImageWidth();
$height = $image->getImageHeight();
if ($width > $height) {
$resize_width = $width * $target_height / $height;
$resize_height = $target_height;
} else {
$resize_width = $target_width;
$resize_height = $height * $target_width / $width;
}
do {
$image->resizeImage(
$resize_width,
$resize_height,
Imagick::FILTER_LANCZOS,
0.9
);
$image->cropImage(
$target_width,
$target_height,
($resize_width - $target_width) / 2,
($resize_height - $target_height) / 2
);
$image->setImagePage(
$target_width,
$target_height,
0,
0
);
} while ($image->nextImage());
return $image->deconstructImages();
}
2018-03-31 22:28:32 +00:00
function running_on_windows(): bool
2017-12-16 22:51:36 +00:00
{
return starts_with(mb_strtolower(PHP_OS), 'win');
2017-12-16 21:44:45 +00:00
}
2018-04-14 02:58:53 +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);
}
2018-04-16 00:33:54 +00:00
2018-05-16 02:58:21 +00:00
function pdo_prepare_array_update(array $keys, bool $useKeys = false, string $format = '%s'): string
{
return pdo_prepare_array($keys, $useKeys, sprintf($format, '`%1$s` = :%1$s'));
}
function pdo_prepare_array(array $keys, bool $useKeys = false, string $format = '`%s`'): string
{
$parts = [];
if ($useKeys) {
$keys = array_keys($keys);
}
foreach ($keys as $key) {
$parts[] = sprintf($format, $key);
}
return implode(', ', $parts);
}
2018-05-24 19:31:48 +00:00
2018-08-06 22:19:35 +00:00
function is_local_url(string $url): bool
{
$length = mb_strlen($url);
2018-08-06 22:19:35 +00:00
if ($length < 1) {
return false;
}
if ($url[0] === '/' && ($length > 1 ? $url[1] !== '/' : true)) {
return true;
}
$prefix = 'http' . (empty($_SERVER['HTTPS']) ? '' : 's') . '://' . $_SERVER['HTTP_HOST'] . '/';
return starts_with($url, $prefix);
}
function render_error(int $code, string $template = 'errors.%d'): string
{
2018-08-06 22:19:35 +00:00
return render_info(null, $code, $template);
}
function render_info(?string $message, int $httpCode, string $template = 'errors.%d'): string
{
http_response_code($httpCode);
try {
2018-08-15 01:12:58 +00:00
tpl_var('http_code', $httpCode);
2018-08-06 22:19:35 +00:00
if (mb_strlen($message)) {
2018-08-15 01:12:58 +00:00
tpl_var('message', $message);
2018-08-06 22:19:35 +00:00
}
$template = sprintf($template, $httpCode);
2018-08-15 01:12:58 +00:00
if (!tpl_exists($template)) {
2018-08-06 22:19:35 +00:00
$template = 'errors.master';
}
2018-08-15 01:12:58 +00:00
return tpl_render(sprintf($template, $httpCode));
} catch (Exception $ex) {
2018-08-06 22:19:35 +00:00
echo $ex->getMessage();
return $message ?? '';
}
}
2018-07-06 01:28:06 +00:00
2018-08-06 22:19:35 +00:00
function render_info_or_json(bool $json, string $message, int $httpCode = 200, string $template = 'errors.%d'): string
{
$error = $httpCode >= 400;
http_response_code($httpCode);
if ($json) {
return json_encode([($error ? 'error' : 'message') => $message]);
}
return render_info($message, $httpCode, $template);
}
2018-07-06 01:28:06 +00:00
function html_link(string $url, ?string $content = null, $attributes = []): string
{
$content = $content ?? $url;
$attributes = array_merge(
is_string($attributes) ? ['class' => $attributes] : $attributes,
['href' => $url]
);
if (mb_strpos($url, '://') !== false) {
2018-07-06 01:28:06 +00:00
$attributes['target'] = '_blank';
$attributes['rel'] = 'noreferrer noopener';
}
$html = '<a';
foreach ($attributes as $name => $value) {
$value = str_replace('"', '\"', $value);
$html .= " {$name}=\"{$value}\"";
}
$html .= ">{$content}</a>";
return $html;
}
2018-09-23 14:42:15 +00:00
function html_colour(?int $colour, $attribs = '--user-colour'): string
2018-07-06 01:28:06 +00:00
{
2018-07-23 13:31:36 +00:00
$colour = $colour ?? colour_none();
2018-09-23 14:42:15 +00:00
if (is_string($attribs)) {
$attribs = [
$attribs => '%s',
];
}
2018-07-06 01:28:06 +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);
foreach ($attribs as $name => $format) {
$css .= $name . ':' . sprintf($format, $value) . ';';
}
return $css;
}
function url_construct(string $path, array $query = [], string $host = ''): string
{
$url = $host . $path;
if (count($query)) {
$url .= mb_strpos($path, '?') !== false ? '&' : '?';
foreach ($query as $key => $value) {
if ($value) {
$url .= urlencode($key) . '=' . urlencode($value) . '&';
}
}
}
return mb_substr($url, 0, -1);
}
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, '_'));
}
2018-09-18 22:16:29 +00:00
function is_user_int($value): bool
{
return ctype_digit(strval($value));
}