Complex classes like MembersList 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 MembersList, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 79 | class MembersList extends Base { |
||
| 80 | |||
| 81 | |||
| 82 | use TNC22ConsoleTree; |
||
| 83 | |||
| 84 | |||
| 85 | /** @var MemberRequest */ |
||
| 86 | private $memberRequest; |
||
| 87 | |||
| 88 | /** @var FederatedUserService */ |
||
| 89 | private $federatedUserService; |
||
| 90 | |||
| 91 | /** @var RemoteService */ |
||
| 92 | private $remoteService; |
||
| 93 | |||
| 94 | /** @var CircleService */ |
||
| 95 | private $circleService; |
||
| 96 | |||
| 97 | /** @var MemberService */ |
||
| 98 | private $memberService; |
||
| 99 | |||
| 100 | /** @var ConfigService */ |
||
| 101 | private $configService; |
||
| 102 | |||
| 103 | |||
| 104 | /** @var InputInterface */ |
||
| 105 | private $input; |
||
| 106 | |||
| 107 | /** @var string */ |
||
| 108 | private $treeType = ''; |
||
| 109 | |||
| 110 | /** |
||
| 111 | * MembersList constructor. |
||
| 112 | * |
||
| 113 | * @param MemberRequest $memberRequest |
||
| 114 | * @param FederatedUserService $federatedUserService |
||
| 115 | * @param RemoteService $remoteService |
||
| 116 | * @param CircleService $circleService |
||
| 117 | * @param MemberService $memberService |
||
| 118 | * @param ConfigService $configService |
||
| 119 | */ |
||
| 120 | public function __construct( |
||
| 134 | |||
| 135 | |||
| 136 | protected function configure() { |
||
| 148 | |||
| 149 | |||
| 150 | /** |
||
| 151 | * @param InputInterface $input |
||
| 152 | * @param OutputInterface $output |
||
| 153 | * |
||
| 154 | * @return int |
||
| 155 | * @throws CircleNotFoundException |
||
| 156 | * @throws FederatedUserException |
||
| 157 | * @throws FederatedUserNotFoundException |
||
| 158 | * @throws InitiatorNotFoundException |
||
| 159 | * @throws InvalidIdException |
||
| 160 | * @throws InvalidItemException |
||
| 161 | * @throws MemberNotFoundException |
||
| 162 | * @throws OwnerNotFoundException |
||
| 163 | * @throws RemoteInstanceException |
||
| 164 | * @throws RemoteNotFoundException |
||
| 165 | * @throws RemoteResourceNotFoundException |
||
| 166 | * @throws RequestNetworkException |
||
| 167 | * @throws SignatoryException |
||
| 168 | * @throws UnknownRemoteException |
||
| 169 | * @throws UserTypeNotFoundException |
||
| 170 | * @throws FederatedItemException |
||
| 171 | * @throws SingleCircleNotFoundException |
||
| 172 | * @throws RequestBuilderException |
||
| 173 | */ |
||
| 174 | protected function execute(InputInterface $input, OutputInterface $output): int { |
||
| 175 | $this->input = $input; |
||
| 176 | $circleId = $input->getArgument('circle_id'); |
||
| 177 | $instance = $input->getOption('instance'); |
||
| 178 | $initiator = $input->getOption('initiator'); |
||
| 179 | $initiatorType = Member::parseTypeString($input->getOption('initiator-type')); |
||
| 180 | $inherited = $input->getOption('inherited'); |
||
| 181 | |||
| 182 | $tree = null; |
||
| 183 | if ($input->getOption('tree') !== false) { |
||
| 184 | $this->treeType = (is_null($input->getOption('tree'))) ? 'all' : $input->getOption('tree'); |
||
| 185 | |||
| 186 | $this->federatedUserService->commandLineInitiator($initiator, $initiatorType, $circleId, true); |
||
| 187 | $circle = $this->circleService->getCircle($circleId); |
||
| 188 | |||
| 189 | $output->writeln('<info>Name</info>: ' . $circle->getName()); |
||
| 190 | $owner = $circle->getOwner(); |
||
| 191 | $output->writeln('<info>Owner</info>: ' . $owner->getUserId() . '@' . $owner->getInstance()); |
||
| 192 | $type = implode(", ", Circle::getCircleFlags($circle, Circle::FLAGS_LONG)); |
||
| 193 | $output->writeln('<info>Config</info>: ' . $type); |
||
| 194 | $output->writeln(' '); |
||
| 195 | |||
| 196 | $tree = new NC22TreeNode(null, new SimpleDataStore(['circle' => $circle])); |
||
| 197 | $inherited = false; |
||
| 198 | } |
||
| 199 | |||
| 200 | if ($inherited) { |
||
| 201 | $this->federatedUserService->commandLineInitiator($initiator, $initiatorType, $circleId, true); |
||
| 202 | $circle = $this->circleService->getCircle($circleId); |
||
| 203 | $members = $circle->getInheritedMembers(true); |
||
| 204 | } else { |
||
| 205 | $members = $this->getMembers($circleId, $instance, $initiator, $initiatorType, $tree); |
||
| 206 | } |
||
| 207 | |||
| 208 | if (!is_null($tree)) { |
||
| 209 | $this->drawTree( |
||
| 210 | $tree, [$this, 'displayLeaf'], |
||
| 211 | [ |
||
| 212 | 'height' => 3, |
||
| 213 | 'node-spacing' => 1, |
||
| 214 | 'item-spacing' => 0, |
||
| 215 | ] |
||
| 216 | ); |
||
| 217 | |||
| 218 | return 0; |
||
| 219 | } |
||
| 220 | |||
| 221 | if (strtolower($input->getOption('output')) === 'json') { |
||
| 222 | $output->writeln(json_encode($members, JSON_PRETTY_PRINT)); |
||
| 223 | |||
| 224 | return 0; |
||
| 225 | } |
||
| 226 | |||
| 227 | $output = new ConsoleOutput(); |
||
| 228 | $output = $output->section(); |
||
| 229 | |||
| 230 | $table = new Table($output); |
||
| 231 | $table->setHeaders( |
||
| 232 | [ |
||
| 233 | 'Circle Id', 'Circle Name', 'Member Id', 'Single Id', 'Type', 'Source', |
||
| 234 | 'Username', 'Instance', 'Level', 'Invited By' |
||
| 235 | ] |
||
| 236 | ); |
||
| 237 | $table->render(); |
||
| 238 | |||
| 239 | foreach ($members as $member) { |
||
| 240 | if ($member->getCircleId() === $circleId) { |
||
| 241 | $level = $member->getLevel(); |
||
| 242 | } else { |
||
| 243 | $level = $member->getInheritanceFrom()->getLevel(); |
||
| 244 | } |
||
| 245 | |||
| 246 | $table->appendRow( |
||
| 247 | [ |
||
| 248 | $member->getCircleId(), |
||
| 249 | $member->getCircle()->getDisplayName(), |
||
| 250 | $member->getId(), |
||
| 251 | $member->getSingleId(), |
||
| 252 | Member::$TYPE[$member->getUserType()], |
||
| 253 | $member->hasBasedOn() ? Circle::$DEF_SOURCE[$member->getBasedOn()->getSource()] : '', |
||
| 254 | $this->configService->displayFederatedUser( |
||
| 255 | $member, $this->input->getOption('display-name') |
||
| 256 | ), |
||
| 257 | $this->configService->displayInstance($member->getInstance()), |
||
| 258 | ($level > 0) ? Member::$DEF_LEVEL[$level] : |
||
| 259 | '(' . strtolower($member->getStatus()) . ')', |
||
| 260 | ($member->hasInvitedBy()) ? $this->configService->displayFederatedUser( |
||
| 261 | $member->getInvitedBy(), $this->input->getOption('display-name') |
||
| 262 | ) : 'Unknown' |
||
| 263 | ] |
||
| 264 | ); |
||
| 265 | } |
||
| 266 | |||
| 267 | return 0; |
||
| 268 | } |
||
| 269 | |||
| 270 | |||
| 271 | /** |
||
| 272 | * @param string $circleId |
||
| 273 | * @param string $instance |
||
| 274 | * @param string $initiator |
||
| 275 | * @param int $initiatorType |
||
| 276 | * @param NC22TreeNode|null $tree |
||
| 277 | * @param array $knownIds |
||
| 278 | * |
||
| 279 | * @return array |
||
| 280 | * @throws CircleNotFoundException |
||
| 281 | * @throws FederatedItemException |
||
| 282 | * @throws FederatedUserException |
||
| 283 | * @throws FederatedUserNotFoundException |
||
| 284 | * @throws InitiatorNotFoundException |
||
| 285 | * @throws InvalidIdException |
||
| 286 | * @throws InvalidItemException |
||
| 287 | * @throws MemberNotFoundException |
||
| 288 | * @throws OwnerNotFoundException |
||
| 289 | * @throws RemoteInstanceException |
||
| 290 | * @throws RemoteNotFoundException |
||
| 291 | * @throws RemoteResourceNotFoundException |
||
| 292 | * @throws RequestBuilderException |
||
| 293 | * @throws RequestNetworkException |
||
| 294 | * @throws SignatoryException |
||
| 295 | * @throws SingleCircleNotFoundException |
||
| 296 | * @throws UnknownRemoteException |
||
| 297 | * @throws UserTypeNotFoundException |
||
| 298 | */ |
||
| 299 | private function getMembers( |
||
| 394 | |||
| 395 | |||
| 396 | /** |
||
| 397 | * @param SimpleDataStore $data |
||
| 398 | * @param int $lineNumber |
||
| 399 | * |
||
| 400 | * @return string |
||
| 401 | * @throws OwnerNotFoundException |
||
| 402 | */ |
||
| 403 | public function displayLeaf(SimpleDataStore $data, int $lineNumber): string { |
||
| 466 | |||
| 467 | } |
||
| 468 | |||
| 469 |