Passed
Push — master ( 531e59...fe1053 )
by Ehsan
02:58
created

CommandExtractor::countKeywordOccurrence()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 32
Code Lines 17

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 5.0406

Importance

Changes 0
Metric Value
dl 0
loc 32
ccs 15
cts 17
cp 0.8824
rs 8.439
c 0
b 0
f 0
cc 5
eloc 17
nc 5
nop 1
crap 5.0406
1
<?php
2
3
namespace Botonomous;
4
5
use Botonomous\utility\MessageUtility;
6
use NlpTools\Stemmers\PorterStemmer;
7
use NlpTools\Tokenizers\WhitespaceTokenizer;
8
9
/**
10
 * Class CommandExtractor.
11
 */
12
class CommandExtractor
13
{
14
    private $config;
15
    private $error;
16
    private $messageUtility;
17
    private $dictionary;
18
    private $commandContainer;
19
20
    /**
21
     * @param null $message
22
     *
23
     * @return Command|void
24
     */
25 7
    public function getCommandByMessage($message)
26
    {
27 7
        if (empty($message)) {
28 1
            $this->setError('Message is empty');
29
30 1
            return;
31
        }
32
33
        /*
34
         * Process the message and find explicitly specified command
35
         */
36 6
        $foundCommand = $this->getCommandObjectByMessage($message);
37
38 6
        return $foundCommand;
39
    }
40
41 1
    public function countKeywordOccurrence($message)
42
    {
43 1
        $stemmer = new PorterStemmer();
44
45
        // tokenize $message
46 1
        $stemmedMessage = implode(' ', $stemmer->stemAll((new WhitespaceTokenizer())->tokenize($message)));
47
48 1
        $keywordCount = [];
49 1
        foreach ($this->getCommandContainer()->getAllAsObject() as $commandKey => $commandObject) {
50 1
            $keywords = $commandObject->getKeywords();
51
52 1
            if (empty($keywords)) {
53 1
                continue;
54
            }
55
56 1
            $keywordsPositions = $this->getMessageUtility()->keywordPos($stemmer->stemAll($keywords), $stemmedMessage);
57
58 1
            $total = 0;
59 1
            if (empty($keywordsPositions)) {
60
                $keywordCount[$commandKey] = $total;
61
                continue;
62
            }
63
64 1
            foreach ($keywordsPositions as $keywordPositions) {
65 1
                $total += count($keywordPositions);
66
            }
67
68 1
            $keywordCount[$commandKey] = $total;
69
        }
70
71 1
        return $keywordCount;
72
    }
73
74
    /**
75
     * @param $message
76
     *
77
     * @return Command|void
78
     */
79 6
    private function getCommandObjectByMessage($message)
80
    {
81 6
        $command = $this->getMessageUtility()->extractCommandName($message);
82
83
        // check command name
84 6
        if (empty($command)) {
85
            // get the default command if no command is find in the message
86 2
            $command = $this->getConfig()->get('defaultCommand');
87
88 2
            if (empty($command)) {
89 2
                $this->setError($this->getDictionary()->get('generic-messages')['noCommandMessage']);
90
91 2
                return;
92
            }
93
        }
94
95 4
        return $this->getCommandObjectByCommand($command);
96
    }
97
98
    /**
99
     * @param $command
100
     *
101
     * @return Command|void
102
     */
103 4
    private function getCommandObjectByCommand($command)
104
    {
105 4
        $commandObject = $this->getCommandContainer()->getAsObject($command);
106
107 4
        if ($this->validateCommandObject($commandObject) !== true) {
108 1
            return;
109
        }
110
111 4
        return $commandObject;
112
    }
113
114
    /**
115
     * Validate the command object.
116
     *
117
     * @param Command|null $commandObject
118
     *
119
     * @return bool
120
     */
121 4
    private function validateCommandObject($commandObject)
122
    {
123
        // check command details
124 4
        if (empty($commandObject)) {
125 1
            $this->setError(
126 1
                $this->getDictionary()->getValueByKey('generic-messages', 'unknownCommandMessage')
127
            );
128
129 1
            return false;
130
        }
131
132 4
        return true;
133
    }
134
135
    /**
136
     * @return string
137
     */
138 4
    public function getError()
139
    {
140 4
        return $this->error;
141
    }
142
143
    /**
144
     * @param string $error
145
     */
146 4
    public function setError($error)
147
    {
148 4
        $this->error = $error;
149 4
    }
150
151
    /**
152
     * @return Config
153
     */
154 3
    public function getConfig()
155
    {
156 3
        if ($this->config === null) {
157 2
            $this->config = (new Config());
158
        }
159
160 3
        return $this->config;
161
    }
162
163
    /**
164
     * @param Config $config
165
     */
166 1
    public function setConfig(Config $config)
167
    {
168 1
        $this->config = $config;
169 1
    }
170
171
    /**
172
     * @return MessageUtility
173
     */
174 7
    public function getMessageUtility()
175
    {
176 7
        if (!isset($this->messageUtility)) {
177 7
            $this->setMessageUtility(new MessageUtility());
178
        }
179
180 7
        return $this->messageUtility;
181
    }
182
183
    /**
184
     * @param MessageUtility $messageUtility
185
     */
186 7
    public function setMessageUtility(MessageUtility $messageUtility)
187
    {
188 7
        $this->messageUtility = $messageUtility;
189 7
    }
190
191
    /**
192
     * @return Dictionary
193
     */
194 3
    public function getDictionary()
195
    {
196 3
        if (!isset($this->dictionary)) {
197 3
            $this->setDictionary(new Dictionary());
198
        }
199
200 3
        return $this->dictionary;
201
    }
202
203
    /**
204
     * @param Dictionary $dictionary
205
     */
206 3
    public function setDictionary(Dictionary $dictionary)
207
    {
208 3
        $this->dictionary = $dictionary;
209 3
    }
210
211
    /**
212
     * @return CommandContainer
213
     */
214 5
    public function getCommandContainer()
215
    {
216 5
        if (!isset($this->commandContainer)) {
217 4
            $this->setCommandContainer(new CommandContainer());
218
        }
219
220 5
        return $this->commandContainer;
221
    }
222
223
    /**
224
     * @param CommandContainer $commandContainer
225
     */
226 5
    public function setCommandContainer(CommandContainer $commandContainer)
227
    {
228 5
        $this->commandContainer = $commandContainer;
229 5
    }
230
}
231