Skip to content

Commit cc792ec

Browse files
committed
Refactor spam detection
1 parent 2f55ad3 commit cc792ec

14 files changed

+323
-185
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace Lio\Content;
3+
4+
class ForeignLanguageSpamDetector implements SpamDetector
5+
{
6+
/** @inheritdoc */
7+
public function detectsSpam($value)
8+
{
9+
return (bool) preg_match("/[일안명빠】]+/iu", $value);
10+
}
11+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace Lio\Content;
3+
4+
class PhoneNumberSpamDetector implements SpamDetector
5+
{
6+
/** @inheritdoc */
7+
public function detectsSpam($value)
8+
{
9+
return (bool) preg_match('/\+(?:\d{1,2})?[\s-+]*?(?:\d{10,})/', $value);
10+
}
11+
}

app/Lio/Content/SpamDetector.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
namespace Lio\Content;
3+
4+
interface SpamDetector
5+
{
6+
/**
7+
* @param mixed $value
8+
* @return bool
9+
*/
10+
public function detectsSpam($value);
11+
}

app/Lio/Content/SpamFilter.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
namespace Lio\Content;
3+
4+
class SpamFilter implements SpamDetector
5+
{
6+
/**
7+
* @var \Lio\Content\SpamDetector[]
8+
*/
9+
private $detectors;
10+
11+
/**
12+
* @param \Lio\Content\SpamDetector[] $detectors
13+
*/
14+
public function __construct(array $detectors)
15+
{
16+
$this->detectors = $detectors;
17+
}
18+
19+
/** @inheritdoc */
20+
public function detectsSpam($value)
21+
{
22+
foreach ($this->detectors as $detector) {
23+
if ($detector->detectsSpam($value)) {
24+
return true;
25+
}
26+
}
27+
28+
return false;
29+
}
30+
}

app/Lio/Forum/Threads/ThreadCreator.php

Lines changed: 8 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
use Illuminate\Support\MessageBag;
44
use Lio\Accounts\User;
5-
use Lio\Validators\DoesNotContainPhoneNumbers;
5+
use Lio\Content\SpamDetector;
66

77
/**
88
* This class can call the following methods on the listener object:
@@ -18,18 +18,18 @@ class ThreadCreator
1818
protected $threads;
1919

2020
/**
21-
* @var \Lio\Validators\DoesNotContainPhoneNumbers
21+
* @var \Lio\Content\SpamDetector
2222
*/
23-
protected $phoneNumbers;
23+
private $spamDetector;
2424

2525
/**
2626
* @param \Lio\Forum\Threads\ThreadRepository $threads
27-
* @param \Lio\Validators\DoesNotContainPhoneNumbers $phoneNumbers
27+
* @param \Lio\Content\SpamDetector $spamDetector
2828
*/
29-
public function __construct(ThreadRepository $threads, DoesNotContainPhoneNumbers $phoneNumbers)
29+
public function __construct(ThreadRepository $threads, SpamDetector $spamDetector)
3030
{
3131
$this->threads = $threads;
32-
$this->phoneNumbers = $phoneNumbers;
32+
$this->spamDetector = $spamDetector;
3333
}
3434

3535
// an additional validator is optional and will be run first, an example of a usage for
@@ -58,15 +58,15 @@ private function getNew($data)
5858

5959
private function validateAndSave($thread, $listener, $data)
6060
{
61-
if ($this->containsSpam($thread->subject)) {
61+
if ($this->spamDetector->detectsSpam($thread->subject)) {
6262
$this->increaseUserSpamCount($thread->author);
6363

6464
return $listener->threadCreationError(
6565
new MessageBag(['subject' => 'Title contains spam. Your account has been flagged.'])
6666
);
6767
}
6868

69-
if ($this->containsSpam($thread->body)) {
69+
if ($this->spamDetector->detectsSpam($thread->body)) {
7070
$this->increaseUserSpamCount($thread->author);
7171

7272
return $listener->threadCreationError(
@@ -87,31 +87,6 @@ private function validateAndSave($thread, $listener, $data)
8787
return $listener->threadCreated($thread);
8888
}
8989

90-
/**
91-
* Determines if one or more subject contain spam
92-
*
93-
* @param string|array $subject
94-
* @return bool
95-
*/
96-
private function containsSpam($subject)
97-
{
98-
if ($this->containsKoreanOrChinese($subject)) {
99-
return true;
100-
}
101-
102-
// If the validator detects phone numbers, return false.
103-
return ! $this->phoneNumbers->validate($subject);
104-
}
105-
106-
/**
107-
* @param string $subject
108-
* @return bool
109-
*/
110-
private function containsKoreanOrChinese($subject)
111-
{
112-
return (bool) preg_match("/[\p{Hangul}|\p{Han}]+/u", $subject);
113-
}
114-
11590
/**
11691
* Increases a user's spam count
11792
*
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php namespace Lio\ServiceProviders;
2+
3+
use Illuminate\Support\ServiceProvider;
4+
use Lio\Content\ForeignLanguageSpamDetector;
5+
use Lio\Content\PhoneNumberSpamDetector;
6+
use Lio\Content\SpamFilter;
7+
8+
class ContentServiceProvider extends ServiceProvider
9+
{
10+
public function register()
11+
{
12+
$this->app->bindShared('Lio\Content\SpamDetector', function () {
13+
return new SpamFilter([
14+
new PhoneNumberSpamDetector,
15+
new ForeignLanguageSpamDetector,
16+
]);
17+
});
18+
}
19+
20+
public function provides()
21+
{
22+
return ['Lio\Content\SpamDetector'];
23+
}
24+
}

app/Lio/Validators/DoesNotContainPhoneNumbers.php

Lines changed: 0 additions & 16 deletions
This file was deleted.

app/config/app.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@
119119
'Lio\ServiceProviders\BackupServiceProvider',
120120
'Lio\ServiceProviders\GithubServiceProvider',
121121
'Lio\ServiceProviders\CommentServiceProvider',
122+
'Lio\ServiceProviders\ContentServiceProvider',
122123
'Lio\ServiceProviders\MarkdownServiceProvider',
123124
'Lio\ServiceProviders\HashidsServiceProvider',
124125
],
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
namespace spec\Lio\Content;
3+
4+
use PhpSpec\ObjectBehavior;
5+
use Prophecy\Argument;
6+
7+
class ForeignLanguageSpamDetectorSpec extends ObjectBehavior
8+
{
9+
private $foreignLanguage = <<<TEXT
10+
【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™【빠나나9넷】≪ВВanana9.NЕT≫일산오피⇔안산오피[광명오피]수원오피™
11+
TEXT;
12+
13+
private $validText = 'This piece of text should pass.
14+
15+
<?php namespace App\\Http\\Requests;
16+
17+
class ModifyContinentRequest extends Request {
18+
19+
public function authorize()
20+
{
21+
return true;
22+
}
23+
24+
public function rules()
25+
{
26+
$id = $this->segment(2);
27+
28+
return [
29+
\'name\' => \'required|unique:continents,name,\' . $id ,
30+
];
31+
}
32+
}';
33+
34+
function it_is_initializable()
35+
{
36+
$this->shouldHaveType('Lio\Content\ForeignLanguageSpamDetector');
37+
$this->shouldHaveType('Lio\Content\SpamDetector');
38+
}
39+
40+
function it_can_detect_foreign_language_as_spam()
41+
{
42+
$this->detectsSpam($this->foreignLanguage)->shouldReturn(true);
43+
}
44+
45+
function it_passes_when_valid_text_was_entered()
46+
{
47+
$this->detectsSpam($this->validText)->shouldReturn(false);
48+
}
49+
}
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
<?php
2+
namespace spec\Lio\Content;
3+
4+
use PhpSpec\ObjectBehavior;
5+
use Prophecy\Argument;
6+
7+
class PhoneNumberSpamDetectorSpec extends ObjectBehavior
8+
{
9+
private $textWithPhoneNumbers = <<<TEXT
10+
+91-8872522276 WORLD FAMOUS ASTROLOGER}...NAGESHEWAR BABA JI [DIAMOND
11+
GOLD MEDLIST]....[+91-8872522276] Make one call and change your life
12+
with in 21 hours call soon get solve your all problems with in 21 hours
13+
that is 101% guaranteed We Provides Highly Effective Solutions For All
14+
Problems Like
15+
To Get Your Lost Love Back
16+
To Attract Any Girl/Boy Towards You With Heart
17+
To Make Agree 15+935=108Your Or Your Partner s Parents To Love Marriage
18+
To Solve The Problems In Any Relationship
19+
To Control The Mi1nd Of Husband/Wife Or A Desired Person
20+
To Improve Professional And Personal Relationships With Others
21+
To Wealth And Peace In Home
22+
To Kundli And Match Making
23+
To Manglik Dosh Niwaran
24+
To Tell Your15 + 935 = 108 Future
25+
To Control Of Others By Hypnotism
26+
To Dosh Nivarana Like Manglik Dosh, Kalasarp Yoga
27+
To Hawan/ Anusthan Etc.
28+
To Get Your Lost Love Back By Vashikaran
29+
To Get Your Lost Love Back By Black Magic
30+
To Get High+919799138999 Income From Business
31+
To Create A Good Impression On Others
32+
To Create Love And Affection In Other s Heart And Mind
33+
To Get Anything From True Astrology
34+
To Get Your Ex Back By Hypnotism
35+
To Get Your Lost Love
36+
LOVE 91+7742228242 AFFARIS
37+
HEART PIECE
38+
BLACK MAGIC
39+
40+
41+
919799138999
42+
91 9799138999
43+
91 - 9799138999
44+
91 979 913 8999
45+
91-979-913-8999
46+
91+979+913+8999
47+
48+
+919799138999
49+
+91 9799138999
50+
+91 - 9799138999
51+
+91 979 913 8999
52+
+91-979-913-8999
53+
+91+979+913+8999
54+
+93
55+
15+77=21
56+
57+
LOVE BACK +91 (3) 42228242
58+
INTERCAST MARRIAGE
59+
LOVE MARRIGES
60+
CHILDREN NOT IN +91+7742228242FAVOUR ETC.
61+
To Win Favors From Others
62+
Get
63+
Your Love Back By Vashikaran, Black Magic, Hypnotism, Get Your Love
64+
Back By Vashikaran, Get Your Love Back By Vashikaran, Get Your Love Back
65+
By Vashikaran, Help +91 - 8872522276 Me To Get My Love Back By Vashikaran, Kala Jadu,
66+
Tantra Mantra, Tankarik Baba, Indian Astrologer
67+
Just Give A Call & Get Your Love Back one call and change your life +91-8872522276 nageshewarbaba.blogspot.com email id nageshewarbaba@yahoo.com
68+
TEXT;
69+
70+
private $textWithoutPhoneNumbers = <<<TEXT
71+
WORLD FAMOUS ASTROLOGER}...NAGESHEWAR BABA JI [DIAMOND
72+
GOLD MEDLIST]....[] Make one call and change your life
73+
with in 21 hours call soon get solve your all problems with in 21 hours
74+
that is 101% guaranteed We Provides Highly Effective Solutions For All
75+
Problems Like
76+
To Get Your Lost Love Back
77+
To Attract Any Girl/Boy Towards You With Heart
78+
To Make Agree 15+935=108Your Or Your Partner s Parents To Love Marriage
79+
To Solve The Problems In Any Relationship
80+
To Control The Mi1nd Of Husband/Wife Or A Desired Person
81+
To Improve Professional And Personal Relationships With Others
82+
To Wealth And Peace In Home
83+
To Kundli And Match Making
84+
To Manglik Dosh Niwaran
85+
To Tell Your15 + 935 = 108 Future
86+
To Control Of Others By Hypnotism
87+
To Dosh Nivarana Like Manglik Dosh, Kalasarp Yoga
88+
To Hawan/ Anusthan Etc.
89+
To Get Your Lost Love Back By Vashikaran
90+
To Get Your Lost Love Back By Black Magic
91+
To Get High Income From Business
92+
To Create A Good Impression On Others
93+
To Create Love And Affection In Other s Heart And Mind
94+
To Get Anything From True Astrology
95+
To Get Your Ex Back By Hypnotism
96+
To Get Your Lost Love
97+
LOVE AFFARIS
98+
HEART PIECE
99+
BLACK MAGIC
100+
101+
102+
919799138999
103+
91 9799138999
104+
91 - 9799138999
105+
91 979 913 8999
106+
91-979-913-8999
107+
91+979+913+8999
108+
109+
+91 979 913 8999
110+
+91-979-913-8999
111+
+91+979+913+8999
112+
+93
113+
15+77=21
114+
115+
LOVE BACK +91 (3) 42228242
116+
INTERCAST MARRIAGE
117+
LOVE MARRIGES
118+
CHILDREN NOT IN ETC.
119+
To Win Favors From Others
120+
Get
121+
Your Love Back By Vashikaran, Black Magic, Hypnotism, Get Your Love
122+
Back By Vashikaran, Get Your Love Back By Vashikaran, Get Your Love Back
123+
By Vashikaran, Help Me To Get My Love Back By Vashikaran, Kala Jadu,
124+
Tantra Mantra, Tankarik Baba, Indian Astrologer
125+
Just Give A Call & Get Your Love Back one call and change your life nageshewarbaba.blogspot.com email id nageshewarbaba@yahoo.com
126+
TEXT;
127+
128+
function it_is_initializable()
129+
{
130+
$this->shouldHaveType('Lio\Content\PhoneNumberSpamDetector');
131+
$this->shouldHaveType('Lio\Content\SpamDetector');
132+
}
133+
134+
function it_can_detect_phone_number_spam()
135+
{
136+
$this->detectsSpam($this->textWithPhoneNumbers)->shouldReturn(true);
137+
}
138+
139+
function it_passes_when_no_phone_numbers_are_detected()
140+
{
141+
$this->detectsSpam($this->textWithoutPhoneNumbers)->shouldReturn(false);
142+
}
143+
}

0 commit comments

Comments
 (0)