Skip to content
This repository was archived by the owner on Mar 12, 2020. It is now read-only.

Commit d6e4071

Browse files
committed
Add the capability for filters to "ignore" events
If a filter returns NULL, it indicates that it wishes to ignore (pass-through) the event passed. In terms of boolean filter logic: * allow AND ignore == allow * allow OR ignore == allow * ignore AND ignore == ignore * ignore OR ignore == ignore * reject AND ignore == reject * reject OR ignore == reject * NOT ignore == ignore Built-in filters that now return NULL for specific events: * ChannelFilter: event is not a UserEvent * ChannelFilter: event is not a channel event * UserFilter: event is not a UserEvent * UserFilter: event did not originate from a user * UserModeFilter: event is not a UserEvent * UserModeFilter: event is not a channel event * UserModeFilter: event did not originate from a user
1 parent 4e0feb2 commit d6e4071

16 files changed

Lines changed: 114 additions & 40 deletions

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,10 @@ Filters are merely classes that implement
257257
[`FilterInterface`](https://github.com/phergie/phergie-irc-plugin-react-eventfilter/blob/master/src/FilterInterface.php).
258258
This interface has a single method, `filter()`, which accepts an event object
259259
that implements [`EventInterface`](https://github.com/phergie/phergie-irc-event/blob/master/src/EventInterface.php)
260-
as its only parameter and returns `true` if the event should be allowed or
261-
`false` if it should not.
260+
as its only parameter and returns one of the following values:
261+
* `true` if the event should be allowed
262+
* `false` if the event should be denied
263+
* `null` if the event should be ignored by the filter ("pass-through")
262264

263265
## Tests
264266

src/AndFilter.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,21 @@ class AndFilter extends CompositeFilter
2424
* Filters events that pass all contained filters.
2525
*
2626
* @param \Phergie\Irc\Event\EventInterface $event
27-
* @return boolean TRUE if the event passes all contained filters, FALSE
28-
* otherwise
27+
* @return boolean|null TRUE if the event passes all contained filters, FALSE
28+
* if it fails any filter, or NULL if all filters return NULL.
2929
*/
3030
public function filter(EventInterface $event)
3131
{
32+
$output = null;
3233
foreach ($this->filters as $filter) {
33-
if (!$filter->filter($event)) {
34+
$result = $filter->filter($event);
35+
if ($result === false) {
3436
return false;
3537
}
38+
if ($result === true) {
39+
$output = true;
40+
}
3641
}
37-
return true;
42+
return $output;
3843
}
3944
}

src/ChannelFilter.php

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,17 +88,21 @@ function($value) {
8888
* channels.
8989
*
9090
* @param \Phergie\Irc\Event\EventInterface $event
91-
* @return boolean TRUE if the event is not channel-specific or originated
92-
* from a matching channel associated with this filter, FALSE
93-
* otherwise
91+
* @return boolean|null TRUE if the event originated from a matching channel
92+
* associated with this filter, FALSE if it originated from a non-matching
93+
* channel, or NULL if it is not associated with a channel.
9494
*/
9595
public function filter(EventInterface $event)
9696
{
9797
if (!$event instanceof UserEventInterface) {
98-
return true;
98+
return null;
9999
}
100100

101101
$channels = $this->getChannels($event);
102+
if (empty($channels)) {
103+
return null;
104+
}
105+
102106
$commonChannels = array_intersect($channels, $this->channels);
103107
if ($commonChannels) {
104108
return true;

src/FilterInterface.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@ interface FilterInterface
2424
* Evaluates an event for forwarding.
2525
*
2626
* @param \Phergie\Irc\Event\EventInterface $event
27-
* @return boolean TRUE if the event should be forwarded, FALSE otherwise
27+
* @return boolean|null TRUE if the event should be allowed, FALSE if it should be rejected,
28+
* or NULL if it should be ignored (ie. the event does not fall under the scope of
29+
* this filter)
2830
*/
2931
public function filter(EventInterface $event);
3032
}

src/NotFilter.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,15 @@ public function __construct(FilterInterface $filter)
4141
* Filters events that do not pass the contained filter.
4242
*
4343
* @param \Phergie\Irc\Event\EventInterface $event
44-
* @return boolean TRUE if the contained filter fails, FALSE if it passes
44+
* @return boolean|null TRUE if the contained filter fails, FALSE if it passes,
45+
* or NULL if it returns NULL.
4546
*/
4647
public function filter(EventInterface $event)
4748
{
48-
return !$this->filter->filter($event);
49+
$result = $this->filter->filter($event);
50+
if ($result === null) {
51+
return null;
52+
}
53+
return !$result;
4954
}
5055
}

src/OrFilter.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,21 @@ class OrFilter extends CompositeFilter
2424
* Filters events that pass any contained filters.
2525
*
2626
* @param \Phergie\Irc\Event\EventInterface $event
27-
* @return boolean TRUE if the event passes any contained filters, FALSE
28-
* otherwise
27+
* @return boolean|null TRUE if the event passes any contained filters, FALSE
28+
* if it fails all filters, or NULL if all filters return NULL.
2929
*/
3030
public function filter(EventInterface $event)
3131
{
32+
$output = null;
3233
foreach ($this->filters as $filter) {
33-
if ($filter->filter($event)) {
34+
$result = $filter->filter($event);
35+
if ($result === true) {
3436
return true;
3537
}
38+
if ($result === false) {
39+
$output = false;
40+
}
3641
}
37-
return false;
42+
return $output;
3843
}
3944
}

src/Plugin.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function handleEvent($event, array $args)
165165
));
166166
} else {
167167
$eventObject = reset($eventObjects);
168-
if (!$this->filter->filter($eventObject)) {
168+
if ($this->filter->filter($eventObject) === false) {
169169
$logger->info('Event did not pass filter, skipping', array(
170170
'event' => $event,
171171
'args' => $args,

src/UserFilter.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,18 +45,23 @@ public function __construct(array $masks)
4545
* Filters events that are not user-specific or are from the specified users.
4646
*
4747
* @param \Phergie\Irc\Event\EventInterface $event
48-
* @return boolean TRUE if the event is not user-specific or originated
49-
* from a user with a matching mask associated with this filter,
50-
* FALSE otherwise
48+
* @return boolean|null TRUE if the event originated from a user with a matching mask
49+
* associated with this filter, FALSE if it originated from a user without a
50+
* matching mask, or NULL if it did not originate from a user.
5151
*/
5252
public function filter(EventInterface $event)
5353
{
5454
if (!$event instanceof UserEventInterface) {
55-
return true;
55+
return null;
56+
}
57+
58+
$nick = $event->getNick();
59+
if ($nick === null) {
60+
return null;
5661
}
5762

5863
$userMask = sprintf('%s!%s@%s',
59-
$event->getNick(),
64+
$nick,
6065
$event->getUsername(),
6166
$event->getHost()
6267
);

src/UserModeFilter.php

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,23 @@ public function __construct(UserModePlugin $userMode, array $modes)
5757
* specified modes.
5858
*
5959
* @param \Phergie\Irc\Event\EventInterface $event
60-
* @return boolean TRUE if the event is not user-specific or originated
61-
* from a user with a matching mode associated with this filter,
62-
* FALSE otherwise
60+
* @return boolean|null TRUE if the event originated from a user with a matching mode
61+
* associated with this filter, FALSE if the event originated from a user
62+
* without a matching mode, or NULL if the event did not originate from a user.
6363
*/
6464
public function filter(EventInterface $event)
6565
{
6666
if (!$event instanceof UserEventInterface) {
67-
return true;
67+
return null;
6868
}
6969

70-
$connection = $event->getConnection();
7170
$channels = $this->getChannels($event);
7271
$nick = $event->getNick();
72+
if (empty($channels) || $nick === null) {
73+
return null;
74+
}
75+
76+
$connection = $event->getConnection();
7377

7478
foreach ($channels as $channel) {
7579
$userModes = $this->userMode->getUserModes($connection, $channel, $nick);

tests/AndFilterTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ public function dataProviderFilter()
3535
array(true, false, false),
3636
array(false, true, false),
3737
array(true, true, true),
38+
array(true, null, true),
39+
array(false, null, false),
40+
array(null, null, null),
3841
);
3942

4043
foreach ($returns as $return) {

0 commit comments

Comments
 (0)