Completed
Push — dev ( ade326...e1b211 )
by
unknown
03:23
created

GuiHandler   B

Complexity

Total Complexity 42

Size/Duplication

Total Lines 280
Duplicated Lines 7.5 %

Coupling/Cohesion

Components 1
Dependencies 6

Test Coverage

Coverage 93.64%

Importance

Changes 0
Metric Value
wmc 42
lcom 1
cbo 6
dl 21
loc 280
ccs 103
cts 110
cp 0.9364
rs 8.295
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 1
A executeMultiCall() 0 9 2
A onPostLoop() 0 4 1
A onPreLoop() 0 3 1
A getDisplayeds() 0 4 1
A setCharLimit() 0 4 1
A addToDisplay() 3 10 2
A addToHide() 6 14 3
B displayManialinks() 0 31 5
D getManialinksToDisplay() 0 35 11
B onEverySecond() 0 25 6
A onExpansionGroupAddUser() 7 13 3
A onExpansionGroupRemoveUser() 5 11 3
A onExpansionGroupDestroy() 0 6 2

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like GuiHandler often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use GuiHandler, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace eXpansion\Framework\Core\Plugins;
4
5
use eXpansion\Framework\Core\DataProviders\Listener\TimerDataListenerInterface;
6
use eXpansion\Framework\Core\DataProviders\Listener\UserGroupDataListenerInterface;
7
use eXpansion\Framework\Core\Model\Gui\ManialinkInterface;
8
use eXpansion\Framework\Core\Model\UserGroups\Group;
9
use eXpansion\Framework\Core\Services\Console;
10
use Maniaplanet\DedicatedServer\Connection;
11
use Monolog\Logger;
12
use oliverde8\AssociativeArraySimplified\AssociativeArray;
13
14
/**
15
 * Class GuiHandler will send manialinks to player as needed.
16
 *
17
 * @package eXpansion\Framework\Core\Plugins\Gui
18
 * @author Oliver de Cramer
19
 */
20
class GuiHandler implements TimerDataListenerInterface, UserGroupDataListenerInterface
21
{
22
    /** @var Connection */
23
    protected $connection;
24
25
    /** @var Logger */
26
    protected $logger;
27
28
    /** @var Console */
29
    protected $console;
30
31
    /** @var int */
32
    protected $charLimit;
33
34
    /** @var ManialinkInterface[][] */
35
    protected $displayQueu = [];
36
37
    /** @var ManialinkInterface[][] */
38
    protected $individualQueu = [];
39
40
    /** @var ManialinkInterface[][] */
41
    protected $displayeds = [];
42
43
    /** @var ManialinkInterface[][] */
44
    protected $hideQueu = [];
45
46
    /** @var String[][] */
47
    protected $hideIndividualQueu = [];
48
49
    private $groupsBuffer = [];
50
    private $windowsBuffer = [];
51
52
    /**
53
     * GuiHandler constructor.
54
     *
55
     * @param Connection $connection
56
     */
57 10
    public function __construct(Connection $connection, Logger $logger, Console $console, $charLimit = 262144)
58
    {
59 10
        $this->connection = $connection;
60
61 10
        $this->connection->sendHideManialinkPage(null);
62
63 10
        $this->logger = $logger;
64 10
        $this->console = $console;
65 10
        $this->charLimit = $charLimit;
66 10
    }
67
68
69
    /**
70
     * Add a manialink to the display queue.
71
     *
72
     * @param ManialinkInterface $manialink
73
     *
74
     * @return void
75
     */
76 8
    public function addToDisplay(ManialinkInterface $manialink)
77
    {
78 8
        $userGroup = $manialink->getUserGroup()->getName();
79
80 8 View Code Duplication
        if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $manialink->getId()])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
81 1
            unset($this->hideQueu[$userGroup][$manialink->getId()]);
82
        }
83
84 8
        $this->displayQueu[$userGroup][$manialink->getId()] = $manialink;
85 8
    }
86
87
    /**
88
     * Add a manialink to the destruction queue.
89
     *
90
     * @param ManialinkInterface $manialink
91
     */
92 3
    public function addToHide(ManialinkInterface $manialink)
93
    {
94 3
        $userGroup = $manialink->getUserGroup()->getName();
95
96 3 View Code Duplication
        if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $manialink->getId()])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
97 1
            unset($this->displayQueu[$userGroup][$manialink->getId()]);
98
        }
99
100 3 View Code Duplication
        if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $manialink->getId()])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
101 1
            unset($this->displayeds[$userGroup][$manialink->getId()]);
102
        }
103
104 3
        $this->hideQueu[$userGroup][$manialink->getId()] = $manialink;
105 3
    }
106
107
    /**
108
     * Display & hide all manialinks.
109
     */
110 9
    protected function displayManialinks()
111
    {
112 9
        $size = 0;
113 9
        foreach ($this->getManialinksToDisplay() as $mlData) {
114 9
            $currentSize = $size;
115 9
            $size += strlen($mlData['ml']);
116
117 9
            if ($currentSize != 0 && $size > $this->charLimit) {
118 2
                $this->executeMultiCall();
119 2
                $size = strlen($mlData['ml']);
120
            }
121
122 9
            $this->connection->sendDisplayManialinkPage(
123 9
                $mlData['logins'],
124 9
                $mlData['ml'],
125 9
                0,
126 9
                false,
127 9
                true
128
            );
129
        }
130
131 9
        if ($size > 0) {
132 9
            $this->executeMultiCall();
133
        }
134
135
        // Reset the queues.
136 9
        $this->displayQueu = [];
137 9
        $this->individualQueu = [];
138 9
        $this->hideQueu = [];
139 9
        $this->hideIndividualQueu = [];
140 9
    }
141
142
    /**
143
     * Execute multi call & handle error.
144
     */
145 9
    protected function executeMultiCall()
146
    {
147
        try {
148 9
            $this->connection->executeMulticall();
149 1
        } catch (\Exception $e) {
150 1
            $this->logger->addError("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]);
151 1
            $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage());
152
        }
153 9
    }
154
155
    /**
156
     * Get list of all manialinks that needs to be displayed
157
     *
158
     * @return \Generator
159
     */
160 9
    protected function getManialinksToDisplay()
161
    {
162 9
        foreach ($this->displayQueu as $groupName => $manialinks) {
163 8
            foreach ($manialinks as $id => $manialink) {
164 8
                $logins = $manialink->getUserGroup()->getLogins();
165
166 8
                $this->displayeds[$groupName][$id] = $manialink;
167 8
                if (!empty($logins)) {
168 8
                    yield ['logins' => $logins, 'ml' => $manialink->getXml()];
169
                }
170
            }
171
        }
172
173 9
        foreach ($this->individualQueu as $login => $manialinks) {
174 1
            foreach ($manialinks as $id => $manialink) {
175 1
                $xml = $manialink->getXml();
176 1
                yield ['logins' => $login, 'ml' => $xml];
177
            }
178
        }
179
180 9
        foreach ($this->hideQueu as $manialinks) {
181 3
            foreach ($manialinks as $id => $manialink) {
182 2
                $logins = $manialink->getUserGroup()->getLogins();
183 2
                if (!empty($logins)) {
184 3
                    yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />'];
185
                }
186
            }
187
        }
188
189 9
        foreach ($this->hideIndividualQueu as $login => $manialinks) {
190 1
            foreach ($manialinks as $id => $manialink) {
191 1
                yield ['logins' => $login, 'ml' => '<manialink id="'.$id.'" />'];
192
            }
193
        }
194 9
    }
195
196
    /**
197
     * @inheritdoc
198
     */
199 9
    public function onPostLoop()
200
    {
201 9
        $this->displayManialinks();
202 9
    }
203
204
    /**
205
     * @inheritdoc
206
     */
207 1
    public function onPreLoop()
208
    {
209 1
    }
210
211
    /**
212
     * @inheritdoc
213
     */
214 1
    public function onEverySecond()
215
    {
216 1
        $groups = array_keys($this->displayeds);
217 1
        if ($groups !== $this->groupsBuffer) {
218
            $this->console->writeln('groups ('.count($this->displayeds).') $0f0'.implode(",",
219
                    $groups));
220
        }
221
222 1
        $windows = [];
223 1
        foreach ($this->displayeds as $group => $ml) {
224
            foreach ($ml as $mlId => $manialink) {
225
                $windows[$group][] = $mlId;
226
            }
227
        }
228
229 1
        if ($windows !== $this->windowsBuffer) {
230
            foreach ($windows as $group => $data) {
231
                $this->console->writeln('windows in group '.$group.':$0f0'.implode(",", $data));
232
            }
233
        }
234
235 1
        $this->windowsBuffer = $windows;
236 1
        $this->groupsBuffer = $groups;
237
238 1
    }
239
240
    /**
241
     * @inheritdoc
242
     */
243 1
    public function onExpansionGroupAddUser(Group $group, $loginAdded)
244
    {
245 1
        $group = $group->getName();
246
247
        // User was added to group, need to display all manialinks of the group to this user
248 1 View Code Duplication
        if (isset($this->displayeds[$group])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
249 1
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
250 1
                $this->individualQueu[$loginAdded][$mlId] = $manialink;
251
            }
252
        } else {
253
            $this->console->writeln('player added to group, but group not found: $ff0'.$group);
254
        }
255 1
    }
256
257
    /**
258
     * @inheritdoc
259
     */
260 1
    public function onExpansionGroupRemoveUser(Group $group, $loginRemoved)
261
    {
262 1
        $group = $group->getName();
263
264
        // User was removed from group, need to hide all manialinks of the group to this user
265 1 View Code Duplication
        if (isset($this->displayeds[$group])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
266 1
            foreach ($this->displayeds[$group] as $mlId => $manialink) {
267 1
                $this->hideIndividualQueu[$loginRemoved][$mlId] = $manialink;
268
            }
269
        }
270 1
    }
271
272
    /**
273
     * @inheritdoc
274
     */
275 1
    public function onExpansionGroupDestroy(Group $group, $lastLogin)
276
    {
277 1
        if (isset($this->displayeds[$group->getName()])) {
278 1
            unset($this->displayeds[$group->getName()]);
279
        }
280 1
    }
281
282
    /**
283
     * List of all manialinks that are currently displayed.
284
     *
285
     * @return ManialinkInterface[][]
286
     */
287 1
    public function getDisplayeds()
288
    {
289 1
        return $this->displayeds;
290
    }
291
292
    /**
293
     * @param int $charLimit
294
     */
295 2
    public function setCharLimit($charLimit)
296
    {
297 2
        $this->charLimit = $charLimit;
298 2
    }
299
}
300