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 FileSharingBroadcaster 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 FileSharingBroadcaster, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 65 | class FileSharingBroadcaster implements IBroadcaster { |
||
| 66 | |||
| 67 | |||
| 68 | /** @var bool */ |
||
| 69 | private $initiated = false; |
||
| 70 | |||
| 71 | /** @var IL10N */ |
||
| 72 | private $l10n = null; |
||
| 73 | |||
| 74 | /** @var IMailer */ |
||
| 75 | private $mailer; |
||
| 76 | |||
| 77 | /** @var IRootFolder */ |
||
| 78 | private $rootFolder; |
||
| 79 | |||
| 80 | /** @var IUserManager */ |
||
| 81 | private $userManager; |
||
| 82 | |||
| 83 | /** @var ICloudFederationFactory */ |
||
| 84 | private $federationFactory; |
||
| 85 | |||
| 86 | /** @var ICloudFederationProviderManager */ |
||
| 87 | private $federationProviderManager; |
||
| 88 | |||
| 89 | /** @var ICloudIdManager */ |
||
| 90 | private $federationCloudIdManager; |
||
| 91 | |||
| 92 | /** @var Notifications */ |
||
| 93 | private $federationNotifications; |
||
| 94 | |||
| 95 | /** @var ILogger */ |
||
| 96 | private $logger; |
||
| 97 | |||
| 98 | /** @var Defaults */ |
||
| 99 | private $defaults; |
||
| 100 | |||
| 101 | /** @var IURLGenerator */ |
||
| 102 | private $urlGenerator; |
||
| 103 | |||
| 104 | /** @var SharesRequest */ |
||
| 105 | private $sharesRequest; |
||
| 106 | |||
| 107 | /** @var TokensRequest */ |
||
| 108 | private $tokensRequest; |
||
| 109 | |||
| 110 | /** @var ConfigService */ |
||
| 111 | private $configService; |
||
| 112 | |||
| 113 | /** @var MiscService */ |
||
| 114 | private $miscService; |
||
| 115 | |||
| 116 | /** @var bool */ |
||
| 117 | private $federatedEnabled = false; |
||
| 118 | |||
| 119 | /** |
||
| 120 | * {@inheritdoc} |
||
| 121 | */ |
||
| 122 | public function init() { |
||
| 123 | if ($this->initiated) { |
||
| 124 | return; |
||
| 125 | } |
||
| 126 | |||
| 127 | $this->initiated = true; |
||
| 128 | $this->l10n = OC::$server->getL10N(Application::APP_NAME); |
||
| 129 | $this->mailer = OC::$server->getMailer(); |
||
| 130 | $this->rootFolder = OC::$server->getLazyRootFolder(); |
||
| 131 | $this->userManager = OC::$server->getUserManager(); |
||
| 132 | $this->federationFactory = OC::$server->getCloudFederationFactory(); |
||
| 133 | $this->federationProviderManager = OC::$server->getCloudFederationProviderManager(); |
||
| 134 | $this->federationCloudIdManager = OC::$server->getCloudIdManager(); |
||
| 135 | $this->logger = OC::$server->getLogger(); |
||
| 136 | $this->urlGenerator = OC::$server->getURLGenerator(); |
||
| 137 | try { |
||
| 138 | $this->defaults = OC::$server->query(Defaults::class); |
||
| 139 | $this->sharesRequest = OC::$server->query(SharesRequest::class); |
||
| 140 | $this->tokensRequest = OC::$server->query(TokensRequest::class); |
||
| 141 | $this->configService = OC::$server->query(ConfigService::class); |
||
| 142 | $this->miscService = OC::$server->query(MiscService::class); |
||
| 143 | } catch (QueryException $e) { |
||
|
|
|||
| 144 | OC::$server->getLogger() |
||
| 145 | ->log(1, 'Circles: cannot init FileSharingBroadcaster - ' . $e->getMessage()); |
||
| 146 | } |
||
| 147 | |||
| 148 | try { |
||
| 149 | $this->federationNotifications = |
||
| 150 | OC::$server->query(Notifications::class); |
||
| 151 | $this->federatedEnabled = true; |
||
| 152 | } catch (QueryException $e) { |
||
| 153 | } |
||
| 154 | |||
| 155 | } |
||
| 156 | |||
| 157 | |||
| 158 | /** |
||
| 159 | * {@inheritdoc} |
||
| 160 | */ |
||
| 161 | public function end() { |
||
| 162 | } |
||
| 163 | |||
| 164 | |||
| 165 | /** |
||
| 166 | * {@inheritdoc} |
||
| 167 | */ |
||
| 168 | public function createShareToCircle(SharingFrame $frame, Circle $circle) { |
||
| 169 | if ($frame->is0Circle()) { |
||
| 170 | return false; |
||
| 171 | } |
||
| 172 | |||
| 173 | return true; |
||
| 174 | } |
||
| 175 | |||
| 176 | |||
| 177 | /** |
||
| 178 | * {@inheritdoc} |
||
| 179 | */ |
||
| 180 | public function deleteShareToCircle(SharingFrame $frame, Circle $circle) { |
||
| 181 | return true; |
||
| 182 | } |
||
| 183 | |||
| 184 | |||
| 185 | /** |
||
| 186 | * {@inheritdoc} |
||
| 187 | */ |
||
| 188 | public function editShareToCircle(SharingFrame $frame, Circle $circle) { |
||
| 189 | return true; |
||
| 190 | } |
||
| 191 | |||
| 192 | |||
| 193 | /** |
||
| 194 | * {@inheritdoc} |
||
| 195 | * @throws IllegalIDChangeException |
||
| 196 | */ |
||
| 197 | public function createShareToMember(SharingFrame $frame, Member $member) { |
||
| 198 | if (!$frame->is0Circle()) { |
||
| 199 | return false; |
||
| 200 | } |
||
| 201 | |||
| 202 | $payload = $frame->getPayload(); |
||
| 203 | if (!key_exists('share', $payload)) { |
||
| 204 | return false; |
||
| 205 | } |
||
| 206 | |||
| 207 | $share = $this->generateShare($payload['share']); |
||
| 208 | if ($member->getType() === Member::TYPE_MAIL || $member->getType() === Member::TYPE_CONTACT) { |
||
| 209 | try { |
||
| 210 | $circle = $frame->getCircle(); |
||
| 211 | |||
| 212 | // federated shared in contact |
||
| 213 | $clouds = $this->getCloudsFromContact($member->getUserId()); |
||
| 214 | if ($this->federatedEnabled && !empty($clouds)) { |
||
| 215 | $sent = false; |
||
| 216 | foreach ($clouds as $cloudId) { |
||
| 217 | $sharesToken = $this->tokensRequest->generateTokenForMember($member, $share->getId()); |
||
| 218 | if ($this->sharedByFederated($circle, $share, $cloudId, $sharesToken)) { |
||
| 219 | $sent = true; |
||
| 220 | } |
||
| 221 | } |
||
| 222 | |||
| 223 | if ($sent) { |
||
| 224 | return true; |
||
| 225 | } |
||
| 226 | } |
||
| 227 | |||
| 228 | $password = ''; |
||
| 229 | if ($this->configService->enforcePasswordProtection()) { |
||
| 230 | $password = $this->miscService->token(15); |
||
| 231 | } |
||
| 232 | |||
| 233 | $sharesToken = $this->tokensRequest->generateTokenForMember($member, $share->getId(), $password); |
||
| 234 | $mails = [$member->getUserId()]; |
||
| 235 | if ($member->getType() === Member::TYPE_CONTACT) { |
||
| 236 | $mails = $this->getMailsFromContact($member->getUserId()); |
||
| 237 | } |
||
| 238 | |||
| 239 | foreach ($mails as $mail) { |
||
| 240 | $this->sharedByMail($circle, $share, $mail, $sharesToken, $password); |
||
| 241 | } |
||
| 242 | } catch (Exception $e) { |
||
| 243 | } |
||
| 244 | } |
||
| 245 | |||
| 246 | return true; |
||
| 247 | } |
||
| 248 | |||
| 249 | |||
| 250 | /** |
||
| 251 | * {@inheritdoc} |
||
| 252 | */ |
||
| 253 | public function deleteShareToMember(SharingFrame $frame, Member $member) { |
||
| 256 | |||
| 257 | |||
| 258 | /** |
||
| 259 | * {@inheritdoc} |
||
| 260 | */ |
||
| 261 | public function editShareToMember(SharingFrame $frame, Member $member) { |
||
| 264 | |||
| 265 | |||
| 266 | /** |
||
| 267 | * @param Circle $circle |
||
| 268 | * @param Member $member |
||
| 269 | */ |
||
| 270 | public function sendMailAboutExistingShares(Circle $circle, Member $member) { |
||
| 316 | |||
| 317 | |||
| 318 | /** |
||
| 319 | * recreate the share from the JSON payload. |
||
| 320 | * |
||
| 321 | * @param array $data |
||
| 322 | * |
||
| 323 | * @return IShare |
||
| 324 | * @throws IllegalIDChangeException |
||
| 325 | */ |
||
| 326 | private function generateShare($data): IShare { |
||
| 341 | |||
| 342 | |||
| 343 | /** |
||
| 344 | * @param Circle $circle |
||
| 345 | * @param IShare $share |
||
| 346 | * @param string $address |
||
| 347 | * @param string $token |
||
| 348 | * |
||
| 349 | * @return bool |
||
| 350 | */ |
||
| 351 | public function sharedByFederated(Circle $circle, IShare $share, string $address, SharesToken $token |
||
| 390 | |||
| 391 | |||
| 392 | /** |
||
| 393 | * @param Circle $circle |
||
| 394 | * @param IShare $share |
||
| 395 | * @param string $email |
||
| 396 | * @param SharesToken $sharesToken |
||
| 397 | * @param string $password |
||
| 398 | */ |
||
| 399 | private function sharedByMail( |
||
| 424 | |||
| 425 | |||
| 426 | /** |
||
| 427 | * @param $fileName |
||
| 428 | * @param string $link |
||
| 429 | * @param string $author |
||
| 430 | * @param $circleName |
||
| 431 | * @param string $email |
||
| 432 | * |
||
| 433 | * @throws Exception |
||
| 434 | */ |
||
| 435 | protected function sendMail($fileName, $link, $author, $circleName, $email) { |
||
| 460 | |||
| 461 | |||
| 462 | /** |
||
| 463 | * @param IShare $share |
||
| 464 | * @param string $circleName |
||
| 465 | * @param string $email |
||
| 466 | * |
||
| 467 | * @param $password |
||
| 468 | * |
||
| 469 | * @throws NotFoundException |
||
| 470 | * @throws Exception |
||
| 471 | */ |
||
| 472 | protected function sendPasswordByMail(IShare $share, $circleName, $email, $password) { |
||
| 543 | |||
| 544 | |||
| 545 | /** |
||
| 546 | * @param $subject |
||
| 547 | * @param $text |
||
| 548 | * @param $fileName |
||
| 549 | * @param $link |
||
| 550 | * @param string $author |
||
| 551 | * @param string $circleName |
||
| 552 | * |
||
| 553 | * @return IEMailTemplate |
||
| 554 | */ |
||
| 555 | private function generateEmailTemplate($subject, $text, $fileName, $link, $author, $circleName |
||
| 579 | |||
| 580 | |||
| 581 | /** |
||
| 582 | * @param array $unknownShares |
||
| 583 | * @param string $author |
||
| 584 | * @param Member $member |
||
| 585 | * @param string $recipient |
||
| 586 | * @param string $circleName |
||
| 587 | */ |
||
| 588 | public function sendMailExitingShares( |
||
| 618 | |||
| 619 | |||
| 620 | /** |
||
| 621 | * @param $author |
||
| 622 | * @param string $email |
||
| 623 | * |
||
| 624 | * @param $password |
||
| 625 | * |
||
| 626 | * @throws Exception |
||
| 627 | */ |
||
| 628 | protected function sendPasswordExistingShares($author, $email, $password) { |
||
| 690 | |||
| 691 | /** |
||
| 692 | * @param array $share |
||
| 693 | * @param Member $member |
||
| 694 | * @param string $password |
||
| 695 | * |
||
| 696 | * @return array |
||
| 697 | * @throws TokenDoesNotExistException |
||
| 698 | */ |
||
| 699 | private function getMailLinkFromShare(array $share, Member $member, string $password = '') { |
||
| 715 | |||
| 716 | |||
| 717 | /** |
||
| 718 | * @param $author |
||
| 719 | * @param string $circleName |
||
| 720 | * |
||
| 721 | * @return IEMailTemplate |
||
| 722 | * @throws Exception |
||
| 723 | */ |
||
| 724 | protected function generateMailExitingShares($author, $circleName) { |
||
| 738 | |||
| 739 | |||
| 740 | /** |
||
| 741 | * @param IEMailTemplate $emailTemplate |
||
| 742 | * @param array $data |
||
| 743 | */ |
||
| 744 | protected function fillMailExistingShares(IEMailTemplate $emailTemplate, array $data) { |
||
| 757 | |||
| 758 | |||
| 759 | /** |
||
| 760 | * @param IEMailTemplate $emailTemplate |
||
| 761 | * @param $author |
||
| 762 | * @param $recipient |
||
| 763 | * |
||
| 764 | * @throws Exception |
||
| 765 | */ |
||
| 766 | protected function sendMailExistingShares(IEMailTemplate $emailTemplate, $author, $recipient) { |
||
| 783 | |||
| 784 | |||
| 785 | /** |
||
| 786 | * @param string $contactId |
||
| 787 | * |
||
| 788 | * @return array |
||
| 789 | */ |
||
| 790 | View Code Duplication | private function getCloudsFromContact(string $contactId): array { |
|
| 798 | |||
| 799 | /** |
||
| 800 | * @param string $contactId |
||
| 801 | * |
||
| 802 | * @return array |
||
| 803 | */ |
||
| 804 | View Code Duplication | private function getMailsFromContact(string $contactId): array { |
|
| 812 | |||
| 813 | } |
||
| 814 |
Scrutinizer analyzes your
composer.json/composer.lockfile if available to determine the classes, and functions that are defined by your dependencies.It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.