Passed
Push — develop ( c9c887...c18356 )
by Michele
53s queued 11s
created

ListenerResolver::resolveListeners()   C

Complexity

Conditions 13
Paths 35

Size

Total Lines 71
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 13
eloc 49
c 0
b 0
f 0
nc 35
nop 1
dl 0
loc 71
rs 6.6166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace Zanzara\Listener;
6
7
use React\Promise\Deferred;
8
use React\Promise\PromiseInterface;
9
use Zanzara\ConversationManager;
10
use Zanzara\Telegram\Type\CallbackQuery;
11
use Zanzara\Telegram\Type\Message;
12
use Zanzara\Telegram\Type\Update;
13
14
/**
15
 *
16
 */
17
abstract class ListenerResolver extends ListenerCollector
18
{
19
20
    /**
21
     * @var ConversationManager
22
     */
23
    protected $conversationManager;
24
25
    /**
26
     * @param Update $update
27
     * @return PromiseInterface
28
     */
29
    public function resolveListeners(Update $update): PromiseInterface
30
    {
31
        $deferred = new Deferred();
32
        $listeners = [];
33
        $updateType = $update->getUpdateType();
34
        $this->mergeListenersByType($listeners, $updateType);
35
        $this->mergeListenersByType($listeners, Update::class);
36
37
        switch ($updateType) {
38
39
            case CallbackQuery::class:
40
                $callbackQuery = $update->getCallbackQuery();
41
                $text = $callbackQuery->getMessage() ? $callbackQuery->getMessage()->getText() : null;
42
                if ($text) {
43
                    $this->findListenerAndPush($listeners, 'cb_query_texts', $text);
44
                }
45
                if ($callbackQuery->getData()) {
46
                    $this->findListenerAndPush($listeners, 'cb_query_data', $callbackQuery->getData());
47
                }
48
                $chatId = $update->getEffectiveChat() ? $update->getEffectiveChat()->getId() : null;
49
                if ($chatId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $chatId of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
50
                    $this->conversationManager->getConversationHandler($chatId)
51
                        ->then(function ($handler) use ($deferred, &$listeners) {
52
                            if ($handler) {
53
                                $listeners[] = new Listener($handler, $this->container);
54
                            }
55
                            $deferred->resolve($listeners);
56
                        });
57
                } else {
58
                    $deferred->resolve($listeners);
59
                }
60
                break;
61
62
            case Message::class:
63
                $text = $update->getMessage()->getText();
64
                if ($text) {
65
                    $chatId = $update->getEffectiveChat()->getId();
66
                    $this->conversationManager->getConversationHandler($chatId)
67
                        ->then(function ($handlerInfo) use ($chatId, $text, $deferred, &$listeners) {
68
                            if (!$handlerInfo) {
69
                                $this->findListenerAndPush($listeners, 'messages', $text);
70
                                $deferred->resolve($listeners);
71
                                return;
72
                            }
73
74
                            $skipListeners = $handlerInfo[1];
75
                            if ($skipListeners) {
76
                                $listeners[] = new Listener($handlerInfo[0], $this->container);
77
                            } else {
78
                                $listener = $this->findListenerAndPush($listeners, 'messages', $text);
79
                                if (!$listener) {
80
                                    $listeners[] = new Listener($handlerInfo[0], $this->container);
81
                                } else {
82
                                    $this->conversationManager->deleteConversationCache($chatId);
83
                                }
84
                            }
85
86
                            $deferred->resolve($listeners);
87
                        });
88
89
                } else {
90
                    $deferred->resolve($listeners);
91
                }
92
                break;
93
94
            default:
95
                $deferred->resolve($listeners);
96
97
        }
98
99
        return $deferred->promise();
100
    }
101
102
    /**
103
     * @param Listener[] $listeners
104
     * @param string $listenerType
105
     * @param string $listenerId
106
     * @return Listener|null
107
     */
108
    private function findListenerAndPush(array &$listeners, string $listenerType, string $listenerId): ?Listener
109
    {
110
        $typedListeners = $this->listeners[$listenerType] ?? [];
111
        foreach ($typedListeners as $regex => $listener) {
112
            if (preg_match($regex, $listenerId)) {
113
                $listeners[] = $listener;
114
                return $listener;
115
            }
116
        }
117
        return null;
118
    }
119
120
    /**
121
     * @param Listener[] $listeners
122
     * @param string $listenerType
123
     */
124
    private function mergeListenersByType(array &$listeners, string $listenerType)
125
    {
126
        $toMerge = $this->listeners[$listenerType] ?? null;
127
        if ($toMerge) {
128
            $listeners = array_merge($listeners, $toMerge);
129
        }
130
    }
131
132
}
133