From 910cd427bdbe7d010888fd48640d2033e60edd0e Mon Sep 17 00:00:00 2001 From: dewanakl Date: Tue, 26 Dec 2023 22:56:46 +0700 Subject: [PATCH] first commit --- .editorconfig | 9 ++ .gitattributes | 17 ++++ .gitignore | 13 +++ README.MD | 1 + composer.json | 31 +++++++ phpunit.xml | 8 ++ src/Aman.php | 155 +++++++++++++++++++++++++++++++ src/db/lists.php | 237 +++++++++++++++++++++++++++++++++++++++++++++++ tests/Test.php | 43 +++++++++ 9 files changed, 514 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 README.MD create mode 100644 composer.json create mode 100644 phpunit.xml create mode 100644 src/Aman.php create mode 100644 src/db/lists.php create mode 100644 tests/Test.php diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..677e36e --- /dev/null +++ b/.editorconfig @@ -0,0 +1,9 @@ +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 4 +indent_style = space +insert_final_newline = true +trim_trailing_whitespace = true diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a0c1a8a --- /dev/null +++ b/.gitattributes @@ -0,0 +1,17 @@ +* text=auto + +*.php diff=php +*.html diff=html +*.css diff=css +*.md diff=markdown + +/.github export-ignore +/tests export-ignore +.editorconfig export-ignore +.gitattributes export-ignore +.gitignore export-ignore +phpunit.xml export-ignore +phpstan-tests.neon export-ignore +phpstan.neon.dist export-ignore +CODE_OF_CONDUCT.md export-ignore +SECURITY.md export-ignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..12ff5a2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,13 @@ +/.idea +/.vscode +/vendor +/.phpunit.cache +composer.phar +composer.lock +.DS_Store +Thumbs.db +.phpunit.result.cache +phpstan.neon +phpstan-baseline.neon +CODE_OF_CONDUCT.md +SECURITY.md diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..0695a38 --- /dev/null +++ b/README.MD @@ -0,0 +1 @@ +# Simple filter kata kotor dengan regex diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..b2523b3 --- /dev/null +++ b/composer.json @@ -0,0 +1,31 @@ +{ + "name": "kamu/aman", + "description": "Replace badword", + "type": "library", + "license": "MIT", + "autoload": { + "psr-4": { + "Kamu\\": "src/" + } + }, + "authors": [ + { + "name": "dewanakl", + "email": "dewanakretarta29@gmail.com" + } + ], + "require": { + "php": "^8.1", + "ext-mbstring": "*" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "config": { + "optimize-autoloader": true, + "preferred-install": "dist", + "sort-packages": true + }, + "minimum-stability": "stable", + "prefer-stable": true +} \ No newline at end of file diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..5a8049c --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,8 @@ + + + + + ./tests + + + diff --git a/src/Aman.php b/src/Aman.php new file mode 100644 index 0000000..5e06a40 --- /dev/null +++ b/src/Aman.php @@ -0,0 +1,155 @@ + '(a|a\.|a\-|4|@|Á|á|À|Â|à|Â|â|Ä|ä|Ã|ã|Å|å|α|Δ|Λ|λ)', + 'b' => '(b|b\.|b\-|8|\|3|ß|Β|β)', + 'c' => '(c|c\.|c\-|Ç|ç|¢|€|<|\(|{|©)', + 'd' => '(d|d\.|d\-|∂|\|\)|Þ|þ|Ð|ð)', + 'e' => '(e|e\.|e\-|3|€|È|è|É|é|Ê|ê|∑)', + 'f' => '(f|f\.|f\-|ƒ)', + 'g' => '(g|g\.|g\-|6|9)', + 'h' => '(h|h\.|h\-|Η)', + 'i' => '(i|i\.|i\-|!|\||\]\[|]|1|∫|Ì|Í|Î|Ï|ì|í|î|ï)', + 'j' => '(j|j\.|j\-)', + 'k' => '(k|k\.|k\-|Κ|κ)', + 'l' => '(l|1\.|l\-|!|\||\]\[|]|£|∫|Ì|Í|Î|Ï)', + 'm' => '(m|m\.|m\-)', + 'n' => '(n|n\.|n\-|η|Ν|Π)', + 'o' => '(o|o\.|o\-|0|Ο|ο|Φ|¤|°|ø)', + 'p' => '(p|p\.|p\-|ρ|Ρ|¶|þ)', + 'q' => '(q|q\.|q\-)', + 'r' => '(r|r\.|r\-|®)', + 's' => '(s|s\.|s\-|5|\$|§)', + 't' => '(t|t\.|t\-|Τ|τ)', + 'u' => '(u|u\.|u\-|υ|µ)', + 'v' => '(v|v\.|v\-|υ|ν)', + 'w' => '(w|w\.|w\-|ω|ψ|Ψ)', + 'x' => '(x|x\.|x\-|Χ|χ)', + 'y' => '(y|y\.|y\-|¥|γ|ÿ|ý|Ÿ|Ý)', + 'z' => '(z|z\.|z\-|Ζ)', + ]; + + /** + * List of words. + * + * @var array $lists + */ + private $lists; + + /** + * Singleton variable. + * + * @var Aman|null + */ + public static $instance; + + /** + * Init object. + * + * @return void + */ + public function __construct() + { + $this->lists = []; + $lists = (array) @require __DIR__ . '/db/lists.php'; + + foreach ($lists as $list) { + $this->lists[] = $this->getFilterRegexp($list); + } + } + + /** + * From list to regex pattern. + * + * @param string $string + * @return string + */ + private function getFilterRegexp(string $string): string + { + $replace = str_ireplace(array_keys($this->similar), array_values($this->similar), $string); + return '/' . $replace . '/iu'; + } + + /** + * Create object. + * + * @return Aman + */ + public static function factory(): Aman + { + if (!static::$instance) { + static::$instance = new Aman(); + } + + return static::$instance; + } + + /** + * Check if contains. + * + * @param string $string + * @return bool + */ + public function check(string $string): bool + { + foreach ($this->lists as $pattern) { + if (preg_match($pattern, $string)) { + return true; + } + } + + return false; + } + + /** + * Mask contains word. + * + * @param string $string + * @param string $masking + * @return string + */ + public function masking(string $string, string $masking = '*'): string + { + return strval(preg_replace_callback($this->lists, function (array $words) use ($masking): string { + return str_repeat($masking, strlen($words[0])); + }, $string)); + } + + /** + * Filter and remove if contains. + * + * @param string $string + * @return string + */ + public function filter(string $string): string + { + return strval(preg_replace_callback($this->lists, function (): string { + return ''; + }, $string)); + } + + /** + * Get from string. + * + * @param string $string + * @return array + */ + public function words(string $string): array + { + $lists = []; + preg_replace_callback($this->lists, function (array $words) use (&$lists): void { + $lists[] = $words[0]; + }, $string); + + return array_reverse($lists); + } +} diff --git a/src/db/lists.php b/src/db/lists.php new file mode 100644 index 0000000..6d902ed --- /dev/null +++ b/src/db/lists.php @@ -0,0 +1,237 @@ +check('k0nt0L'); + $this->assertTrue($check); + } + + public function testCheckFalse() + { + $check = Aman::factory()->check('kantor'); + $this->assertFalse($check); + } + + public function testCheckMixedTrue() + { + $check = Aman::factory()->check('k0nt0L dan m3m3k'); + $this->assertTrue($check); + } + + public function testMaskEquals() + { + $check = Aman::factory()->masking('k0nt0L'); + $this->assertStringContainsString($check, '******'); + } + + public function testMaskEqualsEmpty() + { + $check = Aman::factory()->masking('kantor'); + $this->assertStringContainsString($check, 'kantor'); + } + + public function testMaskEqualsEmptyMixed() + { + $check = Aman::factory()->masking('kantor dan kontol'); + $this->assertStringContainsString($check, 'kantor dan ******'); + } +}