浏览代码

Upgrade method signatures.

mscherer 2 年之前
父节点
当前提交
39ef890765

+ 0 - 8
config/bootstrap.php

@@ -156,10 +156,6 @@ if (!function_exists('hDec')) {
 	 * @return string Converted text
 	 */
 	function hDec(string $text, int $quoteStyle = ENT_QUOTES): string {
-		if (is_array($text)) {
-			return array_map('hDec', $text);
-		}
-
 		return trim(htmlspecialchars_decode($text, $quoteStyle));
 	}
 }
@@ -173,10 +169,6 @@ if (!function_exists('entDec')) {
 	 * @return string Converted text
 	 */
 	function entDec(string $text, int $quoteStyle = ENT_QUOTES): string {
-		if (is_array($text)) {
-			return array_map('entDec', $text);
-		}
-
 		return !empty($text) ? trim(html_entity_decode($text, $quoteStyle, 'UTF-8')) : '';
 	}
 }

+ 60 - 0
src/Utility/Clock.php

@@ -0,0 +1,60 @@
+<?php
+
+namespace Tools\Utility;
+
+class Clock {
+
+	/**
+	 * @var float
+	 */
+	protected static $_counterStartTime = 0.0;
+
+	/**
+	 * Returns microtime as float value
+	 * (to be subtracted right away)
+	 *
+	 * @param int $precision
+	 *
+	 * @return float
+	 */
+	public static function microtime(int $precision = 8): float {
+		return round(microtime(true), $precision);
+	}
+
+	/**
+	 * @return void
+	 */
+	public static function startClock(): void {
+		static::$_counterStartTime = static::microtime();
+	}
+
+	/**
+	 * @param int $precision
+	 * @param bool $restartClock
+	 * @return float
+	 */
+	public static function returnElapsedTime($precision = 8, $restartClock = false): float {
+		$startTime = static::$_counterStartTime;
+		if ($restartClock) {
+			static::startClock();
+		}
+
+		return static::calcElapsedTime($startTime, static::microtime(), $precision);
+	}
+
+	/**
+	 * Returns microtime as float value
+	 * (to be subtracted right away)
+	 *
+	 * @param float $start
+	 * @param float $end
+	 * @param int $precision
+	 * @return float
+	 */
+	public static function calcElapsedTime($start, $end, $precision = 8) {
+		$elapsed = $end - $start;
+
+		return round($elapsed, $precision);
+	}
+
+}

+ 55 - 33
src/Utility/DateTime.php

@@ -2,6 +2,8 @@
 
 namespace Tools\Utility;
 
+use Cake\Chronos\Chronos;
+use Cake\Chronos\ChronosDate;
 use Cake\Core\Configure;
 use Cake\I18n\Date as CakeDate;
 use Cake\I18n\DateTime as CakeDateTime;
@@ -10,6 +12,7 @@ use DateTime as NativeDateTime;
 use DateTimeInterface;
 use DateTimeZone;
 use IntlDateFormatter;
+use InvalidArgumentException;
 
 /**
  * Extend CakeTime with a few important improvements:
@@ -18,10 +21,13 @@ use IntlDateFormatter;
 class DateTime extends CakeDateTime {
 
 	/**
-	 * @param \DateTimeInterface|array|string|int|null $time Fixed or relative time
-	 * @param \DateTimeZone|string|null $tz The timezone for the instance
+	 * @param \Cake\Chronos\Chronos|\Cake\Chronos\ChronosDate|\DateTimeInterface|array|string|int|null $time Fixed or relative time
+	 * @param \DateTimeZone|string|null $timezone The timezone for the instance
 	 */
-	public function __construct($time = null, $tz = null) {
+	public function __construct(
+		Chronos|ChronosDate|DateTimeInterface|string|int|array|null $time = 'now',
+		DateTimeZone|string|null $timezone = null,
+	) {
 		if (is_array($time)) {
 			$value = $time + ['hour' => 0, 'minute' => 0, 'second' => 0];
 
@@ -47,7 +53,7 @@ class DateTime extends CakeDateTime {
 			$time = $format;
 		}
 
-		parent::__construct($time, $tz);
+		parent::__construct($time, $timezone);
 	}
 
 	/**
@@ -56,7 +62,7 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeZone|string|null $timezone User's timezone string or DateTimeZone object
 	 * @return bool
 	 */
-	public function hasDaylightSavingTime($timezone = null) {
+	public function hasDaylightSavingTime($timezone = null): bool {
 		$timezone = $this->safeCreateDateTimeZone($timezone);
 		// a date outside of DST
 		$offset = $timezone->getOffset(new NativeDateTime('@' . mktime(0, 0, 0, 2, 1, (int)date('Y'))));
@@ -81,7 +87,7 @@ class DateTime extends CakeDateTime {
 	 * @param array<string, mixed> $options
 	 * @return int The distance in seconds
 	 */
-	public static function difference($startTime, $endTime = null, array $options = []) {
+	public static function difference($startTime, $endTime = null, array $options = []): int {
 		if (!is_int($startTime)) {
 			$startTime = strtotime($startTime);
 		}
@@ -90,7 +96,7 @@ class DateTime extends CakeDateTime {
 		}
 
 		//@FIXME: make it work for > month
-		return abs($endTime - $startTime);
+		return (int)abs($endTime - $startTime);
 	}
 
 	/**
@@ -102,7 +108,7 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeInterface|string|int|null $end End date (if empty, use today)
 	 * @return int Age (0 if both timestamps are equal or empty, -1 on invalid dates)
 	 */
-	public static function age($start, $end = null) {
+	public static function age($start, $end = null): int {
 		if (!$start && !$end || $start == $end) {
 			return 0;
 		}
@@ -139,9 +145,9 @@ class DateTime extends CakeDateTime {
 	 *
 	 * @param int $year
 	 * @param int|null $month (optional)
-	 * @return string|int Age
+	 * @return string Age
 	 */
-	public static function ageByYear($year, $month = null) {
+	public static function ageByYear(int $year, ?int $month = null): string {
 		if ($month === null) {
 			$maxAge = static::age(mktime(0, 0, 0, 1, 1, $year));
 			$minAge = static::age(mktime(23, 59, 59, 12, 31, $year));
@@ -158,7 +164,7 @@ class DateTime extends CakeDateTime {
 			return implode('/', $ages);
 		}
 
-		return static::age(mktime(0, 0, 0, $month, 1, $year));
+		return (string)static::age(mktime(0, 0, 0, $month, 1, $year));
 	}
 
 	/**
@@ -170,9 +176,10 @@ class DateTime extends CakeDateTime {
 	 * @param int|null $month
 	 * @param int|null $day
 	 * @param int $steps
+	 *
 	 * @return mixed
 	 */
-	public static function ageRange($year, $month = null, $day = null, $steps = 1) {
+	public static function ageRange(int $year, ?int $month = null, ?int $day = null, int $steps = 1) {
 		if ($month == null && $day == null) {
 			$age = (int)date('Y') - $year - 1;
 		} elseif ($day == null) {
@@ -207,9 +214,10 @@ class DateTime extends CakeDateTime {
 	 *
 	 * @param int $year
 	 * @param int $month
+	 *
 	 * @return int Days
 	 */
-	public static function daysInMonth($year, $month) {
+	public static function daysInMonth(int $year, int $month): int {
 		return (int)date('t', mktime(0, 0, 0, $month, 1, $year));
 	}
 
@@ -221,11 +229,11 @@ class DateTime extends CakeDateTime {
 	 * Exception: Dates of the calender week of the previous year return 0. In this case the cweek of the
 	 * last week of the previous year should be used.
 	 *
-	 * @param mixed|null $dateString In DB format - if none is passed, current day is used
+	 * @param string|null $dateString In DB format - if none is passed, current day is used
 	 * @param int $relative - weeks relative to the date (+1 next, -1 previous etc)
 	 * @return string
 	 */
-	public static function cWeek($dateString = null, $relative = 0) {
+	public static function cWeek(?string $dateString = null, int $relative = 0): string {
 		if ($dateString) {
 			$date = explode(' ', $dateString);
 			[$y, $m, $d] = explode('-', $date[0]);
@@ -254,9 +262,10 @@ class DateTime extends CakeDateTime {
 	 * 0=sunday to 7=saturday (default)
 	 *
 	 * @param int $num Number of day.
+	 *
 	 * @return int Days since the start of the week.
 	 */
-	public static function cWeekMod($num) {
+	public static function cWeekMod(int $num): int {
 		$base = 6;
 
 		return (int)($num - $base * floor($num / $base));
@@ -268,9 +277,10 @@ class DateTime extends CakeDateTime {
 	 *
 	 * @param int $year (format xxxx)
 	 * @param int $cWeek (optional, defaults to first, range 1...52/53)
+	 *
 	 * @return int Timestamp
 	 */
-	public static function cWeekBeginning($year, $cWeek = 0) {
+	public static function cWeekBeginning(int $year, int $cWeek = 0): int {
 		if ($cWeek <= 1 || $cWeek > static::cWeeks($year)) {
 			$first = mktime(0, 0, 0, 1, 1, $year);
 			$weekDay = (int)date('w', $first);
@@ -288,6 +298,9 @@ class DateTime extends CakeDateTime {
 			return $firstmonday;
 		}
 		$monday = strtotime($year . 'W' . static::pad((string)$cWeek) . '1');
+		if ($monday === false) {
+			throw new InvalidArgumentException('Not a valid strtotime() value');
+		}
 
 		return $monday;
 	}
@@ -298,9 +311,10 @@ class DateTime extends CakeDateTime {
 	 *
 	 * @param int $year (format xxxx)
 	 * @param int $cWeek (optional, defaults to last, range 1...52/53)
+	 *
 	 * @return int Timestamp
 	 */
-	public static function cWeekEnding($year, $cWeek = 0) {
+	public static function cWeekEnding(int $year, int $cWeek = 0): int {
 		if ($cWeek < 1 || $cWeek >= static::cWeeks($year)) {
 			return static::cWeekBeginning($year + 1) - 1;
 		}
@@ -312,9 +326,10 @@ class DateTime extends CakeDateTime {
 	 * Calculate the amount of calender weeks in a year
 	 *
 	 * @param int|null $year (format xxxx, defaults to current year)
+	 *
 	 * @return int Amount of weeks - 52 or 53
 	 */
-	public static function cWeeks($year = null) {
+	public static function cWeeks(?int $year = null): int {
 		if ($year === null) {
 			$year = date('Y');
 		}
@@ -365,9 +380,10 @@ class DateTime extends CakeDateTime {
 	 * @param int|null $secondAge (defaults to first one if not specified)
 	 * @param bool $returnAsString
 	 * @param string|null $relativeTime
+	 *
 	 * @return array Array('min'=>$min, 'max'=>$max);
 	 */
-	public static function ageBounds($firstAge, $secondAge = null, $returnAsString = false, $relativeTime = null) {
+	public static function ageBounds(int $firstAge, ?int $secondAge = null, bool $returnAsString = false, ?string $relativeTime = null): array {
 		if ($secondAge === null) {
 			$secondAge = $firstAge;
 		}
@@ -390,9 +406,10 @@ class DateTime extends CakeDateTime {
 	 *
 	 * @param string $dateString
 	 * @param int $seconds
+	 *
 	 * @return bool Success
 	 */
-	public static function isInRange($dateString, $seconds) {
+	public static function isInRange(string $dateString, int $seconds): bool {
 		$newDate = time();
 
 		return static::difference($dateString, $newDate) <= $seconds;
@@ -591,7 +608,7 @@ class DateTime extends CakeDateTime {
 	 * @param int $offset int 0-6 (defaults to 0) [1 => 1=monday to 7=sunday]
 	 * @return string translatedText
 	 */
-	public static function dayName($day, $abbr = false, $offset = 0) {
+	public static function dayName($day, $abbr = false, $offset = 0): string {
 		$days = [
 			'long' => [
 				'Sunday',
@@ -633,7 +650,7 @@ class DateTime extends CakeDateTime {
 	 * - appendDot (only for 3 letter abbr; defaults to false)
 	 * @return string translatedText
 	 */
-	public static function monthName($month, $abbr = false, array $options = []) {
+	public static function monthName($month, $abbr = false, array $options = []): string {
 		$months = [
 			'long' => [
 				'January',
@@ -934,9 +951,10 @@ class DateTime extends CakeDateTime {
 	 * - default, separator
 	 * - boolean zero: if false: 0 days 5 hours => 5 hours etc.
 	 * - verbose/past/future: string with %s or boolean true/false
+	 *
 	 * @return array|string
 	 */
-	public static function relLengthOfTime($date, $format = null, array $options = []) {
+	public static function relLengthOfTime($date, ?string $format = null, array $options = []) {
 		$dateTime = $date;
 		if ($date !== null && !is_object($date)) {
 			$dateTime = static::parse($date);
@@ -986,7 +1004,7 @@ class DateTime extends CakeDateTime {
 	 * @param \Cake\Chronos\Chronos $date Datetime
 	 * @return bool True if datetime string was day before yesterday
 	 */
-	public static function wasDayBeforeYesterday($date) {
+	public static function wasDayBeforeYesterday($date): bool {
 		return $date->toDateString() === static::now()->subDays(2)->toDateString();
 	}
 
@@ -996,7 +1014,7 @@ class DateTime extends CakeDateTime {
 	 * @param \Cake\Chronos\Chronos $date Datetime
 	 * @return bool True if datetime string is day after tomorrow
 	 */
-	public static function isDayAfterTomorrow($date) {
+	public static function isDayAfterTomorrow($date): bool {
 		return $date->toDateString() === static::now()->addDays(2)->toDateString();
 	}
 
@@ -1007,7 +1025,7 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeZone|string|null $timezone User's timezone
 	 * @return bool True if datetime is not today AND is in the future
 	 */
-	public static function isNotTodayAndInTheFuture($dateString, $timezone = null) {
+	public static function isNotTodayAndInTheFuture($dateString, $timezone = null): bool {
 		$date = new CakeDateTime($dateString, $timezone);
 		$date = $date->format('U');
 
@@ -1021,7 +1039,7 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeZone|string|null $timezone User's timezone
 	 * @return bool True if datetime is not today AND is in the future
 	 */
-	public static function isInTheFuture($date, $timezone = null) {
+	public static function isInTheFuture($date, $timezone = null): bool {
 		if (!($date instanceof DateTimeInterface)) {
 			$date = new CakeDateTime($date, $timezone);
 		}
@@ -1042,7 +1060,7 @@ class DateTime extends CakeDateTime {
 	 * - end: last second of this interval
 	 * @return string timestamp
 	 */
-	public static function parseLocalizedDate($date, $format = null, $type = 'start') {
+	public static function parseLocalizedDate($date, $format = null, $type = 'start'): string {
 		$date = trim($date);
 		$i18n = [
 			strtolower(__d('tools', 'Today')) => ['start' => date(FORMAT_DB_DATETIME, mktime(0, 0, 0, (int)date('m'), (int)date('d'), (int)date('Y'))), 'end' => date(FORMAT_DB_DATETIME, mktime(23, 59, 59, (int)date('m'), (int)date('d'), (int)date('Y')))],
@@ -1097,9 +1115,10 @@ class DateTime extends CakeDateTime {
 	 * @param array<string, mixed> $options
 	 * - separator (defaults to space [ ])
 	 * - format (defaults to Y-m-d H:i:s)
+	 *
 	 * @return array period [0=>min, 1=>max]
 	 */
-	public static function period($searchString, array $options = []) {
+	public static function period(string $searchString, array $options = []): array {
 		if (strpos($searchString, ' ') !== false) {
 			$filters = explode(' ', $searchString);
 			$filters = [array_shift($filters), array_pop($filters)];
@@ -1121,9 +1140,10 @@ class DateTime extends CakeDateTime {
 	 * @param string $searchString to parse
 	 * @param string $fieldName (Model.field)
 	 * @param array<string, mixed> $options (see Time::period)
+	 *
 	 * @return string query SQL Query
 	 */
-	public static function periodAsSql($searchString, $fieldName, array $options = []) {
+	public static function periodAsSql(string $searchString, string $fieldName, array $options = []): string {
 		$period = static::period($searchString, $options);
 
 		return static::daysAsSql($period[0], $period[1], $fieldName);
@@ -1136,9 +1156,10 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeInterface|string|int $end UNIX timestamp, strtotime() valid string or DateTime object
 	 * @param string $fieldName Name of database field to compare with
 	 * @param \DateTimeZone|string|null $timezone Timezone string or DateTimeZone object
+	 *
 	 * @return string Partial SQL string.
 	 */
-	public static function daysAsSql($begin, $end, $fieldName, $timezone = null) {
+	public static function daysAsSql(DateTimeInterface|int|string $begin, DateTimeInterface|int|string $end, string $fieldName, DateTimeZone|string|null $timezone = null): string {
 		$begin = new CakeDateTime($begin, $timezone);
 		$begin = $begin->format('U');
 		$end = new CakeDateTime($end, $timezone);
@@ -1156,9 +1177,10 @@ class DateTime extends CakeDateTime {
 	 * @param \DateTimeInterface|string|int $dateString UNIX timestamp, strtotime() valid string or DateTime object
 	 * @param string $fieldName Name of database field to compare with
 	 * @param \DateTimeZone|string|null $timezone Timezone string or DateTimeZone object
+	 *
 	 * @return string Partial SQL string.
 	 */
-	public static function dayAsSql($dateString, $fieldName, $timezone = null) {
+	public static function dayAsSql(DateTimeInterface|int|string $dateString, string $fieldName, DateTimeZone|string|null $timezone = null): string {
 		return static::daysAsSql($dateString, $dateString, $fieldName, $timezone);
 	}
 

+ 7 - 8
src/Utility/Language.php

@@ -14,18 +14,15 @@ class Language {
 	 * - forceLowerCase: defaults to true
 	 *
 	 * @param string|null $languageList List of locales/language codes.
-	 * @param array|bool|null $options Flags to forceLowerCase or removeDuplicates locales/language codes
-	 *        deprecated: Set to true/false to toggle lowercase
+	 * @param array $options Flags to forceLowerCase or removeDuplicates locales/language codes
 	 *
 	 * @return array
 	 */
-	public static function parseLanguageList($languageList = null, $options = []) {
+	public static function parseLanguageList(string $languageList = null, array $options = []): array
+	{
 		$defaultOptions = [
 			'forceLowerCase' => true,
 		];
-		if (!is_array($options)) {
-			$options = ['forceLowerCase' => $options];
-		}
 		$options += $defaultOptions;
 
 		if ($languageList === null) {
@@ -118,7 +115,8 @@ class Language {
 	 * @param array $available
 	 * @return array
 	 */
-	public static function findMatches(array $accepted, array $available = []) {
+	public static function findMatches(array $accepted, array $available = []): array
+	{
 		$matches = [];
 		if (!$available) {
 			$available = static::parseLanguageList();
@@ -157,9 +155,10 @@ class Language {
 	 *
 	 * @param string $a
 	 * @param string $b
+	 *
 	 * @return float
 	 */
-	protected static function _matchLanguage($a, $b) {
+	protected static function _matchLanguage(string $a, string $b) {
 		$a = explode('-', strtolower($a));
 		$b = explode('-', strtolower($b));
 

+ 3 - 2
src/Utility/Mime.php

@@ -719,9 +719,10 @@ class Mime extends Response {
 	 * Retrieve the corresponding MIME type, if one exists
 	 *
 	 * @param string|null $file File Name (relative location such as "image_test.jpg" or full "http://site.com/path/to/image_test.jpg")
-	 * @return string MIMEType - The type of the file passed in the argument
+	 *
+	 * @return array|string MIMEType - The type of the file passed in the argument
 	 */
-	public function detectMimeType($file = null) {
+	public function detectMimeType(?string $file = null): array|string {
 		// Attempts to retrieve file info from FINFO
 		// If FINFO functions are not available then try to retrieve MIME type from pre-defined MIMEs
 		// If MIME type doesn't exist, then try (as a last resort) to use the (deprecated) mime_content_type function

+ 26 - 31
src/Utility/Number.php

@@ -45,12 +45,14 @@ class Number extends CakeNumber {
 	/**
 	 * Convenience method to display the default currency
 	 *
-	 * @param float $amount
+	 * @param float $value
 	 * @param array $formatOptions
+	 *
 	 * @return string
 	 */
-	public static function money($amount, array $formatOptions = []) {
-		return static::currency($amount, null, $formatOptions);
+	public static function money($value, array $formatOptions = []): string
+	{
+		return static::currency($value, null, $formatOptions);
 	}
 
 	/**
@@ -141,39 +143,23 @@ class Number extends CakeNumber {
 	 *
 	 * - signed: true/false
 	 *
-	 * @param float $number
+	 * @param string|int|float $value
 	 * @param string|null $currency
 	 * @param array<string, mixed> $options
+	 *
 	 * @return string
 	 */
-	public static function currency($number, ?string $currency = null, array $options = []): string {
+	public static function currency(string|float|int $value, ?string $currency = null, array $options = []): string {
 		$defaults = [
 			'positive' => '+', 'signed' => false,
 		];
 		$options += $defaults;
 		$sign = '';
-		if ($number > 0 && !empty($options['signed'])) {
+		if ($value > 0 && !empty($options['signed'])) {
 			$sign = $options['positive'];
 		}
 
-		return $sign . parent::currency($number, $currency, $options);
-	}
-
-	/**
-	 * Returns a formatted-for-humans file size.
-	 *
-	 * @link http://book.cakephp.org/2.0/en/core-libraries/helpers/number.html#NumberHelper::toReadableSize
-	 * @param int $size Size in bytes
-	 * @param string $decimals
-	 * @return string Human readable size
-	 */
-	public static function _toReadableSize($size, $decimals = '.'): string {
-		$size = parent::toReadableSize($size);
-		if ($decimals !== '.') {
-			$size = str_replace('.', $decimals, $size);
-		}
-
-		return $size;
+		return $sign . parent::currency($value, $currency, $options);
 	}
 
 	/**
@@ -181,9 +167,11 @@ class Number extends CakeNumber {
 	 *
 	 * @param array $values Values: int or float values
 	 * @param int $precision
+	 *
 	 * @return float Average
 	 */
-	public static function average($values, $precision = 0) {
+	public static function average(array $values, int $precision = 0): float
+	{
 		if (!$values) {
 			return 0.0;
 		}
@@ -213,9 +201,11 @@ class Number extends CakeNumber {
 	 *
 	 * @param float $number
 	 * @param int $increment
-	 * @return float result
+	 *
+	 * @return float|int Result
 	 */
-	public static function roundUpTo($number, $increment = 1) {
+	public static function roundUpTo($number, int $increment = 1)
+	{
 		return ceil($number / $increment) * $increment;
 	}
 
@@ -224,9 +214,10 @@ class Number extends CakeNumber {
 	 *
 	 * @param float $number
 	 * @param int $increment
+	 *
 	 * @return float result
 	 */
-	public static function roundDownTo($number, $increment = 1) {
+	public static function roundDownTo($number, int $increment = 1) {
 		return floor($number / $increment) * $increment;
 	}
 
@@ -236,7 +227,8 @@ class Number extends CakeNumber {
 	 * @param float $number
 	 * @return int decimalPlaces
 	 */
-	public static function getDecimalPlaces($number) {
+	public static function getDecimalPlaces($number): int
+	{
 		$decimalPlaces = 0;
 		while ($number > 1 && $number != 0) {
 			$number /= 10;
@@ -259,7 +251,8 @@ class Number extends CakeNumber {
 	 * @param float $precision
 	 * @return bool
 	 */
-	public static function isFloatEqual($x, $y, $precision = 0.0000001) {
+	public static function isFloatEqual($x, $y, $precision = 0.0000001): bool
+	{
 		return ($x + $precision >= $y) && ($x - $precision <= $y);
 	}
 
@@ -267,9 +260,11 @@ class Number extends CakeNumber {
 	 * Get the settings for a specific formatName
 	 *
 	 * @param string $formatName (EUR, ...)
+	 *
 	 * @return array currencySettings
 	 */
-	public static function getFormat($formatName) {
+	public static function getFormat(string $formatName): array
+	{
 		if (!isset(static::$_currencies[$formatName])) {
 			return [];
 		}

+ 10 - 5
src/Utility/Random.php

@@ -17,7 +17,7 @@ class Random {
 	 * @param int $max
 	 * @return int Random int value
 	 */
-	public static function int($min = 0, $max = 999) {
+	public static function int($min = 0, $max = 999): int {
 		return random_int($min, $max);
 	}
 
@@ -29,9 +29,10 @@ class Random {
 	 * @param int|null $minPosition
 	 * @param int|null $maxPosition
 	 * @param bool $integerKeys
+	 *
 	 * @return mixed
 	 */
-	public static function arrayValue(array $array, $minPosition = null, $maxPosition = null, $integerKeys = false) {
+	public static function arrayValue(array $array, ?int $minPosition = null, ?int $maxPosition = null, bool $integerKeys = false): mixed {
 		if ($integerKeys) {
 			$max = count($array) - 1;
 
@@ -48,10 +49,12 @@ class Random {
 	 * Generates a password
 	 *
 	 * @link https://github.com/CakeDC/users/blob/master/models/user.php#L498
+	 *
 	 * @param int $length Password length
+	 *
 	 * @return string
 	 */
-	public static function pronounceablePwd($length = 10) {
+	public static function pronounceablePwd(int $length = 10): string {
 		mt_srand((int)(float)microtime() * 1000000);
 		$password = '';
 		$vowels = ['a', 'e', 'i', 'o', 'u'];
@@ -71,9 +74,10 @@ class Random {
 	 *
 	 * @param int $length (necessary!)
 	 * @param string|null $chars
+	 *
 	 * @return string Password
 	 */
-	public static function pwd($length, $chars = null) {
+	public static function pwd(int $length, ?string $chars = null): string {
 		if ($chars === null) {
 			$chars = '234567890abcdefghijkmnopqrstuvwxyz'; // ABCDEFGHIJKLMNOPQRSTUVWXYZ
 		}
@@ -112,9 +116,10 @@ class Random {
 	 *
 	 * @param string $type Type of pool, or a string of characters to use as the pool
 	 * @param int $length of string to return
+	 *
 	 * @return string
 	 */
-	public static function generate($type = 'alnum', $length = 8) {
+	public static function generate(string $type = 'alnum', int $length = 8): string {
 		switch ($type) {
 			case 'alnum':
 				$pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

+ 28 - 74
src/Utility/Utility.php

@@ -25,7 +25,7 @@ class Utility {
 	 * @param mixed $value
 	 * @return bool
 	 */
-	public static function notBlank($value) {
+	public static function notBlank($value): bool {
 		return $value === 0 || $value === 0.0 || $value === '0' || !empty($value);
 	}
 
@@ -40,7 +40,7 @@ class Utility {
 	 * @param array $haystack
 	 * @return bool Success
 	 */
-	public static function inArray($needle, $haystack) {
+	public static function inArray($needle, $haystack): bool {
 		$strict = !is_numeric($needle);
 
 		return in_array((string)$needle, $haystack, $strict);
@@ -59,7 +59,7 @@ class Utility {
 	 * @param array<string, mixed> $options
 	 * @return array
 	 */
-	public static function tokenize($data, $separator = ',', $options = []) {
+	public static function tokenize($data, $separator = ',', $options = []): array {
 		$defaults = [
 			'clean' => true,
 		];
@@ -99,7 +99,7 @@ class Utility {
 	 * @param int|null $offset
 	 * @return array Result
 	 */
-	public static function pregMatchAll($pattern, $subject, $flags = PREG_SET_ORDER, $offset = null) {
+	public static function pregMatchAll($pattern, $subject, $flags = PREG_SET_ORDER, $offset = null): array {
 		$pattern = substr($pattern, 0, 1) . '(*UTF8)' . substr($pattern, 1);
 		preg_match_all($pattern, $subject, $matches, $flags, (int)$offset);
 
@@ -123,7 +123,7 @@ class Utility {
 	 * @param int|null $offset
 	 * @return array Result
 	 */
-	public static function pregMatch($pattern, $subject, $flags = null, $offset = null) {
+	public static function pregMatch($pattern, $subject, $flags = null, $offset = null): array {
 		$pattern = substr($pattern, 0, 1) . '(*UTF8)' . substr($pattern, 1);
 		preg_match($pattern, $subject, $matches, (int)$flags, (int)$offset);
 
@@ -138,7 +138,7 @@ class Utility {
 	 * @param int $length
 	 * @return array<string> Result
 	 */
-	public static function strSplit($str, $length = 1) {
+	public static function strSplit($str, $length = 1): array {
 		if ($length < 1) {
 			return [];
 		}
@@ -157,7 +157,7 @@ class Utility {
 	 * @param bool $safe
 	 * @return string IP address
 	 */
-	public static function getClientIp($safe = true) {
+	public static function getClientIp($safe = true): string {
 		if (!$safe && env('HTTP_X_FORWARDED_FOR')) {
 			$ipaddr = preg_replace('/(?:,.*)/', '', (string)env('HTTP_X_FORWARDED_FOR'));
 		} elseif (!$safe && env('HTTP_CLIENT_IP')) {
@@ -173,9 +173,9 @@ class Utility {
 	 * Get the current referrer if available.
 	 *
 	 * @param bool $full (defaults to false and leaves the url untouched)
-	 * @return string referer (local or foreign)
+	 * @return string|null Referer (local or foreign)
 	 */
-	public static function getReferer($full = false) {
+	public static function getReferer($full = false): ?string {
 		/** @var string|null $ref */
 		$ref = env('HTTP_REFERER');
 		/** @var string|null $forwarded */
@@ -201,7 +201,7 @@ class Utility {
 	 * @param bool|null $detectHttps
 	 * @return string Cleaned Url
 	 */
-	public static function cleanUrl($url, $headerRedirect = false, $detectHttps = null) {
+	public static function cleanUrl($url, $headerRedirect = false, $detectHttps = null): string {
 		if ($url === '' || $url === 'http://' || $url === 'http://www' || $url === 'http://www.') {
 			$url = '';
 		} else {
@@ -239,7 +239,7 @@ class Utility {
 	 * @param array<string> $protocols Defaults to http and https. Pass empty array for all.
 	 * @return string strippedUrl
 	 */
-	public static function stripProtocol($url, $protocols = ['http', 'https']) {
+	public static function stripProtocol($url, $protocols = ['http', 'https']): string {
 		$pieces = parse_url($url);
 		// Already stripped?
 		if (empty($pieces['scheme'])) {
@@ -262,7 +262,7 @@ class Utility {
 	 * @param string $pattern
 	 * @return bool Success
 	 */
-	public static function fileExists($file, $pattern = '~^https?://~i') {
+	public static function fileExists($file, $pattern = '~^https?://~i'): bool {
 		if (!preg_match($pattern, $file)) {
 			return file_exists($file);
 		}
@@ -279,7 +279,7 @@ class Utility {
 	 * @param array $statusCodes List of accepted status codes. Defaults to 200 OK.
 	 * @return bool Success
 	 */
-	public static function urlExists($url, array $statusCodes = []) {
+	public static function urlExists($url, array $statusCodes = []): bool {
 		if (function_exists('curl_init')) {
 			$curl = curl_init($url);
 			curl_setopt($curl, CURLOPT_NOBODY, true);
@@ -313,7 +313,7 @@ class Utility {
 	 *
 	 * @return mixed array of headers or FALSE on failure
 	 */
-	public static function getHeaderFromUrl($url) {
+	public static function getHeaderFromUrl(string $url) {
 		// @codingStandardsIgnoreStart
 		$urlArray = @parse_url($url);
 		// @codingStandardsIgnoreEnd
@@ -363,9 +363,10 @@ class Utility {
 	 * @param string $url
 	 * @param string|null $prefix
 	 * @param bool|null $detectHttps
+	 *
 	 * @return string
 	 */
-	public static function autoPrefixUrl($url, $prefix = null, $detectHttps = null) {
+	public static function autoPrefixUrl(string $url, ?string $prefix = null, ?bool $detectHttps = null): string {
 		if ($prefix === null) {
 			$prefix = 'http://';
 		}
@@ -392,9 +393,10 @@ class Utility {
 	 * Returns true only if all values are true.
 	 *
 	 * @param array $array
+	 *
 	 * @return bool Result
 	 */
-	public static function logicalAnd($array) {
+	public static function logicalAnd(array $array): bool {
 		if (!$array) {
 			return false;
 		}
@@ -411,9 +413,10 @@ class Utility {
 	 * Returns true if at least one value is true.
 	 *
 	 * @param array $array
+	 *
 	 * @return bool Result
 	 */
-	public static function logicalOr($array) {
+	public static function logicalOr(array $array): bool {
 		foreach ($array as $result) {
 			if ($result) {
 				return true;
@@ -468,9 +471,10 @@ class Utility {
 	 *
 	 * @param mixed $value
 	 * @param bool $transformNullToString
+	 *
 	 * @return mixed
 	 */
-	public static function trimDeep($value, $transformNullToString = false) {
+	public static function trimDeep($value, bool $transformNullToString = false) {
 		if (is_array($value)) {
 			foreach ($value as $k => $v) {
 				$value[$k] = static::trimDeep($v, $transformNullToString);
@@ -515,12 +519,13 @@ class Utility {
 	 * Counts the dimensions of an array. If $all is set to false (which is the default) it will
 	 * only consider the dimension of the first element in the array.
 	 *
-	 * @param array $array Array to count dimensions on
+	 * @param mixed $array Array to count dimensions on
 	 * @param bool $all Set to true to count the dimension considering all elements in array
 	 * @param int $count Start the dimension count at this number
+	 *
 	 * @return int The number of dimensions in $array
 	 */
-	public static function countDim($array, $all = false, $count = 0) {
+	public static function countDim($array, bool $all = false, int $count = 0): int {
 		if ($all) {
 			$depth = [$count];
 			if (is_array($array) && reset($array) !== false) {
@@ -642,9 +647,10 @@ class Utility {
 	 *
 	 * @param array $array Array to flatten
 	 * @param bool $preserveKeys
+	 *
 	 * @return array
 	 */
-	public static function arrayFlatten($array, $preserveKeys = false) {
+	public static function arrayFlatten(array $array, bool $preserveKeys = false): array {
 		if ($preserveKeys) {
 			return static::_arrayFlatten($array);
 		}
@@ -700,7 +706,7 @@ class Utility {
 	 *
 	 * @return string key
 	 */
-	public static function arrayShiftKeys(&$array) {
+	public static function arrayShiftKeys(array &$array): string {
 		foreach ($array as $key => $value) {
 			unset($array[$key]);
 
@@ -710,56 +716,4 @@ class Utility {
 		throw new InvalidArgumentException('Empty array');
 	}
 
-	/**
-	 * @var float
-	 */
-	protected static $_counterStartTime = 0.0;
-
-	/**
-	 * Returns microtime as float value
-	 * (to be subtracted right away)
-	 *
-	 * @param int $precision
-	 * @return float
-	 */
-	public static function microtime($precision = 8) {
-		return round(microtime(true), $precision);
-	}
-
-	/**
-	 * @return void
-	 */
-	public static function startClock() {
-		static::$_counterStartTime = static::microtime();
-	}
-
-	/**
-	 * @param int $precision
-	 * @param bool $restartClock
-	 * @return float
-	 */
-	public static function returnElapsedTime($precision = 8, $restartClock = false) {
-		$startTime = static::$_counterStartTime;
-		if ($restartClock) {
-			static::startClock();
-		}
-
-		return static::calcElapsedTime($startTime, static::microtime(), $precision);
-	}
-
-	/**
-	 * Returns microtime as float value
-	 * (to be subtracted right away)
-	 *
-	 * @param float $start
-	 * @param float $end
-	 * @param int $precision
-	 * @return float
-	 */
-	public static function calcElapsedTime($start, $end, $precision = 8) {
-		$elapsed = $end - $start;
-
-		return round($elapsed, $precision);
-	}
-
 }

+ 32 - 0
tests/TestCase/Utility/ClockTest.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace Tools\Test\TestCase\Utility;
+
+use Shim\TestSuite\TestCase;
+use Tools\Utility\Clock;
+
+/**
+ * @coversDefaultClass \Tools\Utility\Clock
+ */
+class ClockTest extends TestCase {
+
+	/**
+	 * @covers ::returnElapsedTime
+	 * @return void
+	 */
+	public function testTime() {
+		Clock::startClock();
+		time_nanosleep(0, 200000000);
+		$res = Clock::returnElapsedTime();
+		$this->assertTrue(round($res, 1) === 0.2);
+
+		time_nanosleep(0, 100000000);
+		$res = Clock::returnElapsedTime(8, true);
+		$this->assertTrue(round($res, 1) === 0.3);
+
+		time_nanosleep(0, 100000000);
+		$res = Clock::returnElapsedTime();
+		$this->assertTrue(round($res, 1) === 0.1);
+	}
+
+}

+ 4 - 2
tests/TestCase/Utility/DateTimeTest.php

@@ -448,7 +448,8 @@ class DateTimeTest extends TestCase {
 			$is = $this->Time->ageByYear(2000, $month);
 			//$this->out($is);
 			//$this->assertEquals($is, (date('Y')-2001).'/'.(date('Y')-2000), null, '2000/'.$month);
-			$this->assertSame(date('Y') - 2001, $is); //null, '2000/'.$month
+			$expected = (string)(date('Y') - 2001);
+			$this->assertSame($expected, $is);
 		}
 
 		$month = date('n') - 1;
@@ -456,7 +457,8 @@ class DateTimeTest extends TestCase {
 			$is = $this->Time->ageByYear(2000, $month);
 			//$this->out($is);
 			//$this->assertEquals($is, (date('Y')-2001).'/'.(date('Y')-2000), null, '2000/'.$month);
-			$this->assertSame(date('Y') - 2000, $is); //null, '2000/'.$month)
+			$expected = (string)(date('Y') - 2000);
+			$this->assertSame($expected, $is); //null, '2000/'.$month)
 		}
 	}
 

+ 0 - 19
tests/TestCase/Utility/UtilityTest.php

@@ -632,25 +632,6 @@ class UtilityTest extends TestCase {
 	}
 
 	/**
-	 * @covers ::returnElapsedTime
-	 * @return void
-	 */
-	public function testTime() {
-		Utility::startClock();
-		time_nanosleep(0, 200000000);
-		$res = Utility::returnElapsedTime();
-		$this->assertTrue(round($res, 1) === 0.2);
-
-		time_nanosleep(0, 100000000);
-		$res = Utility::returnElapsedTime(8, true);
-		$this->assertTrue(round($res, 1) === 0.3);
-
-		time_nanosleep(0, 100000000);
-		$res = Utility::returnElapsedTime();
-		$this->assertTrue(round($res, 1) === 0.1);
-	}
-
-	/**
 	 * @covers ::logicalAnd
 	 * @return void
 	 */