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 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 |
||
| 25 | class GuiHandler implements |
||
| 26 | ListenerInterfaceExpTimer, |
||
| 27 | ListenerInterfaceExpUserGroup, |
||
| 28 | ListenerInterfaceMpLegacyPlayer, |
||
| 29 | GuiHandlerInterface |
||
| 30 | { |
||
| 31 | /** @var Connection */ |
||
| 32 | protected $connection; |
||
| 33 | |||
| 34 | /** @var LoggerInterface */ |
||
| 35 | protected $logger; |
||
| 36 | |||
| 37 | /** @var Console */ |
||
| 38 | protected $console; |
||
| 39 | |||
| 40 | /** @var ActionFactory */ |
||
| 41 | protected $actionFactory; |
||
| 42 | |||
| 43 | /** @var int */ |
||
| 44 | protected $charLimit; |
||
| 45 | |||
| 46 | /** @var ManialinkInterface[][] */ |
||
| 47 | protected $displayQueu = []; |
||
| 48 | |||
| 49 | /** @var ManialinkInterface[][] */ |
||
| 50 | protected $individualQueu = []; |
||
| 51 | |||
| 52 | /** @var ManialinkInterface[][] */ |
||
| 53 | protected $displayeds = []; |
||
| 54 | |||
| 55 | /** @var ManialinkInterface[][] */ |
||
| 56 | protected $hideQueu = []; |
||
| 57 | |||
| 58 | /** @var String[][] */ |
||
| 59 | protected $hideIndividualQueu = []; |
||
| 60 | |||
| 61 | /** @var String[] */ |
||
| 62 | protected $disconnectedLogins = []; |
||
| 63 | 11 | ||
| 64 | /** |
||
| 65 | 11 | * GuiHandler constructor. |
|
| 66 | * |
||
| 67 | 11 | * @param Connection $connection |
|
| 68 | */ |
||
| 69 | 11 | public function __construct( |
|
| 70 | 11 | Connection $connection, |
|
| 71 | 11 | LoggerInterface $logger, |
|
| 72 | 11 | Console $console, |
|
| 73 | ActionFactory $actionFactory, |
||
| 74 | $charLimit = 262144 |
||
| 75 | ) { |
||
| 76 | $this->connection = $connection; |
||
| 77 | |||
| 78 | $this->connection->sendHideManialinkPage(null); |
||
| 79 | |||
| 80 | $this->logger = $logger; |
||
| 81 | $this->console = $console; |
||
| 82 | 9 | $this->actionFactory = $actionFactory; |
|
| 83 | $this->charLimit = $charLimit; |
||
| 84 | } |
||
| 85 | 9 | ||
| 86 | 9 | ||
| 87 | /** |
||
| 88 | 9 | * Add a manialink to the display queue. |
|
| 89 | 1 | * |
|
| 90 | * @param ManialinkInterface $manialink |
||
| 91 | * @param ManialinkFactory $manialinkFactory |
||
| 92 | 9 | * |
|
| 93 | 9 | * @return void |
|
| 94 | */ |
||
| 95 | public function addToDisplay(ManialinkInterface $manialink, ManialinkFactoryInterface $manialinkFactory) |
||
| 96 | { |
||
| 97 | |||
| 98 | $userGroup = $manialink->getUserGroup()->getName(); |
||
| 99 | $id = $manialinkFactory->getId(); |
||
| 100 | 3 | ||
| 101 | if (AssociativeArray::getFromKey($this->hideQueu, [$userGroup, $id])) { |
||
| 102 | 3 | unset($this->hideQueu[$userGroup][$id]); |
|
| 103 | 3 | } |
|
| 104 | |||
| 105 | 3 | $this->displayQueu[$userGroup][$id] = $manialink; |
|
| 106 | 1 | } |
|
| 107 | |||
| 108 | /** |
||
| 109 | 3 | * Add a manialink to the destruction queue. |
|
| 110 | 1 | * |
|
| 111 | * @param ManialinkInterface $manialink |
||
| 112 | * @param ManialinkFactory $manialinkFactory |
||
| 113 | 3 | */ |
|
| 114 | 3 | public function addToHide(ManialinkInterface $manialink, ManialinkFactoryInterface $manialinkFactory) |
|
| 115 | { |
||
| 116 | $userGroup = $manialink->getUserGroup()->getName(); |
||
| 117 | $id = $manialinkFactory->getId(); |
||
| 118 | |||
| 119 | 10 | if (AssociativeArray::getFromKey($this->displayQueu, [$userGroup, $id])) { |
|
| 120 | unset($this->displayQueu[$userGroup][$id]); |
||
| 121 | 10 | } |
|
| 122 | 10 | ||
| 123 | 10 | if (AssociativeArray::getFromKey($this->displayeds, [$userGroup, $id])) { |
|
| 124 | 10 | unset($this->displayeds[$userGroup][$id]); |
|
| 125 | } |
||
| 126 | 10 | ||
| 127 | 2 | $this->actionFactory->destroyManialinkActions($manialink); |
|
| 128 | 2 | $this->hideQueu[$userGroup][$id] = $manialink; |
|
| 129 | } |
||
| 130 | |||
| 131 | 10 | /** |
|
| 132 | 10 | * Get manialink for a group and manialink factory. |
|
| 133 | 10 | * |
|
| 134 | 10 | * @param Group $group |
|
| 135 | 10 | * @param ManialinkFactory $manialinkFactory |
|
| 136 | 10 | * |
|
| 137 | * @return null |
||
| 138 | */ |
||
| 139 | public function getManialink(Group $group, ManialinkFactoryInterface $manialinkFactory) |
||
| 140 | 10 | { |
|
| 141 | 10 | $varsToCheck = ['displayeds', 'hideQueu', 'displayQueu']; |
|
| 142 | |||
| 143 | foreach ($varsToCheck as $var) { |
||
| 144 | if (isset($this->$var[$group->getName()]) && isset($this->$var[$group->getName()][$manialinkFactory->getId()])) { |
||
| 145 | 10 | return $this->$var[$group->getName()][$manialinkFactory->getId()]; |
|
| 146 | 10 | } |
|
| 147 | 10 | } |
|
| 148 | 10 | ||
| 149 | 10 | return null; |
|
| 150 | 10 | } |
|
| 151 | |||
| 152 | /** |
||
| 153 | * Display & hide all manialinks. |
||
| 154 | */ |
||
| 155 | 10 | protected function displayManialinks() |
|
| 156 | { |
||
| 157 | $size = 0; |
||
| 158 | 10 | foreach ($this->getManialinksToDisplay() as $mlData) { |
|
| 159 | 1 | $currentSize = $size; |
|
| 160 | 1 | $size += strlen($mlData['ml']); |
|
| 161 | 1 | ||
| 162 | if ($currentSize != 0 && $size > $this->charLimit) { |
||
| 163 | 10 | $this->executeMultiCall(); |
|
| 164 | $size = strlen($mlData['ml']); |
||
| 165 | } |
||
| 166 | |||
| 167 | $this->connection->sendDisplayManialinkPage( |
||
| 168 | $mlData['logins'], |
||
| 169 | $mlData['ml'], |
||
| 170 | 10 | 0, |
|
| 171 | false, |
||
| 172 | 10 | true |
|
| 173 | 9 | ); |
|
| 174 | 9 | } |
|
| 175 | |||
| 176 | 9 | if ($size > 0) { |
|
| 177 | 9 | $this->executeMultiCall(); |
|
| 178 | 9 | } |
|
| 179 | |||
| 180 | // Reset the queues. |
||
| 181 | $this->displayQueu = []; |
||
| 182 | $this->individualQueu = []; |
||
| 183 | 10 | $this->hideQueu = []; |
|
| 184 | 1 | $this->hideIndividualQueu = []; |
|
| 185 | 1 | $this->disconnectedLogins = []; |
|
| 186 | 1 | } |
|
| 187 | |||
| 188 | /** |
||
| 189 | * Execute multi call & handle error. |
||
| 190 | 10 | */ |
|
| 191 | 3 | protected function executeMultiCall() |
|
| 192 | 2 | { |
|
| 193 | 2 | try { |
|
| 194 | $this->connection->executeMulticall(); |
||
| 195 | 2 | } catch (\Exception $e) { |
|
| 196 | 3 | $this->logger->error("Couldn't deliver all manialinks : ".$e->getMessage(), ['exception' => $e]); |
|
| 197 | $this->console->writeln('$F00ERROR - Couldn\'t deliver all manialinks : '.$e->getMessage()); |
||
| 198 | } |
||
| 199 | } |
||
| 200 | |||
| 201 | 10 | /** |
|
| 202 | 2 | * Get list of all manialinks that needs to be displayed |
|
| 203 | 2 | * |
|
| 204 | 2 | * @return \Generator |
|
| 205 | */ |
||
| 206 | protected function getManialinksToDisplay() |
||
| 207 | { |
||
| 208 | 10 | foreach ($this->displayQueu as $groupName => $manialinks) { |
|
| 209 | foreach ($manialinks as $factoryId => $manialink) { |
||
| 210 | $logins = $manialink->getUserGroup()->getLogins(); |
||
| 211 | |||
| 212 | $this->displayeds[$groupName][$factoryId] = $manialink; |
||
| 213 | 2 | if (!empty($logins)) { |
|
| 214 | yield ['logins' => $logins, 'ml' => $manialink->getXml()]; |
||
| 215 | 2 | } |
|
| 216 | 2 | } |
|
| 217 | } |
||
| 218 | |||
| 219 | foreach ($this->individualQueu as $login => $manialinks) { |
||
| 220 | foreach ($manialinks as $manialink) { |
||
| 221 | $xml = $manialink->getXml(); |
||
| 222 | yield ['logins' => $login, 'ml' => $xml]; |
||
| 223 | 1 | } |
|
| 224 | } |
||
| 225 | 1 | ||
| 226 | foreach ($this->hideQueu as $manialinks) { |
||
| 227 | foreach ($manialinks as $manialink) { |
||
| 228 | $id = $manialink->getId(); |
||
| 229 | |||
| 230 | $logins = $manialink->getUserGroup()->getLogins(); |
||
| 231 | 10 | $logins = array_diff($logins, $this->disconnectedLogins); |
|
| 232 | |||
| 233 | 10 | if (!empty($logins)) { |
|
| 234 | 10 | yield ['logins' => $logins, 'ml' => '<manialink id="'.$id.'" />']; |
|
| 235 | } |
||
| 236 | } |
||
| 237 | } |
||
| 238 | |||
| 239 | 1 | foreach ($this->hideIndividualQueu as $login => $manialinks) { |
|
| 240 | foreach ($manialinks as $manialink) { |
||
| 241 | 1 | $id = $manialink->getId(); |
|
|
|
|||
| 242 | |||
| 243 | if (!in_array($login, $this->disconnectedLogins)) { |
||
| 244 | yield ['logins' => $login, 'ml' => '<manialink id="'.$id.'" />']; |
||
| 245 | } |
||
| 246 | 1 | } |
|
| 247 | } |
||
| 248 | 1 | } |
|
| 249 | |||
| 250 | /** |
||
| 251 | * @param int $charLimit |
||
| 252 | */ |
||
| 253 | 1 | public function setCharLimit($charLimit) |
|
| 254 | { |
||
| 255 | 1 | $this->charLimit = $charLimit; |
|
| 256 | } |
||
| 257 | |||
| 258 | 1 | /** |
|
| 259 | 1 | * List of all manialinks that are currently displayed. |
|
| 260 | 1 | * |
|
| 261 | * @return ManialinkInterface[][] |
||
| 262 | */ |
||
| 263 | 1 | public function getDisplayeds() |
|
| 264 | { |
||
| 265 | return $this->displayeds; |
||
| 266 | } |
||
| 267 | |||
| 268 | 2 | /** |
|
| 269 | * @inheritdoc |
||
| 270 | 2 | */ |
|
| 271 | public function onPostLoop() |
||
| 272 | { |
||
| 273 | 2 | $this->displayManialinks(); |
|
| 274 | 2 | } |
|
| 275 | 2 | ||
| 276 | /** |
||
| 277 | * @inheritdoc |
||
| 278 | 2 | */ |
|
| 279 | public function onPreLoop() |
||
| 280 | { |
||
| 281 | } |
||
| 282 | |||
| 283 | 1 | /** |
|
| 284 | * @inheritdoc |
||
| 285 | 1 | */ |
|
| 286 | 1 | public function onEverySecond() |
|
| 289 | |||
| 290 | 1 | /** |
|
| 291 | * @inheritdoc |
||
| 292 | 1 | */ |
|
| 293 | View Code Duplication | public function onExpansionGroupAddUser(Group $group, $loginAdded) |
|
| 304 | |||
| 305 | 1 | /** |
|
| 306 | * @inheritdoc |
||
| 307 | */ |
||
| 308 | View Code Duplication | public function onExpansionGroupRemoveUser(Group $group, $loginRemoved) |
|
| 309 | { |
||
| 310 | $group = $group->getName(); |
||
| 311 | |||
| 312 | // User was removed from group, need to hide all manialinks of the group to this user |
||
| 313 | if (isset($this->displayeds[$group])) { |
||
| 314 | foreach ($this->displayeds[$group] as $mlId => $manialink) { |
||
| 315 | $this->hideIndividualQueu[$loginRemoved][$mlId] = $manialink; |
||
| 319 | |||
| 320 | /** |
||
| 321 | * @inheritdoc |
||
| 322 | */ |
||
| 323 | public function onExpansionGroupDestroy(Group $group, $lastLogin) |
||
| 329 | |||
| 330 | public function onPlayerConnect(Player $player) |
||
| 333 | |||
| 334 | public function onPlayerDisconnect(Player $player, $disconnectionReason) |
||
| 338 | |||
| 339 | public function onPlayerInfoChanged(Player $oldPlayer, Player $player) |
||
| 342 | |||
| 343 | public function onPlayerAlliesChanged(Player $oldPlayer, Player $player) |
||
| 346 | } |
||
| 347 |
Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.