Completed
Push — master ( a7a6f1...c2ad89 )
by Ehsan
02:45
created

CommandExtractor::countKeywordOccurrence()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 22
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 22
ccs 12
cts 12
cp 1
rs 9.2
c 0
b 0
f 0
cc 3
eloc 12
nc 3
nop 1
crap 3
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
    /**
42
     * @param $message
43
     *
44
     * @return array
45
     */
46 1
    public function countKeywordOccurrence($message)
47
    {
48 1
        $stemmer = new PorterStemmer();
49
50
        // tokenize $message
51 1
        $stemmedMessage = implode(' ', $stemmer->stemAll((new WhitespaceTokenizer())->tokenize($message)));
52
53 1
        $count = [];
54 1
        foreach ($this->getCommandContainer()->getAllAsObject() as $commandKey => $commandObject) {
55 1
            $keywordsCount = $this->commandKeywordOccurrence($commandObject, $stemmedMessage);
56
57 1
            $total = 0;
58 1
            if (empty($keywordsCount)) {
59 1
                $count[$commandKey] = $total;
60 1
                continue;
61
            }
62
63 1
            $count[$commandKey] = array_sum($keywordsCount);
64
        }
65
66 1
        return $count;
67
    }
68
69
    /**
70
     * @param Command $command
71
     * @param         $message
72
     *
73
     * @return array|void
74
     */
75 1
    private function commandKeywordOccurrence(Command $command, $message)
76
    {
77 1
        $stemmer = new PorterStemmer();
78 1
        $keywords = $command->getKeywords();
79 1
        if (empty($keywords)) {
80 1
            return;
81
        }
82
83 1
        return $this->getMessageUtility()->keywordCount(
84 1
            $stemmer->stemAll($keywords),
85
            $message
86
        );
87
    }
88
89
    /**
90
     * @param $message
91
     *
92
     * @return Command|void
93
     */
94 6
    private function getCommandObjectByMessage($message)
95
    {
96 6
        $command = $this->getMessageUtility()->extractCommandName($message);
97
98
        // check command name
99 6
        if (empty($command)) {
100
            // get the default command if no command is find in the message
101 2
            $command = $this->getConfig()->get('defaultCommand');
102
103 2
            if (empty($command)) {
104 2
                $this->setError($this->getDictionary()->get('generic-messages')['noCommandMessage']);
105
106 2
                return;
107
            }
108
        }
109
110 4
        return $this->getCommandObjectByCommand($command);
111
    }
112
113
    /**
114
     * @param $command
115
     *
116
     * @return Command|void
117
     */
118 4
    private function getCommandObjectByCommand($command)
119
    {
120 4
        $commandObject = $this->getCommandContainer()->getAsObject($command);
121
122 4
        if ($this->validateCommandObject($commandObject) !== true) {
123 1
            return;
124
        }
125
126 4
        return $commandObject;
127
    }
128
129
    /**
130
     * Validate the command object.
131
     *
132
     * @param Command|null $commandObject
133
     *
134
     * @return bool
135
     */
136 4
    private function validateCommandObject($commandObject)
137
    {
138
        // check command details
139 4
        if (empty($commandObject)) {
140 1
            $this->setError(
141 1
                $this->getDictionary()->getValueByKey('generic-messages', 'unknownCommandMessage')
142
            );
143
144 1
            return false;
145
        }
146
147 4
        return true;
148
    }
149
150
    /**
151
     * @return string
152
     */
153 4
    public function getError()
154
    {
155 4
        return $this->error;
156
    }
157
158
    /**
159
     * @param string $error
160
     */
161 4
    public function setError($error)
162
    {
163 4
        $this->error = $error;
164 4
    }
165
166
    /**
167
     * @return Config
168
     */
169 3
    public function getConfig()
170
    {
171 3
        if ($this->config === null) {
172 2
            $this->config = (new Config());
173
        }
174
175 3
        return $this->config;
176
    }
177
178
    /**
179
     * @param Config $config
180
     */
181 1
    public function setConfig(Config $config)
182
    {
183 1
        $this->config = $config;
184 1
    }
185
186
    /**
187
     * @return MessageUtility
188
     */
189 7
    public function getMessageUtility()
190
    {
191 7
        if (!isset($this->messageUtility)) {
192 7
            $this->setMessageUtility(new MessageUtility());
193
        }
194
195 7
        return $this->messageUtility;
196
    }
197
198
    /**
199
     * @param MessageUtility $messageUtility
200
     */
201 7
    public function setMessageUtility(MessageUtility $messageUtility)
202
    {
203 7
        $this->messageUtility = $messageUtility;
204 7
    }
205
206
    /**
207
     * @return Dictionary
208
     */
209 3
    public function getDictionary()
210
    {
211 3
        if (!isset($this->dictionary)) {
212 3
            $this->setDictionary(new Dictionary());
213
        }
214
215 3
        return $this->dictionary;
216
    }
217
218
    /**
219
     * @param Dictionary $dictionary
220
     */
221 3
    public function setDictionary(Dictionary $dictionary)
222
    {
223 3
        $this->dictionary = $dictionary;
224 3
    }
225
226
    /**
227
     * @return CommandContainer
228
     */
229 5
    public function getCommandContainer()
230
    {
231 5
        if (!isset($this->commandContainer)) {
232 4
            $this->setCommandContainer(new CommandContainer());
233
        }
234
235 5
        return $this->commandContainer;
236
    }
237
238
    /**
239
     * @param CommandContainer $commandContainer
240
     */
241 5
    public function setCommandContainer(CommandContainer $commandContainer)
242
    {
243 5
        $this->commandContainer = $commandContainer;
244 5
    }
245
}
246