| Total Complexity | 53 |
| Total Lines | 434 |
| Duplicated Lines | 0 % |
| Changes | 2 | ||
| Bugs | 0 | Features | 0 |
Complex classes like InputLinkElement 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.
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 InputLinkElement, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 38 | class InputLinkElement extends AbstractFormElement |
||
| 39 | { |
||
| 40 | /** |
||
| 41 | * Default field information enabled for this element. |
||
| 42 | * |
||
| 43 | * @var array |
||
| 44 | */ |
||
| 45 | protected $defaultFieldInformation = [ |
||
| 46 | 'tcaDescription' => [ |
||
| 47 | 'renderType' => 'tcaDescription', |
||
| 48 | ], |
||
| 49 | ]; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * Default field controls render the link icon |
||
| 53 | * |
||
| 54 | * @var array |
||
| 55 | */ |
||
| 56 | protected $defaultFieldControl = [ |
||
| 57 | 'linkPopup' => [ |
||
| 58 | 'renderType' => 'linkPopup', |
||
| 59 | 'options' => [] |
||
| 60 | ], |
||
| 61 | ]; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Default field wizards enabled for this element. |
||
| 65 | * |
||
| 66 | * @var array |
||
| 67 | */ |
||
| 68 | protected $defaultFieldWizard = [ |
||
| 69 | 'localizationStateSelector' => [ |
||
| 70 | 'renderType' => 'localizationStateSelector', |
||
| 71 | ], |
||
| 72 | 'otherLanguageContent' => [ |
||
| 73 | 'renderType' => 'otherLanguageContent', |
||
| 74 | 'after' => [ |
||
| 75 | 'localizationStateSelector' |
||
| 76 | ], |
||
| 77 | ], |
||
| 78 | 'defaultLanguageDifferences' => [ |
||
| 79 | 'renderType' => 'defaultLanguageDifferences', |
||
| 80 | 'after' => [ |
||
| 81 | 'otherLanguageContent', |
||
| 82 | ], |
||
| 83 | ], |
||
| 84 | ]; |
||
| 85 | |||
| 86 | /** |
||
| 87 | * This will render a single-line input form field, possibly with various control/validation features |
||
| 88 | * |
||
| 89 | * @return array As defined in initializeResultArray() of AbstractNode |
||
| 90 | */ |
||
| 91 | public function render() |
||
| 315 | } |
||
| 316 | |||
| 317 | /** |
||
| 318 | * @param string $itemValue |
||
| 319 | * @return array |
||
| 320 | */ |
||
| 321 | protected function getLinkExplanation(string $itemValue): array |
||
| 322 | { |
||
| 323 | if (empty($itemValue)) { |
||
| 324 | return []; |
||
| 325 | } |
||
| 326 | $data = ['text' => '', 'icon' => '']; |
||
| 327 | $typolinkService = GeneralUtility::makeInstance(TypoLinkCodecService::class); |
||
| 328 | $linkParts = $typolinkService->decode($itemValue); |
||
| 329 | $linkService = GeneralUtility::makeInstance(LinkService::class); |
||
| 330 | |||
| 331 | try { |
||
| 332 | $linkData = $linkService->resolve($linkParts['url']); |
||
| 333 | } catch (FileDoesNotExistException|FolderDoesNotExistException|UnknownLinkHandlerException|InvalidPathException $e) { |
||
| 334 | return $data; |
||
| 335 | } |
||
| 336 | |||
| 337 | // Resolving the TypoLink parts (class, title, params) |
||
| 338 | $additionalAttributes = []; |
||
| 339 | foreach ($linkParts as $key => $value) { |
||
| 340 | if ($key === 'url') { |
||
| 341 | continue; |
||
| 342 | } |
||
| 343 | if ($value) { |
||
| 344 | switch ($key) { |
||
| 345 | case 'class': |
||
| 346 | $label = $this->getLanguageService()->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:class'); |
||
| 347 | break; |
||
| 348 | case 'title': |
||
| 349 | $label = $this->getLanguageService()->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:title'); |
||
| 350 | break; |
||
| 351 | case 'additionalParams': |
||
| 352 | $label = $this->getLanguageService()->sL('LLL:EXT:recordlist/Resources/Private/Language/locallang_browse_links.xlf:params'); |
||
| 353 | break; |
||
| 354 | default: |
||
| 355 | $label = (string)$key; |
||
| 356 | } |
||
| 357 | |||
| 358 | $additionalAttributes[] = '<span><strong>' . htmlspecialchars($label) . ': </strong> ' . htmlspecialchars($value) . '</span>'; |
||
| 359 | } |
||
| 360 | } |
||
| 361 | |||
| 362 | // Resolve the actual link |
||
| 363 | switch ($linkData['type']) { |
||
| 364 | case LinkService::TYPE_PAGE: |
||
| 365 | $pageRecord = BackendUtility::readPageAccess($linkData['pageuid'], '1=1'); |
||
| 366 | // Is this a real page |
||
| 367 | if ($pageRecord['uid']) { |
||
| 368 | $fragmentTitle = ''; |
||
| 369 | if (isset($linkData['fragment'])) { |
||
| 370 | if (MathUtility::canBeInterpretedAsInteger($linkData['fragment'])) { |
||
| 371 | $contentElement = BackendUtility::getRecord('tt_content', (int)$linkData['fragment'], '*', 'pid=' . $pageRecord['uid']); |
||
| 372 | if ($contentElement) { |
||
| 373 | $fragmentTitle = BackendUtility::getRecordTitle('tt_content', $contentElement, false, false); |
||
| 374 | } |
||
| 375 | } |
||
| 376 | $fragmentTitle = ' #' . ($fragmentTitle ?: $linkData['fragment']); |
||
| 377 | } |
||
| 378 | $data = [ |
||
| 379 | 'text' => $pageRecord['_thePathFull'] . '[' . $pageRecord['uid'] . ']' . $fragmentTitle, |
||
| 380 | 'icon' => $this->iconFactory->getIconForRecord('pages', $pageRecord, Icon::SIZE_SMALL)->render() |
||
|
|
|||
| 381 | ]; |
||
| 382 | } |
||
| 383 | break; |
||
| 384 | case LinkService::TYPE_EMAIL: |
||
| 385 | $data = [ |
||
| 386 | 'text' => $linkData['email'], |
||
| 387 | 'icon' => $this->iconFactory->getIcon('content-elements-mailform', Icon::SIZE_SMALL)->render() |
||
| 388 | ]; |
||
| 389 | break; |
||
| 390 | case LinkService::TYPE_URL: |
||
| 391 | $data = [ |
||
| 392 | 'text' => $linkData['url'], |
||
| 393 | 'icon' => $this->iconFactory->getIcon('apps-pagetree-page-shortcut-external', Icon::SIZE_SMALL)->render() |
||
| 394 | |||
| 395 | ]; |
||
| 396 | break; |
||
| 397 | case LinkService::TYPE_FILE: |
||
| 398 | /** @var File $file */ |
||
| 399 | $file = $linkData['file']; |
||
| 400 | if ($file) { |
||
| 401 | $data = [ |
||
| 402 | 'text' => $file->getPublicUrl(), |
||
| 403 | 'icon' => $this->iconFactory->getIconForFileExtension($file->getExtension(), Icon::SIZE_SMALL)->render() |
||
| 404 | ]; |
||
| 405 | } |
||
| 406 | break; |
||
| 407 | case LinkService::TYPE_FOLDER: |
||
| 408 | /** @var Folder $folder */ |
||
| 409 | $folder = $linkData['folder']; |
||
| 410 | if ($folder) { |
||
| 411 | $data = [ |
||
| 412 | 'text' => $folder->getPublicUrl(), |
||
| 413 | 'icon' => $this->iconFactory->getIcon('apps-filetree-folder-default', Icon::SIZE_SMALL)->render() |
||
| 414 | ]; |
||
| 415 | } |
||
| 416 | break; |
||
| 417 | case LinkService::TYPE_RECORD: |
||
| 418 | $table = $this->data['pageTsConfig']['TCEMAIN.']['linkHandler.'][$linkData['identifier'] . '.']['configuration.']['table']; |
||
| 419 | $record = BackendUtility::getRecord($table, $linkData['uid']); |
||
| 420 | if ($record) { |
||
| 421 | $recordTitle = BackendUtility::getRecordTitle($table, $record); |
||
| 422 | $tableTitle = $this->getLanguageService()->sL($GLOBALS['TCA'][$table]['ctrl']['title']); |
||
| 423 | $data = [ |
||
| 424 | 'text' => sprintf('%s [%s:%d]', $recordTitle, $tableTitle, $linkData['uid']), |
||
| 425 | 'icon' => $this->iconFactory->getIconForRecord($table, $record, Icon::SIZE_SMALL)->render(), |
||
| 426 | ]; |
||
| 427 | } else { |
||
| 428 | $data = [ |
||
| 429 | 'text' => sprintf('%s', $linkData['uid']), |
||
| 430 | 'icon' => $this->iconFactory->getIcon('tcarecords-' . $table . '-default', Icon::SIZE_SMALL, 'overlay-missing')->render(), |
||
| 431 | ]; |
||
| 432 | } |
||
| 433 | break; |
||
| 434 | case LinkService::TYPE_TELEPHONE: |
||
| 435 | $telephone = $linkData['telephone']; |
||
| 436 | if ($telephone) { |
||
| 437 | $data = [ |
||
| 438 | 'text' => $telephone, |
||
| 439 | 'icon' => $this->iconFactory->getIcon('actions-device-mobile', Icon::SIZE_SMALL)->render() |
||
| 440 | ]; |
||
| 441 | } |
||
| 442 | break; |
||
| 443 | default: |
||
| 444 | // Please note that this hook is preliminary and might change, as this element could become its own |
||
| 445 | // TCA type in the future |
||
| 446 | if (isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['linkHandler'][$linkData['type']])) { |
||
| 447 | $linkBuilder = GeneralUtility::makeInstance($GLOBALS['TYPO3_CONF_VARS']['SYS']['formEngine']['linkHandler'][$linkData['type']]); |
||
| 448 | $data = $linkBuilder->getFormData($linkData, $linkParts, $this->data, $this); |
||
| 449 | } elseif ($linkData['type'] === LinkService::TYPE_UNKNOWN) { |
||
| 450 | $data = [ |
||
| 451 | 'text' => $linkData['file'], |
||
| 452 | 'icon' => $this->iconFactory->getIcon('actions-link', Icon::SIZE_SMALL)->render() |
||
| 453 | ]; |
||
| 454 | } else { |
||
| 455 | $data = [ |
||
| 456 | 'text' => 'not implemented type ' . $linkData['type'], |
||
| 457 | 'icon' => '' |
||
| 458 | ]; |
||
| 459 | } |
||
| 460 | } |
||
| 461 | |||
| 462 | $data['additionalAttributes'] = '<div class="help-block">' . implode(' - ', $additionalAttributes) . '</div>'; |
||
| 463 | return $data; |
||
| 464 | } |
||
| 465 | |||
| 466 | /** |
||
| 467 | * @return LanguageService |
||
| 468 | */ |
||
| 469 | protected function getLanguageService() |
||
| 472 | } |
||
| 473 | } |
||
| 474 |