From 4ba89c9f993a26aa85c84e88e04d07b0c56f7728 Mon Sep 17 00:00:00 2001 From: Thomas Bruederli <thomas@roundcube.net> Date: Mon, 16 Mar 2015 10:21:24 -0400 Subject: [PATCH] Backport new utility function for compatibility reasons --- program/lib/Roundcube/rcube_utils.php | 63 +++++++++++++++++++++++++------ 1 files changed, 50 insertions(+), 13 deletions(-) diff --git a/program/lib/Roundcube/rcube_utils.php b/program/lib/Roundcube/rcube_utils.php index 330322f..e6f9493 100644 --- a/program/lib/Roundcube/rcube_utils.php +++ b/program/lib/Roundcube/rcube_utils.php @@ -103,13 +103,14 @@ } foreach ($domain_array as $part) { - if (!preg_match('/^(([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $part)) { + if (!preg_match('/^((xn--)?([A-Za-z0-9][A-Za-z0-9-]{0,61}[A-Za-z0-9])|([A-Za-z0-9]))$/', $part)) { return false; } } // last domain part - if (preg_match('/[^a-zA-Z]/', array_pop($domain_array))) { + $last_part = array_pop($domain_array); + if (strpos($last_part, 'xn--') !== 0 && preg_match('/[^a-zA-Z]/', $last_part)) { return false; } @@ -751,12 +752,14 @@ * Improved equivalent to strtotime() * * @param string $date Date string + * @param object DateTimeZone to use for DateTime object * * @return int Unix timestamp */ - public static function strtotime($date) + public static function strtotime($date, $timezone = null) { $date = self::clean_datestr($date); + $tzname = $timezone ? ' ' . $timezone->getName() : ''; // unix timestamp if (is_numeric($date)) { @@ -765,7 +768,7 @@ // if date parsing fails, we have a date in non-rfc format. // remove token from the end and try again - while ((($ts = @strtotime($date)) === false) || ($ts < 0)) { + while ((($ts = @strtotime($date . $tzname)) === false) || ($ts < 0)) { $d = explode(' ', $date); array_pop($d); if (!$d) { @@ -781,6 +784,7 @@ * Date parsing function that turns the given value into a DateTime object * * @param string $date Date string + * @param object DateTimeZone to use for DateTime object * * @return object DateTime instance or false on failure */ @@ -796,7 +800,7 @@ // try to parse string with DateTime first if (!empty($date)) { try { - $dt = new DateTime($date, $timezone); + $dt = $timezone ? new DateTime($date, $timezone) : new DateTime($date); } catch (Exception $e) { // ignore @@ -804,9 +808,12 @@ } // try our advanced strtotime() method - if (!$dt && ($timestamp = self::strtotime($date))) { + if (!$dt && ($timestamp = self::strtotime($date, $timezone))) { try { $dt = new DateTime("@".$timestamp); + if ($timezone) { + $dt->setTimezone($timezone); + } } catch (Exception $e) { // ignore @@ -905,14 +912,21 @@ * Split the given string into word tokens * * @param string Input to tokenize + * @param integer Minimum length of a single token * @return array List of tokens */ - public static function tokenize_string($str) + public static function tokenize_string($str, $minlen = 2) { - return explode(" ", preg_replace( - array('/[\s;\/+-]+/i', '/(\d)[-.\s]+(\d)/', '/\s\w{1,3}\s/u'), - array(' ', '\\1\\2', ' '), - $str)); + $expr = array('/[\s;\/+-]+/ui', '/(\d)[-.\s]+(\d)/u'); + $repl = array(' ', '\\1\\2'); + + if ($minlen > 1) { + $minlen--; + $expr[] = "/(^|\s+)\w{1,$minlen}(\s+|$)/u"; + $repl[] = ' '; + } + + return array_filter(explode(" ", preg_replace($expr, $repl, $str))); } /** @@ -921,10 +935,11 @@ * * @param string Input string (UTF-8) * @param boolean True to return list of words as array + * @param integer Minimum length of tokens * * @return mixed Normalized string or a list of normalized tokens */ - public static function normalize_string($str, $as_array = false) + public static function normalize_string($str, $as_array = false, $minlen = 2) { // replace 4-byte unicode characters with '?' character, // these are not supported in default utf-8 charset on mysql, @@ -936,7 +951,7 @@ . ')/', '?', $str); // split by words - $arr = self::tokenize_string($str); + $arr = self::tokenize_string($str, $minlen); // detect character set if (utf8_encode(utf8_decode($str)) == $str) { @@ -970,6 +985,28 @@ } /** + * Compare two strings for matching words (order not relevant) + * + * @param string Haystack + * @param string Needle + * @return boolen True if match, False otherwise + */ + public static function words_match($haystack, $needle) + { + $a_needle = self::tokenize_string($needle, 1); + $haystack = join(" ", self::tokenize_string($haystack, 1)); + + $hits = 0; + foreach ($a_needle as $w) { + if (stripos($haystack, $w) !== false) { + $hits++; + } + } + + return $hits >= count($a_needle); + } + + /** * Parse commandline arguments into a hash array * * @param array $aliases Argument alias names -- Gitblit v1.9.1