functions.inc (mrbs-1.9.4) | : | functions.inc (mrbs-1.10.0) | ||
---|---|---|---|---|
skipping to change at line 121 | skipping to change at line 121 | |||
} | } | |||
if (function_exists('openssl_random_pseudo_bytes')) | if (function_exists('openssl_random_pseudo_bytes')) | |||
{ | { | |||
return bin2hex(openssl_random_pseudo_bytes($length)); | return bin2hex(openssl_random_pseudo_bytes($length)); | |||
} | } | |||
return md5(uniqid(rand(), true)); | return md5(uniqid(rand(), true)); | |||
} | } | |||
// A locale aware version of strcasecmp() | ||||
function strcasecmp_locale(string $string1, string $string2) : int | ||||
{ | ||||
// Sort the array. If the order is reversed then $string1 > $string2 | ||||
// (When this function is being used as a callback for usort, and if the origi | ||||
nal array | ||||
// is sorted in ascending order, which it well might be if it's the result of | ||||
// an SQL query with an ORDER BY, then it's fastest to test for $string1 > $st | ||||
ring2 | ||||
// first, as below.) | ||||
$original_array = array($string1, $string2); | ||||
$array = $original_array; | ||||
asort($array,SORT_LOCALE_STRING | SORT_FLAG_CASE); | ||||
if ($array !== $original_array) | ||||
{ | ||||
return 1; | ||||
} | ||||
// Otherwise, flip the array and try again. If the order is reversed then $st | ||||
ring2 > $string1 | ||||
$original_array = array($string2, $string1); | ||||
$array = $original_array; | ||||
asort($array,SORT_LOCALE_STRING | SORT_FLAG_CASE); | ||||
if ($array !== $original_array) | ||||
{ | ||||
return -1; | ||||
} | ||||
// Otherwise they must be equal | ||||
return 0; | ||||
} | ||||
// Returns a name in the format last_name first_name for sorting | // Returns a name in the format last_name first_name for sorting | |||
function get_sortable_name($name) | function get_sortable_name(?string $name) : ?string | |||
{ | { | |||
global $sort_users_by_last_name; | global $sort_users_by_last_name; | |||
if (!isset($name)) | if (!isset($name)) | |||
{ | { | |||
return null; | return null; | |||
} | } | |||
if (empty($sort_users_by_last_name)) | if (empty($sort_users_by_last_name)) | |||
{ | { | |||
return $name; | return $name; | |||
} | } | |||
// Look for anything in brackets (ordinary or square) at the | ||||
// end of the name and treat it as a suffix. For example if | ||||
// the display name is "Joe Bloggs (visitor)" then the last name | ||||
// is really "Bloggs". | ||||
$pattern = '/\s*\(.*\)$|[.*]$/'; | ||||
if (preg_match($pattern, $name, $matches)) | ||||
{ | ||||
$suffix = $matches[0]; | ||||
$name = preg_replace($pattern, '', $name); | ||||
} | ||||
$tokens = explode(' ', $name); | $tokens = explode(' ', $name); | |||
// Get rid of other whitespace (eg tabs) | // Get rid of other whitespace (eg tabs) | |||
$tokens = array_map('trim', $tokens); | $tokens = array_map('trim', $tokens); | |||
// Get the last name | // Get the last name | |||
$result = array_pop($tokens); | $result = array_pop($tokens); | |||
// Add back in the first names | // Add back in the first names | |||
while (null !== ($token = array_shift($tokens))) | while (null !== ($token = array_shift($tokens))) | |||
{ | { | |||
if ($token !== '') // weeds out multiple spaces in a name | if ($token !== '') // weeds out multiple spaces in a name | |||
{ | { | |||
$result .= ' ' . $token; | $result .= ' ' . $token; | |||
} | } | |||
} | } | |||
// Add back in any suffix | ||||
if (isset($suffix)) | ||||
{ | ||||
$result .= $suffix; | ||||
} | ||||
return $result; | return $result; | |||
} | } | |||
function compare_display_names(string $name1, string $name2) : int | ||||
{ | ||||
return strcasecmp_locale(get_sortable_name($name1), get_sortable_name($name2)) | ||||
; | ||||
} | ||||
// Tests whether the request has come via an Ajax call or not. | // Tests whether the request has come via an Ajax call or not. | |||
function is_ajax() | function is_ajax() | |||
{ | { | |||
global $server; | global $server; | |||
return (isset($server['HTTP_X_REQUESTED_WITH']) && | return (isset($server['HTTP_X_REQUESTED_WITH']) && | |||
(utf8_strtolower($server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' )); | (utf8_strtolower($server['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' )); | |||
} | } | |||
// Returns the contents of the URL. If $if_modified_since is set it will send th at | // Returns the contents of the URL. If $if_modified_since is set it will send th at | |||
skipping to change at line 285 | skipping to change at line 334 | |||
if (count($header) == 2) | if (count($header) == 2) | |||
{ | { | |||
$result['headers'][strtolower(trim($header[0]))] = trim($header[1]); | $result['headers'][strtolower(trim($header[0]))] = trim($header[1]); | |||
} | } | |||
} | } | |||
} | } | |||
return $result; | return $result; | |||
} | } | |||
function get_type_options($include_admin_types=false) | function get_type_options(bool $include_admin_types) : array | |||
{ | { | |||
global $booking_types, $auth; | global $booking_types, $auth; | |||
$result = array(); | $result = array(); | |||
if (isset($booking_types)) | if (isset($booking_types)) | |||
{ | { | |||
foreach ($booking_types as $key) | foreach ($booking_types as $key) | |||
{ | { | |||
if (!$include_admin_types && | if (!$include_admin_types && | |||
skipping to change at line 580 | skipping to change at line 629 | |||
} | } | |||
$result = ''; | $result = ''; | |||
} | } | |||
return $result; | return $result; | |||
} | } | |||
// Returns the base URL for MRBS. If the config variable $url_base is set then that | // Returns the base URL for MRBS. If the config variable $url_base is set then that | |||
// overrides the automatic calculation. A '/' will be appended to the end of th e string, | // overrides the automatic calculation. A '/' will be appended to the end of th e string, | |||
// unless it is empty or already ends in a '/'. | // unless it is empty or already ends in a '/'. | |||
function url_base() | function url_base() : string | |||
{ | { | |||
global $url_base, $server; | global $url_base, $server; | |||
if (isset($url_base)) | if (isset($url_base)) | |||
{ | { | |||
$result = $url_base; | $result = $url_base; | |||
} | } | |||
elseif (isset($server['HTTP_HOST'])) | elseif (isset($server['HTTP_HOST'])) | |||
{ | { | |||
$result = $server['HTTP_HOST'] . dirname(url_path()); | $result = $server['HTTP_HOST'] . dirname(url_path()); | |||
} | } | |||
else | else | |||
{ | { | |||
$result = ''; | $result = ''; | |||
} | } | |||
// Add a scheme if we haven't got one | ||||
if (null === parse_url($result, PHP_URL_SCHEME)) | ||||
{ | ||||
$result = ((is_https()) ? 'https' : 'http') . '://' . $result; | ||||
} | ||||
// Add a trailing '/' if there isn't one | ||||
if (($result !== '') && (substr($result, -1) !== '/')) | if (($result !== '') && (substr($result, -1) !== '/')) | |||
{ | { | |||
$result .= '/'; | $result .= '/'; | |||
} | } | |||
return $result; | return $result; | |||
} | } | |||
function is_https() | function is_https() | |||
{ | { | |||
skipping to change at line 629 | skipping to change at line 685 | |||
return (strcasecmp($server['HTTP_X_FORWARDED_SSL'], 'on') === 0); | return (strcasecmp($server['HTTP_X_FORWARDED_SSL'], 'on') === 0); | |||
} | } | |||
return (isset($server['HTTPS']) && | return (isset($server['HTTPS']) && | |||
!empty($server['HTTPS']) && | !empty($server['HTTPS']) && | |||
(strcasecmp($server['HTTPS'], 'off') !== 0)); | (strcasecmp($server['HTTPS'], 'off') !== 0)); | |||
} | } | |||
// Returns the current page. If the page ends in $suffix this will be cut off. | // Returns the current page. If the page ends in $suffix this will be cut off. | |||
// The existing query string is optionally added. | // The existing query string is optionally added. | |||
function this_page($with_query_string=false, $suffix=null) | function this_page($with_query_string=false, $suffix='') | |||
{ | { | |||
global $server; | global $server; | |||
assert(is_bool($with_query_string), '$with_query_string should be a boolean'); | assert(is_bool($with_query_string), '$with_query_string should be a boolean'); | |||
assert(is_null($suffix) || is_string($suffix), '$suffix should be null or a st ring'); | assert(is_string($suffix), '$suffix should be a string'); | |||
if ((!isset($server['SCRIPT_NAME']) || ($server['SCRIPT_NAME'] === '') && !is_ cli())) | if ((!isset($server['SCRIPT_NAME']) || ($server['SCRIPT_NAME'] === '') && !is_ cli())) | |||
{ | { | |||
trigger_error('$_SERVER["SCRIPT_NAME"] is empty. Check your server configur ation.', E_USER_NOTICE); | trigger_error('$_SERVER["SCRIPT_NAME"] is empty. Check your server configur ation.', E_USER_NOTICE); | |||
} | } | |||
// We use basename() because the full name causes problems when reverse proxie s are being used. | // We use basename() because the full name causes problems when reverse proxie s are being used. | |||
$result = basename($server['SCRIPT_NAME'], $suffix); | $result = basename($server['SCRIPT_NAME'], $suffix); | |||
// Get the query string if required | // Get the query string if required | |||
skipping to change at line 692 | skipping to change at line 748 | |||
(isset($parts['pass']) ? ":{$parts['pass']}" : '') . | (isset($parts['pass']) ? ":{$parts['pass']}" : '') . | |||
(isset($parts['user']) ? '@' : '') . | (isset($parts['user']) ? '@' : '') . | |||
(isset($parts['host']) ? "{$parts['host']}" : '') . | (isset($parts['host']) ? "{$parts['host']}" : '') . | |||
(isset($parts['port']) ? ":{$parts['port']}" : '') . | (isset($parts['port']) ? ":{$parts['port']}" : '') . | |||
(isset($parts['path']) ? "{$parts['path']}" : '') . | (isset($parts['path']) ? "{$parts['path']}" : '') . | |||
(isset($parts['query']) ? "?{$parts['query']}" : '') . | (isset($parts['query']) ? "?{$parts['query']}" : '') . | |||
(isset($parts['fragment']) ? "#{$parts['fragment']}" : ''); | (isset($parts['fragment']) ? "#{$parts['fragment']}" : ''); | |||
} | } | |||
// A wrapper for sending a Location header. This function will urlencode and ad d | // A wrapper for sending a Location header. This function will urlencode and ad d | |||
// the site parameter as necesary | // the site parameter as necessary | |||
function location_header($location) | function location_header($location) | |||
{ | { | |||
// Add the site parameter if necessary | // Add the site parameter if necessary | |||
$location = multisite($location); | $location = multisite($location); | |||
// Encode the query string if there is one | // Encode the query string if there is one | |||
$parts = parse_url($location); | $parts = parse_url($location); | |||
if (isset($parts['query'])) | if (isset($parts['query'])) | |||
{ | { | |||
skipping to change at line 1252 | skipping to change at line 1308 | |||
return (($t_secs >= $start_day_secs) || ($t_secs <= $end_day_secs)); | return (($t_secs >= $start_day_secs) || ($t_secs <= $end_day_secs)); | |||
} | } | |||
else | else | |||
{ | { | |||
return (($t_secs >= $start_day_secs) && ($t_secs <= $end_day_secs)); | return (($t_secs >= $start_day_secs) && ($t_secs <= $end_day_secs)); | |||
} | } | |||
} | } | |||
// Takes a Unix timestamp and sets the time, while keeping the day the same. | // Takes a Unix timestamp and sets the time, while keeping the day the same. | |||
// $time is a string in hh:mm format (24 hour clock) | // $time is a string in hh:mm format (24 hour clock) | |||
function timestamp_set_time($timestamp, $time) | function timestamp_set_time(int $timestamp, string $time) : int | |||
{ | { | |||
list($hour, $minute) = explode(':', $time); | list($hour, $minute) = explode(':', $time); | |||
$hour = intval($hour); | $hour = intval($hour); | |||
$minute = intval($minute); | $minute = intval($minute); | |||
$date = new DateTime(); | $date = new DateTime(); | |||
$date->setTimestamp($timestamp); | $date->setTimestamp($timestamp); | |||
$date->setTime($hour, $minute, 0); | $date->setTime($hour, $minute, 0); | |||
return $date->getTimestamp(); | return $date->getTimestamp(); | |||
} | } | |||
skipping to change at line 1717 | skipping to change at line 1773 | |||
$value = filter_var($value, FILTER_SANITIZE_NUMBER_INT); | $value = filter_var($value, FILTER_SANITIZE_NUMBER_INT); | |||
$value = ($value === '') ? null : (int) ltrim($value, '0'); | $value = ($value === '') ? null : (int) ltrim($value, '0'); | |||
} | } | |||
} | } | |||
unset($value); // Break the reference (not necessary here, but good practice) | unset($value); // Break the reference (not necessary here, but good practice) | |||
return $result; | return $result; | |||
} | } | |||
// Validates that a string is a valid ISO date in yyyy-mm-dd format | ||||
function validate_iso_date($date) : bool | ||||
{ | ||||
if (!is_string($date)) | ||||
{ | ||||
return false; | ||||
} | ||||
// Try creating a DateTime object. If that is successful and | ||||
// the inverse operation gives the original string then it is | ||||
// valid. (This is to check that, for example, 2021-09-31 hasn't | ||||
// been converted into 2021-10-01). | ||||
$format = 'Y-m-d'; | ||||
$datetime = DateTime::createFromFormat($format, $date); | ||||
return ($datetime && ($datetime->format($format) === $date)); | ||||
} | ||||
// Get the local day name based on language. Note 2000-01-02 is a Sunday. | // Get the local day name based on language. Note 2000-01-02 is a Sunday. | |||
function day_name($daynumber, $format=null) | function day_name($daynumber, $format=null) | |||
{ | { | |||
global $strftime_format; | global $strftime_format; | |||
if (!isset($format)) | if (!isset($format)) | |||
{ | { | |||
$format = $strftime_format['dayname']; | $format = $strftime_format['dayname']; | |||
} | } | |||
End of changes. 13 change blocks. | ||||
7 lines changed or deleted | 85 lines changed or added |