Completed
Push — master ( 10de85...76baec )
by Kacper
03:21
created

BetterEmitter::emit()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 9
nc 5
nop 2
dl 0
loc 16
ccs 0
cts 8
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
/**
3
 * Nucleus - XMPP Library for PHP
4
 *
5
 * Copyright (C) 2016, Some rights reserved.
6
 *
7
 * @author Kacper "Kadet" Donat <[email protected]>
8
 *
9
 * Contact with author:
10
 * Xmpp: [email protected]
11
 * E-mail: [email protected]
12
 *
13
 * From Kadet with love.
14
 */
15
16
namespace Kadet\Xmpp\Utils;
17
18
use Kadet\Xmpp\Utils\filter as with;
19
use Evenement\EventEmitterTrait;
20
21
trait BetterEmitter
22
{
23
    /**
24
     * @var PriorityCollection[]
25
     */
26
    protected $listeners;
27
28
    use EventEmitterTrait;
29
30
    public function on($event, callable $listener, $condition = null, int $priority = 0)
31
    {
32
        return $this->addListener($event, $this->getConditionalCallable($listener, $condition), $priority);
33
    }
34
35
    public function once($event, callable $listener, $condition = null, int $priority = 0)
36
    {
37
        return $this->on($event, $this->getOnceCallable($this->getConditionalCallable($listener, $condition), $event), null, $priority);
38
    }
39
40
    public function removeListener($event, callable $listener)
41
    {
42
        if (!isset($this->listeners[$event])) {
43
            return false;
44
        }
45
46
        $this->listeners[$event]->remove($listener);
47
48
        return true;
49
    }
50
51
    public function emit($event, array $arguments = [])
52
    {
53
        foreach ($this->listeners($event) as $listener) {
54
            try {
55
                if ($listener(...$arguments) === false) {
56
                    return false;
57
                }
58
            } catch (\Throwable $exception) {
59
                if($this->emit('exception', [ $exception, $event ])) {
60
                    throw $exception;
61
                }
62
            }
63
        }
64
65
        return true;
66
    }
67
68
    public function reference(callable $callable, int $position = 0) : callable
69
    {
70
        return \Kadet\Xmpp\Utils\helper\partial($callable, $this, $position);
71
    }
72
73
    private function addListener($event, callable $listener, int $priority = 0)
74
    {
75
        if (!isset($this->listeners[$event])) {
76
            $this->listeners[$event] = new PriorityCollection();
77
        }
78
79
        $this->listeners[$event]->insert($listener, $priority);
80
81
        return $listener;
82
    }
83
84
    private function getConditionalCallable(callable $listener, $condition) : callable
85
    {
86
        if ($condition === null) {
87
            return $listener;
88
        }
89
90
        $condition = with\predicate($condition);
91
92
        return function (...$arguments) use ($listener, $condition) {
93
            if ($condition(...$arguments)) {
94
                return (bool)$listener(...$arguments);
95
            }
96
97
            return null;
98
        };
99
    }
100
101
    private function getOnceCallable(callable $listener, $event) : callable
102
    {
103
        return $onceListener = function (...$arguments) use (&$onceListener, $event, $listener) {
0 ignored issues
show
Unused Code introduced by
$onceListener is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
104
            if(($result = $listener(...$arguments)) !== null) {
105
                $this->removeListener($event, $onceListener);
106
                return $result;
107
            }
108
109
            return null;
110
        };
111
    }
112
}
113