summaryrefslogtreecommitdiffstats
path: root/system
diff options
context:
space:
mode:
authorEric Roberts <eric@cryode.com>2013-01-18 01:12:47 +0100
committerEric Roberts <eric@cryode.com>2013-01-18 01:12:47 +0100
commit8093bd7a1ae63cacb87c16aad9910c053349739f (patch)
treec45113203b776ccfb5fa109ca7cfb0248d02464d /system
parente9eb64f863ffeacd2986eb75e0aaaeb95d12a122 (diff)
Fix and optimize auto_link() URL helper function.
Signed-off-by: Eric Roberts <eric@cryode.com>
Diffstat (limited to 'system')
-rw-r--r--system/helpers/url_helper.php53
1 files changed, 22 insertions, 31 deletions
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].'<a href="http'.$matches[4][$i].'://'
- .$matches[5][$i].$matches[6][$i].'"'.$pop.'>http'
- .$matches[4][$i].'://'.$matches[5][$i]
- .$matches[6][$i].'</a>'.$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;
}
}