0

After allot of searching around SO and other forums also stumbling over various php function documentation, I tried to edit a function that I found on here(converts URLs to clickable links) so it will also handle embedded video, unfortunately my skill set is poor and I believe I don't fully understand create_function() to be successful at this.

So here's my scrambled egg code:

private function _check4Links($text){
    $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';
    $callback = create_function('$matches', '
       $url       = array_shift($matches);
       $url_parts = parse_url($url);

       if(preg_match("%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})%i", $url, $match)){
            return sprintf(\'<iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/\'.$match[1].\'" frameborder="0" allowFullScreen></iframe>\', $url, $text);
       }else{

            $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
            $text = preg_replace("/^www./", "", $text);

            $last = -(strlen(strrchr($text, "/"))) + 1;
            if ($last < 0) {
               $text = substr($text, 0, $last) . "&hellip;";
            }

            return sprintf(\'<a target="_blank"rel="nofollow" href="%s">%s</a>\', $url, $text);
       }');

    return preg_replace_callback($pattern, $callback, $text);
}

I should also mention that i'm not looking for someone to just show me the correct code, I'm looking for someone to explain to me why my code is not working and what i am doing wrong. Thank you for your time :)

Elgoog
  • 2,205
  • 7
  • 36
  • 48
  • 2
    Why are you using lambda-function for this? Can't see any dynamic generated code inside it. I think that it'll be much easier to debug with normal function. Moreover, you don't have any placeholders for video `sprintf()`. That's not an error though. – WASD42 Jul 08 '11 at 13:09
  • @WASD42 Well that's just what they were using so I just tried to edit it as little as possible trying to keep most of the code intact. Would you suggest I do it normally? – Elgoog Jul 08 '11 at 13:14
  • 2
    Yes, I will :) it seems that there is an unclosed quote (") in your regexp. – WASD42 Jul 08 '11 at 13:17
  • @WASD42, if that quote is in `preg_match()`, then it is rather unescaped than unclosed. – binaryLV Jul 08 '11 at 14:20

1 Answers1

2

Here is a fix:

<?php
function _check4Links($text){
    $pattern  = '#\b(([\w-]+://?|www[.])[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/)))#';

    return preg_replace_callback($pattern, 'fnc', $text);
}

function fnc($matches) {
    $url       = array_shift($matches);
    $url_parts = parse_url($url);

    if(preg_match("%(?:youtube\.com/(?:user/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^\"&?/ ]{11})%i", $url, $match)){
          return '<iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/'.$match[1].'" frameborder="0" allowFullScreen></iframe>';
    } else {

        $text = parse_url($url, PHP_URL_HOST) . parse_url($url, PHP_URL_PATH);
        $text = preg_replace("/^www./", "", $text);

        $last = -(strlen(strrchr($text, "/"))) + 1;
        if ($last < 0) {
            $text = substr($text, 0, $last) . "&hellip;";
        }

        return sprintf('<a target="_blank"rel="nofollow" href="%s">%s</a>', $url, $text);
        }
    }

$txt = <<<TXT
Let's do some tests!
http://www.google.com
http://www.youtube.com/watch?v=L25R4DR79mU
TXT;

echo _check4Links($txt);
?>

The output is:

Let's do some tests!
<a target="_blank"rel="nofollow" href="http://www.google.com">google.com</a>
<iframe title="YouTube video player" class="youtube-player" type="text/html" width="400" height="244" src="http://www.youtube.com/embed/L25R4DR79mU" frameborder="0" allowFullScreen></iframe>
WASD42
  • 2,352
  • 6
  • 27
  • 41
  • Thanks alot, I will say that I had to edit `5: return preg_replace_callback($pattern, array($this, 'fnc'), $text);` but that is no fault of yours. Thank you again. – Elgoog Jul 08 '11 at 13:37
  • 1
    Of course, because in your case it is a class method, while in my example it is a stand-alone function :) You are welcome! – WASD42 Jul 08 '11 at 13:39
  • 1
    I would add a space between `target="_blank"` and `rel="nofollow"`. – binaryLV Jul 08 '11 at 14:21