php youtube and links regex are combining and in turn rendering useless - php

i have a posting feature on my site that can embed links and youtube videos. the problem is, that the two clash together, and the youtube iframe ends up being a 404 page on my site. my codes for the youtube videos and links are below, but im not sure how to stop them from combining and ruining it.
by combining, i mean this http://www.youtube.com/watch?v=VhqiT2nWCVU turns to
<iframe src="http://www.youtube.com/watch?v=VhqiT2nWCVU">
which then turns into
<iframe src="">
sorry if i am unclear in any way. my codes are below.
function youtube($string)
{
return preg_replace(
'#(http://(www.)?youtube.com)?/(v/|watch\?v\=)([-|~_0-9A-Za-z]+)&?.*?#i',
'<iframe title="YouTube video player" width="480" height="390" src="http://www.youtube.com/embed/$4?rel=0" frameborder="0" allowfullscreen></iframe>',
$string
);
}
$posted = youtube($posted);
$rexProtocol = '(https?://)?';
$rexDomain = '((?:[-a-zA-Z0-9]{1,63}\.)+[-a-zA-Z0-9]{2,63}|(?:[0-9]{1,3}\.){3}[0-9]{1,3})';
$rexPort = '(:[0-9]{1,5})?';
$rexPath = '(/[!$-/0-9:;=#_\':;!a-zA-Z\x7f-\xff]*?)?';
$rexQuery = '(\?[!$-/0-9:;=#_\':;!a-zA-Z\x7f-\xff]+?)?';
$rexFragment = '(#[!$-/0-9:;=#_\':;!a-zA-Z\x7f-\xff]+?)?';
// Solution 1:
function callback($match)
{
// Prepend http:// if no protocol specified
$completeUrl = $match[1] ? $match[0] : "http://{$match[0]}";
return '<a href="' . $completeUrl . '">'
. $match[2] . $match[3] . $match[4] . '</a>';
}
$posted = preg_replace_callback("&\\b$rexProtocol$rexDomain$rexPort$rexPath$rexQuery$rexFragment(?=[?.!,;:\"]?(\s|$))&",
'callback', $posted);

A popular solution to this problem is to use placeholders. On your first pass you turn all YouTube links into a placeholder, for example:
{{youtube:VhqiT2nWCVU}}
After that you run your normal link converter. And at the end your run yet another regex to turn all your palceholders into youtube embeds.

Related

How to make direct youtube video url work not embeded?

How to make youtube video work on site without embeded code? I mean direct code as: https://www.youtube.com/watch?v=ouDmKW1FGjo. I want the user to paste direct video url into a field VIDEO_LINK not the embeded code. How can I do that? Only embeded link works on the below code not the direct link.
<iframe width="100%" height="550" src="<?php the_field('video_link') ?>" frameborder="0" allowfullscreen></iframe>
Use the following code to get video key (assuming the URL is https://www.youtube.com/watch?v=ouDmKW1FGjo):
<?php
$video_url=get_field('video_link');
$url = urldecode(rawurldecode($video_url));
preg_match("/^(?:http(?:s)?:\/\/)?(?:www\.)?(?:m\.)?(?:youtu\.be\/|youtube\.com\/(?:(?:watch)?\?(?:.*&)?v(?:i)?=|(?:embed|v|vi|user)\/))([^\?&\"'>]+)/", $url, $matches);
// Get key of youtube by preg_match and put it in iframe
$videoKey= $matches[1];
?>
<iframe width="100%" height="550" src="https://www.youtube.com/embed/<?php echo $videoKey ;?>" frameborder="0" allowfullscreen></iframe>
You may use this function to convert Youtube URL to embeded code:
function get_youtube_embed($youtube_url, $width=560, $height=315)
{
$height = (int)$height;
$width = (int)$width;
$embed_html = '';
$parts = parse_url($youtube_url);
if(isset($parts['query'])) {
parse_str($parts['query'], $query);
if(isset($query['v'])) {
$embed_html = '<iframe width="'.$width.'" height="'.$height.'" src="https://www.youtube.com/embed/'.$query['v'].'" frameborder="0" allowfullscreen></iframe>';
}
}
return $embed_html;
}

convert url to hyperlink on text as formatted

I am using following code for convert url to hyperlink on text.But the problem is i want to use shorten title for hyperlink for example this is url http://stackoverflow.com/questions/ask?title=convert%20url%20to%20hyperlink%20on%20text%20as%20formatted and after convert like this :
http://stackoverflow.com/questions/ask?title=convert%20url%20to%20hyperlink%20on%20text%20as%20formatted
I want to this :
http://stackoverflow.com/...
This is my code :
$stringdata = preg_replace('|([\w\d]*)\s?(https?://([\d\w\.-]+\.[\w\.]{2,6})[^\s\]\[\<\>]*/?)|i', '$1 $2', $stringdata);
Title should be shorten but url should be same of original.
Thankyou.
You could always use parse_url found here
Here's an example:
$url = 'http://www.stackoverflow.com/questions/ask?title=convert%20url%20to%20hyperlink%20on%20text%20as%20formatted';
$splitUrl = parse_url($url);
echo '<a href="' . $url . '"/>' . $splitUrl['scheme'] . '://' . $splitUrl['host'] .'/... </a>';
parse_urlcreates an array from the URL provided.
UPDATE:
Using Mikael Roos answer at that link I came up with what you needed it to do.
function make_clickable($text) {
$regex = '#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#';
return preg_replace_callback($regex, function ($matches) {
$splitUrl = parse_url($matches[0]);
return "<a href='{$matches[0]}'>{$splitUrl['scheme']}://{$splitUrl['host']}/..</a>";
}, $text);
}
echo make_clickable('Some odd text here that makes https://stackoverflow.com/questions/ask?title=convert%20url%20to%20hyperlink%20on%20text%20as%20formatted clickable');
try this
$var='http://stackoverflow.com/questions/ask?title=convert%20url%20to%20hyperlink%20on%20text%20as%20formatted';
$array=explode('/', $var);
$url=$array[0]."//".$array[2]."/...";

Replace youtube link with embed and leave other text unharmed

I'm trying to turn youtube links into embed iframes, to play the videos. However, my current code is replacing the entire sentence with the embed code. What I want to do is to just convert the youtube link to an embed code, and leave the rest of the text unharmed.
Example: This is a youtube link: https://www.youtube.com/watch?v=T-8XurAKMkU and some text after.
Turned into: This is a youtube link: <embed> and some text after.
My current code:
$testing = "This is a youtube link: https://www.youtube.com/watch?v=T-8XurAKMkU and some text after.";
echo $core->convertyoutube($testing);
And the function:
public function convertyoutube($link) {
if (strpos($link, 'youtube.com/watch?v=') == true) {
$url = $link;
parse_str(parse_url($url, PHP_URL_QUERY), $youtube_array);
$videoid = $youtube_array['v'];
$embed = "<iframe width='420' height='315' src='https://www.youtube.com/embed/".$videoid."'></iframe>"; // what it should create with the extracted code
return $embed;
}
}
Well You are returning only embed code:
return $embed;
You need to replace only youtube part:
public function convertyoutube($link) {
$position = strpos($link, 'youtube.com/watch?v=');
if ($position !== false) {
$chunks = explode(' ', $link);
foreach ($chunks as &$chunk) {
$isYoutubeLink = strpos($chunk, 'youtube.com/watch?v=');
if ($isYoutubeLink !== false) {
$url = $chunk;
parse_str(parse_url($url, PHP_URL_QUERY), $youtube_array);
$videoid = $youtube_array['v'];
$chunk = "<iframe width='420' height='315' src='https://www.youtube.com/embed/".$videoid."'></iframe>"; // what it should create with the extracted code
}
}
return implode(' ', $chunks);
}
}
It works with multiple links in sentence. I guess there is "better" way with using regexp, however I am not very good at regexp and don't like to use it where it is not mandatory.
You could actually do this all with a single regex.
echo preg_replace('/https?:\/\/(?:www\.)?youtube\.com\/watch\?v=(.+?)(?:&|\s|$)/',
'<iframe width="420" height="315" src="https://www.youtube.com/embed/$1"></iframe>',
'This is a youtube link: https://www.youtube.com/watch?v=T-8XurAKMkU and some text after.');
Output:
This is a youtube link: https://www.youtube.com/watch?v=T-8XurAKMkU and some text after.
Regex101 Demo: https://regex101.com/r/cT2mW1/2
It will be better if you convert the links at the front-end view with javascript to avoid a excess loading of server. But it's your choise.
Single youtube video has different links like these:
1) https://www.youtube.com/watch?v=lfKON5AMvTM
2) https://youtu.be/lfKON5AMvTM
For this reason you should write your codes like this to catch every type of youtube links:
public function convertYouTube($content) {
$content = preg_replace("/http(s)?:\/\/youtu\.be\/([^\40\t\r\n\<]+)/i", '<iframe width="420" height="315" src="https://www.youtube.com/embed/$2"></iframe>', $content);
$content = preg_replace("/http(s)?:\/\/(w{3}\.)?youtube\.com\/watch\/?\?v=([^\40\t\r\n\<]+)/i", '<iframe width="420" height="315" src="https://www.youtube.com/embed/$3"></iframe>', $content);
return $content;
}

wordpress php change oembed code for videos

As most people know, wordpress uses oembed to fetch the embed code for videos when adding a youtube video to a post. For example, pasting:
https://www.youtube.com/watch?v=pATcvr3zAhg
Would output this in the html:
<iframe width="420" height="315" src="https://www.youtube.com/embed/pATcvr3zAhg" frameborder="0" allowfullscreen></iframe>
I want to change this markup so it uses fancybox and an image, so my markup should look like this:
<a class="fancybox.iframe various" href="VIDEO SOURCE"><img src="IMAGE HERE"></a>
I was using this code which originally replaced the video with an image and when clicked, changed to the video - however, I want to modify this code now so that it outputs the markup above.
add_filter( 'oembed_dataparse', function($str, $data, $url) {
if ( ($yt = $data->provider_name == 'YouTube') || ($vm = $data->provider_name == 'Vimeo') )
{
if($yt) $html = str_replace('feature=oembed', 'feature=oembed&autoplay=1', $str);
else $html = str_replace('" width=', '?autoplay=1" width=', $str);
$html = htmlentities($html, ENT_QUOTES);
$img = $data->thumbnail_url;
$title = esc_attr($data->title);
return '<img src="'. $img . '" onclick="this.outerHTML=\'' . $html . '\'" title="' . $title . '">';
}
return $str;
}, 10, 3);

Replace html tags and pass to function in php

I have an HTML file that has external assets on a secure server that needs a url generated in order to load. I can load the HTML file fine, but none of the images will load. Relative paths wont work. I need to pass the image src attribute to my generateURL method and replace the current relative src paths with my generated url. An example HTML file I need to replace the tags in would be:
<img id="Im0" src="slide1page1/img/1/Im0.png" alt="Im0" width="720" height="540" style="display: none" />
<img id="Im1" src="slide1page1/img/1/Im1.png" alt="Im1" width="136" height="60" style="display: none" />
<img id="Im2" src="slide1page1/img/1/Im2.png" alt="Im2" width="669" height="45" style="display: none" />
My php script that I load the page through is:
<?php
function generateURL($target,$seconds)
{
$secret = "mysecretpasscode";
$end = time() + $seconds;
$url = $target . "?e=" . $end;
$toHash = $secret . $url;
$secure = $url . "&h=" . md5($toHash);
return $secure;
}
$id = $_POST['id'];
$loc = $_POST['loc'];
$url = $loc . "slide" . $id . ".html";
$secure = generateURL($url,600);
$page = file_get_contents($secure);
?>
if I echo $page, I can see the page as if I just loaded an html page (but no images). What I need to do before that is find all the src tags in the HTML and run them through my generateURL method so I can generate the correct URL with proper hashing to load. I am thinking a str_replace will work, but I am not familiar enough with regex to continue. Any help would be appreciated.
First have a look at this answer: RegEx match open tags except XHTML self-contained tags
Though I think you could use PHP's preg_replace_callback as follows:
src_regex = "/src=\"([^\"]+\/";
preg_replace_callback(src_regex, generateURL, html);
Do take into account that the second parameter (generateURL) must be a function with only a single argument, take a look at this page.
A html parser would be better. Provided you've selected all the tags, you can extract the relative path with the function below.
$u = '<img id="Im0" src="slide1page1/img/1/Im0.png" alt="Im0" width="720" height="540" style="display: none" />';
$v = explode(" ", $u);
$x = explode("=", $v[2]);
echo str_replace("\"", "", $x[1]);
Outputs
slide1page1/img/1/Im0.png

Categories