-4

If i type

www.google.com or http://www.google.com

using auto_link() function will add link correctly..

However, if i type

google.com

the function doesnt work since the www. part is missing...

how can i make sure it will include these links as well??

This is the function from codeigniter:

/**
 * Auto-linker
 *
 * Automatically links URL and Email addresses.
 * Note: There's a bit of extra code here to deal with
 * URLs or emails that end in a period.  We'll strip these
 * off and add them after the link.
 *
 * @access  public
 * @param   string  the string
 * @param   string  the type: email, url, or both
 * @param   bool    whether to create pop-up links
 * @return  string
 */
if ( ! function_exists('auto_link'))
{
    function auto_link($str, $type = 'both', $popup = FALSE)
    {
        if ($type != 'email')
        {
            if (preg_match_all("#(^|\s|\()((http(s?)://)|(www\.))(\w+[^\s\)\<]+)#i", $str, $matches))
            {
                $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $period = '';
                    if (preg_match("|\.$|", $matches['6'][$i]))
                    {
                        $period = '.';
                        $matches['6'][$i] = substr($matches['6'][$i], 0, -1);
                    }

                    $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>'.
                                        $period, $str);
                }
            }
        }

        if ($type != 'url')
        {
            if (preg_match_all("/([a-zA-Z0-9_\.\-\+]+)@([a-zA-Z0-9\-]+)\.([a-zA-Z0-9\-\.]*)/i", $str, $matches))
            {
                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $period = '';
                    if (preg_match("|\.$|", $matches['3'][$i]))
                    {
                        $period = '.';
                        $matches['3'][$i] = substr($matches['3'][$i], 0, -1);
                    }

                    $str = str_replace($matches['0'][$i], safe_mailto($matches['1'][$i].'@'.$matches['2'][$i].'.'.$matches['3'][$i]).$period, $str);
                }
            }
        }

        return $str;
    }
}

SOLUTION : function auto_link($str, $type = 'both', $popup = FALSE) { if ($type != 'email') { if (!preg_match_all("/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\.([a-zA-Z])+([a-zA-Z])+/", $str, $matches)){

        if (preg_match_all("/(?:https?\:?(?:\/\/)?|www\.)?([a-zA-Z0-9\-\.]+\.(?:.[a-z]*))/mi", $str, $matches))
        {
            $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

            for ($i = 0; $i < count($matches['0']); $i++)
            {

                            $str = str_replace($matches[0][$i],
                                                '<a href="http://'.$matches[1][0].'" class="auto_link_color">'.$matches[1][0].'</a>', $str);
            }
        }
            }else{
                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $str = str_replace($matches[0][$i], $matches[0][0], $str);
                }
            }
    }

    return $str;
}

This solved my problems so whatever link the user enters will find it and add a link... Even if the user enters an email it wont add links on the domain part but instead will show it as text.

stergosz
  • 5,754
  • 13
  • 62
  • 133
  • 3
    your logic is flawed with trying to force `auto_link()` to do this. It will create a mess for you with `.`'s and you will end up with random URLs for pieces of text that shouldn't have it. Even SO here isn't as ambitious about formatting all URLs as real links. Think about it. you would be fighting over wether something is an EMAIL or a URL, or just a sting with a period in it. Just don't mess with something that isn't broken at least IMHO. – Jakub Feb 23 '12 at 03:13

4 Answers4

3

The autolink should correctly catch http://google.com. Are you saying that doesn't work?

The autolink regex is using the presence of http(s) or www to indicate that a link is present. Without either of those options you'd have to change the regex to detect merely on the top level domain of .com which will get very problematic given the wide array of possible top level domains (.net, .org, .biz, etc.). If you think it through you probably don't want to change this regex because the maintenance on all the possible domains and new ones being added will be far more cumbersome than it's worth.

davidethell
  • 11,708
  • 6
  • 43
  • 63
  • i am saying that autolink wont catch google.com and requires http://www. or www. to work. How could the regex be modified to work even if www or http is missing in my case? – stergosz Feb 17 '12 at 11:57
  • @fxuser you don't need to modify the Regex. Just use the `prep_url()` function from the URL helper, and then apply the `auto_link()` function to the value returned from `prep_url()`. – Kemal Fadillah Feb 17 '12 at 12:16
  • the thing is that i have a bunch of text which might have urls in it... if i add prep_url() before and then add auto_link() it will simply add http:// in front of the whole text and not in the links... – stergosz Feb 17 '12 at 13:41
  • I don't have the regex change you'd need offhand. The entire logic of the regex changes because instead of searching from a known starting string to the end of the domain you are instead searching from the end and working your way back to the front. I really don't think you want it. You'd have to catch all the variations of top level domains which would be cumbersome to maintain at best. – davidethell Feb 17 '12 at 20:14
1

I'm sorry but you're using auto_link() the wrong way.

The parameter is supposed to be a VALID url or email. Putting just "www.google.com" is not allowed and should'nt work at all :-)

So you should do :

auto_link('http://www.google.com')
auto_link('http://google.com')

Never ommitting the "http://" at the begining.

0

If you're not using "http://" or "www." as your "link this" trigger, you'd have to code it to catch .com, .org, .net (and an ever-expanding set of possibilities). As others have suggested, making this reg ex "greedier" will match things that shouldn't be links. It's up to you to weigh the balance based on your priorities.

Here's a (very simplistic) little experiment I tried:

<?php

header("Content-type: text/plain");

$text = 'http://google.com
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed in urna auctor tellus consequat cursus.
Cras malesuada magna eget felis accumsan vel dictum urna sodales. Vestibulum erat ante, rutrum et
aliquet vel, convallis eu google.com. Phasellus interdum velit at urna google.com porta. Donec at interdum
nibh. Fusce ultricies varius elit id egestas. Suspendisse dolor risus, vulputate vel rutrum in,
http://google.com et nisi. Etiam non massa non neque lacinia adipiscing sed nec metus. Sed fermentum ultricies
dui at porta. Duis at lacinia tortor. Nam mi est, mollis sed viverra et, mollis ac lorem. In mattis
lacinia tempor.

Sed in luctus nunc. Mauris nec tincidunt dui. Vivamus interdum, velit sed lobortis lobortis, nulla dui
vestibulum dui, eu tincidunt arcu felis et massa. google.COM vitae porta felis. Sed sit amet magna augue.
Aenean dignissim tempus porta. Donec ultrices lectus ac sapien gravida sodales. Quisque malesuada
sagittis rhoncus. Vestibulum mattis auctor ligula, eu tempus odio hendrerit in. Ut vel elit ipsum. Sed
ante lorem, www.google.com et dictum nec, ultricies a lorem.
';

$domains = 'com|org|net';

if ( !preg_match_all('#([\S]*)(\.('.$domains.']))#i', $text, $matches))
{
    die('no matches');
}

print_r($matches);

Output:

Array
(
    [0] => Array
        (
            [0] => http://google.com
            [1] => google.com
            [2] => google.com
            [3] => http://google.com
            [4] => google.COM
            [5] => www.google.com
        )

    [1] => Array
        (
            [0] => http://google
            [1] => google
            [2] => google
            [3] => http://google
            [4] => google
            [5] => www.google
        )

    [2] => Array
        (
            [0] => .com
            [1] => .com
            [2] => .com
            [3] => .com
            [4] => .COM
            [5] => .com
        )

    [3] => Array
        (
            [0] => com
            [1] => com
            [2] => com
            [3] => com
            [4] => COM
            [5] => com
        )

)
landons
  • 9,502
  • 3
  • 33
  • 46
0
function auto_link($str, $type = 'both', $popup = FALSE)
{
    if ($type != 'email')
    {
            if (!preg_match_all("/^([a-zA-Z0-9_.-])+@([a-zA-Z0-9_.-])+\\.([a-zA-Z])+([a-zA-Z])+/", $str, $matches)){

        if (preg_match_all("/(?:https?\:?(?:\/\/)?|www\.)?([a-zA-Z0-9\-\.]+\.(?:.[a-z]*))/mi", $str, $matches))
        {
            $pop = ($popup == TRUE) ? " target=\"_blank\" " : "";

            for ($i = 0; $i < count($matches['0']); $i++)
            {

                            $str = str_replace($matches[0][$i],
                                                '<a href="http://'.$matches[1][0].'" class="auto_link_color">'.$matches[1][0].'</a>', $str);
            }
        }
            }else{
                for ($i = 0; $i < count($matches['0']); $i++)
                {
                    $str = str_replace($matches[0][$i], $matches[0][0], $str);
                }
            }
    }

    return $str;
}

This solved my problems so whatever link the user enters will find it and add a link... Even if the user enters an email it wont add links on the domain part but instead will show it as text.

stergosz
  • 5,754
  • 13
  • 62
  • 133