Passed
Push — master ( 18b067...61ba31 )
by Ehsan
02:47
created

MessageUtility::compareLength()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
crap 1
1
<?php
2
3
namespace Botonomous\utility;
4
5
use Botonomous\CommandContainer;
6
7
/**
8
 * Class MessageUtility.
9
 */
10
class MessageUtility extends AbstractUtility
11
{
12
    /**
13
     * Remove the mentioned bot username from the message.
14
     *
15
     * @param $message
16
     *
17
     * @throws \Exception
18
     *
19
     * @return string
20
     */
21 9
    public function removeMentionedBot($message)
22
    {
23 9
        $userLink = $this->getUserLink();
24
25 9
        return preg_replace("/{$userLink}/", '', $message, 1);
26
    }
27
28
    /**
29
     * Check if the bot user id is mentioned in the message.
30
     *
31
     * @param $message
32
     *
33
     * @throws \Exception
34
     *
35
     * @return bool
36
     */
37 2
    public function isBotMentioned($message)
38
    {
39 2
        $userLink = $this->getUserLink();
40
41 2
        return (new StringUtility())->findInString($userLink, $message, false);
42
    }
43
44
    /**
45
     * Return command name in the message.
46
     *
47
     * @param $message
48
     *
49
     * @return null|string
50
     */
51 8
    public function extractCommandName($message)
52
    {
53
        // remove the bot mention if it exists
54 8
        $message = $this->removeMentionedBot($message);
55
56
        /**
57
         * Command must start with / and at the beginning of the sentence.
58
         */
59 8
        $commandPrefix = $this->getConfig()->get('commandPrefix');
60 8
        $commandPrefix = preg_quote($commandPrefix, '/');
61
62 8
        $pattern = '/^('.$commandPrefix.'\w{1,})/';
63
64 8
        preg_match($pattern, ltrim($message), $groups);
65
66
        // If command is found, remove command prefix from the beginning of the command
67 8
        return isset($groups[1]) ? ltrim($groups[1], $commandPrefix) : null;
68
    }
69
70
    /**
71
     * Return command details in the message.
72
     *
73
     * @param $message
74
     *
75
     * @return \Botonomous\Command|null
76
     */
77 1
    public function extractCommandDetails($message)
78
    {
79
        // first get the command name
80 1
        $command = $this->extractCommandName($message);
81
82
        // then get the command details
83 1
        return (new CommandContainer())->getAsObject($command);
84
    }
85
86
    /**
87
     * @param $triggerWord
88
     * @param $message
89
     *
90
     * @return string
91
     */
92 4
    public function removeTriggerWord($message, $triggerWord)
93
    {
94 4
        $count = 1;
95
96 4
        return ltrim(str_replace($triggerWord, '', $message, $count));
97
    }
98
99
    /**
100
     * @param        $userId
101
     * @param string $userName
102
     *
103
     * @throws \Exception
104
     *
105
     * @return string
106
     */
107 12
    public function linkToUser($userId, $userName = '')
108
    {
109 12
        if (empty($userId)) {
110 1
            throw new \Exception('User id is not provided');
111
        }
112
113 12
        if (!empty($userName)) {
114 1
            $userName = "|{$userName}";
115
        }
116
117 12
        return "<@{$userId}{$userName}>";
118
    }
119
120
    /**
121
     * @return string
122
     */
123 11
    private function getUserLink()
124
    {
125 11
        return $this->linkToUser($this->getConfig()->get('botUserId'));
126
    }
127
128 2
    public function keywordPos(array $keywords, $message)
129
    {
130 2
        $found = [];
131
132 2
        if (empty($keywords)) {
133
            return $found;
134
        }
135
136 2
        usort($keywords, [$this, 'compareLength']);
137
138 2
        foreach ($keywords as $keyword) {
139 2
            $result = preg_match_all("/\b{$keyword}\b/", $message, $matches, PREG_OFFSET_CAPTURE);
140
141 2
            if ($result && !empty($matches[0])) {
142 2
                foreach ($matches[0] as $match) {
143
                    // check if the keyword does not overlap with one of the already found
144 2
                    if ($this->isPositionTaken($found, $match[1]) === false) {
145 2
                        $found[$keyword][] = $match[1];
146
                    }
147
                }
148
            }
149
        }
150
151 2
        return $found;
152
    }
153
154 2
    private function compareLength($array1, $array2)
155
    {
156 2
        return strlen($array2) <=> strlen($array1);
157
    }
158
159 2
    private function isPositionTaken(array $tokensPositions, $newPosition)
160
    {
161 2
        if (empty($tokensPositions)) {
162 2
            return false;
163
        }
164
165 2
        foreach ($tokensPositions as $token => $positions) {
166 2
            $tokenLength = strlen($token);
167 2
            foreach ($positions as $position) {
168 2
                if ($newPosition >= $position && $newPosition < $position + $tokenLength) {
169 2
                    return true;
170
                }
171
            }
172
        }
173
174 2
        return false;
175
    }
176
}
177