Issue
I use this code to make urls clickable as anchor links in forum posts.
function makelink($str) {
$str = preg_replace_callback('/((((http)(s)?:\/\/)|www\.)[-0-9æøåa-zA-Z?-??-?\(\)%_+\.~#?&;:@\/\/=]+)(?<!\.)/i', function($matches) {
if (strtolower(substr($matches[0], 0 , 4)) == 'www.') {
$matches[0] = 'http://' . $matches[0];
}
return '<a href="'.$matches[0].'" title="link" rel="noreferrer">'.$matches[0].'</a>';
}, $str);
return trim($str);
}
It works fine. Now I need to also make youtube links into embed codes underneath the link (appended to the link I guess).
It's ok for this that there is an extra replacement routine going on.
How could I make some code that replaces the resulting anchor (if it's a youtube link):
<a href="https://www.youtube.com/watch?v=LOLAy72Tv24" title="link" rel="noreferrer">https://www.youtube.com/watch?v=LOLAy72Tv24</a>
With this:
<a href="https://www.youtube.com/watch?v=LOLAy72Tv24" title="link" rel="noreferrer">https://www.youtube.com/watch?v=LOLAy72Tv24</a>
<br />
<iframe class="youtube" width="350" height="250" src="https://www.youtube.com/embed/LOLAy72Tv24/" allowfullscreen></iframe>
So it just needs to take the video id and put out embed code underneath the original link, while outputting both together.
Solution
Here's my proposed solution:
function makelink($str) {
$pattern = '/((((http)(s)?:\/\/)|www\.)[-0-9æøåa-zA-Z?-??-?\(\)%_+\.~#?&;:@\/\/=]+)(?<!\.)/i';
$str = preg_replace_callback($pattern, function($matches) {
if (strtolower(substr($matches[0], 0 , 4)) == 'www.') {
$matches[0] = 'http://' . $matches[0];
}
// store anchor tag html in a variable instead of returning immediately
$html = '<a href="'.$matches[0].'" title="link" rel="noreferrer">'.$matches[0].'</a>';
if (isYouTubeVideoUrl($matches[0])) {
$html .= '<br />'.makeiFrame($matches[0]);
}
return $html;
}, $str);
return trim($str);
}
function isYouTubeVideoUrl(string $url): bool
{
return (parse_url($url, PHP_URL_HOST) === 'www.youtube.com' || isYouTubeShortUrl($url))
&& strpos(parse_url($url, PHP_URL_QUERY), 'v=') !== false;
}
function isYouTubeShortUrl(string $url): bool
{
return parse_url($url, PHP_URL_HOST) === 'youtu.be';
}
function makeiFrame(string $url): string {
$embedUrl = 'https://www.youtube.com/embed/'.getYouTubeVideoId($url).'/';
return '<iframe class="youtube" width="350" height="250" src="'.$embedUrl.'" allowfullscreen></iframe>';
}
function getYouTubeVideoId(string $url): string
{
if (isYouTubeShortUrl($url)) {
preg_match('/[^\/]+$/', $url, $matches);
return $matches[0];
}
preg_match('/(?<=v=)(.*?)(?=(&|$))/', $url, $matches);
return $matches[0];
}
It is designed to work both with regular YouTube URLs (https://www.youtube.com/watch?v=LOLAy72Tv24
) and short YouTube URLs (https://youtu.be/LOLAy72Tv24
). It also supports the v
parameter being anywhere in the query string for regular URLs.
Most of the code is pretty straightforward, the key lies in extracting the video id.
Short URLs have the format where the id is behind a slash, so [^\/]+$
looks for any characters that are not a slash at the end of the string:
[^\/]
matches any character not a slash+
is a quantifier for one or more, greedy$
asserts the position at the end of the string
Regular URLs have the format where the id is in a parameter named v
, so (?<=v=)(.+?)(?=(&|$))
looks for everything between v=
and either &
or the end of the string:
(?<=v=)
is a positive lookbehind, assuring that we look for a string right afterv=
(.+?)
matches one or more characters (any, except for line terminators), lazy(?=(&|$))
is a positive lookahead, assuring that we look for a string right before an ampersand (&
) or the end of a string ($
)
Answered By - El_Vanja Answer Checked By - Willingham (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.