Passed
Push — master ( 84e2aa...3af321 )
by Ehsan
03:02
created

MessageUtility::isPositionIn()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 2
cts 2
cp 1
rs 10
c 0
b 0
f 0
cc 2
eloc 2
nc 2
nop 3
crap 2
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
    /**
129
     * @param array $keywords
130
     * @param       $message
131
     *
132
     * @return array
133
     */
134 2
    public function keywordPos(array $keywords, $message)
135
    {
136 2
        $found = [];
137
138 2
        if (empty($keywords)) {
139
            return $found;
140
        }
141
142 2
        usort($keywords, function ($array1, $array2) {
143 2
            return strlen($array2) <=> strlen($array1);
144 2
        });
145
146 2
        foreach ($keywords as $keyword) {
147 2
            $result = preg_match_all("/\b{$keyword}\b/", $message, $matches, PREG_OFFSET_CAPTURE);
148
149 2
            if ($result && !empty($matches[0])) {
150 2
                foreach ($matches[0] as $match) {
151
                    // check if the keyword does not overlap with one of the already found
152 2
                    if ($this->isPositionTaken($found, $match[1]) === false) {
153 2
                        $found[$keyword][] = $match[1];
154
                    }
155
                }
156
            }
157
        }
158
159 2
        return $found;
160
    }
161
162
    /**
163
     * @param array $tokensPositions
164
     * @param       $newPosition
165
     *
166
     * @return bool
167
     */
168 2
    private function isPositionTaken(array $tokensPositions, $newPosition)
169
    {
170 2
        if (empty($tokensPositions)) {
171 2
            return false;
172
        }
173
174 2
        foreach ($tokensPositions as $token => $positions) {
175 2
            $tokenLength = strlen($token);
176 2
            foreach ($positions as $position) {
177 2
                if ($this->isPositionIn($newPosition, $position, $tokenLength) === true) {
178 2
                    return true;
179
                }
180
            }
181
        }
182
183 2
        return false;
184
    }
185
186
    /**
187
     * @param $newPosition
188
     * @param $position
189
     * @param $tokenLength
190
     *
191
     * @return bool
192
     */
193 2
    private function isPositionIn($newPosition, $position, $tokenLength)
194
    {
195 2
        return $newPosition >= $position && $newPosition < $position + $tokenLength;
196
    }
197
}
198