├── .gitignore
├── .styleci.yml
├── .travis.yml
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── composer.json
├── phpunit.xml
├── src
├── Dictionary.php
├── ProfaneServiceProvider.php
├── ProfaneValidator.php
├── Str.php
├── dict
│ ├── de.php
│ ├── en.php
│ ├── es-cl.php
│ ├── es.php
│ ├── fil.php
│ ├── fr-ca.php
│ ├── fr.php
│ ├── gr.php
│ ├── id.php
│ ├── it.php
│ ├── ml.php
│ ├── nl.php
│ ├── pt-br.php
│ ├── ro-md.php
│ ├── ro.php
│ ├── ru.php
│ ├── sk.php
│ ├── sr-rs.php
│ └── zh-tw.php
└── lang
│ ├── de
│ └── validation.php
│ ├── en
│ └── validation.php
│ ├── es-cl
│ └── validation.php
│ ├── es
│ └── validation.php
│ ├── fr
│ └── validation.php
│ ├── gr
│ └── validation.php
│ ├── id
│ └── validation.php
│ ├── it
│ └── validation.php
│ ├── ml
│ └── validation.php
│ ├── nl
│ └── validation.php
│ ├── pt-br
│ └── validation.php
│ ├── ro-md
│ └── validation.php
│ ├── ro
│ └── validation.php
│ ├── sk
│ └── validation.php
│ ├── sr-rs
│ └── validation.php
│ └── zh-tw
│ └── validation.php
└── tests
├── DictionaryTest.php
├── ProfaneValidatorTest.php
├── StrTest.php
├── Support
└── ProfaneValidatorBuilder.php
└── TestCase.php
/.gitignore:
--------------------------------------------------------------------------------
1 | vendor
2 | .idea
3 | composer.lock
--------------------------------------------------------------------------------
/.styleci.yml:
--------------------------------------------------------------------------------
1 | preset: recommended
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 |
3 | php:
4 | - 8.0
5 | - 7.4
6 | - 7.3
7 | - 7.2
8 |
9 | env:
10 | matrix:
11 | - COMPOSER_FLAGS="--prefer-lowest"
12 | - COMPOSER_FLAGS=""
13 |
14 | before_install:
15 | - travis_retry composer self-update
16 |
17 | install:
18 | - travis_retry composer update --prefer-source $PREFER_LOWEST
19 |
20 | script:
21 | - phpunit
22 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Hi!
2 | Thanks to contribute in this project. **Changes and contributions must be added as pull request**
3 |
4 | ## Add a new dictionary
5 |
6 | You can help to make this project better by adding a new dictionary of swear words in your native language. The dictionary file MUST follow this points:
7 |
8 | 1. It must be a `.php` file in `src/dict`
9 | 2. Its filename must be a valid language code, check [here](https://www.science.co.il/language/Locale-codes.php)
10 | 3. It must return an array with your swear words
11 | 4. You MUST use array brackets declaration instead of `array()` function.
12 | 5. Each word must be in a single line
13 | 6. Each word must be single quoted
14 | 7. Each word MUST NOT contains accents
15 |
16 | ### Example
17 |
18 | ```php
19 |
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Laravel Profanity Validator
2 |
3 | [](https://packagist.org/packages/arandilopez/laravel-profane)
4 | [](https://packagist.org/packages/arandilopez/laravel-profane)
5 | [](https://packagist.org/packages/arandilopez/laravel-profane)
6 | [](https://packagist.org/packages/arandilopez/laravel-profane)
7 | [](https://packagist.org/packages/arandilopez/laravel-profane)
8 | 
9 | [](https://styleci.io/repos/63648834)
10 |
11 | I made this package to perform a validation for swearwords using Laravel validation service.
12 |
13 | ## Installation
14 |
15 | Install via composer
16 |
17 | ```shell
18 | composer require arandilopez/laravel-profane
19 | ```
20 |
21 | ## Configuration
22 |
23 | Add the `ProfaneServiceProvider` class in your `config/app.php` file.
24 |
25 | ```php
26 | [
31 | // ...
32 | LaravelProfane\ProfaneServiceProvider::class,
33 | ];
34 |
35 | // ...
36 | ];
37 | ```
38 |
39 | Publish vendor lang files if you need to replace by your own.
40 |
41 | ```shell
42 | php artisan vendor:publish
43 | ```
44 |
45 | ## Usage
46 |
47 | This package register a custom validator. You can use in your controller's `validate` function.
48 |
49 | ```php
50 | validate($request, [
57 | 'username' => 'required|profane'
58 | ]);
59 |
60 | // ...
61 | }
62 | }
63 | ```
64 |
65 | The validator will load the default locale in your `config/app.php` file configuration which by is `en`. **If your locale is not supported, please [post an issue for this project](https://github.com/arandilopez/laravel-profane/issues)**
66 |
67 | If you want to use others dictionaries you can pass them as parameters in the validator.
68 |
69 | ```php
70 | validate($request, [
77 | 'username' => 'required|profane:es,en'
78 | ]);
79 |
80 | // ...
81 | }
82 | }
83 | ```
84 |
85 | You can also send as parameter a path of a file which is a dictionary in order to replace the default dictionary or **add a new non supported locale**.
86 |
87 | ```php
88 | validate($request, [
95 | 'username' => 'required|profane:es,en,'.resource_path('lang/fr/dict.php')
96 | ]);
97 |
98 | // ...
99 | }
100 | }
101 | ```
102 |
103 | #### Strict validation
104 |
105 | Now you can strictly validate the exact profane word in the content.
106 |
107 | ```php
108 | validate($request, [
115 | 'username' => 'required|strictly_profane:es,en'
116 | ]);
117 |
118 | // ...
119 | }
120 | }
121 | ```
122 |
123 | This fixes known issues when you get a error in validation for words like `class` or `analysis`, as they include `ass` and `anal` respectively, but fails the validation for content like `sucker69`.
124 |
125 | ## Getting Help
126 |
127 | If you're stuck getting something to work, or need to report a bug, please [post an issue in the Github Issues for this project](https://github.com/arandilopez/laravel-profane/issues).
128 |
129 | ## Contributing
130 |
131 | If you're interesting in contributing code to this project, clone it by running:
132 |
133 | ```shell
134 | git clone git@github.com:arandilopez/laravel-profane.git
135 | ```
136 |
137 | Please read the [CONTRIBUTING](CONTRIBUTING.md) file.
138 |
139 | Pull requests are welcome, but please make sure you provide unit tests to cover your changes. **You can help to add and support more locales!**
140 |
141 | _Thanks to [@dorianneto](https://github.com/dorianneto) for his contributions._
142 |
143 | ### Supported Locales
144 |
145 | - English ( provided by [@arandilopez](https://github.com/arandilopez) )
146 | - Spanish ( provided by [@arandilopez](https://github.com/arandilopez) and [@xDidier901](https://github.com/xDidier901))
147 | - Italian ( provided by [@aletundo](https://github.com/aletundo) )
148 | - Brazilian Portuguese ( provided by [@ianrodriguesbr](https://github.com/ianrodriguesbr) and [@LeonardoTeixeira](https://github.com/LeonardoTeixeira))
149 | - Traditional Chinese ( provided by [@Nationalcat](https://github.com/Nationalcat) )
150 | - Slovak ( provided by [@kotass](https://github.com/kotass) )
151 | - Dutch (Netherlands) ( provided by [@Cannonb4ll](https://github.com/Cannonb4ll) and [@WouterVanmulken](https://github.com/WouterVanmulken))
152 | - Greek ( provided by [@siokas](https://github.com/siokas) )
153 | - Malayalam ( provided by [@abinodh](https://github.com/abinodh) )
154 | - Russian ( provided by [@alex2sat](https://github.com/alex2sat) )
155 | - Serbian ( provided by [@Djuki](https://github.com/Djuki) )
156 | - Filipino ( provided by [@credocleo](https://github.com/credocleo) )
157 | - Romanian ( provided by [@rchioreanu](https://github.com/rchioreanu) )
158 | - Indonesian ( provided by [@rizasaputra](https://github.com/rizasaputra) )
159 |
160 | ## License
161 |
162 | This project is open-sourced software licensed under the [MIT license](http://opensource.org/licenses/MIT).
163 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "arandilopez/laravel-profane",
3 | "description": "Laravel Profanity Valitador",
4 | "license": "MIT",
5 | "authors": [
6 | {
7 | "name": "Arandi Lopez",
8 | "email": "arandilopez.93@gmail.com"
9 | }
10 | ],
11 | "autoload": {
12 | "psr-4": {
13 | "LaravelProfane\\": "src/",
14 | "LaravelProfaneTests\\": "tests/"
15 | }
16 | },
17 | "minimum-stability": "stable",
18 | "require": {
19 | "illuminate/support": ">=5.2|^6.0|^7.0|^8.0"
20 | },
21 | "require-dev": {
22 | "phpunit/phpunit": "^8.0|^8.5",
23 | "mockery/mockery": "^1.3"
24 | },
25 | "extra": {
26 | "laravel": {
27 | "providers": ["LaravelProfane\\ProfaneServiceProvider"]
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/phpunit.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | tests
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/Dictionary.php:
--------------------------------------------------------------------------------
1 | setDictionary($dictionary ?: $locale);
28 | }
29 |
30 | /**
31 | * [getDictionary description].
32 | *
33 | * @return [type] [description]
34 | */
35 | public function getDictionary()
36 | {
37 | return $this->dictionary;
38 | }
39 |
40 | /**
41 | * Set the dictionary to use.
42 | *
43 | * @param array|string $dictionary
44 | */
45 | public function setDictionary($dictionary)
46 | {
47 | $this->dictionary = $this->readDictionary($dictionary);
48 | }
49 |
50 | /**
51 | * [readDictionary description].
52 | *
53 | * @param [type] $dictionary [description]
54 | *
55 | * @return [type] [description]
56 | */
57 | protected function readDictionary($dictionary)
58 | {
59 | $words = [];
60 | $baseDictPath = $this->getBaseDictPath();
61 | if (is_array($dictionary)) {
62 | foreach ($dictionary as $file) {
63 | if (file_exists($baseDictPath.$file.'.php')) {
64 | $dict = include $baseDictPath.$file.'.php';
65 | $words = array_merge($words, $dict);
66 | } else {
67 | // if the file isn't in the dict directory,
68 | // it's probably a custom user library
69 | $dict = include $file;
70 | $words = array_merge($words, $dict);
71 | }
72 | }
73 | // just a single string, not an array
74 | } elseif (is_string($dictionary)) {
75 | if (file_exists($baseDictPath.$dictionary.'.php')) {
76 | $dict = include $baseDictPath.$dictionary.'.php';
77 | $words = array_merge($words, $dict);
78 | } else {
79 | if (file_exists($dictionary)) {
80 | $dict = include $dictionary;
81 | $words = array_merge($words, $dict);
82 | } // else nothing is merged
83 | }
84 | }
85 |
86 | return $words;
87 | }
88 |
89 | /**
90 | * [getBaseDictPath description].
91 | *
92 | * @return [type] [description]
93 | */
94 | protected function getBaseDictPath()
95 | {
96 | return property_exists($this, 'baseDictPath') ? $this->baseDictPath : __DIR__.DIRECTORY_SEPARATOR.'dict/';
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/ProfaneServiceProvider.php:
--------------------------------------------------------------------------------
1 | loadTranslationsFrom(__DIR__.'/lang', 'laravel-profane');
14 |
15 | $this->publishes([
16 | __DIR__.'/lang' => resource_path('lang/vendor/laravel-profane'),
17 | ]);
18 |
19 | // Rule for caseless content matching
20 | Validator::extend('profane', 'LaravelProfane\ProfaneValidator@validate', Lang::get('laravel-profane::validation.profane'));
21 |
22 | Validator::replacer('profane', function ($message, $attribute) {
23 | return str_replace(':attribute', $attribute, $message);
24 | });
25 |
26 | // Rule for caseless but strict word matching
27 | Validator::extend('strictly_profane', 'LaravelProfane\ProfaneValidator@validateStrict', Lang::get('laravel-profane::validation.profane'));
28 |
29 | Validator::replacer('strictly_profane', function ($message, $attribute) {
30 | return str_replace(':attribute', $attribute, $message);
31 | });
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/ProfaneValidator.php:
--------------------------------------------------------------------------------
1 | dictionary = $dictionary;
23 | $this->badwords = $dictionary->getDictionary();
24 | }
25 |
26 | /**
27 | * Method to extends to Validation Service.
28 | *
29 | * @param string $attribute
30 | * @param mixed $value
31 | * @param array $parameters
32 | *
33 | * @return bool
34 | */
35 | public function validate($attribute, $value, $parameters)
36 | {
37 | if ($parameters) {
38 | $this->setDictionary($parameters);
39 | }
40 |
41 | return !$this->isProfane($value);
42 | }
43 |
44 | /**
45 | * Method to extends to Validation Service for strict word matching.
46 | *
47 | * @param string $attribute
48 | * @param mixed $value
49 | * @param array $parameters
50 | *
51 | * @return bool
52 | */
53 | public function validateStrict($attribute, $value, $parameters)
54 | {
55 | if ($parameters) {
56 | $this->setDictionary($parameters);
57 | }
58 |
59 | return !$this->isProfane($value, true);
60 | }
61 |
62 | /**
63 | * Check profanity of text.
64 | *
65 | * @param string $text
66 | *
67 | * @return bool
68 | */
69 | public function isProfane($text, $strict = false)
70 | {
71 | return Str::containsCaseless(
72 | $this->sanitizeText($text),
73 | $this->badwords,
74 | $strict
75 | );
76 | }
77 |
78 | private function setDictionary($dictionaries)
79 | {
80 | $this->dictionary->setDictionary($dictionaries);
81 | $this->badwords = $this->dictionary->getDictionary();
82 | }
83 |
84 | private function sanitizeText($text)
85 | {
86 | return Str::removeAccent(strip_tags($text));
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/Str.php:
--------------------------------------------------------------------------------
1 | '-', 'Ь' => '-', 'Ъ' => '-', 'ь' => '-',
40 | 'Ă' => 'A', 'Ą' => 'A', 'À' => 'A', 'Ã' => 'A', 'Á' => 'A', 'Æ' => 'A', 'Â' => 'A', 'Å' => 'A', 'Ä' => 'Ae',
41 | 'Þ' => 'B',
42 | 'Ć' => 'C', 'ץ' => 'C', 'Ç' => 'C',
43 | 'È' => 'E', 'Ę' => 'E', 'É' => 'E', 'Ë' => 'E', 'Ê' => 'E',
44 | 'Ğ' => 'G',
45 | 'İ' => 'I', 'Ï' => 'I', 'Î' => 'I', 'Í' => 'I', 'Ì' => 'I',
46 | 'Ł' => 'L',
47 | 'Ñ' => 'N', 'Ń' => 'N',
48 | 'Ø' => 'O', 'Ó' => 'O', 'Ò' => 'O', 'Ô' => 'O', 'Õ' => 'O', 'Ö' => 'Oe',
49 | 'Ş' => 'S', 'Ś' => 'S', 'Ș' => 'S', 'Š' => 'S',
50 | 'Ț' => 'T',
51 | 'Ù' => 'U', 'Û' => 'U', 'Ú' => 'U', 'Ü' => 'Ue',
52 | 'Ý' => 'Y',
53 | 'Ź' => 'Z', 'Ž' => 'Z', 'Ż' => 'Z',
54 | 'â' => 'a', 'ǎ' => 'a', 'ą' => 'a', 'á' => 'a', 'ă' => 'a', 'ã' => 'a', 'Ǎ' => 'a', 'а' => 'a', 'А' => 'a', 'å' => 'a', 'à' => 'a', 'א' => 'a', 'Ǻ' => 'a', 'Ā' => 'a', 'ǻ' => 'a', 'ā' => 'a', 'ä' => 'ae', 'æ' => 'ae', 'Ǽ' => 'ae', 'ǽ' => 'ae',
55 | 'б' => 'b', 'ב' => 'b', 'Б' => 'b', 'þ' => 'b',
56 | 'ĉ' => 'c', 'Ĉ' => 'c', 'Ċ' => 'c', 'ć' => 'c', 'ç' => 'c', 'ц' => 'c', 'צ' => 'c', 'ċ' => 'c', 'Ц' => 'c', 'Č' => 'c', 'č' => 'c', 'Ч' => 'ch', 'ч' => 'ch',
57 | 'ד' => 'd', 'ď' => 'd', 'Đ' => 'd', 'Ď' => 'd', 'đ' => 'd', 'д' => 'd', 'Д' => 'D', 'ð' => 'd',
58 | 'є' => 'e', 'ע' => 'e', 'е' => 'e', 'Е' => 'e', 'Ə' => 'e', 'ę' => 'e', 'ĕ' => 'e', 'ē' => 'e', 'Ē' => 'e', 'Ė' => 'e', 'ė' => 'e', 'ě' => 'e', 'Ě' => 'e', 'Є' => 'e', 'Ĕ' => 'e', 'ê' => 'e', 'ə' => 'e', 'è' => 'e', 'ë' => 'e', 'é' => 'e',
59 | 'ф' => 'f', 'ƒ' => 'f', 'Ф' => 'f',
60 | 'ġ' => 'g', 'Ģ' => 'g', 'Ġ' => 'g', 'Ĝ' => 'g', 'Г' => 'g', 'г' => 'g', 'ĝ' => 'g', 'ğ' => 'g', 'ג' => 'g', 'Ґ' => 'g', 'ґ' => 'g', 'ģ' => 'g',
61 | 'ח' => 'h', 'ħ' => 'h', 'Х' => 'h', 'Ħ' => 'h', 'Ĥ' => 'h', 'ĥ' => 'h', 'х' => 'h', 'ה' => 'h',
62 | 'î' => 'i', 'ï' => 'i', 'í' => 'i', 'ì' => 'i', 'į' => 'i', 'ĭ' => 'i', 'ı' => 'i', 'Ĭ' => 'i', 'И' => 'i', 'ĩ' => 'i', 'ǐ' => 'i', 'Ĩ' => 'i', 'Ǐ' => 'i', 'и' => 'i', 'Į' => 'i', 'י' => 'i', 'Ї' => 'i', 'Ī' => 'i', 'І' => 'i', 'ї' => 'i', 'і' => 'i', 'ī' => 'i', 'ij' => 'ij', 'IJ' => 'ij',
63 | 'й' => 'j', 'Й' => 'j', 'Ĵ' => 'j', 'ĵ' => 'j', 'я' => 'ja', 'Я' => 'ja', 'Э' => 'je', 'э' => 'je', 'ё' => 'jo', 'Ё' => 'jo', 'ю' => 'ju', 'Ю' => 'ju',
64 | 'ĸ' => 'k', 'כ' => 'k', 'Ķ' => 'k', 'К' => 'k', 'к' => 'k', 'ķ' => 'k', 'ך' => 'k',
65 | 'Ŀ' => 'l', 'ŀ' => 'l', 'Л' => 'l', 'ł' => 'l', 'ļ' => 'l', 'ĺ' => 'l', 'Ĺ' => 'l', 'Ļ' => 'l', 'л' => 'l', 'Ľ' => 'l', 'ľ' => 'l', 'ל' => 'l',
66 | 'מ' => 'm', 'М' => 'm', 'ם' => 'm', 'м' => 'm',
67 | // 'ñ'=>'n', // for spanish cono != coño
68 | 'н' => 'n', 'Ņ' => 'n', 'ן' => 'n', 'ŋ' => 'n', 'נ' => 'n', 'Н' => 'n', 'ń' => 'n',
69 | 'Ŋ' => 'n', 'ņ' => 'n', 'ʼn' => 'n', 'Ň' => 'n', 'ň' => 'n',
70 | 'о' => 'o', 'О' => 'o', 'ő' => 'o', 'õ' => 'o', 'ô' => 'o', 'Ő' => 'o', 'ŏ' => 'o', 'Ŏ' => 'o', 'Ō' => 'o', 'ō' => 'o', 'ø' => 'o', 'ǿ' => 'o', 'ǒ' => 'o', 'ò' => 'o', 'Ǿ' => 'o', 'Ǒ' => 'o', 'ơ' => 'o', 'ó' => 'o', 'Ơ' => 'o', 'œ' => 'oe', 'Œ' => 'oe', 'ö' => 'oe',
71 | 'פ' => 'p', 'ף' => 'p', 'п' => 'p', 'П' => 'p',
72 | 'ק' => 'q',
73 | 'ŕ' => 'r', 'ř' => 'r', 'Ř' => 'r', 'ŗ' => 'r', 'Ŗ' => 'r', 'ר' => 'r', 'Ŕ' => 'r', 'Р' => 'r', 'р' => 'r',
74 | 'ș' => 's', 'с' => 's', 'Ŝ' => 's', 'š' => 's', 'ś' => 's', 'ס' => 's', 'ş' => 's', 'С' => 's', 'ŝ' => 's', 'Щ' => 'sch', 'щ' => 'sch', 'ш' => 'sh', 'Ш' => 'sh', 'ß' => 'ss',
75 | 'т' => 't', 'ט' => 't', 'ŧ' => 't', 'ת' => 't', 'ť' => 't', 'ţ' => 't', 'Ţ' => 't', 'Т' => 't', 'ț' => 't', 'Ŧ' => 't', 'Ť' => 't', '™' => 'tm',
76 | 'ū' => 'u', 'у' => 'u', 'Ũ' => 'u', 'ũ' => 'u', 'Ư' => 'u', 'ư' => 'u', 'Ū' => 'u', 'Ǔ' => 'u', 'ų' => 'u', 'Ų' => 'u', 'ŭ' => 'u', 'Ŭ' => 'u', 'Ů' => 'u', 'ů' => 'u', 'ű' => 'u', 'Ű' => 'u', 'Ǖ' => 'u', 'ǔ' => 'u', 'Ǜ' => 'u', 'ù' => 'u', 'ú' => 'u', 'û' => 'u', 'У' => 'u', 'ǚ' => 'u', 'ǜ' => 'u', 'Ǚ' => 'u', 'Ǘ' => 'u', 'ǖ' => 'u', 'ǘ' => 'u', 'ü' => 'ue',
77 | 'в' => 'v', 'ו' => 'v', 'В' => 'v',
78 | 'ש' => 'w', 'ŵ' => 'w', 'Ŵ' => 'w',
79 | 'ы' => 'y', 'ŷ' => 'y', 'ý' => 'y', 'ÿ' => 'y', 'Ÿ' => 'y', 'Ŷ' => 'y',
80 | 'Ы' => 'y', 'ž' => 'z', 'З' => 'z', 'з' => 'z', 'ź' => 'z', 'ז' => 'z', 'ż' => 'z', 'ſ' => 'z', 'Ж' => 'zh', 'ж' => 'zh', 'ά' => 'α', 'έ' => 'ε', 'ή' => 'η', 'ί' => 'ι', 'ό' => 'ο', 'ύ' => 'υ', 'ώ' => 'ω',
81 | ];
82 |
83 | return strtr($string, $replace);
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/dict/de.php:
--------------------------------------------------------------------------------
1 | 'Das :attribute enthält vulgäre Wörter',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/en/validation.php:
--------------------------------------------------------------------------------
1 | 'The :attribute contains vulgar content',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/es-cl/validation.php:
--------------------------------------------------------------------------------
1 | 'El :attribute contiene palabras vulgares',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/es/validation.php:
--------------------------------------------------------------------------------
1 | 'El :attribute contiene palabras vulgares',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/fr/validation.php:
--------------------------------------------------------------------------------
1 | 'Le champ :attribute comporte du contenu vulgaire',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/gr/validation.php:
--------------------------------------------------------------------------------
1 | 'Στο πεδίο :attribute εμπεριέχονται χυδαίες εκφράσεις',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/id/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute mengandung konten yang vulgar',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/it/validation.php:
--------------------------------------------------------------------------------
1 | 'Il campo :attribute contiene parole volgari o offensive',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/ml/validation.php:
--------------------------------------------------------------------------------
1 | 'ഈ :attribute നകത്തു മ്ലേച്ഛമായ ഭാഷ ഉണ്ട്',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/nl/validation.php:
--------------------------------------------------------------------------------
1 | 'Het :attribute veld bevat vulgaire inhoud',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/pt-br/validation.php:
--------------------------------------------------------------------------------
1 | 'O campo :attribute contém palavras vulgares',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/ro-md/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute are un continut vulgar',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/ro/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute are un continut vulgar',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/sk/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute obsahuje vulgárny obsah',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/sr-rs/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute sadrži vulgarne reči',
5 | ];
6 |
--------------------------------------------------------------------------------
/src/lang/zh-tw/validation.php:
--------------------------------------------------------------------------------
1 | ':attribute欄位內容包含粗俗用詞,請您修正:)',
5 | ];
6 |
--------------------------------------------------------------------------------
/tests/DictionaryTest.php:
--------------------------------------------------------------------------------
1 | assertEquals($dictionary->getDictionary(), $expected);
16 | }
17 |
18 | public function test_words_from_only_one_file()
19 | {
20 | $dictionary = new Dictionary(__DIR__.'/../src/dict/es.php');
21 |
22 | $expected = include __DIR__.'/../src/dict/es.php';
23 |
24 | $this->assertEquals($dictionary->getDictionary(), $expected);
25 | }
26 |
27 | public function test_words_from_locale_array()
28 | {
29 | $dictionary = new Dictionary([
30 | 'es',
31 | 'gr',
32 | ]);
33 |
34 | $expected = array_merge(
35 | include __DIR__.'/../src/dict/es.php',
36 | include __DIR__.'/../src/dict/gr.php'
37 | );
38 |
39 | $this->assertEquals($dictionary->getDictionary(), $expected);
40 | }
41 |
42 | public function test_words_from_file_array()
43 | {
44 | $dictionary = new Dictionary([
45 | __DIR__.'/../src/dict/es.php',
46 | __DIR__.'/../src/dict/gr.php',
47 | __DIR__.'/../src/dict/it.php',
48 | ]);
49 |
50 | $expected = array_merge(
51 | include __DIR__.'/../src/dict/es.php',
52 | include __DIR__.'/../src/dict/gr.php',
53 | include __DIR__.'/../src/dict/it.php'
54 | );
55 |
56 | $this->assertEquals($dictionary->getDictionary(), $expected);
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/tests/ProfaneValidatorTest.php:
--------------------------------------------------------------------------------
1 | assertFalse($builder->validate(['username', 'culero23', ['es']]));
14 | }
15 |
16 | public function test_can_not_validate_a_word_with_numbers_in_strict_mode()
17 | {
18 | $builder = new ProfaneValidatorBuilder();
19 |
20 | $this->assertTrue($builder->validate(['username', 'culero23', ['es']], true));
21 | }
22 |
23 | public function test_can_validate_a_text()
24 | {
25 | $builder = new ProfaneValidatorBuilder();
26 |
27 | $this->assertFalse($builder->validate(['description', 'fck you bitch. 幹!', ['es', 'en', 'zh-tw']]));
28 | }
29 |
30 | public function test_can_evaluate_profanity_of_a_word()
31 | {
32 | $builder = new ProfaneValidatorBuilder();
33 |
34 | $word = 'fuck';
35 |
36 | $this->assertTrue($builder->build()->isProfane($word));
37 | }
38 |
39 | public function test_can_evaluate_profanity_of_a_sentence()
40 | {
41 | $builder = new ProfaneValidatorBuilder();
42 |
43 | $word = 'fuck you if you read this';
44 |
45 | $this->assertTrue($builder->build()->isProfane($word));
46 | }
47 |
48 | public function test_can_evaluate_profanity_of_a_sentence_in_strict_mode()
49 | {
50 | $builder = new ProfaneValidatorBuilder();
51 |
52 | $word = 'fuck you if you read this';
53 |
54 | $this->assertTrue($builder->build()->isProfane($word), true);
55 | }
56 |
57 | public function test_can_evaluate_profanity_of_a_html_string()
58 | {
59 | $builder = new ProfaneValidatorBuilder();
60 |
61 | $word = 'fuck you if you read this.';
62 |
63 | $this->assertTrue($builder->build()->isProfane($word));
64 | }
65 |
66 | public function test_can_evaluate_as_caseless_mode()
67 | {
68 | $builder = new ProfaneValidatorBuilder();
69 |
70 | $word = 'FUCK you BITCH if you read this.';
71 |
72 | $this->assertTrue($builder->build()->isProfane($word));
73 | }
74 |
75 | public function test_match_content()
76 | {
77 | $builder = new ProfaneValidatorBuilder();
78 |
79 | // it thinks class ~= ass
80 | $this->assertTrue($builder->build()->isProfane('class'));
81 |
82 | // but this should be profane
83 | $this->assertTrue($builder->build()->isProfane('sucker96'));
84 | }
85 |
86 | public function test_match_exact_word_in_strict_mode()
87 | {
88 | $builder = new ProfaneValidatorBuilder();
89 |
90 | // class is a safe word
91 | $this->assertFalse($builder->build()->isProfane('class', true));
92 |
93 | // in strict mode this will pass a safe word
94 | $this->assertFalse($builder->build()->isProfane('sucker96', true));
95 | }
96 |
97 | public function test_can_validate_a_bad_word_with_accent()
98 | {
99 | $builder = new ProfaneValidatorBuilder('sk');
100 |
101 | $word = 'piča';
102 |
103 | $this->assertTrue($builder->build()->isProfane($word));
104 | }
105 |
106 | public function test_enie_in_spanish_is_evaluated()
107 | {
108 | $builder = new ProfaneValidatorBuilder('es');
109 |
110 | // in spanish coño =! cono
111 | $word = 'coño';
112 |
113 | $this->assertTrue($builder->build()->isProfane($word));
114 | }
115 |
116 | public function test_can_validate_a_word_in_greek()
117 | {
118 | $this->mockConfigs();
119 |
120 | $builder = new ProfaneValidatorBuilder('gr');
121 |
122 | $word = 'μαλάκας';
123 |
124 | $this->assertTrue($builder->build()->isProfane($word));
125 | }
126 |
127 | public function test_can_validate_a_text_in_greek()
128 | {
129 | $this->mockConfigs();
130 |
131 | $builder = new ProfaneValidatorBuilder();
132 |
133 | $this->assertFalse($builder->validate(['description', 'εισαι πουτανα', ['en', 'gr']]));
134 | }
135 |
136 | public function test_can_validate_a_word_in_french()
137 | {
138 | $this->mockConfigs();
139 |
140 | $builder = new ProfaneValidatorBuilder();
141 |
142 | $this->assertFalse($builder->validate(['description', 'Va te faire enculer, sac à merde', ['en', 'fr']]));
143 | }
144 |
145 | public function test_can_validate_a_word_in_french_canadian()
146 | {
147 | $this->mockConfigs();
148 |
149 | $builder = new ProfaneValidatorBuilder();
150 |
151 | $this->assertFalse($builder->validate(['description', 'Décrisse gros cave', ['en', 'fr-ca']]));
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/tests/StrTest.php:
--------------------------------------------------------------------------------
1 | assertTrue(Str::containsCaseless('Fuck! This class is so bad!', 'ass'));
12 | }
13 |
14 | public function test_text_contains_insensitive_match_from_array()
15 | {
16 | $this->assertTrue(Str::containsCaseless('Fuck! This class is so bad!', ['fuk', 'fuck']));
17 | }
18 |
19 | public function test_text_contains_insensitive_match_from_string()
20 | {
21 | $this->assertTrue(Str::containsCaseless('Fuck! This class is so bad!', 'fUcK'));
22 | }
23 |
24 | public function test_text_does_not_contain_match_in_strict_mode()
25 | {
26 | $this->assertFalse(Str::containsCaseless('This class is so bad!', 'ass', true));
27 | $this->assertFalse(Str::containsCaseless('Theorem Analisys', 'anal', true));
28 | }
29 |
30 | public function test_text_contains_match_in_strict_mode()
31 | {
32 | $this->assertTrue(Str::containsCaseless('This class is a crap!', 'crap', true));
33 | $this->assertFalse(Str::containsCaseless('Theorem Analisys', 'anal', true));
34 | $this->assertFalse(Str::containsCaseless('Sucker69', 'sucker', true));
35 | }
36 |
37 | public function test_text_contains_match_in_not_strict_mode()
38 | {
39 | $this->assertTrue(Str::containsCaseless('This class is so bad!', 'ass', false));
40 | $this->assertTrue(Str::containsCaseless('Theorem Analisys', 'anal', false));
41 | }
42 |
43 | public function test_text_contains_the_same_insensitive_match_from_string()
44 | {
45 | $this->assertTrue(Str::containsCaseless('Fuck! This class is so bad!', 'Fuck'));
46 | }
47 |
48 | public function test_remove_accents_in_spanish_text()
49 | {
50 | $this->assertEquals('cojon', Str::removeAccent('cojón'));
51 | }
52 |
53 | public function test_enie_char_is_allowed()
54 | {
55 | $this->assertEquals('coño', Str::removeAccent('coño'));
56 | }
57 |
58 | public function test_remove_accents_in_greek()
59 | {
60 | $this->assertEquals('μαλακας', Str::removeAccent('μαλάκας'));
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/tests/Support/ProfaneValidatorBuilder.php:
--------------------------------------------------------------------------------
1 | profaneValidator = new ProfaneValidator(new Dictionary($dictionary));
25 | }
26 |
27 | /**
28 | * [validate description].
29 | *
30 | * @param array $parameters [description]
31 | *
32 | * @return [type] [description]
33 | */
34 | public function validate(array $parameters, $strict = false)
35 | {
36 | list($attribute, $text, $dictionaries) = $parameters;
37 |
38 | if ($strict) {
39 | return $this->build()->validateStrict($attribute, $text, $dictionaries);
40 | }
41 |
42 | return $this->build()->validate($attribute, $text, $dictionaries);
43 | }
44 |
45 | /**
46 | * [build description].
47 | *
48 | * @return LaravelProfane\ProfaneValidator
49 | */
50 | public function build()
51 | {
52 | return $this->profaneValidator;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/tests/TestCase.php:
--------------------------------------------------------------------------------
1 | mockConfigs();
18 | }
19 |
20 | /**
21 | * [tearDown description].
22 | *
23 | * @return [type] [description]
24 | */
25 | public function tearDown(): void
26 | {
27 | parent::tearDown();
28 | Mockery::close();
29 | }
30 |
31 | /**
32 | * [mockConfigs description].
33 | *
34 | * @return void
35 | */
36 | protected function mockConfigs()
37 | {
38 | Config::shouldReceive('get')
39 | ->once()
40 | ->with('app.locale')
41 | ->andReturn('en');
42 |
43 | Config::shouldReceive('has')
44 | ->once()
45 | ->with('app.locale')
46 | ->andReturn(true);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------