convert text url into clickable text or image link

350 Views Asked by At

Here's is something I would like to add to my website.

I am proposing to have website users submit their profile page with links in this format:

(*http://example.com X click_here*)
(*https://www.facebook.com/xyz X facebook*)
(*http://twitter.com X twitter*)
(*http://www.linkedin.com X linkedin*)
(*http://www.other.com*)

And the plan is to produce links such as:

<a href="https://facebook.com/xyz" target="_blank"><img src="facebook.gif" alt="facebook"></a>
<a href="http://twitter.com?foo=bar&foo2=bar2" target="_blank"><img src="twitter.gif" alt="twitter"></a>
<a href="http://linkedin.com/xyz" target="_blank"><img src="facebook.gif" alt="facebook"></a>
<a href="http://example.com?foo=bar&foo2=bar2" target="_blank">click_here</a> 
<a href="http://www.other.com" target="_blank">http://www.other.com</a>


Parameters:
1. Allow members with no knowledge of html to submit a profile page with links to their personal website, facebook, twitter, linkedin, etc.
2. Prevent XSS


I have taken this as far as my limited knowledge allows. The code below is my feeble attempt. I will continue to try to solve out how this can be done. I trust you will be able to follow the logic of what I am trying to do.

Any assistance would be greatly appreciated.

<?php


    // member profile retrieved from MySQL
$unsafe = "
   blah blah blah (*http://example.com X click_here*) blah blah blah 
   blah blah blah (*https://www.facebook.com/xyz X facebook*)  blah blah blah blah
   blah blah blah (*http://twitter.com X twitter*)   blah blah blah blah blah
   blah blah blah (*http://www.linkedin.com X linkedin*) blah blah blah
   blah blah blah (*http://www.other.com*) blah blah blah";

$safe_text = htmlspecialchars($unsafe, ENT_QUOTES, 'UTF-8'); 

     // I assume this can not be done without creating a function
function hyperlinks ($safe_text) 
{

    $pattern = "%\(\*(.*)\*\)%";

    preg_match($pattern, $safe_text, $matches); 
    // $matches[1]  "http://example.com X click_here"

    $pairs = explode(" X ", $matches[1]);  

    $var1 = $pairs[0]; // result: http://example.com
    $var2 = $pairs[1]; // result: click_here

    if (isset($var2))
    { 
       if ($var2 === "facebook") $var2 = '<img src="/images/facebook.gif" alt="facebook">';
       if ($var2 === "twitter")  $var2 = '<img src="/images/twitter.gif" alt="twitter">';
       if ($var2 === "linkedin") $var2 = '<img src="/images/linkedin.gif" alt="linkedin">';
       if (($var2 != "facebook") && ($var2 != "twitter") && ($var2 != "linkedin")) 
       { 
          // this line is not needed, just shows logic
          $var2 = $var2; // the text provided is var2
       } 

    } else { $var2 = $var1; }  // var2 doesn't exist



    $replacement = "<a href='$var1' target='_blank'>$var2</a>"; //edit switched "''"     


    $new_string = preg_replace($pattern, $replacement, $safe_text);

echo $new_string ."<br/>";


   return $new_string; // edit added
}
hyperlinks($safe_text); //edit added




   /************
$new_string should look like:

$new_string = "
 blah blah blah <a href="https://facebook.com/xyz" target="_blank"><img src="facebook.gif" alt="facebook"></a>  blah blah blah
 blah blah blah <a href="http://twitter.com?foo=bar&foo2=bar2" target="_blank"><img src="twitter.gif" alt="twitter"></a> blah blah blah
 blah blah blah <a href="http://linkedin.com/xyz" target="_blank"><img src="facebook.gif" alt="facebook"></a> blah blah blah
 blah blah blah <a href="http://example.com?foo=bar&foo2=bar2" target="_blank">click_here</a> blah blah blah 
 blah blah blah <a href="http://www.other.com" target="_blank">http://www.other.com</a> blah blah blah";

*************/




 ?>

Ok. So the first attempt didn't get very far.

Here my second attempt.

<?php

error_reporting( E_ALL );

    // member profile retrieved from mysql
$unsafe = "blah blah blah (*http://example.com?foo=bar&foo2=bar2 X click_here*) blah blah blah
           blah blah blah (*https://www.facebook.com/xyz X facebook*)  blah blah blah blah
           blah blah blah (*http://twitter.com X twitter*)   blah blah blah blah blah
           blah blah blah (*http://www.linkedin.com X linkedin*) blah blah blah
           blah blah blah (*http://www.other.com*) blah blah blah";

$safe_text = htmlspecialchars($unsafe, ENT_QUOTES, 'UTF-8'); 

     // I assume this can not be done without creating a function
function hyperlinks ($safe_text) 
{


    $pattern = "%\(\*(.*)\*\)%";


    preg_match_all($pattern, $safe_text, $matches); // matches[1]  "http://example.com X click_here"



foreach($matches[1] as $result)
   {

 $pairs = explode(" X ", $result);  

    $var1 = $pairs[0]; // result: http://example.com
    $var2 = $pairs[1]; // result: click_here


if (isset($var2))
    { 
       if ($var2 === "facebook") $var2 = '<img src="/images/facebook.gif" alt="facebook">';
       if ($var2 === "twitter")  $var2 = '<img src="/images/twitter.gif" alt="twitter">';
       if ($var2 === "linkedin") $var2 = '<img src="/images/linkedin.gif" alt="linkedin">';
       if (($var2 != "facebook") && ($var2 != "twitter") && ($var2 != "linkedin")) 
       { 
          // this line is not needed, just shows logic
          $var2 = $var2; // the text provided is var2
       } 

    } else { $var2 = $var1; }  // var2 doesn't exist


// var_dump($result);


    $replacement = "<a href='$var1' target='_blank'>$var2</a>";


// echo $replacement ."<br/>"; 

    $new_string = preg_replace($pattern, $replacement, $safe_text);

 echo $new_string ."<br/>";



   }// close foreach



   return $new_string;
}// close function


hyperlinks($safe_text);



?>

This one outputs results... Too many results.

The first preg_match_all() finds 5 links which ends up getting multiplied be the preg_replace() so it produces 25 links. 5 of each variety.

Basically figured out that I should only have 1 preg_something?? Googled: Calling a function inside preg_replace and found that I should be using preg_replace_callback and that it does allow for a function within.

So third attempt:

<?php

error_reporting( E_ALL );

    // member profile retrieved from mysql
$unsafe = "blah blah blah (*http://example.com?foo=bar&foo2=bar2 X click_here*) blah blah blah
           blah blah blah (*https://www.facebook.com/xyz X facebook*)  blah blah blah blah
           blah blah blah (*http://twitter.com X twitter*)   blah blah blah blah blah
           blah blah blah (*http://www.linkedin.com X linkedin*) blah blah blah
           blah blah blah (*http://www.other.com*) blah blah blah";

$safe_text = htmlspecialchars($unsafe, ENT_QUOTES, 'UTF-8'); 


// I assume this can not be done without creating a function

$pattern = "%\(\*(.*)\*\)%";

 $new_string = preg_replace_callback($pattern, 'safe_text', $safe_text);

// Error: preg_replace_callback(): Requires argument 2, 'safe_text', to be a valid callback 

function safe_text($text) {   // edit 


foreach($safe_text as $result)
   {

 $pairs = explode(" X ", $result);  

    $var1 = $pairs[0]; // result: http://example.com
    $var2 = $pairs[1]; // result: click_here


if (isset($var2))
    { 
       if ($var2 === "facebook") $var2 = '<img src="/images/facebook.gif" alt="facebook">';
       if ($var2 === "twitter")  $var2 = '<img src="/images/twitter.gif" alt="twitter">';
       if ($var2 === "linkedin") $var2 = '<img src="/images/linkedin.gif" alt="linkedin">';
       if (($var2 != "facebook") && ($var2 != "twitter") && ($var2 != "linkedin")) 
       { 
          // this line is not needed, just shows logic
          $var2 = $var2; // the text provided is var2
       } 

    } else { $var2 = $var1; }  // var2 doesn't exist

   } // close foreach


    $replacement = "<a href='$var1' target='_blank'>$var2</a>";

echo $replacement ."<br/>";

       return $new_string;


} // close function


// $new_text = hyperlinks($safe_text);



 echo $new_string; //error: unexpected 'echo' (T_ECHO) 



?> 
1

There are 1 best solutions below

0
On BEST ANSWER

It took a lot of effort but I finally got it. I will be using this on my website.

All the other "Convert plain text into hyperlinks" examples created links in this style:

<a href="http://www.example.com">http://www.example.com</a>

I thought it would be much better to have the option to say:
Come visit my_website or Find me on Facebook


<?php

$unsafe = "blah blah blah (*http://example.com?foo=bar&foo2=bar2 X click_here*) blah blah blah
           blah blah blah (*https://www.facebook.com/xyz X facebook*)  blah blah blah blah
           blah blah blah (*http://twitter.com X twitter*)   blah blah blah blah blah
           blah blah blah (*http://www.linkedin.com X linkedin*) blah blah blah
           blah blah blah (*http://www.other.com*) blah blah blah";



$safe_text = htmlspecialchars($unsafe, ENT_QUOTES, 'UTF-8'); 

function make_hyperlinks($matches)
{

$matches = $matches[1];

  if (strpos($matches, " X ") !== FALSE)
   {
     $pairs = explode(" X ", $matches);

      } else {

     $pairs[0] .= $matches;
   }    

    $var0 = $pairs[0]; 
    $var1 = $pairs[1]; 

   if (isset($var1))
         { 
         if ($var1 === "facebook") $var1 = '<img src="/images/facebook.gif" alt="facebook">';
         if ($var1 === "twitter")  $var1 = '<img src="/images/twitter.gif" alt="twitter">';
         if ($var1 === "linkedin") $var1 = '<img src="/images/linkedin.gif" alt="linkedin">';
         } else {$var1 = $var0; }  // var1 doesn't exist

   return "<a href='$var0' rel='nofollow' target='_blank'>$var1</a>";

}

$new_string = preg_replace_callback("%\(\*(.*)\*\)%", "make_hyperlinks", $safe_text);

// echo $new_string;

?>