SettingProvider   A
last analyzed

Complexity

Total Complexity 35

Size/Duplication

Total Lines 300
Duplicated Lines 0 %

Importance

Changes 13
Bugs 0 Features 0
Metric Value
eloc 67
c 13
b 0
f 0
dl 0
loc 300
rs 9.6
wmc 35

13 Methods

Rating   Name   Duplication   Size   Complexity  
A getGuildID() 0 6 3
A setupGuildGroup() 0 6 3
A callbackCommandPrefixChange() 0 6 2
A attachListeners() 0 13 2
A callbackCommandStatusChange() 0 6 2
A setupGuild() 0 24 6
A callbackGroupStatusChange() 0 6 2
A getState() 0 2 1
A callbackGroupRegister() 0 7 4
A removeListeners() 0 13 2
A callbackCommandRegister() 0 7 4
A callbackGuildCreate() 0 2 1
A setupGuildCommand() 0 6 3
1
<?php
2
/**
3
 * Livia
4
 * Copyright 2017-2019 Charlotte Dunois, All Rights Reserved
5
 *
6
 * Website: https://charuru.moe
7
 * License: https://github.com/CharlotteDunois/Livia/blob/master/LICENSE
8
*/
9
10
namespace CharlotteDunois\Livia\Providers;
11
12
/**
13
 * Loads and stores settings associated with guilds.
14
 * Classes extending this class must assign the client received in the `init` method to the `client` property.
15
 *
16
 * @property \CharlotteDunois\Livia\Client  $client  The client this provider is for. This property is NOT accessible outside of the class and is only for documentation purpose here (for extending the class).
17
 */
18
abstract class SettingProvider {
19
    /**
20
     * The Provider state, idling waiting to have a connection.
21
     * @var int
22
     * @source
23
     */
24
    const STATE_IDLE = 0;
25
    
26
    /**
27
     * The Provider state, ready to get work done.
28
     * @var int
29
     * @source
30
     */
31
    const STATE_READY = 1;
32
    
33
    /**
34
     * The current provider state.
35
     * Implementations must set this state accordingly.
36
     * @var int
37
     */
38
    protected $providerState = 0;
39
    
40
    /**
41
     * The client this provider is for.
42
     * @var \CharlotteDunois\Livia\Client
43
     */
44
    protected $client;
45
    
46
    /**
47
     * An array of guilds getting set up. If in the array, events doing further setup should ignore the event.
48
     * @property array
49
     */
50
    protected $setup = array();
51
    
52
    /**
53
     * Returns the provider state.
54
     * @return int
55
     */
56
    function getState() {
57
        return $this->providerState;
58
    }
59
    
60
    /**
61
     * Initializes the provider by connecting to databases and/or caching all data in memory. Client::setProvider will automatically call this once the client is ready.
62
     * @param \CharlotteDunois\Livia\Client  $client
63
     * @return \React\Promise\ExtendedPromiseInterface
64
     */
65
    abstract function init(\CharlotteDunois\Livia\Client $client): \React\Promise\ExtendedPromiseInterface;
66
    
67
    /**
68
     * Destroys the provider, removing any event listeners.
69
     * @return mixed|void
70
     */
71
    abstract function destroy();
72
    
73
    /**
74
     * Creates a new table row in the db for the guild, if it doesn't exist already - otherwise loads the row.
75
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
76
     * @param array|\ArrayObject                           $settings
77
     * @return \React\Promise\ExtendedPromiseInterface
78
     * @throws \InvalidArgumentException
79
     */
80
    abstract function create($guild, $settings = array()): \React\Promise\ExtendedPromiseInterface;
81
    
82
    /**
83
     * Gets a setting from a guild.
84
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
85
     * @param string                                       $key
86
     * @param mixed                                        $defaultValue
87
     * @return mixed
88
     * @throws \BadMethodCallException
89
     * @throws \InvalidArgumentException
90
     */
91
    abstract function get($guild, string $key, $defaultValue = null);
92
    
93
    /**
94
     * Sets a setting for a guild.
95
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
96
     * @param string                                       $key
97
     * @param mixed                                        $value
98
     * @return mixed
99
     * @throws \BadMethodCallException
100
     * @throws \InvalidArgumentException
101
     */
102
    abstract function set($guild, string $key, $value);
103
    
104
    /**
105
     * Removes a setting from a guild.
106
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
107
     * @param string                                       $key
108
     * @return mixed
109
     * @throws \BadMethodCallException
110
     * @throws \InvalidArgumentException
111
     */
112
    abstract function remove($guild, string $key);
113
    
114
    /**
115
     * Removes all settings in a guild.
116
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
117
     * @return mixed
118
     * @throws \InvalidArgumentException
119
     */
120
    abstract function clear($guild);
121
    
122
    /**
123
     * Obtains the ID of the provided guild.
124
     * @param \CharlotteDunois\Yasmin\Models\Guild|string|int|null  $guild
125
     * @return string
126
     * @throws \InvalidArgumentException
127
     */
128
    function getGuildID($guild) {
129
        if($guild === null || $guild === 'global') {
130
            return 'global';
131
        }
132
        
133
        return $this->client->guilds->resolve($guild)->id;
134
    }
135
    
136
    /**
137
     * This method will attach all necessary event listeners to the client.
138
     * Providers extending this class must call this method when initializing the provider (in the `init` method).
139
     * @return void
140
     * @throws \BadMethodCallException
141
     */
142
    function attachListeners() {
143
        if(!($this->client instanceof \CharlotteDunois\Livia\Client)) {
144
            throw new \BadMethodCallException('The client property is not set or not a valid instance of Client');
145
        }
146
        
147
        $this->client->on('commandPrefixChange', array($this, 'callbackCommandPrefixChange'));
148
        $this->client->on('commandStatusChange', array($this, 'callbackCommandStatusChange'));
149
        $this->client->on('groupStatusChange', array($this, 'callbackGroupStatusChange'));
150
        $this->client->on('guildCreate', array($this, 'callbackGuildCreate'));
151
        $this->client->on('commandRegister', array($this, 'callbackCommandRegister'));
152
        $this->client->on('commandReregister', array($this, 'callbackCommandRegister'));
153
        $this->client->on('groupRegister', array($this, 'callbackGroupRegister'));
154
        $this->client->on('groupReregister', array($this, 'callbackGroupRegister'));
155
    }
156
    
157
    /**
158
     * This method will remove the attached event listeners from the client.
159
     * Providers extending this class must call this method when destroying the provider (in the `destroy` method).
160
     * @return void
161
     */
162
    function removeListeners() {
163
        if(!($this->client instanceof \CharlotteDunois\Livia\Client)) {
164
            return;
165
        }
166
        
167
        $this->client->removeListener('commandPrefixChange', array($this, 'callbackCommandPrefixChange'));
168
        $this->client->removeListener('commandStatusChange', array($this, 'callbackCommandStatusChange'));
169
        $this->client->removeListener('groupStatusChange', array($this, 'callbackGroupStatusChange'));
170
        $this->client->removeListener('guildCreate', array($this, 'callbackGuildCreate'));
171
        $this->client->removeListener('commandRegister', array($this, 'callbackCommandRegister'));
172
        $this->client->removeListener('commandReregister', array($this, 'callbackCommandRegister'));
173
        $this->client->removeListener('groupRegister', array($this, 'callbackGroupRegister'));
174
        $this->client->removeListener('groupReregister', array($this, 'callbackGroupRegister'));
175
    }
176
    
177
    /**
178
     * Loads all settings for a guild. Used in listener callbacks.
179
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
180
     * @return void
181
     */
182
    function setupGuild($guild) {
183
        $guild = $this->getGuildID($guild);
184
        
185
        $settings = $this->settings->get($guild);
186
        if(!$settings) {
187
            $this->create($guild)->done(null, array($this->client, 'handlePromiseRejection'));
188
            return;
189
        }
190
        
191
        $this->setup[$guild] = true;
192
        
193
        if($guild === 'global' && \array_key_exists('commandPrefix', $settings)) {
194
            $this->client->setCommandPrefix($settings['commandPrefix'], true);
195
        }
196
        
197
        foreach($this->client->registry->commands as $command) {
198
            $this->setupGuildCommand($guild, $command, $settings);
199
        }
200
        
201
        foreach($this->client->registry->groups as $group) {
202
            $this->setupGuildGroup($guild, $group, $settings);
203
        }
204
        
205
        unset($this->setup[$guild]);
206
    }
207
    
208
    /**
209
     * Sets up a command's status in a guild from the guild's settings. Used in listener callbacks.
210
     * @param string|\CharlotteDunois\Yasmin\Models\Guild  $guild
211
     * @param \CharlotteDunois\Livia\Commands\Command      $command
212
     * @param array|\ArrayObject                           $settings
213
     * @return void
214
     */
215
    function setupGuildCommand($guild, \CharlotteDunois\Livia\Commands\Command $command, &$settings) {
216
        if(!isset($settings['command-'.$command->name])) {
217
            return;
218
        }
219
        
220
        $command->setEnabledIn(($guild !== 'global' ? $guild : null), $settings['command-'.$command->name]);
221
    }
222
    
223
    /**
224
     * Sets up a group's status in a guild from the guild's settings. Used in listener callbacks.
225
     * @param string|\CharlotteDunois\Yasmin\Models\Guild   $guild
226
     * @param \CharlotteDunois\Livia\Commands\CommandGroup  $group
227
     * @param array|\ArrayObject                            $settings
228
     * @return void
229
     */
230
    function setupGuildGroup($guild, \CharlotteDunois\Livia\Commands\CommandGroup $group, &$settings) {
231
        if(!isset($settings['group-'.$group->id])) {
232
            return;
233
        }
234
        
235
        $group->setEnabledIn(($guild !== 'global' ? $guild : null), $settings['group-'.$group->id]);
236
    }
237
    
238
    /**
239
     * The callback for the command prefix change event.
240
     * @param \CharlotteDunois\Yasmin\Models\Guild|null  $guild
241
     * @param string|null                                $prefix
242
     * @return void
243
     */
244
    function callbackCommandPrefixChange(?\CharlotteDunois\Yasmin\Models\Guild $guild, ?string $prefix) {
245
        if(!empty($this->setup[$this->getGuildID($guild)])) {
246
            return;
247
        }
248
        
249
        $this->set($guild, 'commandPrefix', $prefix);
250
    }
251
    
252
    /**
253
     * The callback for the command status change event.
254
     * @param \CharlotteDunois\Yasmin\Models\Guild|null  $guild
255
     * @param string|null                                $prefix
256
     * @param bool                                       $enabled
257
     * @return void
258
     */
259
    function callbackCommandStatusChange(?\CharlotteDunois\Yasmin\Models\Guild $guild, \CharlotteDunois\Livia\Commands\Command $command, bool $enabled) {
260
        if(!empty($this->setup[$this->getGuildID($guild)])) {
261
            return;
262
        }
263
        
264
        $this->set($guild, 'command-'.$command->name, $enabled);
265
    }
266
    
267
    /**
268
     * The callback for the group status change event.
269
     * @param \CharlotteDunois\Yasmin\Models\Guild|null  $guild
270
     * @param string|null                                $prefix
271
     * @param bool                                       $enabled
272
     * @return void
273
     */
274
    function callbackGroupStatusChange(?\CharlotteDunois\Yasmin\Models\Guild $guild, \CharlotteDunois\Livia\Commands\CommandGroup $group, bool $enabled) {
275
        if(!empty($this->setup[$this->getGuildID($guild)])) {
276
            return;
277
        }
278
        
279
        $this->set($guild, 'group-'.$group->id, $enabled);
280
    }
281
    
282
    /**
283
     * The callback for the guild create event.
284
     * @param \CharlotteDunois\Yasmin\Models\Guild  $guild
285
     * @return void
286
     */
287
    function callbackGuildCreate(\CharlotteDunois\Yasmin\Models\Guild $guild) {
288
        $this->setupGuild($guild);
289
    }
290
    
291
    /**
292
     * The callback for the command register and reregister event.
293
     * @param \CharlotteDunois\Livia\Commands\Command  $copmmand
294
     * @return void
295
     */
296
    function callbackCommandRegister(\CharlotteDunois\Livia\Commands\Command $command) {
297
        foreach($this->settings as $guild => $settings) {
298
            if($guild !== 'global' && !$this->client->guilds->has($guild)) {
299
                continue;
300
            }
301
            
302
            $this->setupGuildCommand($guild, $command, $settings);
303
        }
304
    }
305
    
306
    /**
307
     * The callback for the group register and reregister event.
308
     * @param \CharlotteDunois\Livia\Commands\CommandGroup  $group
309
     * @return void
310
     */
311
    function callbackGroupRegister(\CharlotteDunois\Livia\Commands\CommandGroup $group) {
312
        foreach($this->settings as $guild => $settings) {
313
            if($guild !== 'global' && !$this->client->guilds->has($guild)) {
314
                continue;
315
            }
316
            
317
            $this->setupGuildGroup($guild, $group, $settings);
318
        }
319
    }
320
}
321