Test Failed
Branch trunk (412648)
by SuperNova.WS
03:40
created

EventBus::subscribe()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 12
Code Lines 7

Duplication

Lines 6
Ratio 50 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 5
nop 2
dl 6
loc 12
rs 9.2
c 0
b 0
f 0
1
<?php
2
/**
3
 * Created by Gorlum 22.06.2017 16:50
4
 */
5
6
namespace Event;
7
8
use Common\GlobalContainer;
9
10
/**
11
 * Class EventBus
12
 * @package Event
13
 */
14
class EventBus {
15
16
  /**
17
   * @var IObserver[][] $subscriptions
18
   */
19
  protected $subscriptions;
20
21
  /**
22
   * @var GlobalContainer $gc
23
   */
24
  protected $gc;
25
26
  public function __construct(GlobalContainer $gc) {
27
    $this->gc = $gc;
28
  }
29
30
  /**
31
   * @param IObserver $observer
32
   * @param int       $eventId
33
   *
34
   * @return bool|mixed - false if observer not subscribed to event or observer subscription ID
35
   */
36
  public function haveSubscription(IObserver $observer, $eventId) {
37
    if (!is_array($this->subscriptions[$eventId])) {
38
      return false;
39
    }
40
41
    return array_search($observer, $this->subscriptions[$eventId]);
42
  }
43
44
  protected function unSubscribeFromOne(IObserver $observer, $eventId) {
45
    if (($foundKey = $this->haveSubscription($observer, $eventId)) !== false) {
46
      unset($this->subscriptions[$eventId][$foundKey]);
47
    }
48
  }
49
50
  /**
51
   * Unsubscribes observer from all events
52
   *
53
   * @param IObserver $observer
54
   */
55
  protected function unSubscribeFromAll(IObserver $observer) {
56
    foreach ($this->subscriptions as $eventId => $cork) {
57
      $this->unSubscribeFromOne($observer, $eventId);
58
    }
59
  }
60
61
62
  public function subscribe(IObserver $observer, $eventId = EVENT_ALL) {
63
    // In case of global subscription removing secondary subscriptions to avoid duplicate calls
64 View Code Duplication
    if ($eventId === EVENT_ALL) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65
      $this->unSubscribeFromAll($observer);
66
    } elseif ($this->haveSubscription($observer, $eventId) !== false) {
67
      // Observer already subscribed
68
      return;
69
    }
70
71
    !isset($this->subscriptions[$eventId]) ? $this->subscriptions[$eventId] = [] : false;
72
    $this->subscriptions[$eventId][] = $observer;
73
  }
74
75
  public function unSubscribe($observer, $eventId = EVENT_ALL) {
76 View Code Duplication
    if ($eventId === EVENT_ALL) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
77
      $this->unSubscribeFromAll($observer);
78
    } elseif ($this->haveSubscription($observer, $eventId) !== false) {
79
      $this->unSubscribeFromOne($observer, $eventId);
80
    }
81
  }
82
83
  public function dispatch(Event $event) {
84
    $subscriptions = empty($this->subscriptions[$event->getType()]) ? [] : $this->subscriptions[$event->getType()];
85
    $subscriptions = $this->mergeEventAllObservers($subscriptions);
86
87
    if (empty($subscriptions)) {
88
      return;
89
    }
90
91
    $methodName = STR_OBSERVER_ENTRY_METHOD_NAME;
92
    foreach ($subscriptions as $observer) {
93
      if (is_object($observer) && method_exists($observer, $methodName)) {
94
        $observer->$methodName($event);
95
      }
96
    }
97
98
  }
99
100
  /**
101
   * @param IObserver[] $typeSubscriptions
102
   *
103
   * @return IObserver[]
104
   */
105
  protected function mergeEventAllObservers($typeSubscriptions) {
106
    $eventAllObservers = empty($this->subscriptions[EVENT_ALL]) ? [] : $this->subscriptions[EVENT_ALL];
107
    foreach ($eventAllObservers as $object) {
108
      if (!array_search($object, $typeSubscriptions)) {
109
        $typeSubscriptions[] = $object;
110
      }
111
    }
112
113
    return $typeSubscriptions;
114
  }
115
116
}
117