diff --git a/README.md b/README.md index 47cfd04..092db1e 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,13 @@ use Blaspsoft\Blasp\Facades\Blasp; $sentence = 'This is a fucking shit sentence'; $check = Blasp::check($sentence); ``` +you can also change the default language to french +```php +use Blaspsoft\Blasp\Facades\Blasp; +$sentence = 'Cette phrase est merdique'; +$check = Blasp::check($sentence, 'fr'); +``` The returned object will contain the following properties: - **sourceString**: The original string you passed. @@ -79,7 +85,12 @@ $validated = $request->validate([ // If the sentence contains profanities, validation will fail. ``` - +or for french +```php +$validated = $request->validate([ + 'sentence' => ['blasp_check:fr'], +]); +``` ### Configuration Blasp uses a configuration file (`config/blasp.php`) to manage the list of profanities, separators, and substitutions. You can publish the configuration file using the following Artisan command: diff --git a/config/config.php b/config/config.php index f47dd9d..edad69f 100644 --- a/config/config.php +++ b/config/config.php @@ -2,6 +2,28 @@ return [ + /* + |-------------------------------------------------------------------------- + | Default language + |-------------------------------------------------------------------------- + | + | Define the default language + | + | + */ + 'default_language' => 'en', + + /* + |-------------------------------------------------------------------------- + | Languages + |-------------------------------------------------------------------------- + | + | Define the list of languages available in the package + | + | + */ + 'languages' => ['en', 'fr'], + /* |-------------------------------------------------------------------------- | Character separators @@ -93,28 +115,38 @@ | */ 'false_positives' => [ - 'scunthorpe', - 'cockburn', - 'penistone', - 'lightwater', - 'assume', - 'bass', - 'class', - 'compass', - 'pass', - 'dickinson', - 'middlesex', - 'cockerel', - 'butterscotch', - 'blackcock', - 'countryside', - 'arsenal', - 'flick', - 'flicker', - 'analyst', - 'cocktail', + 'en' => [ + 'scunthorpe', + 'cockburn', + 'penistone', + 'lightwater', + 'assume', + 'bass', + 'class', + 'compass', + 'pass', + 'dickinson', + 'middlesex', + 'cockerel', + 'butterscotch', + 'blackcock', + 'countryside', + 'arsenal', + 'flick', + 'flicker', + 'analyst', + 'cocktail', + ], + 'fr' => [ + 'passeur', + 'classe', + 'passage', + 'assumer', + 'passant', + 'bassiste', + ] ], - + /* |-------------------------------------------------------------------------- @@ -126,1309 +158,1340 @@ | */ 'profanities' => [ - 'abbo', - 'abortionist', - 'abuser', - 'ahole', - 'alabama hotpocket', - 'alligatorbait', - 'anal', - 'analannie', - 'analsex', - 'areola', - 'arse', - 'arsebagger', - 'arsebandit', - 'arseblaster', - 'arsecowboy', - 'arsefuck', - 'arsefucker', - 'arsehat', - 'arsehole', - 'arseholes', - 'arsehore', - 'arsejockey', - 'arsekiss', - 'arsekisser', - 'arselick', - 'arselicker', - 'arselover', - 'arseman', - 'arsemonkey', - 'arsemunch', - 'arsemuncher', - 'arsepacker', - 'arsepirate', - 'arsepuppies', - 'arseranger', - 'arses', - 'arsewhore', - 'arsewipe', - 'ass', - 'assbag', - 'assbagger', - 'assbandit', - 'assbanger', - 'assbite', - 'assblaster', - 'assclown', - 'asscock', - 'asscowboy', - 'asscracker', - 'asses', - 'assface', - 'assfuck', - 'assfucker', - 'assgoblin', - 'ass-hat', - 'asshat', - 'asshead', - 'asshole', - 'assholes', - 'assholz', - 'asshopper', - 'asshore', - 'ass-jabber', - 'assjacker', - 'assjockey', - 'asskiss', - 'asskisser', - 'assklown', - 'asslick', - 'asslicker', - 'asslover', - 'assman', - 'assmonkey', - 'ass monkey', - 'assmunch', - 'assmuncher', - 'assnigger', - 'asspacker', - 'ass-pirate', - 'asspirate', - 'asspuppies', - 'assranger', - 'assshit', - 'assshole', - 'asssucker', - 'asswad', - 'asswhore', - 'asswipe', - 'axwound', - 'azzhole', - 'backdoorman', - 'badfuck', - 'baldy', - 'ball licker', - 'balllicker', - 'ballsack', - 'bampot', - 'banging', - 'barelylegal', - 'barface', - 'barfface', - 'bassterds', - 'bastard', - 'bastards', - 'bastardz', - 'basterds', - 'basterdz', - 'bazongas', - 'bazooms', - 'beaner', - 'beastality', - 'beastial', - 'beastiality', - 'beat-off', - 'beatoff', - 'beatyourmeat', - 'bestial', - 'bestiality', - 'biatch', - 'bicurious', - 'bigass', - 'bigbastard', - 'bigbutt', - 'bitch', - 'bitchass', - 'bitcher', - 'bitches', - 'bitchez', - 'bitchin', - 'bitching', - 'bitchslap', - 'bitchtits', - 'bitchy', - 'biteme', - 'blow job', - 'blowjob', - 'boffing', - 'bohunk', - 'bollick', - 'bollock', - 'bollocks', - 'bollox', - 'bondage', - 'boner', - 'boob', - 'boobies', - 'boobs', - 'booby', - 'bootycall', - 'bountybar', - 'breastjob', - 'breastlover', - 'breastman', - 'brothel', - 'brotherfucker', - 'bugger', - 'buggered', - 'buggery', - 'bukake', - 'bullcrap', - 'bulldike', - 'bulldyke', - 'bullshit', - 'bumblefuck', - 'bumfuck', - 'bungabunga', - 'bunghole', - 'butchbabes', - 'butchdike', - 'butchdyke', - 'butt-bang', - 'buttbang', - 'buttcheeks', - 'buttface', - 'butt-fuck', - 'buttfuck', - 'buttfucka', - 'butt-fucker', - 'buttfucker', - 'butt-fuckers', - 'buttfuckers', - 'butthead', - 'butthole', - 'buttman', - 'buttmunch', - 'buttmuncher', - 'butt-pirate', - 'buttpirate', - 'butt plug', - 'buttplug', - 'buttstain', - 'buttwipe', - 'byatch', - 'cacker', - 'cameljockey', - 'camel toe', - 'cameltoe', - 'carpet muncher', - 'carpetmuncher', - 'cawk', - 'cawks', - 'chav', - 'cherrypopper', - 'chesticle', - 'chickslick', - 'chinc', - 'chink', - 'choad', - 'chode', - 'clamdigger', - 'clamdiver', - 'clit', - 'clitface', - 'clitfuck', - 'clitoris', - 'clogwog', - 'clunge', - 'clusterfuck', - 'cnts', - 'cntz', - 'cock', - 'cockass', - 'cockbite', - 'cockblock', - 'cockblocker', - 'cockburger', - 'cockcowboy', - 'cockface', - 'cockfight', - 'cockfucker', - 'cock-head', - 'cockhead', - 'cockjockey', - 'cockknob', - 'cockknoker', - 'cocklicker', - 'cocklover', - 'cockmaster', - 'cockmongler', - 'cockmongruel', - 'cockmonkey', - 'cockmuncher', - 'cocknob', - 'cocknose', - 'cocknugget', - 'cockqueen', - 'cockrider', - 'cocks', - 'cockshit', - 'cocksman', - 'cocksmith', - 'cocksmoke', - 'cocksmoker', - 'cocksniffer', - 'cocksucer', - 'cocksuck', - 'cocksucked', - 'cock-sucker', - 'cocksucker', - 'cocksucking', - 'cocktease', - 'cockwaffle', - 'cocky', - 'coitus', - 'cok', - 'commie', - 'coochie', - 'coochy', - 'coon', - 'coondog', - 'cooter', - 'copulate', - 'cracker', - 'crackpipe', - 'crack-whore', - 'crackwhore', - 'crap', - 'crappy', - 'crotchjockey', - 'crotchmonkey', - 'crotchrot', - 'cuck', - 'cum', - 'cumbubble', - 'cumdumpster', - 'cumfest', - 'cumguzzler', - 'cumjockey', - 'cumm', - 'cumquat', - 'cumqueen', - 'cumshot', - 'cumslut', - 'cumtart', - 'cunilingus', - 'cunillingus', - 'cunnie', - 'cunnilingus', - 'cunntt', - 'cunt', - 'cuntass', - 'cunteyed', - 'cuntface', - 'cuntfuck', - 'cuntfucker', - 'cunthole', - 'cuntlick', - 'cuntlicker', - 'cuntlicker', - 'cuntlicking', - 'cuntrag', - 'cunts', - 'cuntslut', - 'cuntsucker', - 'cuntz', - 'cybersex', - 'cyberslimer', - 'dago', - 'dammit', - 'damn', - 'damnation', - 'damnit', - 'darkie', - 'darky', - 'datnigga', - 'deapthroat', - 'deepthroat', - 'deggo', - 'dego', - 'devilworshipper', - 'dick', - 'dickbag', - 'dickbeaters', - 'dickbrain', - 'dickface', - 'dickforbrains', - 'dickfuck', - 'dickfucker', - 'dickhead', - 'dickhole', - 'dickjuice', - 'dickless', - 'dicklick', - 'dicklicker', - 'dickmilk', - 'dickmonger', - 'dicks', - 'dickslap', - 'dick-sneeze', - 'dicksucker', - 'dicksucking', - 'dicktickler', - 'dickwad', - 'dickweasel', - 'dickweed', - 'dickwod', - 'dike', - 'dildo', - 'dildos', - 'dilldo', - 'dilldos', - 'dipshit', - 'dipstick', - 'dixiedike', - 'dixiedyke', - 'doggiestyle', - 'doggystyle', - 'dominatricks', - 'dominatrics', - 'dominatrix', - 'doochbag', - 'dookie', - 'douch', - 'douchbag', - 'douche', - 'douchebag', - 'douche-fag', - 'douchewaffle', - 'drag queen', - 'dragqueen', - 'dragqween', - 'dripdick', - 'dumass', - 'dumb ass', - 'dumbass', - 'dumbbitch', - 'dumbfuck', - 'dumbshit', - 'dumshit', - 'dyke', - 'easyslut', - 'eatballs', - 'eatme', - 'eatpussy', - 'ejaculate', - 'ejaculated', - 'ejaculating', - 'ejaculation', - 'enema', - 'excrement', - 'facefucker', - 'facist', - 'faeces', - 'fag', - 'fagbag', - 'faget', - 'fagfucker', - 'fagging', - 'faggit', - 'faggot', - 'faggotcock', - 'faggots', - 'fagit', - 'fagot', - 'fags', - 'fagtard', - 'fagz', - 'faig', - 'faigs', - 'fannyfucker', - 'fark', - 'farted', - 'farting', - 'farty', - 'fastfuck', - 'fatass', - 'fatfuck', - 'fatfucker', - 'fatso', - 'feces', - 'felatio', - 'felch', - 'felcher', - 'felching', - 'fellatio', - 'feltch', - 'feltcher', - 'feltching', - 'fingerfuck', - 'fingerfucked', - 'fingerfucker', - 'fingerfuckers', - 'fingerfucking', - 'fister', - 'fistfuck', - 'fistfucked', - 'fistfucker', - 'fistfucking', - 'fisting', - 'flamer', - 'flasher', - 'flid', - 'flipping the bird', - 'flyd', - 'flydie', - 'flydye', - 'fondle', - 'footaction', - 'footfuck', - 'footfucker', - 'footlicker', - 'fornicate', - 'freakfuck', - 'freakyfucker', - 'freefuck', - 'fubar', - 'fucck', - 'fuck', - 'fucka', - 'fuckable', - 'fuckass', - 'fuckbag', - 'fuckboy', - 'fuckbrain', - 'fuckbuddy', - 'fuckbutt', - 'fuckbutter', - 'fucked', - 'fuckedup', - 'fucker', - 'fuckers', - 'fuckersucker', - 'fuckface', - 'fuckfest', - 'fuckfreak', - 'fuckfriend', - 'fuckhead', - 'fuckher', - 'fuckhole', - 'fuckin', - 'fuckina', - 'fucking', - 'fuckingbitch', - 'fuckingcunt', - 'fuckinnuts', - 'fuckinright', - 'fuckit', - 'fuckknob', - 'fuckme', - 'fuckmehard', - 'fuckmonkey', - 'fucknut', - 'fucknutt', - 'fuckoff', - 'fuckpig', - - 'fuckstick', - 'fucktard', - 'fucktart', - 'fuckup', - 'fuckwad', - 'fuckwhore', - 'fuckwit', - 'fuckwitt', - 'fuckyou', - 'fudge packer', - 'fudgepacker', - 'Fudge Packer', - 'fugly', - 'fuk', - 'Fukah', - 'Fuken', - 'fuker', - 'Fukin', - 'Fukk', - 'Fukkah', - 'Fukken', - 'Fukker', - 'Fukkin', - 'fuks', - 'funfuck', - 'fuuck', - 'gang bang', - 'gangbang', - 'gangbanged', - 'gangbanger', - 'gatorbait', - 'gayass', - 'gaybob', - 'gayboy', - 'gaydo', - 'gayfuck', - 'gayfuckist', - 'gaygirl', - 'gaylord', - 'gaymuthafuckinwhore', - 'gays', - 'gaysex', - 'gaytard', - 'gaywad', - 'gayz', - 'getiton', - 'givehead', - 'glazeddonut', - 'godammit', - 'goddamit', - 'goddammit', - 'goddamn', - 'goddamned', - 'god-damned', - 'goddamnes', - 'goddamnit', - 'goddamnmuthafucker', - 'goldenshower', - 'gonorrehea', - 'gonzagas', - 'gooch', - 'gook', - 'gotohell', - 'greaseball', - 'gringo', - 'grostulation', - 'guido', - 'gypo', - 'gypp', - 'gyppie', - 'gyppo', - 'gyppy', - 'handjob', - 'hard on', - 'hardon', - 'headfuck', - 'heeb', - 'hells', - 'herpes', - 'hijacker', - 'hijacking', - 'hillbillies', - 'hindoo', - 'hitler', - 'hitlerism', - 'hitlerist', - 'hoar', - 'hobo', - 'hoe', - 'hoes', - 'holestuffer', - 'homo', - 'homobangers', - 'homodumbshit', - 'honger', - 'honkers', - 'honkey', - 'honky', - 'hookers', - 'hoor', - 'hoore', - 'hore', - 'horney', - 'horniest', - 'horny', - 'horseshit', - 'hosejob', - 'hotdamn', - 'hotpussy', - 'hottotrot', - 'humping', - 'hymen', - 'iblowu', - 'idiot', - 'incest', - 'insest', - 'internet wife', - 'intheass', - 'inthebuff', - 'jackass', - 'jackoff', - 'jackshit', - 'jagoff', - 'jap', - 'japcrap', - 'japs', - 'jerkass', - 'jerk off', - 'jerk-off', - 'jerkoff', - 'jesuschrist', - 'jigaboo', - 'jiggabo', - 'jihad', - 'jijjiboo', - 'jisim', - 'jism', - 'jiss', - 'jizim', - 'jizjuice', - 'jizm', - 'jizm', - 'jizz', - 'jizzim', - 'jizzum', - 'jubblies', - 'juggalo', - 'jungle bunny', - 'junglebunny', - 'kiddy fiddler', - 'kike', - 'kinky', - 'kissass', - 'knobz', - 'kondum', - 'kooch', - 'kootch', - 'krap', - 'krappy', - 'kraut', - 'kumbubble', - 'kumbullbe', - 'kummer', - 'kumming', - 'kums', - 'kunilingus', - 'kunnilingus', - 'kunt', - 'kunts', - 'kuntz', - 'kyke', - 'labia', - 'lactate', - 'lady boy', - 'ladyboy', - 'lameass', - 'lapdance', - 'lardass', - 'lesbain', - 'lesbayn', - 'lesbian', - 'lesbin', - 'lesbo', - 'lezbe', - 'lezbefriends', - 'lezbo', - 'lezz', - 'lezzer', - 'lezzie', - 'lezzo', - 'libido', - 'lickme', - 'limpdick', - 'lipshits', - 'lipshitz', - 'livesex', - 'lmfao', - 'loadedgun', - 'lovebone', - 'lovegoo', - 'lovegun', - 'lovejuice', - 'lovemuscle', - 'lovepistol', - 'loverocket', - 'low life', - 'lowlife', - 'lubejob', - 'luckycameltoe', - 'manhater', - 'manpaste', - 'masochist', - 'masokist', - 'massterbait', - 'masstrbait', - 'masstrbate', - 'mastabate', - 'mastabater', - 'masterbaiter', - 'masterbate', - 'master bates', - 'masterbates', - 'mastrabator', - 'masturbate', - 'masturbating', - 'mattressprincess', - 'mcfagget', - 'meatbeater', - 'meatrack', - 'mgger', - 'mggor', - 'milf', - 'minge', - 'mofo', - 'molest', - 'molestation', - 'molester', - 'molestor', - 'moneyshot', - 'mooncricket', - 'moron', - 'mothafuck', - 'mothafucka', - 'mothafuckaz', - 'mothafucked', - 'mothafucker', - 'motha fucker', - 'mothafuckin', - 'mothafucking', - 'mothafuckings', - 'motha fuker', - 'motha fukkah', - 'motha fukker', - 'motherfuck', - 'motherfucked', - 'mother-fucker', - 'motherfucker', - 'mother fucker', - 'motherfuckin', - 'motherfucking', - 'motherfuckings', - 'mother fukah', - 'mother fuker', - 'mother fukkah', - 'mother fukker', - 'motherlovebone', - 'muff', - 'muffdive', - 'muffdiver', - 'muffindiver', - 'mufflikcer', - 'muncher', - 'munging', - 'muthafucker', - 'mutha fucker', - 'mutha fukah', - 'mutha fuker', - 'mutha fukkah', - 'mutha fukker', - 'nastt', - 'nastybitch', - 'nastyho', - 'nastyslut', - 'nastywhore', - 'nazi', - 'necro', - 'negro', - 'negroes', - 'negroid', - 'nigaboo', - 'nigga', - 'niggah', - 'niggaracci', - 'niggard', - 'niggarded', - 'niggarding', - 'niggardliness', - "niggardliness's", - 'niggardly', - "niggard's", - 'niggards', - 'niggaz', - 'nigger', - 'niggerhead', - 'niggerhole', - "nigger's", - 'niggers', - 'niggle', - 'niggled', - 'niggles', - 'niggling', - 'nigglings', - 'niggor', - 'niggur', - 'niglet', - 'nignog', - 'nigr', - 'nigra', - 'nigre', - 'nigur', - 'niiger', - 'niigr', - 'nipple', - 'nipplering', - 'nittit', - 'nlgger', - 'nlggor', - 'nofuckingway', - 'nonce', - 'nookey', - 'nookie', - 'nudger', - 'nut case', - 'nutcase', - 'nutfucker', - 'nut sack', - 'nutsack', - 'ontherag', - 'orafis', - 'orgasim', - 'orgasim', - 'orgasm', - 'orgasum', - 'orgies', - 'orgy', - 'oriface', - 'orifice', - 'orifiss', - 'osama bin laden', - 'packi', - 'packie', - 'packy', - 'paedo', - 'paedofile', - 'paedophile', - 'paki', - 'pakie', - 'paky', - 'palesimian', - 'panooch', - 'panti', - 'pearlnecklace', - 'pecker', - 'peckerhead', - 'peckerwood', - 'peedo', - 'peeenus', - 'peeenusss', - 'peehole', - 'peenus', - 'peinus', - 'penas', - 'penile', - 'penisbanger', - 'penis-breath', - 'penises', - 'penisfucker', - 'penispuffer', - 'penus', - 'penuus', - 'perv', - 'perversion', - 'pervert', - 'phonesex', - 'phuc', - 'phuck', - 'phuk', - 'phuked', - 'phuker', - 'phuking', - 'phukked', - 'phukker', - 'phukking', - 'phungky', - 'phuq', - 'pi55', - 'picaninny', - 'piccaninny', - 'pickaninny', - 'pikey', - 'piky', - 'pimper', - 'pimpjuic', - 'pimpjuice', - 'pimpsimp', - 'pindick', - 'piss', - 'pissed', - 'pissed off', - 'pisser', - 'pisses', - 'pissflaps', - 'pisshead', - 'pissin', - 'pissing', - 'pissoff', - 'play boy', - 'playboy', - 'play bunny', - 'playbunny', - 'play girl', - 'playgirl', - 'plumper', - 'pocketpool', - 'polac', - 'polack', - 'polak', - 'polesmoker', - 'pollock', - 'poon', - 'poonani', - 'poonany', - 'poontang', - 'pooperscooper', - 'pooping', - 'poorwhitetrash', - 'poostabber', - 'popimp', - 'porch monkey', - 'porchmonkey', - 'porn', - 'pornflick', - 'pornking', - 'porno', - 'pornprincess', - 'pric', - 'prick', - 'prik', - 'prickhead', - 'prostitute', - 'pu55i', - 'pu55y', - 'pube', - 'pubiclice', - 'puke', - 'punanny', - 'punta', - 'puntang', - 'purinaprincess', - 'pusse', - 'pussee', - 'pussie', - 'pussies', - 'pussy', - 'pussyeater', - 'pussyfucker', - 'pussylicker', - 'pussylicking', - 'pussylips', - 'pussylover', - 'pussypounder', - 'pusy', - 'puto', - 'puuke', - 'puuker', - 'queef', - 'queer', - 'queerbait', - 'queerhole', - 'queers', - 'queerz', - 'quim', - 'qweers', - 'qweerz', - 'qweir', - 'rag head', - 'raghead', - 'raped', - 'rapist', - 'rearend', - 'rearentry', - 'recktum', - 'rectum', - 'redneck', - 'renob', - 'rentafuck', - 'rimjob', - 'rimming', - 'ruski', - 'russki', - 'russkie', - 'sadist', - 'sadom', - 'saeema butt', - 'sandm', - 'sand nigger', - 'sandnigger', - 'scag', - 'scank', - 'scat', - 'schlong', - 'screwing', - 'screwyou', - 'scrote', - 'scrotum', - 'scum', - 'scumbag', - 'seaman staines', - 'semen', - 'sexed', - 'sexfarm', - 'sexhound', - 'sexhouse', - 'sexing', - 'sexkitten', - 'sexpot', - 'sexslave', - 'sextogo', - 'sextoy', - 'sextoys', - 'sexwhore', - 'sexymoma', - 'sexy-slim', - 'seymour butts', - 'shag', - 'shagger', - 'shaggin', - 'shagging', - 'shat', - 'shhit', - 'shit', - 'shitass', - 'shitbag', - 'shitbagger', - 'shitbrains', - 'shitbreath', - 'shitcan', - 'shitcanned', - 'shitcunt', - 'shitdick', - 'shite', - 'shiteater', - 'shited', - 'shiter', - 'shitface', - 'shitfaced', - 'shitfit', - 'shitforbrains', - 'shitfuck', - 'shitfucker', - 'shitfull', - 'shithapens', - 'shithappens', - 'shithead', - 'shithole', - 'shithouse', - 'shiting', - 'shitlist', - 'shitola', - 'shitoutofluck', - 'shits', - 'shitspitter', - 'shitstain', - 'shitted', - 'shitter', - 'shittiest', - 'shitting', - 'shitty', - 'shity', - 'shitz', - 'shiz', - 'shiznit', - 'shortfuck', - 'shyt', - 'shyte', - 'shytty', - 'shyty', - 'sissy', - 'sixsixsix', - 'sixtynine', - 'sixtyniner', - 'skanck', - 'skank', - 'skankbitch', - 'skankee', - 'skankey', - 'skankfuck', - 'skanks', - 'skankwhore', - 'skanky', - 'skankybitch', - 'skankywhore', - 'skeet', - 'skinflute', - 'skullfuck', - 'skum', - 'skumbag', - 'slanteye', - 'slantyeye', - 'slapper', - 'slavedriver', - 'sleezebag', - 'sleezeball', - 'slideitin', - 'slimeball', - 'slimebucket', - 'slopehead', - 'slopey', - 'slopy', - 'slut', - 'slutbag', - 'sluts', - 'slutt', - 'slutting', - 'slutty', - 'slutwear', - 'slutwhore', - 'slutz', - 'smackthemonkey', - 'smeg', - 'smelly', - 'smut', - 'snatch', - 'snatchpatch', - 'snot', - 'snowback', - 'snownigger', - 'sodom', - 'sodomise', - 'sodomite', - 'sodomize', - 'sodomy', - 'son-of-a-bitch', - 'sonofabitch', - 'sonofbitch', - 'spac', - 'spacca', - 'spaghettibender', - 'spaghettinigger', - 'spankthemonkey', - 'spazza', - 'sperm', - 'spermacide', - 'spermbag', - 'spermhearder', - 'spermherder', - 'spic', - 'spick', - 'spig', - 'spigotty', - 'spik', - 'spitter', - 'splittail', - 'splooge', - 'spooge', - 'spook', - 'spreadeagle', - 'squaw', - 'stabber', - 'stiffy', - 'strapon', - 'stripclub', - 'stroking', - 'stupidfuck', - 'stupidfucker', - 'suckass', - 'suckdick', - 'sucker', - 'suckme', - 'suckmyass', - 'suckmydick', - 'suckmytit', - 'suckoff', - 'swastika', - 'tampon', - 'tarbaby', - 'tard', - 'teat', - 'teste', - 'testicle', - 'testicles', - 'thicklips', - 'thicko', - 'thirdeye', - 'thirdleg', - 'threesome', - 'thundercunt', - 'timbernigger', - 'tit', - 'titbitnipply', - 'titfuck', - 'titfucker', - 'titfuckin', - 'titjob', - 'titlicker', - 'titlover', - 'tits', - 'tittie', - 'titties', - 'titty', - 'tittyfuck', - 'tonguethrust', - 'tonguethruster', - 'tonguetramp', - 'torture', - 'tosser', - 'tosspot', - 'towel head', - 'towelhead', - 'trailertrash', - 'tramp', - 'trannie', - 'tranny', - 'trots', - 'trouser snake', - 'tuckahoe', - 'tunneloflove', - 'turd', - 'twat', - 'twatlips', - 'twats', - 'twatwaffle', - 'twink', - 'twinkie', - 'twobitwhore', - 'unclefucker', - 'unfuckable', - 'upskirt', - 'uptheass', - 'upthebutt', - 'urinate', - 'urine', - 'usama bin laden', - 'uterus', - 'vag', - 'vagina', - 'vaginal', - 'vajayjay', - 'vajina', - 'va-j-j', - 'valjina', - 'vibrater', - 'vibrator', - 'vietcong', - 'violate', - 'violation', - 'virginbreaker', - 'vjayjay', - 'vomit', - 'vullva', - 'vulva', - 'wank', - 'wanker', - 'wanking', - 'wankjob', - 'waysted', - 'welcher', - 'wetback', - 'wetspot', - 'whacker', - 'whigger', - 'whiskeydick', - 'whiskydick', - 'whitenigger', - 'whitetrash', - 'whitey', - 'whoor', - 'whop', - 'whore', - 'whorebag', - 'whoreface', - 'whorefucker', - 'whorehouse', - 'wife beater', - 'williewanker', - 'wog', - 'wop', - 'wuss', - 'wuzzie', - 'x-rated', - 'xrated', - 'yellowman', - 'zigabo', - 'zipperhea', - 'zipper head', - ] + 'en' => [ + 'abbo', + 'abortionist', + 'abuser', + 'ahole', + 'alabama hotpocket', + 'alligatorbait', + 'anal', + 'analannie', + 'analsex', + 'areola', + 'arse', + 'arsebagger', + 'arsebandit', + 'arseblaster', + 'arsecowboy', + 'arsefuck', + 'arsefucker', + 'arsehat', + 'arsehole', + 'arseholes', + 'arsehore', + 'arsejockey', + 'arsekiss', + 'arsekisser', + 'arselick', + 'arselicker', + 'arselover', + 'arseman', + 'arsemonkey', + 'arsemunch', + 'arsemuncher', + 'arsepacker', + 'arsepirate', + 'arsepuppies', + 'arseranger', + 'arses', + 'arsewhore', + 'arsewipe', + 'ass', + 'assbag', + 'assbagger', + 'assbandit', + 'assbanger', + 'assbite', + 'assblaster', + 'assclown', + 'asscock', + 'asscowboy', + 'asscracker', + 'asses', + 'assface', + 'assfuck', + 'assfucker', + 'assgoblin', + 'ass-hat', + 'asshat', + 'asshead', + 'asshole', + 'assholes', + 'assholz', + 'asshopper', + 'asshore', + 'ass-jabber', + 'assjacker', + 'assjockey', + 'asskiss', + 'asskisser', + 'assklown', + 'asslick', + 'asslicker', + 'asslover', + 'assman', + 'assmonkey', + 'ass monkey', + 'assmunch', + 'assmuncher', + 'assnigger', + 'asspacker', + 'ass-pirate', + 'asspirate', + 'asspuppies', + 'assranger', + 'assshit', + 'assshole', + 'asssucker', + 'asswad', + 'asswhore', + 'asswipe', + 'axwound', + 'azzhole', + 'backdoorman', + 'badfuck', + 'baldy', + 'ball licker', + 'balllicker', + 'ballsack', + 'bampot', + 'banging', + 'barelylegal', + 'barface', + 'barfface', + 'bassterds', + 'bastard', + 'bastards', + 'bastardz', + 'basterds', + 'basterdz', + 'bazongas', + 'bazooms', + 'beaner', + 'beastality', + 'beastial', + 'beastiality', + 'beat-off', + 'beatoff', + 'beatyourmeat', + 'bestial', + 'bestiality', + 'biatch', + 'bicurious', + 'bigass', + 'bigbastard', + 'bigbutt', + 'bitch', + 'bitchass', + 'bitcher', + 'bitches', + 'bitchez', + 'bitchin', + 'bitching', + 'bitchslap', + 'bitchtits', + 'bitchy', + 'biteme', + 'blow job', + 'blowjob', + 'boffing', + 'bohunk', + 'bollick', + 'bollock', + 'bollocks', + 'bollox', + 'bondage', + 'boner', + 'boob', + 'boobies', + 'boobs', + 'booby', + 'bootycall', + 'bountybar', + 'breastjob', + 'breastlover', + 'breastman', + 'brothel', + 'brotherfucker', + 'bugger', + 'buggered', + 'buggery', + 'bukake', + 'bullcrap', + 'bulldike', + 'bulldyke', + 'bullshit', + 'bumblefuck', + 'bumfuck', + 'bungabunga', + 'bunghole', + 'butchbabes', + 'butchdike', + 'butchdyke', + 'butt-bang', + 'buttbang', + 'buttcheeks', + 'buttface', + 'butt-fuck', + 'buttfuck', + 'buttfucka', + 'butt-fucker', + 'buttfucker', + 'butt-fuckers', + 'buttfuckers', + 'butthead', + 'butthole', + 'buttman', + 'buttmunch', + 'buttmuncher', + 'butt-pirate', + 'buttpirate', + 'butt plug', + 'buttplug', + 'buttstain', + 'buttwipe', + 'byatch', + 'cacker', + 'cameljockey', + 'camel toe', + 'cameltoe', + 'carpet muncher', + 'carpetmuncher', + 'cawk', + 'cawks', + 'chav', + 'cherrypopper', + 'chesticle', + 'chickslick', + 'chinc', + 'chink', + 'choad', + 'chode', + 'clamdigger', + 'clamdiver', + 'clit', + 'clitface', + 'clitfuck', + 'clitoris', + 'clogwog', + 'clunge', + 'clusterfuck', + 'cnts', + 'cntz', + 'cock', + 'cockass', + 'cockbite', + 'cockblock', + 'cockblocker', + 'cockburger', + 'cockcowboy', + 'cockface', + 'cockfight', + 'cockfucker', + 'cock-head', + 'cockhead', + 'cockjockey', + 'cockknob', + 'cockknoker', + 'cocklicker', + 'cocklover', + 'cockmaster', + 'cockmongler', + 'cockmongruel', + 'cockmonkey', + 'cockmuncher', + 'cocknob', + 'cocknose', + 'cocknugget', + 'cockqueen', + 'cockrider', + 'cocks', + 'cockshit', + 'cocksman', + 'cocksmith', + 'cocksmoke', + 'cocksmoker', + 'cocksniffer', + 'cocksucer', + 'cocksuck', + 'cocksucked', + 'cock-sucker', + 'cocksucker', + 'cocksucking', + 'cocktease', + 'cockwaffle', + 'cocky', + 'coitus', + 'cok', + 'commie', + 'coochie', + 'coochy', + 'coon', + 'coondog', + 'cooter', + 'copulate', + 'cracker', + 'crackpipe', + 'crack-whore', + 'crackwhore', + 'crap', + 'crappy', + 'crotchjockey', + 'crotchmonkey', + 'crotchrot', + 'cuck', + 'cum', + 'cumbubble', + 'cumdumpster', + 'cumfest', + 'cumguzzler', + 'cumjockey', + 'cumm', + 'cumquat', + 'cumqueen', + 'cumshot', + 'cumslut', + 'cumtart', + 'cunilingus', + 'cunillingus', + 'cunnie', + 'cunnilingus', + 'cunntt', + 'cunt', + 'cuntass', + 'cunteyed', + 'cuntface', + 'cuntfuck', + 'cuntfucker', + 'cunthole', + 'cuntlick', + 'cuntlicker', + 'cuntlicker', + 'cuntlicking', + 'cuntrag', + 'cunts', + 'cuntslut', + 'cuntsucker', + 'cuntz', + 'cybersex', + 'cyberslimer', + 'dago', + 'dammit', + 'damn', + 'damnation', + 'damnit', + 'darkie', + 'darky', + 'datnigga', + 'deapthroat', + 'deepthroat', + 'deggo', + 'dego', + 'devilworshipper', + 'dick', + 'dickbag', + 'dickbeaters', + 'dickbrain', + 'dickface', + 'dickforbrains', + 'dickfuck', + 'dickfucker', + 'dickhead', + 'dickhole', + 'dickjuice', + 'dickless', + 'dicklick', + 'dicklicker', + 'dickmilk', + 'dickmonger', + 'dicks', + 'dickslap', + 'dick-sneeze', + 'dicksucker', + 'dicksucking', + 'dicktickler', + 'dickwad', + 'dickweasel', + 'dickweed', + 'dickwod', + 'dike', + 'dildo', + 'dildos', + 'dilldo', + 'dilldos', + 'dipshit', + 'dipstick', + 'dixiedike', + 'dixiedyke', + 'doggiestyle', + 'doggystyle', + 'dominatricks', + 'dominatrics', + 'dominatrix', + 'doochbag', + 'dookie', + 'douch', + 'douchbag', + 'douche', + 'douchebag', + 'douche-fag', + 'douchewaffle', + 'drag queen', + 'dragqueen', + 'dragqween', + 'dripdick', + 'dumass', + 'dumb ass', + 'dumbass', + 'dumbbitch', + 'dumbfuck', + 'dumbshit', + 'dumshit', + 'dyke', + 'easyslut', + 'eatballs', + 'eatme', + 'eatpussy', + 'ejaculate', + 'ejaculated', + 'ejaculating', + 'ejaculation', + 'enema', + 'excrement', + 'facefucker', + 'facist', + 'faeces', + 'fag', + 'fagbag', + 'faget', + 'fagfucker', + 'fagging', + 'faggit', + 'faggot', + 'faggotcock', + 'faggots', + 'fagit', + 'fagot', + 'fags', + 'fagtard', + 'fagz', + 'faig', + 'faigs', + 'fannyfucker', + 'fark', + 'farted', + 'farting', + 'farty', + 'fastfuck', + 'fatass', + 'fatfuck', + 'fatfucker', + 'fatso', + 'feces', + 'felatio', + 'felch', + 'felcher', + 'felching', + 'fellatio', + 'feltch', + 'feltcher', + 'feltching', + 'fingerfuck', + 'fingerfucked', + 'fingerfucker', + 'fingerfuckers', + 'fingerfucking', + 'fister', + 'fistfuck', + 'fistfucked', + 'fistfucker', + 'fistfucking', + 'fisting', + 'flamer', + 'flasher', + 'flid', + 'flipping the bird', + 'flyd', + 'flydie', + 'flydye', + 'fondle', + 'footaction', + 'footfuck', + 'footfucker', + 'footlicker', + 'fornicate', + 'freakfuck', + 'freakyfucker', + 'freefuck', + 'fubar', + 'fucck', + 'fuck', + 'fucka', + 'fuckable', + 'fuckass', + 'fuckbag', + 'fuckboy', + 'fuckbrain', + 'fuckbuddy', + 'fuckbutt', + 'fuckbutter', + 'fucked', + 'fuckedup', + 'fucker', + 'fuckers', + 'fuckersucker', + 'fuckface', + 'fuckfest', + 'fuckfreak', + 'fuckfriend', + 'fuckhead', + 'fuckher', + 'fuckhole', + 'fuckin', + 'fuckina', + 'fucking', + 'fuckingbitch', + 'fuckingcunt', + 'fuckinnuts', + 'fuckinright', + 'fuckit', + 'fuckknob', + 'fuckme', + 'fuckmehard', + 'fuckmonkey', + 'fucknut', + 'fucknutt', + 'fuckoff', + 'fuckpig', - - -]; + 'fuckstick', + 'fucktard', + 'fucktart', + 'fuckup', + 'fuckwad', + 'fuckwhore', + 'fuckwit', + 'fuckwitt', + 'fuckyou', + 'fudge packer', + 'fudgepacker', + 'Fudge Packer', + 'fugly', + 'fuk', + 'Fukah', + 'Fuken', + 'fuker', + 'Fukin', + 'Fukk', + 'Fukkah', + 'Fukken', + 'Fukker', + 'Fukkin', + 'fuks', + 'funfuck', + 'fuuck', + 'gang bang', + 'gangbang', + 'gangbanged', + 'gangbanger', + 'gatorbait', + 'gayass', + 'gaybob', + 'gayboy', + 'gaydo', + 'gayfuck', + 'gayfuckist', + 'gaygirl', + 'gaylord', + 'gaymuthafuckinwhore', + 'gays', + 'gaysex', + 'gaytard', + 'gaywad', + 'gayz', + 'getiton', + 'givehead', + 'glazeddonut', + 'godammit', + 'goddamit', + 'goddammit', + 'goddamn', + 'goddamned', + 'god-damned', + 'goddamnes', + 'goddamnit', + 'goddamnmuthafucker', + 'goldenshower', + 'gonorrehea', + 'gonzagas', + 'gooch', + 'gook', + 'gotohell', + 'greaseball', + 'gringo', + 'grostulation', + 'guido', + 'gypo', + 'gypp', + 'gyppie', + 'gyppo', + 'gyppy', + 'handjob', + 'hard on', + 'hardon', + 'headfuck', + 'heeb', + 'hells', + 'herpes', + 'hijacker', + 'hijacking', + 'hillbillies', + 'hindoo', + 'hitler', + 'hitlerism', + 'hitlerist', + 'hoar', + 'hobo', + 'hoe', + 'hoes', + 'holestuffer', + 'homo', + 'homobangers', + 'homodumbshit', + 'honger', + 'honkers', + 'honkey', + 'honky', + 'hookers', + 'hoor', + 'hoore', + 'hore', + 'horney', + 'horniest', + 'horny', + 'horseshit', + 'hosejob', + 'hotdamn', + 'hotpussy', + 'hottotrot', + 'humping', + 'hymen', + 'iblowu', + 'idiot', + 'incest', + 'insest', + 'internet wife', + 'intheass', + 'inthebuff', + 'jackass', + 'jackoff', + 'jackshit', + 'jagoff', + 'jap', + 'japcrap', + 'japs', + 'jerkass', + 'jerk off', + 'jerk-off', + 'jerkoff', + 'jesuschrist', + 'jigaboo', + 'jiggabo', + 'jihad', + 'jijjiboo', + 'jisim', + 'jism', + 'jiss', + 'jizim', + 'jizjuice', + 'jizm', + 'jizm', + 'jizz', + 'jizzim', + 'jizzum', + 'jubblies', + 'juggalo', + 'jungle bunny', + 'junglebunny', + 'kiddy fiddler', + 'kike', + 'kinky', + 'kissass', + 'knobz', + 'kondum', + 'kooch', + 'kootch', + 'krap', + 'krappy', + 'kraut', + 'kumbubble', + 'kumbullbe', + 'kummer', + 'kumming', + 'kums', + 'kunilingus', + 'kunnilingus', + 'kunt', + 'kunts', + 'kuntz', + 'kyke', + 'labia', + 'lactate', + 'lady boy', + 'ladyboy', + 'lameass', + 'lapdance', + 'lardass', + 'lesbain', + 'lesbayn', + 'lesbian', + 'lesbin', + 'lesbo', + 'lezbe', + 'lezbefriends', + 'lezbo', + 'lezz', + 'lezzer', + 'lezzie', + 'lezzo', + 'libido', + 'lickme', + 'limpdick', + 'lipshits', + 'lipshitz', + 'livesex', + 'lmfao', + 'loadedgun', + 'lovebone', + 'lovegoo', + 'lovegun', + 'lovejuice', + 'lovemuscle', + 'lovepistol', + 'loverocket', + 'low life', + 'lowlife', + 'lubejob', + 'luckycameltoe', + 'manhater', + 'manpaste', + 'masochist', + 'masokist', + 'massterbait', + 'masstrbait', + 'masstrbate', + 'mastabate', + 'mastabater', + 'masterbaiter', + 'masterbate', + 'master bates', + 'masterbates', + 'mastrabator', + 'masturbate', + 'masturbating', + 'mattressprincess', + 'mcfagget', + 'meatbeater', + 'meatrack', + 'mgger', + 'mggor', + 'milf', + 'minge', + 'mofo', + 'molest', + 'molestation', + 'molester', + 'molestor', + 'moneyshot', + 'mooncricket', + 'moron', + 'mothafuck', + 'mothafucka', + 'mothafuckaz', + 'mothafucked', + 'mothafucker', + 'motha fucker', + 'mothafuckin', + 'mothafucking', + 'mothafuckings', + 'motha fuker', + 'motha fukkah', + 'motha fukker', + 'motherfuck', + 'motherfucked', + 'mother-fucker', + 'motherfucker', + 'mother fucker', + 'motherfuckin', + 'motherfucking', + 'motherfuckings', + 'mother fukah', + 'mother fuker', + 'mother fukkah', + 'mother fukker', + 'motherlovebone', + 'muff', + 'muffdive', + 'muffdiver', + 'muffindiver', + 'mufflikcer', + 'muncher', + 'munging', + 'muthafucker', + 'mutha fucker', + 'mutha fukah', + 'mutha fuker', + 'mutha fukkah', + 'mutha fukker', + 'nastt', + 'nastybitch', + 'nastyho', + 'nastyslut', + 'nastywhore', + 'nazi', + 'necro', + 'negro', + 'negroes', + 'negroid', + 'nigaboo', + 'nigga', + 'niggah', + 'niggaracci', + 'niggard', + 'niggarded', + 'niggarding', + 'niggardliness', + "niggardliness's", + 'niggardly', + "niggard's", + 'niggards', + 'niggaz', + 'nigger', + 'niggerhead', + 'niggerhole', + "nigger's", + 'niggers', + 'niggle', + 'niggled', + 'niggles', + 'niggling', + 'nigglings', + 'niggor', + 'niggur', + 'niglet', + 'nignog', + 'nigr', + 'nigra', + 'nigre', + 'nigur', + 'niiger', + 'niigr', + 'nipple', + 'nipplering', + 'nittit', + 'nlgger', + 'nlggor', + 'nofuckingway', + 'nonce', + 'nookey', + 'nookie', + 'nudger', + 'nut case', + 'nutcase', + 'nutfucker', + 'nut sack', + 'nutsack', + 'ontherag', + 'orafis', + 'orgasim', + 'orgasim', + 'orgasm', + 'orgasum', + 'orgies', + 'orgy', + 'oriface', + 'orifice', + 'orifiss', + 'osama bin laden', + 'packi', + 'packie', + 'packy', + 'paedo', + 'paedofile', + 'paedophile', + 'paki', + 'pakie', + 'paky', + 'palesimian', + 'panooch', + 'panti', + 'pearlnecklace', + 'pecker', + 'peckerhead', + 'peckerwood', + 'peedo', + 'peeenus', + 'peeenusss', + 'peehole', + 'peenus', + 'peinus', + 'penas', + 'penile', + 'penisbanger', + 'penis-breath', + 'penises', + 'penisfucker', + 'penispuffer', + 'penus', + 'penuus', + 'perv', + 'perversion', + 'pervert', + 'phonesex', + 'phuc', + 'phuck', + 'phuk', + 'phuked', + 'phuker', + 'phuking', + 'phukked', + 'phukker', + 'phukking', + 'phungky', + 'phuq', + 'pi55', + 'picaninny', + 'piccaninny', + 'pickaninny', + 'pikey', + 'piky', + 'pimper', + 'pimpjuic', + 'pimpjuice', + 'pimpsimp', + 'pindick', + 'piss', + 'pissed', + 'pissed off', + 'pisser', + 'pisses', + 'pissflaps', + 'pisshead', + 'pissin', + 'pissing', + 'pissoff', + 'play boy', + 'playboy', + 'play bunny', + 'playbunny', + 'play girl', + 'playgirl', + 'plumper', + 'pocketpool', + 'polac', + 'polack', + 'polak', + 'polesmoker', + 'pollock', + 'poon', + 'poonani', + 'poonany', + 'poontang', + 'pooperscooper', + 'pooping', + 'poorwhitetrash', + 'poostabber', + 'popimp', + 'porch monkey', + 'porchmonkey', + 'porn', + 'pornflick', + 'pornking', + 'porno', + 'pornprincess', + 'pric', + 'prick', + 'prik', + 'prickhead', + 'prostitute', + 'pu55i', + 'pu55y', + 'pube', + 'pubiclice', + 'puke', + 'punanny', + 'punta', + 'puntang', + 'purinaprincess', + 'pusse', + 'pussee', + 'pussie', + 'pussies', + 'pussy', + 'pussyeater', + 'pussyfucker', + 'pussylicker', + 'pussylicking', + 'pussylips', + 'pussylover', + 'pussypounder', + 'pusy', + 'puto', + 'puuke', + 'puuker', + 'queef', + 'queer', + 'queerbait', + 'queerhole', + 'queers', + 'queerz', + 'quim', + 'qweers', + 'qweerz', + 'qweir', + 'rag head', + 'raghead', + 'raped', + 'rapist', + 'rearend', + 'rearentry', + 'recktum', + 'rectum', + 'redneck', + 'renob', + 'rentafuck', + 'rimjob', + 'rimming', + 'ruski', + 'russki', + 'russkie', + 'sadist', + 'sadom', + 'saeema butt', + 'sandm', + 'sand nigger', + 'sandnigger', + 'scag', + 'scank', + 'scat', + 'schlong', + 'screwing', + 'screwyou', + 'scrote', + 'scrotum', + 'scum', + 'scumbag', + 'seaman staines', + 'semen', + 'sexed', + 'sexfarm', + 'sexhound', + 'sexhouse', + 'sexing', + 'sexkitten', + 'sexpot', + 'sexslave', + 'sextogo', + 'sextoy', + 'sextoys', + 'sexwhore', + 'sexymoma', + 'sexy-slim', + 'seymour butts', + 'shag', + 'shagger', + 'shaggin', + 'shagging', + 'shat', + 'shhit', + 'shit', + 'shitass', + 'shitbag', + 'shitbagger', + 'shitbrains', + 'shitbreath', + 'shitcan', + 'shitcanned', + 'shitcunt', + 'shitdick', + 'shite', + 'shiteater', + 'shited', + 'shiter', + 'shitface', + 'shitfaced', + 'shitfit', + 'shitforbrains', + 'shitfuck', + 'shitfucker', + 'shitfull', + 'shithapens', + 'shithappens', + 'shithead', + 'shithole', + 'shithouse', + 'shiting', + 'shitlist', + 'shitola', + 'shitoutofluck', + 'shits', + 'shitspitter', + 'shitstain', + 'shitted', + 'shitter', + 'shittiest', + 'shitting', + 'shitty', + 'shity', + 'shitz', + 'shiz', + 'shiznit', + 'shortfuck', + 'shyt', + 'shyte', + 'shytty', + 'shyty', + 'sissy', + 'sixsixsix', + 'sixtynine', + 'sixtyniner', + 'skanck', + 'skank', + 'skankbitch', + 'skankee', + 'skankey', + 'skankfuck', + 'skanks', + 'skankwhore', + 'skanky', + 'skankybitch', + 'skankywhore', + 'skeet', + 'skinflute', + 'skullfuck', + 'skum', + 'skumbag', + 'slanteye', + 'slantyeye', + 'slapper', + 'slavedriver', + 'sleezebag', + 'sleezeball', + 'slideitin', + 'slimeball', + 'slimebucket', + 'slopehead', + 'slopey', + 'slopy', + 'slut', + 'slutbag', + 'sluts', + 'slutt', + 'slutting', + 'slutty', + 'slutwear', + 'slutwhore', + 'slutz', + 'smackthemonkey', + 'smeg', + 'smelly', + 'smut', + 'snatch', + 'snatchpatch', + 'snot', + 'snowback', + 'snownigger', + 'sodom', + 'sodomise', + 'sodomite', + 'sodomize', + 'sodomy', + 'son-of-a-bitch', + 'sonofabitch', + 'sonofbitch', + 'spac', + 'spacca', + 'spaghettibender', + 'spaghettinigger', + 'spankthemonkey', + 'spazza', + 'sperm', + 'spermacide', + 'spermbag', + 'spermhearder', + 'spermherder', + 'spic', + 'spick', + 'spig', + 'spigotty', + 'spik', + 'spitter', + 'splittail', + 'splooge', + 'spooge', + 'spook', + 'spreadeagle', + 'squaw', + 'stabber', + 'stiffy', + 'strapon', + 'stripclub', + 'stroking', + 'stupidfuck', + 'stupidfucker', + 'suckass', + 'suckdick', + 'sucker', + 'suckme', + 'suckmyass', + 'suckmydick', + 'suckmytit', + 'suckoff', + 'swastika', + 'tampon', + 'tarbaby', + 'tard', + 'teat', + 'teste', + 'testicle', + 'testicles', + 'thicklips', + 'thicko', + 'thirdeye', + 'thirdleg', + 'threesome', + 'thundercunt', + 'timbernigger', + 'tit', + 'titbitnipply', + 'titfuck', + 'titfucker', + 'titfuckin', + 'titjob', + 'titlicker', + 'titlover', + 'tits', + 'tittie', + 'titties', + 'titty', + 'tittyfuck', + 'tonguethrust', + 'tonguethruster', + 'tonguetramp', + 'torture', + 'tosser', + 'tosspot', + 'towel head', + 'towelhead', + 'trailertrash', + 'tramp', + 'trannie', + 'tranny', + 'trots', + 'trouser snake', + 'tuckahoe', + 'tunneloflove', + 'turd', + 'twat', + 'twatlips', + 'twats', + 'twatwaffle', + 'twink', + 'twinkie', + 'twobitwhore', + 'unclefucker', + 'unfuckable', + 'upskirt', + 'uptheass', + 'upthebutt', + 'urinate', + 'urine', + 'usama bin laden', + 'uterus', + 'vag', + 'vagina', + 'vaginal', + 'vajayjay', + 'vajina', + 'va-j-j', + 'valjina', + 'vibrater', + 'vibrator', + 'vietcong', + 'violate', + 'violation', + 'virginbreaker', + 'vjayjay', + 'vomit', + 'vullva', + 'vulva', + 'wank', + 'wanker', + 'wanking', + 'wankjob', + 'waysted', + 'welcher', + 'wetback', + 'wetspot', + 'whacker', + 'whigger', + 'whiskeydick', + 'whiskydick', + 'whitenigger', + 'whitetrash', + 'whitey', + 'whoor', + 'whop', + 'whore', + 'whorebag', + 'whoreface', + 'whorefucker', + 'whorehouse', + 'wife beater', + 'williewanker', + 'wog', + 'wop', + 'wuss', + 'wuzzie', + 'x-rated', + 'xrated', + 'yellowman', + 'zigabo', + 'zipperhea', + 'zipper head', + ], + 'fr' => [ + 'con', + 'connard', + 'connasse', + 'merde', + 'merdique', + 'putain', + 'enculé', + 'salope', + 'batard', + 'bordel', + 'fils de pute', + 'pute', + 'cul', + 'abruti', + 'crétin', + 'imbécile', + 'ordure', + 'débile', + 'dégénéré', + 'foutre', + 'chiant', + 'chiotte', + 'bouffon', + 'gros con', + 'pédé', + 'tapette', + 'bite', + 'couille', + 'enfoiré', + 'trou du cul', + ] + ], +]; \ No newline at end of file diff --git a/src/Abstracts/StringNormalizer.php b/src/Abstracts/StringNormalizer.php new file mode 100644 index 0000000..da99a78 --- /dev/null +++ b/src/Abstracts/StringNormalizer.php @@ -0,0 +1,10 @@ +chosenLanguage = $language; + $this->loadConfiguration(); $this->separatorExpression = $this->generateSeparatorExpression(); @@ -70,16 +98,27 @@ public function __construct() $this->characterExpressions = $this->generateSubstitutionExpression(); $this->generateProfanityExpressionArray(); + + $this->generateFalsePositiveExpressionArray(); } /** * Load Profanities, Separators and Substitutions * from config file. * + * @throws Exception */ - private function loadConfiguration() + private function loadConfiguration(): void { - $this->profanities = config('blasp.profanities'); + $this->supportedLanguages = config('blasp.languages'); + + if (empty($this->chosenLanguage)) { + $this->chosenLanguage = config('blasp.default_language'); + } + + $this->validateChosenLanguage(); + + $this->profanities = config('blasp.profanities')[$this->chosenLanguage]; $this->separators = config('blasp.separators'); $this->substitutions = config('blasp.substitutions'); } @@ -129,7 +168,7 @@ private function generateEscapedExpression(array $characters = [], array $escape * and order the array longest to shortest. * */ - private function generateProfanityExpressionArray() + private function generateProfanityExpressionArray(): void { $profanityCount = count($this->profanities); @@ -141,7 +180,7 @@ private function generateProfanityExpressionArray() /** * Generate a regex expression foreach profanity. - * + * * @param $profanity * @return string */ @@ -155,4 +194,25 @@ private function generateProfanityExpression($profanity): string return $expression; } + + /** + * Generate an array of false positive expressions. + * + * @return void + */ + private function generateFalsePositiveExpressionArray(): void + { + $this->falsePositives = array_map('strtolower', config('blasp.false_positives')[$this->chosenLanguage]); + } + + /** + * @return void + * @throws Exception + */ + private function validateChosenLanguage(): void + { + if (!in_array($this->chosenLanguage, $this->supportedLanguages, true)) { + throw new Exception('Unsupported language.'); + } + } } \ No newline at end of file diff --git a/src/BlaspService.php b/src/BlaspService.php index 79fe8d3..97785d9 100644 --- a/src/BlaspService.php +++ b/src/BlaspService.php @@ -2,6 +2,8 @@ namespace Blaspsoft\Blasp; +use Blaspsoft\Blasp\Abstracts\StringNormalizer; +use Blaspsoft\Blasp\Normalizers\Normalize; use Exception; class BlaspService extends BlaspExpressionService @@ -42,14 +44,40 @@ class BlaspService extends BlaspExpressionService */ public array $uniqueProfanitiesFound = []; + + /** + * Language the package should use + * + * @var string|null + */ + protected ?string $chosenLanguage; + + /** + * Profanity detector instance. + * + * @var ProfanityDetector + */ + private ProfanityDetector $profanityDetector; + + /** + * String normalizer instance. + * + * @var StringNormalizer + */ + private StringNormalizer $stringNormalizer; + /** * Initialise the class and parent class. - * + * */ - public function __construct() + public function __construct(?string $language = null) { - parent::__construct(); - return $this; + + parent::__construct($language); + + $this->profanityDetector = new ProfanityDetector($this->profanityExpressions, $this->falsePositives); + + $this->stringNormalizer = Normalize::getLanguageNormalizerInstance($this->chosenLanguage); } /** @@ -81,21 +109,17 @@ public function check(string $string): self */ private function handle(): self { - // Convert false positives to lowercase for case-insensitive comparison - $falsePositives = array_map('strtolower', config('blasp.false_positives')); $continue = true; - // Sort profanities by length (longer first) to match longer profanities first - uksort($this->profanityExpressions, function($a, $b) { - return strlen($b) - strlen($a); // Sort by length, descending - }); + $stringToNormalize = $this->cleanString; + $normalizedString = $this->stringNormalizer->normalize($stringToNormalize); // Loop through until no more profanities are detected while ($continue) { $continue = false; - - foreach ($this->profanityExpressions as $profanity => $expression) { - preg_match_all($expression, $this->cleanString, $matches, PREG_OFFSET_CAPTURE); + $normalizedString = preg_replace('/\s+/', ' ', $normalizedString); + foreach ($this->profanityDetector->getProfanityExpressions() as $profanity => $expression) { + preg_match_all($expression, $normalizedString, $matches, PREG_OFFSET_CAPTURE); if (!empty($matches[0])) { foreach ($matches[0] as $match) { @@ -104,10 +128,10 @@ private function handle(): self $length = strlen($match[0]); // Use boundaries to extract the full word around the match - $fullWord = $this->getFullWordContext($this->cleanString, $start, $length); + $fullWord = $this->getFullWordContext($normalizedString, $start, $length); // Check if the full word (in lowercase) is in the false positives list - if (in_array(strtolower($fullWord), $falsePositives, true)) { + if ($this->profanityDetector->isFalsePositive($fullWord)) { continue; // Skip checking this word if it's a false positive } @@ -116,7 +140,9 @@ private function handle(): self $this->hasProfanity = true; // Replace the found profanity - $this->generateProfanityReplacement($match); + $this->generateProfanityReplacement((array) $match); + + $normalizedString = substr_replace($normalizedString, str_repeat('*', $length), $start, $length); // Avoid adding duplicates to the unique list if (!in_array($profanity, $this->uniqueProfanitiesFound)) { @@ -132,9 +158,9 @@ private function handle(): self /** * Mask the profanities found in the incoming string. - * - * @param string $profanity - * @return string + * + * @param array $match + * @return void */ private function generateProfanityReplacement(array $match): void { @@ -143,9 +169,8 @@ private function generateProfanityReplacement(array $match): void $replacement = str_repeat("*", $length); // Mask with asterisks // Replace only the profanity in the cleanString, preserving the original case and spaces - $this->cleanString = mb_substr($this->cleanString, 0, $start) . - $replacement . - mb_substr($this->cleanString, $start + $length); + $this->cleanString = mb_substr($this->cleanString, 0, $start) . $replacement . + mb_substr($this->cleanString, $start + $length); // Increment profanity count $this->profanitiesCount++; @@ -153,7 +178,7 @@ private function generateProfanityReplacement(array $match): void /** * Get the full word context surrounding the matched profanity. - * + * * @param string $string * @param int $start * @param int $length @@ -182,7 +207,7 @@ private function getFullWordContext(string $string, int $start, int $length): st /** * Get the incoming string. - * + * * @return string */ public function getSourceString(): string @@ -192,7 +217,7 @@ public function getSourceString(): string /** * Get the clean string with profanities masked. - * + * * @return string */ public function getCleanString(): string @@ -203,7 +228,7 @@ public function getCleanString(): string /** * Get a boolean value indicating if the incoming * string contains any profanities. - * + * * @return bool */ public function hasProfanity(): bool @@ -213,7 +238,7 @@ public function hasProfanity(): bool /** * Get the number of profanities found in the incoming string. - * + * * @return int */ public function getProfanitiesCount(): int @@ -223,7 +248,7 @@ public function getProfanitiesCount(): int /** * Get the unique profanities found in the incoming string. - * + * * @return array */ public function getUniqueProfanitiesFound(): array diff --git a/src/Normalizers/EnglishStringNormalizer.php b/src/Normalizers/EnglishStringNormalizer.php new file mode 100644 index 0000000..93857d8 --- /dev/null +++ b/src/Normalizers/EnglishStringNormalizer.php @@ -0,0 +1,14 @@ +replaceSpecialChars($string); + } + + /** + * @param string $string + * @return string + */ + private function replaceSpecialChars(string $string): string + { + $substitution = config('blasp.substitutions'); + foreach ($substitution as $replacementWithSlashes => $chars) { + $replacement = trim($replacementWithSlashes, '/'); + $pattern = '/\b[' . implode('', array_map('preg_quote', $chars)) . ']\b/u'; + $string = preg_replace($pattern, $replacement, $string); + } + return $string; + } +} \ No newline at end of file diff --git a/src/Normalizers/Normalize.php b/src/Normalizers/Normalize.php new file mode 100644 index 0000000..86d7863 --- /dev/null +++ b/src/Normalizers/Normalize.php @@ -0,0 +1,18 @@ +profanityExpressions = $profanityExpressions; + + $this->falsePositives = $falsePositives; + } + + /** + * Return an array containing all profanities, substitutions + * and separator variants. + * + * @return array + */ + public function getProfanityExpressions(): array + { + uksort($this->profanityExpressions, function($a, $b) { + return strlen($b) - strlen($a); // Sort by length, descending + }); + + return $this->profanityExpressions; + } + + /** + * Determine if an expression is a false positive + * + * @param string $word + * @return bool + */ + public function isFalsePositive(string $word): bool + { + return in_array(strtolower($word), $this->falsePositives, true); + } +} diff --git a/src/ServiceProvider.php b/src/ServiceProvider.php index 34a929f..529be19 100644 --- a/src/ServiceProvider.php +++ b/src/ServiceProvider.php @@ -17,8 +17,12 @@ public function boot() ], 'blasp-config'); } - app('validator')->extend('blasp_check', function ($attribute, $value, $parameters, $validator,) { - return ! app('blasp')->check($value)->hasProfanity; + app('validator')->extend('blasp_check', function($attribute, $value, $parameters, $validator) { + $language = $parameters[0] ?? null; + + $blaspService = new BlaspService($language); + + return !$blaspService->check($value)->hasProfanity(); }, 'The :attribute contains profanity.'); } @@ -30,7 +34,7 @@ public function register() $this->mergeConfigFrom(__DIR__.'/../config/config.php', 'blasp'); $this->app->bind('blasp', function () { - return new \Blaspsoft\Blasp\BlaspService(); + return new BlaspService(); }); } } diff --git a/tests/BlaspCheckFrenchTest.php b/tests/BlaspCheckFrenchTest.php new file mode 100644 index 0000000..4fe0abe --- /dev/null +++ b/tests/BlaspCheckFrenchTest.php @@ -0,0 +1,123 @@ +blaspService = new BlaspService('fr'); + } + + /** + * @throws Exception + */ + public function testInvalidLanguage():void + { + $this->expectExceptionMessage('Unsupported language.'); + $blaspService = new BlaspService('es'); + $blaspService->check('This for test the language'); + } + + public function french_test_data_provider(): array + { + return [ + 'test_real_blasp_service' => [ + 'string' => 'Ceci est une putain de phrase', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ****** de phrase', + ], + 'test_straight_match' => [ + 'string' => 'Ceci est une connasse', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ********', + ], + 'test_substitution_match' => [ + 'string' => 'Ceci est une c0nn4ss3', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ********', + ], + 'test_obscured_match' => [ + 'string' => 'Ceci est une c-o-n-n-a-s-s-e', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ***************', + ], + 'test_doubled_match' => [ + 'string' => 'Ceci est une ccoonnaassee', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ************', + ], + 'test_combination_match' => [ + 'string' => 'Ceci est une c-ooonn4ss3', + 'hasProfanity' => true, + 'count' => 1, + 'expectedText' => 'Ceci est une ***********', + ], + 'test_multiple_profanities_no_spaces' => [ + 'string' => 'merdiqueputain foutre', + 'hasProfanity' => true, + 'count' => 3, + 'expectedText' => '************** ******', + ], + 'test_multiple_profanities' => [ + 'string' => 'Ceci est une putain de phrase de connard !', + 'hasProfanity' => true, + 'count' => 2, + 'expectedText' => 'Ceci est une ****** de phrase de ******* !', + ], 'test_scunthorpe_problem' => [ + 'string' => 'je suis un passeur', + 'hasProfanity' => false, + 'count' => 0, + 'expectedText' => 'je suis un passeur', + ], 'test_paragraph' => [ + 'string' => "Ce projet est tellement merdique. C'est un vrai bordel, et personne n'en a rien à foutre.", + 'hasProfanity' => true, + 'count' => 3, + 'expectedText' => "Ce projet est tellement ********. C'est un vrai ******, et personne n'en a rien à ******.", + ], + ]; + } + + + /** + * @throws Exception + * @dataProvider french_test_data_provider + */ + public function test_language_french(string $string, bool $hasProfanity, int $profanitiesCount, string $expectedText): void + { + $result = $this->blaspService->check($string); + + $this->assertEquals($hasProfanity, $result->hasProfanity); + $this->assertSame($profanitiesCount, $result->profanitiesCount); + $this->assertSame($expectedText, $result->cleanString); + } + + /** + * @throws Exception + */ + public function test_paragraph_french(): void + { + $paragraph = "Ce projet est tellement merdique. C'est un vrai bordel, et personne n'en a rien à foutre."; + + $result = $this->blaspService->check($paragraph, 'fr'); + + $expectedOutcome = "Ce projet est tellement ********. C'est un vrai ******, et personne n'en a rien à ******."; + $this->assertTrue($result->hasProfanity); + $this->assertSame(3, $result->profanitiesCount); + $this->assertCount(3, $result->uniqueProfanitiesFound); + $this->assertSame($expectedOutcome, $result->cleanString); + } +} diff --git a/tests/BlaspCheckTest.php b/tests/BlaspCheckTest.php index 458988e..b2cfe1d 100644 --- a/tests/BlaspCheckTest.php +++ b/tests/BlaspCheckTest.php @@ -3,8 +3,7 @@ namespace Blaspsoft\Blasp\Tests; use Blaspsoft\Blasp\BlaspService; -use Blaspsoft\Blasp\Tests\TestCase; -use Illuminate\Support\Facades\Config; +use Exception; class BlaspCheckTests extends TestCase { @@ -12,55 +11,28 @@ class BlaspCheckTests extends TestCase public function setUp(): void { + parent::setUp(); + $this->blaspService = new BlaspService(); - Config::set('blasp.profanities', ['fucking', 'shit', 'cunt', 'fuck', 'penis', 'cock', 'twat', 'ass', 'dick', 'sex', 'butt', 'arse', 'lick', 'anal', 'clusterfuck', 'bullshit', 'fucked', 'damn', 'crap', 'hell']); - Config::set('blasp.separators', [' ', '-', '_']); - Config::set('blasp.substitutions', [ - '/a/' => ['a', '4', '@', 'Á', 'á', 'À', 'Â', 'à', 'Â', 'â', 'Ä', 'ä', 'Ã', 'ã', 'Å', 'å', 'æ', 'Æ', 'α', 'Δ', 'Λ', 'λ'], - '/b/' => ['b', '8', '\\', '3', 'ß', 'Β', 'β'], - '/c/' => ['c', 'Ç', 'ç', 'ć', 'Ć', 'č', 'Č', '¢', '€', '<', '(', '{', '©'], - '/d/' => ['d', '\\', ')', 'Þ', 'þ', 'Ð', 'ð'], - '/e/' => ['e', '3', '€', 'È', 'è', 'É', 'é', 'Ê', 'ê', 'ë', 'Ë', 'ē', 'Ē', 'ė', 'Ė', 'ę', 'Ę', '∑'], - '/f/' => ['f', 'ƒ'], - '/g/' => ['g', '6', '9'], - '/h/' => ['h', 'Η'], - '/i/' => ['i', '!', '|', ']', '[', '1', '∫', 'Ì', 'Í', 'Î', 'Ï', 'ì', 'í', 'î', 'ï', 'ī', 'Ī', 'į', 'Į'], - '/j/' => ['j'], - '/k/' => ['k', 'Κ', 'κ'], - '/l/' => ['l', '!', '|', ']', '[', '£', '∫', 'Ì', 'Í', 'Î', 'Ï', 'ł', 'Ł'], - '/m/' => ['m'], - '/n/' => ['n', 'η', 'Ν', 'Π', 'ñ', 'Ñ', 'ń', 'Ń'], - '/o/' => ['o', '0', 'Ο', 'ο', 'Φ', '¤', '°', 'ø', 'ô', 'Ô', 'ö', 'Ö', 'ò', 'Ò', 'ó', 'Ó', 'œ', 'Œ', 'ø', 'Ø', 'ō', 'Ō', 'õ', 'Õ'], - '/p/' => ['p', 'ρ', 'Ρ', '¶', 'þ'], - '/q/' => ['q'], - '/r/' => ['r', '®'], - '/s/' => ['s', '5', '$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], - '/t/' => ['t', 'Τ', 'τ'], - '/u/' => ['u', 'υ', 'µ', 'û', 'ü', 'ù', 'ú', 'ū', 'Û', 'Ü', 'Ù', 'Ú', 'Ū'], - '/v/' => ['v', 'υ', 'ν'], - '/w/' => ['w', 'ω', 'ψ', 'Ψ'], - '/x/' => ['x', 'Χ', 'χ'], - '/y/' => ['y', '¥', 'γ', 'ÿ', 'ý', 'Ÿ', 'Ý'], - '/z/' => ['z', 'Ζ', 'ž', 'Ž', 'ź', 'Ź', 'ż', 'Ż'], - - ]); } + /** + * @throws Exception + */ public function test_real_blasp_service() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a fuck!ng sentence'); + $result = $this->blaspService->check('This is a fuck!ng sentence'); $this->assertTrue($result->hasProfanity); } + /** + * @throws Exception + */ public function test_straight_match() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a fucking sentence'); + $result = $this->blaspService->check('This is a fucking sentence'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); @@ -68,11 +40,12 @@ public function test_straight_match() $this->assertSame('This is a ******* sentence', $result->cleanString); } + /** + * @throws Exception + */ public function test_substitution_match() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a fÛck!ng sentence'); + $result = $this->blaspService->check('This is a fÛck!ng sentence'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); @@ -80,11 +53,12 @@ public function test_substitution_match() $this->assertSame('This is a ******* sentence', $result->cleanString); } + /** + * @throws Exception + */ public function test_obscured_match() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a f-u-c-k-i-n-g sentence'); + $result = $this->blaspService->check('This is a f-u-c-k-i-n-g sentence'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); @@ -92,11 +66,12 @@ public function test_obscured_match() $this->assertSame('This is a ************* sentence', $result->cleanString); } + /** + * @throws Exception + */ public function test_doubled_match() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a ffuucckkiinngg sentence'); + $result = $this->blaspService->check('This is a ffuucckkiinngg sentence'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); @@ -104,11 +79,12 @@ public function test_doubled_match() $this->assertSame('This is a ************** sentence', $result->cleanString); } + /** + * @throws Exception + */ public function test_combination_match() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a f-uuck!ng sentence'); + $result = $this->blaspService->check('This is a f-uuck!ng sentence'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); @@ -116,11 +92,12 @@ public function test_combination_match() $this->assertSame('This is a ********* sentence', $result->cleanString); } + /** + * @throws Exception + */ public function test_multiple_profanities_no_spaces() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('cuntfuck shit'); + $result = $this->blaspService->check('cuntfuck shit'); $this->assertTrue($result->hasProfanity); $this->assertSame(3, $result->profanitiesCount); @@ -128,11 +105,12 @@ public function test_multiple_profanities_no_spaces() $this->assertSame('******** ****', $result->cleanString); } + /** + * @throws Exception + */ public function test_multiple_profanities() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('This is a fuuckking sentence you fucking cunt!'); + $result = $this->blaspService->check('This is a fuuckking sentence you fucking cunt!'); $this->assertTrue($result->hasProfanity); $this->assertSame(3, $result->profanitiesCount); @@ -140,11 +118,12 @@ public function test_multiple_profanities() $this->assertSame('This is a ********* sentence you ******* ****!', $result->cleanString); } + /** + * @throws Exception + */ public function test_scunthorpe_problem() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('I live in a town called Scunthorpe'); + $result = $this->blaspService->check('I live in a town called Scunthorpe'); $this->assertTrue(!$result->hasProfanity); $this->assertSame(0, $result->profanitiesCount); @@ -152,11 +131,12 @@ public function test_scunthorpe_problem() $this->assertSame('I live in a town called Scunthorpe', $result->cleanString); } + /** + * @throws Exception + */ public function test_penistone_problem() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('I live in a town called Penistone'); + $result = $this->blaspService->check('I live in a town called Penistone'); $this->assertTrue(!$result->hasProfanity); $this->assertSame(0, $result->profanitiesCount); @@ -164,6 +144,9 @@ public function test_penistone_problem() $this->assertSame('I live in a town called Penistone', $result->cleanString); } + /** + * @throws Exception + */ public function test_false_positives() { $words = [ @@ -191,9 +174,9 @@ public function test_false_positives() foreach ($words as $word) { - $blaspService = new BlaspService(); + - $result = $blaspService->check($word); + $result = $this->blaspService->check($word); $this->assertTrue(!$result->hasProfanity); $this->assertSame(0, $result->profanitiesCount); @@ -202,11 +185,12 @@ public function test_false_positives() } } + /** + * @throws Exception + */ public function test_cuntfuck_fuckcunt() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('cuntfuck fuckcunt'); + $result = $this->blaspService->check('cuntfuck fuckcunt'); $this->assertTrue($result->hasProfanity); $this->assertSame(4, $result->profanitiesCount); @@ -214,11 +198,12 @@ public function test_cuntfuck_fuckcunt() $this->assertSame('******** ********', $result->cleanString); } + /** + * @throws Exception + */ public function test_fucking_shit_cunt_fuck() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('fuckingshitcuntfuck'); + $result = $this->blaspService->check('fuckingshitcuntfuck'); $this->assertTrue($result->hasProfanity); $this->assertSame(4, $result->profanitiesCount); @@ -226,25 +211,26 @@ public function test_fucking_shit_cunt_fuck() $this->assertSame('*******************', $result->cleanString); } + /** + * @throws Exception + */ public function test_billy_butcher() { - $blaspService = new BlaspService(); - - $result = $blaspService->check('oi! cunt!'); - + $result = $this->blaspService->check('oi! cunt!'); $this->assertTrue($result->hasProfanity); $this->assertSame(1, $result->profanitiesCount); $this->assertCount(1, $result->uniqueProfanitiesFound); $this->assertSame('oi! ****!', $result->cleanString); } + /** + * @throws Exception + */ public function test_paragraph() { - $blaspService = new BlaspService(); - $paragraph = "This damn project is such a pain in the ass. I can't believe I have to deal with this bullshit every single day. It's like everything is completely fucked up, and nobody gives a shit. Sometimes I just want to scream, 'What the hell is going on?' Honestly, it's a total clusterfuck, and I'm so fucking done with this crap."; - $result = $blaspService->check($paragraph); + $result = $this->blaspService->check($paragraph); $expectedOutcome = "This **** project is such a pain in the ***. I can't believe I have to deal with this ******** every single day. It's like everything is completely ****** up, and nobody gives a ****. Sometimes I just want to scream, 'What the **** is going on?' Honestly, it's a total ***********, and I'm so ******* done with this ****."; diff --git a/tests/BlaspCheckValidationTest.php b/tests/BlaspCheckValidationTest.php new file mode 100644 index 0000000..895b061 --- /dev/null +++ b/tests/BlaspCheckValidationTest.php @@ -0,0 +1,71 @@ + 'This is a clean message.']; + + $rules = ['message' => 'blasp_check']; + + $validator = Validator::make($data, $rules); + + $this->assertTrue($validator->passes()); + } + + /** + * Test validation fails with profane text. + * + * @return void + */ + public function test_blasp_check_validation_fails_with_profanity() + { + $data = ['message' => 'This is a fucking message.']; + + $rules = ['message' => 'blasp_check']; + + $validator = Validator::make($data, $rules); + + $this->assertTrue($validator->fails()); + } + + /** + * Test validation passes with clean French text. + * + * @return void + */ + public function test_blasp_check_validation_passes_with_clean_french_text() + { + $data = ['message' => 'Ceci est un message propre.']; + + $rules = ['message' => 'blasp_check:fr']; + + $validator = Validator::make($data, $rules); + + $this->assertTrue($validator->passes()); + } + + /** + * Test validation fails with profane French text. + * + * @return void + */ + public function test_blasp_check_validation_fails_with_french_profanity() + { + $data = ['message' => 'Ceci est un message de merdique.']; + + $rules = ['message' => 'blasp_check:fr']; + + $validator = Validator::make($data, $rules); + + $this->assertTrue($validator->fails()); + } +} diff --git a/tests/TestCase.php b/tests/TestCase.php index e17667c..e5d5f39 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -3,10 +3,12 @@ namespace Blaspsoft\Blasp\Tests; use Blaspsoft\Blasp\ServiceProvider; +use Illuminate\Support\Facades\Config; use Orchestra\Testbench\TestCase as BaseTestCase; abstract class TestCase extends BaseTestCase { + protected function getPackageProviders($app) { return [ @@ -17,5 +19,40 @@ protected function getPackageProviders($app) protected function setUp(): void { parent::setUp(); + Config::set('blasp.profanities', [ + 'en' => ['fucking', 'shit', 'cunt', 'fuck', 'penis', 'cock', 'twat', 'ass', 'dick', 'sex', 'butt', 'arse', 'lick', 'anal', 'clusterfuck', 'bullshit', 'fucked', 'damn', 'crap', 'hell'], + 'fr' => ['putain', 'connasse', 'c0nn4ss3', 'putain', 'connard', 'merdique', 'bordel', 'foutre', 'Putain', 'merde']]); + Config::set('blasp.false_positives', ['fr' => ['passeur', 'classe'], 'en' => ['Scunthorpe', 'Cockburn', 'Penistone', 'Lightwater', 'Assume', 'bass', 'class', 'Compass', 'Pass', + 'Dickinson', 'Middlesex', 'Cockerel', 'Butterscotch', 'Blackcock', 'Countryside', 'Arsenal', 'Flick', 'Flicker', 'Analyst', 'blackCocktail',]]); + Config::set('blasp.languages', ['en', 'fr']); + Config::set('blasp.separators', [' ', '-', '_']); + Config::set('blasp.substitutions', [ + '/a/' => ['a', '4', '@', 'Á', 'á', 'À', 'Â', 'à', 'Â', 'â', 'Ä', 'ä', 'Ã', 'ã', 'Å', 'å', 'æ', 'Æ', 'α', 'Δ', 'Λ', 'λ'], + '/b/' => ['b', '8', '\\', '3', 'ß', 'Β', 'β'], + '/c/' => ['c', 'Ç', 'ç', 'ć', 'Ć', 'č', 'Č', '¢', '€', '<', '(', '{', '©'], + '/d/' => ['d', '\\', ')', 'Þ', 'þ', 'Ð', 'ð'], + '/e/' => ['e', '3', '€', 'È', 'è', 'É', 'é', 'Ê', 'ê', 'ë', 'Ë', 'ē', 'Ē', 'ė', 'Ė', 'ę', 'Ę', '∑'], + '/f/' => ['f', 'ƒ'], + '/g/' => ['g', '6', '9'], + '/h/' => ['h', 'Η'], + '/i/' => ['i', '!', '|', ']', '[', '1', '∫', 'Ì', 'Í', 'Î', 'Ï', 'ì', 'í', 'î', 'ï', 'ī', 'Ī', 'į', 'Į'], + '/j/' => ['j'], + '/k/' => ['k', 'Κ', 'κ'], + '/l/' => ['l', '!', '|', ']', '[', '£', '∫', 'Ì', 'Í', 'Î', 'Ï', 'ł', 'Ł'], + '/m/' => ['m'], + '/n/' => ['n', 'η', 'Ν', 'Π', 'ñ', 'Ñ', 'ń', 'Ń'], + '/o/' => ['o', '0', 'Ο', 'ο', 'Φ', '¤', '°', 'ø', 'ô', 'Ô', 'ö', 'Ö', 'ò', 'Ò', 'ó', 'Ó', 'œ', 'Œ', 'ø', 'Ø', 'ō', 'Ō', 'õ', 'Õ'], + '/p/' => ['p', 'ρ', 'Ρ', '¶', 'þ'], + '/q/' => ['q'], + '/r/' => ['r', '®'], + '/s/' => ['s', '5', '$', '§', 'ß', 'Ś', 'ś', 'Š', 'š'], + '/t/' => ['t', 'Τ', 'τ'], + '/u/' => ['u', 'υ', 'µ', 'û', 'ü', 'ù', 'ú', 'ū', 'Û', 'Ü', 'Ù', 'Ú', 'Ū'], + '/v/' => ['v', 'υ', 'ν'], + '/w/' => ['w', 'ω', 'ψ', 'Ψ'], + '/x/' => ['x', 'Χ', 'χ'], + '/y/' => ['y', '¥', 'γ', 'ÿ', 'ý', 'Ÿ', 'Ý'], + '/z/' => ['z', 'Ζ', 'ž', 'Ž', 'ź', 'Ź', 'ż', 'Ż'], + ]); } }