Completed
Push — master ( 0b92a4...d3ac05 )
by Ehsan
04:17
created

CommandExtractor::getConfig()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2.0625

Importance

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