Ch Minn Ch Minn - 7 months ago 44
PHP Question

Filter bad word using javascript

<div class = "filterW"><p class = "lineMsgAlign"><?php echo $rowSelectMsg['comment']; ?></p></div>


produce bad word filter code

//select all bad wordfilter
$querySelectWordFilter = "SELECT * FROM badwordfilter";
$stmtSelectWordFilter = $conn->prepare($querySelectWordFilter);
$stmtSelectWordFilter->execute();
while($rowSelectWordFilter = $stmtSelectWordFilter->fetch()){
$Array[] = $rowSelectWordFilter["filterWord"];
}

//filter word part
var filter = <?php echo json_encode($Array); ?>;
String.prototype.repeat = function(num){
return new Array(num + 1).join(this);
}

$('.filterW').text(function(i, txt){
// Check all words in array
for(var i=0; i<filter.length; i++){


var pattern = new RegExp('\\b' + filter[i] + '\\b', 'gi');
// Create a new string filled with '*'
var replacement = '*'.repeat(filter[i].length);
txt = txt.replace(pattern, replacement);
}
return txt;
});


Question : Above code are work property , the problem of this is it will filter my html code as well. But i dont want to filter html code, how can i do that??

For example (this is above code did)

enter by user : i am tester sohai

Result : i am tester *****

What i want the result should be like is

enter by user : i am tester sohai

Result : i am tester *****

How can i do this?? T.T

Answer

Instead of using the jQuery text() method, use the html() method. The text() method removes all HTML markup from the element body, whereas the html() method returns the entire contents, including markup.

This code is an updated version of the javascript, which implements the word filter mechanism:

//filter word part
var filter = <?php echo json_encode($Array); ?>;
String.prototype.repeat = function(num) {
    return new Array(num + 1).join(this);
}

$('.filterW').html(function(i, html) {
    // Check all words in array
    for (var i=0; i<filter.length; i++) {
        var pattern = new RegExp('\\b' + filter[i] + '\\b', 'gi');
        // Create a new string filled with '*'
        var replacement = '*'.repeat(filter[i].length);
        html = html.replace(pattern, replacement);
    }
    return html;
});

This should work for your purposes, but there are at least 2 issues with this implementation. The first is that the HTML markup will be effected if the word filter contains words that appear in the markup. For instance, consider this example:

<a href="#" id="igloo">Igloo</a>

If you choose to filter for 'igloo', then both the body and id attribute of the link will be affected. Depending on your needs, this might be acceptable. If this is not acceptable, a full HTML parser is required to solve the problem.

The second issue is that words divided by markup will not be identified. Consider this example:

<p>This is an exa<i>m</i>ple</p>

In this case, searching for 'example' will succeed when using the text() method, but will not when using the html() method. It can be argued that markup embedded within a word indicates that the word is not actually a word, however, this is one of the approaches that spammers have historically used to bypass spam detection software.