I have a function which convert user input to various services like youtube and opengraph
function link_to_opengraph($content) {
// patterns author https://github.com/LeonardoCardoso/Facebook-Link-Preview/blob/master/php/classes/Regex.php
// overall code inspiration https://github.com/LeonardoCardoso/Facebook-Link-Preview/
$urlRegex = "/(https?\:\/\/|\s)[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,4})(\/+[a-z0-9_.\:\;-]*)*(\?[\&\%\|\+a-z0-9_=,\.\:\;-]*)?([\&\%\|\+&a-z0-9_=,\:\;\.-]*)([\!\#\/\&\%\|\+a-z0-9_=,\:\;\.-]*)}*/i";
$imageRegex = "/<img(.*?)src=(\"|\')(.+?)(gif|jpg|png|bmp)(\"|\')(.*?)(\/)?>(<\/img>)?/";
$imagePrefixRegex = "/\.(jpg|png|gif|bmp)$/i";
$pattern_youtube = '#\b(?:https?://)?(?:www\.)?(?:youtube(?:-nocookie)?\.com/(?:[^/]+/.+/|(?:v|e(?:mbed)?)/|.*[?&]v=)|youtu\.be/)([^"&?/ ]{11})[^\s,]*#x';
preg_match_all( $urlRegex, $content, $allStars );
if($allStars) {
require_once(APFPATH . '/lib/OpenGraph.php');
foreach( $allStars[0] as $key => $star ) {
if (preg_match($imagePrefixRegex, $star)) {
// first check if its image
$markup = '{.class}';
$content = str_replace( $star, $markup, $content );
} else if (preg_match($pattern_youtube, $star, $match)) {
// else if test youtube link
$graph = OpenGraph::fetch($star);
$markup = '[](http://youtu.be/'.$match[1].' "'.$graph->title.'"){#'.$match[1].' .ytmarkdown}';
$content = str_replace( $star, $markup, $content );
} else if(2 == 4) {
// reserved for local links
} else {
// else check if this is external link
$graph = OpenGraph::fetch($star);
$markup = '[**'.$graph->title.'** '.$graph->description.']('.$star.' "'.$star.'"){.graphmarkdown}';
$content = str_replace( $star, $markup, $content );
}
}
}
//return json_encode($allStars);
return $content;
}
The idea is to convert services to markdown before parsing it with markdown extra.
Now problem is str_replace. For example consider case when user input is:
https://www.youtube.com/watch?v=wxsV37GY1IU&feature=share
https://www.youtube.com/watch?v=wxsV37GY1IU&feature=share
http://youtu.be/wxsV37GY1IU
Since first I replace $content the oput will be:
"[]([](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown} "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown}
[]([](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown} "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown}
[](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown} "
As you can see it replaced strings I inserted previously.
When it should return string like this:
"[](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown}
[](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown}
[](http://youtu.be/wxsV37GY1IU "Project Gooseberry - Why should you contribute to it?"){#wxsV37GY1IU .ytmarkdown} "
I dont want to disallow entering same link multiple times.
So question is: Is there any way to tell where I want to replace this $star (link) exactly?