From 8093bd7a1ae63cacb87c16aad9910c053349739f Mon Sep 17 00:00:00 2001 From: Eric Roberts Date: Thu, 17 Jan 2013 18:12:47 -0600 Subject: Fix and optimize auto_link() URL helper function. Signed-off-by: Eric Roberts --- system/helpers/url_helper.php | 53 ++++++++++++++++++------------------------- 1 file changed, 22 insertions(+), 31 deletions(-) (limited to 'system/helpers/url_helper.php') diff --git a/system/helpers/url_helper.php b/system/helpers/url_helper.php index 130f6f962..8be327276 100644 --- a/system/helpers/url_helper.php +++ b/system/helpers/url_helper.php @@ -383,47 +383,38 @@ if ( ! function_exists('auto_link')) */ function auto_link($str, $type = 'both', $popup = FALSE) { - if ($type !== 'email' && preg_match_all('#(^|\s|\(|\b)((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i', $str, $matches)) + // Find and replace any URLs. + if ($type !== 'email' && preg_match_all('#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#', $str, $matches, PREG_OFFSET_CAPTURE)) { - $pop = ($popup) ? ' target="_blank" ' : ''; - - for ($i = 0, $c = count($matches[0]); $i < $c; $i++) + // Set our target HTML if using popup links. + $target = ($popup) ? 'target="_blank"' : ''; + + // We process the links in reverse order (last -> first) so that + // the returned string offsets from preg_match_all() are not + // moved as we add more HTML. + foreach (array_reverse($matches[0]) as $match) { - if (preg_match('/(\.|\,)$/i', $matches[6][$i], $m)) - { - $punct = $m[1]; - $matches[6][$i] = substr($matches[6][$i], 0, -1); - } - else - { - $punct = ''; - } - - $str = str_replace($matches[0][$i], - $matches[1][$i].'http' - .$matches[4][$i].'://'.$matches[5][$i] - .$matches[6][$i].''.$punct, - $str); + // $match is an array generated by the PREG_OFFSET_CAPTURE flag. + // $match[0] is the matched string, $match[1] is the string offset. + + $anchor = anchor($match[0], '', $target); + + $str = substr_replace($str, $anchor, $match[1], strlen($match[0])); } } - - if ($type !== 'url' && preg_match_all('/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]+)/i', $str, $matches, PREG_OFFSET_CAPTURE)) + + // Find and replace any emails. + if ($type !== 'url' && preg_match_all('#([\w\.\-\+]+@[a-z0-9\-]+\.[a-z0-9\-\.]+[^[:punct:]\s])#i', $str, $matches, PREG_OFFSET_CAPTURE)) { - for ($i = count($matches[0]) - 1; $i > -1; $i--) + foreach (array_reverse($matches[0]) as $match) { - if (preg_match('/(\.|\,)$/i', $matches[3][$i][0], $m)) + if (filter_var($match[0], FILTER_VALIDATE_EMAIL) !== FALSE) { - $matches[3][$i][0] = substr($matches[3][$i][0], 0, -1); - } - - if (filter_var(($m = $matches[1][$i][0].'@'.$matches[2][$i][0].'.'.$matches[3][$i][0]), FILTER_VALIDATE_EMAIL) !== FALSE) - { - $str = substr_replace($str, safe_mailto($m), $matches[0][$i][1], strlen($m)); + $str = substr_replace($str, safe_mailto($match[0]), $match[1], strlen($match[0])); } } } - + return $str; } } -- cgit v1.2.3-24-g4f1b