2009-08-27 12:48:09 +00:00
|
|
|
<?php
|
|
|
|
|
|
2014-01-28 12:38:06 +00:00
|
|
|
/*
|
2022-02-06 20:37:02 +00:00
|
|
|
This file is a part of myTinyTodo.
|
|
|
|
|
(C) Copyright 2009-2010,2020-2022 Max Pozdeev <maxpozdeev@gmail.com>
|
|
|
|
|
Licensed under the GNU GPL version 2 or any later. See file COPYRIGHT for details.
|
2014-01-28 12:38:06 +00:00
|
|
|
*/
|
|
|
|
|
|
2009-08-27 12:48:09 +00:00
|
|
|
function htmlarray($a, $exclude=null)
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
htmlarray_ref($a, $exclude);
|
|
|
|
|
return $a;
|
2009-08-27 12:48:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function htmlarray_ref(&$a, $exclude=null)
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if(!$a) return;
|
|
|
|
|
if(!is_array($a)) {
|
|
|
|
|
$a = htmlspecialchars($a);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
reset($a);
|
|
|
|
|
if($exclude && !is_array($exclude)) $exclude = array($exclude);
|
|
|
|
|
foreach($a as $k=>$v)
|
|
|
|
|
{
|
|
|
|
|
if(is_array($v)) $a[$k] = htmlarray($v, $exclude);
|
2022-02-17 17:13:41 +00:00
|
|
|
elseif(!$exclude) $a[$k] = htmlspecialchars($v ?? '');
|
|
|
|
|
elseif(!in_array($k, $exclude)) $a[$k] = htmlspecialchars($v ?? '');
|
2022-02-06 20:37:02 +00:00
|
|
|
}
|
|
|
|
|
return;
|
2009-08-27 12:48:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _post($param,$defvalue = '')
|
|
|
|
|
{
|
2022-07-10 12:35:19 +00:00
|
|
|
if(!isset($_POST[$param])) {
|
2022-02-06 20:37:02 +00:00
|
|
|
return $defvalue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return $_POST[$param];
|
|
|
|
|
}
|
2009-08-27 12:48:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function _get($param,$defvalue = '')
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if(!isset($_GET[$param])) {
|
|
|
|
|
return $defvalue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return $_GET[$param];
|
|
|
|
|
}
|
2020-10-14 18:20:44 +00:00
|
|
|
}
|
2009-08-27 12:48:09 +00:00
|
|
|
|
2020-09-12 13:17:43 +00:00
|
|
|
function _server($param, $defvalue = '')
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if ( !isset($_SERVER[$param]) ) {
|
|
|
|
|
return $defvalue;
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
return $_SERVER[$param];
|
|
|
|
|
}
|
2020-09-12 13:17:43 +00:00
|
|
|
}
|
|
|
|
|
|
2009-11-01 14:42:36 +00:00
|
|
|
function formatDate3($format, $ay, $am, $ad, $lang)
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
# F - month long, M - month short
|
|
|
|
|
# m - month 2-digit, n - month 1-digit
|
|
|
|
|
# d - day 2-digit, j - day 1-digit
|
|
|
|
|
$ml = $lang->get('months_long');
|
|
|
|
|
$ms = $lang->get('months_short');
|
|
|
|
|
$Y = $ay;
|
|
|
|
|
$YC = 100 * floor($Y/100); //...1900,2000,2100...
|
|
|
|
|
if ($YC == 2000) $y = $Y < $YC+10 ? '0'.($Y-$YC) : $Y-$YC;
|
|
|
|
|
else $y = $Y;
|
|
|
|
|
$n = $am;
|
|
|
|
|
$m = $n < 10 ? '0'.$n : $n;
|
|
|
|
|
$F = $ml[$am-1];
|
|
|
|
|
$M = $ms[$am-1];
|
|
|
|
|
$j = $ad;
|
|
|
|
|
$d = $j < 10 ? '0'.$j : $j;
|
|
|
|
|
return strtr($format, array('Y'=>$Y, 'y'=>$y, 'F'=>$F, 'M'=>$M, 'n'=>$n, 'm'=>$m, 'd'=>$d, 'j'=>$j));
|
2009-11-01 14:42:36 +00:00
|
|
|
}
|
|
|
|
|
|
2023-09-10 08:54:22 +00:00
|
|
|
function daysInMonth(int $m, int $y = 0): int
|
|
|
|
|
{
|
|
|
|
|
if ($y == 0) $y = (int)date('Y');
|
|
|
|
|
$isLeap = (0 == $y % 4) && ((0 != $y % 100) || (0 == $y % 400));
|
|
|
|
|
$a = array(1=>31, ($isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
|
|
|
|
|
if (isset($a[$m])) return $a[$m];
|
|
|
|
|
else return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2022-02-06 11:15:21 +00:00
|
|
|
function getRequestUri()
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
// Do not use HTTP_X_REWRITE_URL due to CVE-2018-14773
|
|
|
|
|
// SCRIPT_NAME or PATH_INFO ?
|
2022-07-10 12:23:53 +00:00
|
|
|
if (isset($_SERVER['SCRIPT_NAME'])) {
|
|
|
|
|
return $_SERVER['SCRIPT_NAME'];
|
|
|
|
|
}
|
|
|
|
|
elseif (isset($_SERVER['REQUEST_URI'])) {
|
2022-02-06 20:37:02 +00:00
|
|
|
return $_SERVER['REQUEST_URI'];
|
|
|
|
|
}
|
|
|
|
|
else if (isset($_SERVER['ORIG_PATH_INFO'])) // IIS 5.0 CGI
|
|
|
|
|
{
|
|
|
|
|
$uri = $_SERVER['ORIG_PATH_INFO']; //has no query
|
|
|
|
|
if (!empty($_SERVER['QUERY_STRING'])) $uri .= '?'. $_SERVER['QUERY_STRING'];
|
|
|
|
|
return $uri;
|
|
|
|
|
}
|
2022-02-06 11:15:21 +00:00
|
|
|
}
|
|
|
|
|
|
2020-10-05 15:16:20 +00:00
|
|
|
function url_dir($url, $onlyPath = 1)
|
2010-02-06 14:51:44 +00:00
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if (false !== $p = strpos($url, '?')) {
|
|
|
|
|
$url = substr($url, 0, $p); # to avoid parse errors on strange query strings
|
|
|
|
|
}
|
|
|
|
|
if ($onlyPath) {
|
|
|
|
|
$url = parse_url($url, PHP_URL_PATH);
|
|
|
|
|
}
|
|
|
|
|
if ($url == '') {
|
|
|
|
|
return '/';
|
|
|
|
|
}
|
|
|
|
|
if (substr($url, -1) == '/') {
|
|
|
|
|
return $url;
|
|
|
|
|
}
|
|
|
|
|
if (false !== $p = strrpos($url, '/')) {
|
|
|
|
|
return substr($url, 0, $p+1);
|
|
|
|
|
}
|
|
|
|
|
return '/';
|
2010-02-06 14:51:44 +00:00
|
|
|
}
|
|
|
|
|
|
2021-09-06 19:52:08 +00:00
|
|
|
function removeNewLines($s)
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
return str_replace( ["\r","\n"], '', $s );
|
2021-09-06 19:52:08 +00:00
|
|
|
}
|
|
|
|
|
|
2022-01-31 20:01:59 +00:00
|
|
|
/**
|
|
|
|
|
* Generates UUID v4
|
|
|
|
|
* Implementation from https://github.com/symfony/polyfill-uuid
|
|
|
|
|
*/
|
|
|
|
|
function generateUUID(): string
|
2010-08-14 17:02:35 +00:00
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
$uuid = bin2hex(random_bytes(16));
|
|
|
|
|
return sprintf('%08s-%04s-4%03s-%04x-%012s',
|
|
|
|
|
substr($uuid, 0, 8),
|
|
|
|
|
substr($uuid, 8, 4),
|
|
|
|
|
// $uuid[14] = 4
|
|
|
|
|
substr($uuid, 13, 3),
|
|
|
|
|
hexdec(substr($uuid, 16, 4)) & 0x3fff | 0x8000,
|
|
|
|
|
substr($uuid, 20, 12)
|
2010-08-14 17:02:35 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-02-06 11:08:15 +00:00
|
|
|
function passwordHash(string $p): string
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if ($p == '') return '';
|
|
|
|
|
return 'sha256:'. hash('sha256', $p);
|
2022-02-06 11:08:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Compares raw (not hashed) password with password hash. Return true if equals.
|
|
|
|
|
* @param string $p Raw password
|
|
|
|
|
* @param string $hash Password hash
|
|
|
|
|
* @return bool
|
|
|
|
|
*/
|
|
|
|
|
function isPasswordEqualsToHash(string $p, string $hash): bool
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if ($hash == '' && $p == '') return true;
|
|
|
|
|
if ($hash == '' || $p == '') return false;
|
|
|
|
|
if ( false !== $pos = strpos($hash, ':') ) {
|
|
|
|
|
$algo = substr($hash, 0, $pos);
|
|
|
|
|
if ($algo != 'sha256') throw new Exception("Unsupported algo of password hash");
|
|
|
|
|
if ( hash_equals($hash, passwordHash($p)) ) return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
2022-02-06 11:08:15 +00:00
|
|
|
}
|
|
|
|
|
|
2022-02-06 11:52:39 +00:00
|
|
|
function idSignature(string $id, string $key, string $salt): string
|
|
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
$secret = $key.$salt;
|
|
|
|
|
return hash_hmac('sha256', $id, $secret);
|
2022-02-06 11:52:39 +00:00
|
|
|
}
|
|
|
|
|
|
2022-02-07 06:57:03 +00:00
|
|
|
function isValidSignature(string $signature, string $id, string $key, string $salt): bool
|
2022-02-06 11:52:39 +00:00
|
|
|
{
|
2022-02-06 20:37:02 +00:00
|
|
|
if ( hash_equals($signature, idSignature($id, $key, $salt)) ) return true;
|
|
|
|
|
return false;
|
2022-02-06 11:52:39 +00:00
|
|
|
}
|
2022-08-11 14:59:57 +00:00
|
|
|
|
|
|
|
|
|
2022-09-08 08:18:31 +00:00
|
|
|
function randomString(int $len = 16, string $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ') : string
|
2022-08-11 14:59:57 +00:00
|
|
|
{
|
|
|
|
|
$a = [];
|
|
|
|
|
$max = strlen($chars) - 1;
|
|
|
|
|
for ($i = 0; $i < $len; $i++) {
|
|
|
|
|
$a[]= $chars[random_int(0, $max)];
|
|
|
|
|
}
|
|
|
|
|
return implode('', $a);
|
|
|
|
|
}
|