| Total Complexity | 64 |
| Total Lines | 297 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like ImageContentObject 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 ImageContentObject, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 28 | class ImageContentObject extends AbstractContentObject |
||
| 29 | { |
||
| 30 | /** |
||
| 31 | * Rendering the cObject, IMAGE |
||
| 32 | * |
||
| 33 | * @param array $conf Array of TypoScript properties |
||
| 34 | * @return string Output |
||
| 35 | */ |
||
| 36 | public function render($conf = []) |
||
| 47 | } |
||
| 48 | |||
| 49 | /** |
||
| 50 | * Returns a <img> tag with the image file defined by $file and processed according to the properties in the TypoScript array. |
||
| 51 | * Mostly this function is a sub-function to the IMAGE function which renders the IMAGE cObject in TypoScript. |
||
| 52 | * |
||
| 53 | * @param string $file File TypoScript resource |
||
| 54 | * @param array $conf TypoScript configuration properties |
||
| 55 | * @return string HTML <img> tag, (possibly wrapped in links and other HTML) if any image found. |
||
| 56 | */ |
||
| 57 | protected function cImage($file, $conf) |
||
| 58 | { |
||
| 59 | $tsfe = $this->getTypoScriptFrontendController(); |
||
| 60 | $info = $this->cObj->getImgResource($file, $conf['file.']); |
||
| 61 | if (!is_array($info)) { |
||
| 62 | return ''; |
||
| 63 | } |
||
| 64 | if (is_file(Environment::getPublicPath() . '/' . $info['3'])) { |
||
| 65 | $source = $tsfe->absRefPrefix . str_replace('%2F', '/', rawurlencode($info['3'])); |
||
| 66 | } else { |
||
| 67 | $source = $info[3]; |
||
| 68 | } |
||
| 69 | // Remove file objects for AssetCollector, as it only allows to store scalar values |
||
| 70 | unset($info['originalFile'], $info['processedFile']); |
||
| 71 | GeneralUtility::makeInstance(AssetCollector::class)->addMedia( |
||
| 72 | $source, |
||
| 73 | $info |
||
| 74 | ); |
||
| 75 | |||
| 76 | $layoutKey = $this->cObj->stdWrapValue('layoutKey', $conf); |
||
| 77 | $imageTagTemplate = $this->getImageTagTemplate($layoutKey, $conf); |
||
| 78 | $sourceCollection = $this->getImageSourceCollection($layoutKey, $conf, $file); |
||
| 79 | |||
| 80 | $altParam = $this->getAltParam($conf); |
||
| 81 | $params = $this->cObj->stdWrapValue('params', $conf); |
||
| 82 | if ($params !== '' && $params[0] !== ' ') { |
||
| 83 | $params = ' ' . $params; |
||
| 84 | } |
||
| 85 | |||
| 86 | $imageTagValues = [ |
||
| 87 | 'width' => (int)$info[0], |
||
| 88 | 'height' => (int)$info[1], |
||
| 89 | 'src' => htmlspecialchars($source), |
||
| 90 | 'params' => $params, |
||
| 91 | 'altParams' => $altParam, |
||
| 92 | 'border' => $this->getBorderAttr(' border="' . (int)$conf['border'] . '"'), |
||
| 93 | 'sourceCollection' => $sourceCollection, |
||
| 94 | 'selfClosingTagSlash' => !empty($tsfe->xhtmlDoctype) ? ' /' : '', |
||
| 95 | ]; |
||
| 96 | |||
| 97 | $markerTemplateEngine = GeneralUtility::makeInstance(MarkerBasedTemplateService::class); |
||
| 98 | $theValue = $markerTemplateEngine->substituteMarkerArray($imageTagTemplate, $imageTagValues, '###|###', true, true); |
||
| 99 | |||
| 100 | $linkWrap = $this->cObj->stdWrapValue('linkWrap', $conf); |
||
| 101 | if ($linkWrap) { |
||
| 102 | $theValue = $this->linkWrap($theValue, $linkWrap); |
||
| 103 | } elseif ($conf['imageLinkWrap']) { |
||
| 104 | $originalFile = !empty($info['originalFile']) ? $info['originalFile'] : $info['origFile']; |
||
| 105 | $theValue = $this->cObj->imageLinkWrap($theValue, $originalFile, $conf['imageLinkWrap.']); |
||
| 106 | } |
||
| 107 | $wrap = $this->cObj->stdWrapValue('wrap', $conf); |
||
| 108 | if ((string)$wrap !== '') { |
||
| 109 | $theValue = $this->cObj->wrap($theValue, $conf['wrap']); |
||
| 110 | } |
||
| 111 | return $theValue; |
||
| 112 | } |
||
| 113 | |||
| 114 | /** |
||
| 115 | * Returns the 'border' attribute for an <img> tag only if the doctype is not xhtml_strict, xhtml_11 or html5 |
||
| 116 | * or if the config parameter 'disableImgBorderAttr' is not set. |
||
| 117 | * |
||
| 118 | * @param string $borderAttr The border attribute |
||
| 119 | * @return string The border attribute |
||
| 120 | */ |
||
| 121 | protected function getBorderAttr($borderAttr) |
||
| 133 | } |
||
| 134 | |||
| 135 | /** |
||
| 136 | * Returns the html-template for rendering the image-Tag if no template is defined via typoscript the |
||
| 137 | * default <img> tag template is returned |
||
| 138 | * |
||
| 139 | * @param string $layoutKey rendering key |
||
| 140 | * @param array $conf TypoScript configuration properties |
||
| 141 | * @return string |
||
| 142 | */ |
||
| 143 | protected function getImageTagTemplate($layoutKey, $conf): string |
||
| 144 | { |
||
| 145 | if ($layoutKey && isset($conf['layout.']) && isset($conf['layout.'][$layoutKey . '.'])) { |
||
| 146 | return $this->cObj->stdWrapValue('element', $conf['layout.'][$layoutKey . '.']); |
||
|
|
|||
| 147 | } |
||
| 148 | return '<img src="###SRC###" width="###WIDTH###" height="###HEIGHT###" ###PARAMS### ###ALTPARAMS### ###BORDER######SELFCLOSINGTAGSLASH###>'; |
||
| 149 | } |
||
| 150 | |||
| 151 | /** |
||
| 152 | * Render alternate sources for the image tag. If no source collection is given an empty string is returned. |
||
| 153 | * |
||
| 154 | * @param string $layoutKey rendering key |
||
| 155 | * @param array $conf TypoScript configuration properties |
||
| 156 | * @param string $file |
||
| 157 | * @throws \UnexpectedValueException |
||
| 158 | * @return string |
||
| 159 | */ |
||
| 160 | protected function getImageSourceCollection($layoutKey, $conf, $file) |
||
| 258 | } |
||
| 259 | |||
| 260 | /** |
||
| 261 | * Wraps the input string by the $wrap value and implements the "linkWrap" data type as well. |
||
| 262 | * The "linkWrap" data type means that this function will find any integer encapsulated in {} (curly braces) in the first wrap part and substitute it with the corresponding page uid from the rootline where the found integer is pointing to the key in the rootline. See link below. |
||
| 263 | * |
||
| 264 | * @param string $content Input string |
||
| 265 | * @param string $wrap A string where the first two parts separated by "|" (vertical line) will be wrapped around the input string |
||
| 266 | * @return string Wrapped output string |
||
| 267 | * @see wrap() |
||
| 268 | * @see cImage() |
||
| 269 | */ |
||
| 270 | protected function linkWrap($content, $wrap) |
||
| 271 | { |
||
| 272 | $wrapArr = explode('|', $wrap); |
||
| 273 | if (preg_match('/\\{([0-9]*)\\}/', $wrapArr[0], $reg)) { |
||
| 274 | $uid = $this->getTypoScriptFrontendController()->tmpl->rootLine[$reg[1]]['uid'] ?? null; |
||
| 275 | if ($uid) { |
||
| 276 | $wrapArr[0] = str_replace($reg[0], $uid, $wrapArr[0]); |
||
| 277 | } |
||
| 278 | } |
||
| 279 | return trim($wrapArr[0] ?? '') . $content . trim($wrapArr[1] ?? ''); |
||
| 280 | } |
||
| 281 | |||
| 282 | /** |
||
| 283 | * An abstraction method which creates an alt or title parameter for an HTML img, applet, area or input element and the FILE content element. |
||
| 284 | * From the $conf array it implements the properties "altText", "titleText" and "longdescURL" |
||
| 285 | * |
||
| 286 | * @param array $conf TypoScript configuration properties |
||
| 287 | * @param bool $longDesc If set, the longdesc attribute will be generated - must only be used for img elements! |
||
| 288 | * @return string Parameter string containing alt and title parameters (if any) |
||
| 289 | * @see cImage() |
||
| 290 | */ |
||
| 291 | public function getAltParam($conf, $longDesc = true) |
||
| 292 | { |
||
| 293 | $altText = trim($this->cObj->stdWrapValue('altText', $conf)); |
||
| 294 | $titleText = trim($this->cObj->stdWrapValue('titleText', $conf)); |
||
| 295 | if (isset($conf['longdescURL.']) && $this->getTypoScriptFrontendController()->config['config']['doctype'] !== 'html5') { |
||
| 296 | $longDescUrl = $this->cObj->typoLink_URL($conf['longdescURL.']); |
||
| 297 | } else { |
||
| 298 | $longDescUrl = trim($conf['longdescURL']); |
||
| 299 | } |
||
| 300 | $longDescUrl = strip_tags($longDescUrl); |
||
| 301 | |||
| 302 | // "alt": |
||
| 303 | $altParam = ' alt="' . htmlspecialchars($altText) . '"'; |
||
| 304 | // "title": |
||
| 305 | $emptyTitleHandling = $this->cObj->stdWrapValue('emptyTitleHandling', $conf); |
||
| 306 | // Choices: 'keepEmpty' | 'useAlt' | 'removeAttr' |
||
| 307 | if ($titleText || $emptyTitleHandling === 'keepEmpty') { |
||
| 308 | $altParam .= ' title="' . htmlspecialchars($titleText) . '"'; |
||
| 309 | } elseif (!$titleText && $emptyTitleHandling === 'useAlt') { |
||
| 310 | $altParam .= ' title="' . htmlspecialchars($altText) . '"'; |
||
| 311 | } |
||
| 312 | // "longDesc" URL |
||
| 313 | if ($longDesc && !empty($longDescUrl)) { |
||
| 314 | $altParam .= ' longdesc="' . htmlspecialchars($longDescUrl) . '"'; |
||
| 315 | } |
||
| 316 | return $altParam; |
||
| 317 | } |
||
| 318 | |||
| 319 | /** |
||
| 320 | * @return TypoScriptFrontendController |
||
| 321 | */ |
||
| 322 | protected function getTypoScriptFrontendController() |
||
| 325 | } |
||
| 326 | } |
||
| 327 |