diff --git a/link.module b/link.module index df8d635..d071f23 100644 --- a/link.module +++ b/link.module @@ -9,6 +9,7 @@ define('LINK_EXTERNAL', 'external'); define('LINK_INTERNAL', 'internal'); define('LINK_FRONT', 'front'); define('LINK_EMAIL', 'email'); +define('LINK_TEL', 'tel'); define('LINK_NEWS', 'news'); define('LINK_FILE', 'file'); define('LINK_TARGET_DEFAULT', 'default'); @@ -584,6 +585,9 @@ function _link_sanitize(&$item, $delta, &$field, $instance, &$entity) { if ($type == LINK_EMAIL) { $display_url = str_replace('mailto:', '', $url); } + elseif ($type == LINK_TEL) { + $display_url = str_replace('tel:', '', $url); + } else { $display_url = url($url_parts['url'], array( @@ -1548,6 +1552,7 @@ function link_url_type($text) { 'ssh', 'sftp', 'webcal', + 'tel', )); $link_domains = _link_domains(); @@ -1581,6 +1586,7 @@ function link_url_type($text) { $user = '[a-zA-Z0-9' . $link_ichars . '_\-\.\+\^!#\$%&*+\/\=\?\`\|\{\}~\'\[\]]+'; $email_pattern = '/^mailto:' . $user . '@' . '(?:' . $domain . '|' . $ipv4 . '|' . $ipv6 . '|localhost)' . $query . '?$/'; + $tel_pattern = '/^tel:(?:\+[1-9]\d{1,14}|\d{2,15})$/'; $file_pattern = "/^(?:file:\/\/)" . "(?:\/?[a-z0-9" . $link_ichars . "_\-\.\\\~+%=&,$'#!():;*@\[\]]*)*" . '$/i'; @@ -1590,6 +1596,19 @@ function link_url_type($text) { if (in_array('mailto', $allowed_protocols) && preg_match($email_pattern, $text)) { return LINK_EMAIL; } + if (in_array('tel', $allowed_protocols) && strpos($text, 'tel:') === 0) { + if (preg_match($tel_pattern, $text)) { + // Based on our tel pattern this is a 'valid' phone number so return tel + // type. + return LINK_TEL; + } + else { + // Based on our tel pattern this is using the tel protocol, but is not a + // 'valid' phone number. If we don't return false here $text will match + // LINK_EXTERNAL which is incorrect. + return FALSE; + } + } if (in_array('news', $allowed_protocols) && preg_match($news_pattern, $text)) { return LINK_NEWS; } diff --git a/tests/link.validate.test b/tests/link.validate.test index 9b87d8c..6338840 100644 --- a/tests/link.validate.test +++ b/tests/link.validate.test @@ -544,6 +544,9 @@ class LinkValidateUrlLight extends DrupalWebTestCase { case LINK_EMAIL: return "Email"; + case LINK_TEL: + return "Telephone"; + case LINK_NEWS: return "Newsgroup"; @@ -585,6 +588,37 @@ class LinkValidateUrlLight extends DrupalWebTestCase { $this->assertEqual(FALSE, $valid, 'Make sure just a bad address is correctly failed'); } + function testValidateTelLinks() { + $links = array( + 'tel:01', + 'tel:123456789012345', + 'tel:+123456789012345', + ); + foreach ($links as $link) { + $type = link_url_type($link); + $this->assertEqual(LINK_TEL, $type, 'Test ' . $link . ' is a tel link.'); + $valid = link_validate_url($link); + $this->assertTrue($valid, 'Test ' . $link . ' is valid tel link.'); + } + } + + function testValidateTelLinksBad() { + $links = array( + 'tel:0', + 'tel:1234567890123456', + 'tel:+1', + 'tel:+0123456789', + 'tel:+1234567890123456', + ':12345678', + ); + foreach ($links as $link) { + $type = link_url_type($link); + $this->assertFalse($type, 'Test ' . $link . ' is not a tel link.'); + $valid = link_validate_url($link); + $this->assertFalse($valid, 'Test ' . $link . ' is not a valid tel link.'); + } + } + /** * Validate Newsgroup Link. */