Completed
Push — master ( daaf64...6e4339 )
by Dan
02:16
created

PluginManager::getPrefix()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
1
<?php
2
3
namespace Nopolabs\Yabot\Plugin;
4
5
6
use Exception;
7
use Nopolabs\Yabot\Helpers\LogTrait;
8
use Nopolabs\Yabot\Message\Message;
9
use Nopolabs\Yabot\Yabot;
10
use Psr\Log\LoggerInterface;
11
12
class PluginManager
13
{
14
    use LogTrait;
15
16
    const NO_PREFIX = '<none>';
17
    const AUTHED_USER_PREFIX = 'AUTHED_USER';
18
19
    /** @var array */
20
    private $plugins;
21
22
    /** @var array */
23
    private $prefixMap;
24
25
    public function __construct(LoggerInterface $logger)
26
    {
27
        $this->setLog($logger);
28
29
        $this->plugins = [];
30
        $this->prefixMap = [];
31
    }
32
33
    public function getPrefixMap() : array
34
    {
35
        return $this->prefixMap;
36
    }
37
38
    public function loadPlugin($pluginId, PluginInterface $plugin)
39
    {
40
        if (isset($this->plugins[$pluginId])) {
41
            $this->warning("$pluginId already loaded, ignoring duplicate.");
42
            return;
43
        }
44
45
        $this->addPlugin($pluginId, $plugin);
46
47
        $this->info('loaded', ['pluginId' => $pluginId, 'prefix' => $plugin->getPrefix()]);
48
    }
49
50
    public function getHelp() : array
51
    {
52
        $help = [];
53
        foreach ($this->getPrefixMap() as $prefix => $plugins) {
54
            /** @var PluginInterface $plugin */
55
            foreach ($plugins as $pluginId => $plugin) {
56
                $help[] = $pluginId;
57
                foreach (explode("\n", $plugin->help()) as $line) {
58
                    $prefix = ($prefix === self::NO_PREFIX) ? '' : $prefix;
59
                    $help[] = '    '.str_replace('<prefix>', $prefix, $line);
60
                }
61
            }
62
        }
63
64
        return $help;
65
    }
66
67
    public function getStatuses() : array
68
    {
69
        $count = count($this->plugins);
70
71
        $statuses = [];
72
        $statuses[] = "There are $count plugins loaded.";
73
        foreach (array_values($this->getPrefixMap()) as $plugins) {
74
            /** @var PluginInterface $plugin */
75
            foreach ($plugins as $pluginId => $plugin) {
76
                $statuses[] = "$pluginId ".$plugin->status();
77
            }
78
        }
79
80
        return $statuses;
81
    }
82
83
    public function dispatchMessage(Message $message)
84
    {
85
        $text = $message->getFormattedText();
86
87
        $this->info('dispatchMessage: ', ['formattedText' => $text]);
88
89
        foreach ($this->getPrefixMap() as $prefix => $plugins) {
90
91
            if (!($matches = $this->matchesPrefix($prefix, $text))) {
92
                continue;
93
            }
94
95
            $this->debug('Matched prefix', ['prefix' => $prefix]);
96
97
            $text = ltrim($matches[1]);
98
99
            $message->setPluginText($text);
100
101 View Code Duplication
            foreach ($plugins as $pluginId => $plugin) {
102
                /** @var PluginInterface $plugin */
103
                try {
104
                    $plugin->handle($message);
105
                } catch (Exception $e) {
106
                    $this->warning("Unhandled Exception in $pluginId: ".$e->getMessage());
107
                    $this->warning($e->getTraceAsString());
108
                }
109
110
                if ($message->isHandled()) {
111
                    return;
112
                }
113
            }
114
115
            if ($message->isHandled()) {
116
                return;
117
            }
118
        }
119
    }
120
121
    public function updatePrefixes($authedUsername)
122
    {
123
        $updated = [];
124
125
        foreach ($this->getPrefixMap() as $prefix => $plugins) {
126
            if ($prefix === self::AUTHED_USER_PREFIX) {
127
                $prefix = '@'.$authedUsername;
128
            }
129
130
            $updated[$prefix] = $plugins;
131
        }
132
133
        $this->prefixMap = $updated;
134
    }
135
136
    public function matchesPrefix($prefix, $text) : array
137
    {
138
        if ($prefix === self::NO_PREFIX) {
139
            return [$text, $text];
140
        }
141
142
        preg_match("/^$prefix\\s+(.*)/", $text, $matches);
143
144
        return $matches;
145
    }
146
147
    protected function addPlugin($pluginId, PluginInterface $plugin)
148
    {
149
        $this->plugins[$pluginId] = $plugin;
150
151
        $prefix = $this->getPrefix($plugin);
152
153
        if (!isset($this->prefixMap[$prefix])) {
154
            $this->prefixMap[$prefix] = [];
155
        }
156
157
        $this->prefixMap[$prefix][$pluginId] = $plugin;
158
    }
159
160
    protected function getPrefix(PluginInterface $plugin) : string
161
    {
162
        $prefix = $plugin->getPrefix();
163
164
        if ($prefix === '') {
165
            return self::NO_PREFIX;
166
        }
167
168
        return $prefix;
169
    }
170
}