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 |