Welcome Guest, Not a member yet? Register   Sign In
eMail Obfuscator
#1

[eluser]Muppit[/eluser]
Morning all,

CI's safe_mailto() works well under certain conditions, but it is limited in the sense that it fails in a non-JS environment, and that it won't parse an entire block of [ usually RTE generated such as TinyMCE/FCKEditor ] code and strip out the eMails.

Also to note I'm not quite yet a seasoned programmer, so it's probably mostly twice as heavy as it should be, and to me regular expressions are like the culinary equivalent of cactus pies, so bear this in mind as you laugh at my totally un-l33t coding skillz.

If you do improve it please flick me a copy! If you deem it unsafe and unfit for human consumption do me a favor and let me know also.

Copy the code as below and place the it as Secemail.php file into your application/libraries/ folder and load it in via the usual method from within your controller/model function:

Code:
function thisFunc(){
    $this->load->library('secemail');
}

From here, you simply call the function inside the class file 'cleanEmail()' and pass it your raw HTML data that you want obfuscated like this:

Code:
$rawHTML = 'Lorem ipsum...';
  $cleanedHTML = $this->secemail->cleanEmail($rawHTML);

And the result is un-readable eMail addresses, but functional mailto: links [providing JS is on].

Secemail.php ____________________________________
Code:
<?php if (!defined('BASEPATH')) exit('No direct script access allowed');

class Secemail {

//Removes any occurences of raw eMail addresses within an HTML code block.
/*
The way it works:
- Read in HTML, count number of occurences of eMail addresses.
- Loop through, strip out name & domain for each eMail address, and stupify the usual suspects: @ . - _
- Place the obfuscated eMail address into a unique DIV as 'name [AT] domain.co.nz' for non-JS users.
- Lace this with self-loading JS code that replaces itself with an obfuscated mailto: version at run-time, so in a JS environment, the mailto: works as expected.
*/
    function cleanEmail($theData){
        $cnt ='';
        $finalOutput = '';
        $rawHTML = stripslashes($theData);
        //Extract and count total number of <a href ... a/> tags present in the HTML
        $tagSetResult = preg_match_all("/<a\shref=\"mailto:[a-zA-Z0-9-_\.]+@*[a-zA-Z0-9\.]+\">[-!a-zA-Z0-9\s@\.]*<\/a>/", $rawHTML, $matches);    
        if ($tagSetResult) {
            for($j=0;$j<$tagSetResult;$j++){
                //Now strip out the LINK portion of the eMail address i.e( 'Click Here' or '[email protected]');
                $eLinkResultRaw = preg_match("/>.*</",$matches[0][$j],$eLink[$j]);    
                //Remove the leading / trailing brackets ( < > )
                $eLink_phaseII[0][$j] = trim($eLink[$j][0],"<>");
                //And replace critical chars ( @ . - _)

                //Setup which characters should be converted across into HTML hash codes -
                $specialChars = array("@", ".");
                //And their respective hash codes ...
                $replaceChars = array("_[AT]_","{%q");

                //Mash it all up...
                $eLinkNew[0][$j] = str_replace($specialChars,$replaceChars,$eLink_phaseII[0][$j]);

                //For every href set extracted, extract the eMail address [ which exists between the [ " " ]
                $emailOnly = preg_match("/\".+\"/", $matches[0][$j], $emailMatch[$j]);

                //Each eMail address now in this format: "[email protected]" [incl quotes];

                //Now split off the "mailto:" section of the result, and trim off the quote marks too. This leaves a pure eMail address
                $purEmailArr[$j] = split("mailto:",trim($emailMatch[$j][0],"\""));    
    
                //Split the email address off at the '@' to reveal the name / domain name portion
                $nameOnly[$j] = split("@",$purEmailArr[$j][1]);

                //Replace the "@" with the mangle code. This looks like "name.here [AT] mysite.co.nz" and is used for non-javascript rendering
                $atMangle = "[AT]";
                $atMangledAdd[$j] = str_replace("@",$atMangle,$purEmailArr[$j][1]);
        
                //Replace any periods with the HTML Number counterpart [ mash it up just a little bit more ]
                $completeMangledAdd[$j] = str_replace(".",".",$atMangledAdd[$j]);
                
                //Generate the HTML / JavaScript code-block which will be the codeblock replacing all the <a href ... a/> blocks
                $finalOutput[$j] = '
                <span id="kshemsp'.$cnt.'"><a href="[removed]void(null);">'.$completeMangledAdd[$j].'</a></span>
                
                    document.getElementById("kshemsp'.$cnt.'")[removed].removeChild(document.getElementById("kshemsp'.$cnt.'"));obfusEma("'.$nameOnly[$j][0].'", "'.$eLinkNew[0][$j].'", "'.$nameOnly[$j][1].'");
                
                ';
                $cnt++;
      }
    }
    //Replace all occurences of the <ahref> code-block with our new HTML/javaScript block
    $newText = str_replace($matches[0],$finalOutput,$rawHTML);

    //Finally, return the newly updated string
    return $newText;
    }
}

?&gt;

secemail_js.js________________________________________
Code:
function obfusEma(name,elink,domain){
        //Return PHP hashed char's back to 'readable' HTML Codes
        elink_enc = elink.replace(/_[AT]_/g, "@");
        elink_enc2 = elink_enc.replace(/{%q/g,".");

        var m_ = "mail";
        var m_II = "to:";
        var a_ = "@";
        var dom_ = domain;
        [removed]('<span id="ksemhc"><a href="'+m_+m_II+name+a_+dom_+'">'+elink_enc2+'</a></span>');
}

Hope someone finds it useful, feedback would be appreciated!

G.
#2

[eluser]Muppit[/eluser]
Okay so obviously half the code's been stripped out but it does work and it works pretty well - so if you need this solution feel free to message me.




Theme © iAndrew 2016 - Forum software by © MyBB