[BUGFIX] Image besides text uses wrong margin
[TYPO3CMS/Extensions/dam_ttcontent.git] / pi_cssstyledcontent / class.tx_damttcontent_pi1.php
1 <?php
2 /***************************************************************
3 * Copyright notice
4 *
5 * (c) 1999-2005 Kasper Skaarhoj (kasperYYYY@typo3.com)
6 * All rights reserved
7 *
8 * This script is part of the TYPO3 project. The TYPO3 project is
9 * free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * The GNU General Public License can be found at
15 * http://www.gnu.org/copyleft/gpl.html.
16 * A copy is found in the textfile GPL.txt and important notices to the license
17 * from the author is found in LICENSE.txt distributed with these scripts.
18 *
19 *
20 * This script is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * This copyright notice MUST APPEAR in all copies of the script!
26 ***************************************************************/
27 /**
28 * Plugin 'Content rendering' for the 'css_styled_content' extension.
29 *
30 * $Id: class.tx_cssstyledcontent_pi1.php 1618 2006-07-10 17:24:44Z baschny $
31 *
32 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
33 */
34 /**
35 *
36 * TOTAL FUNCTIONS: 6
37 * (This index is automatically created/updated by the extension "extdeveval")
38 *
39 */
40
41 require_once(t3lib_extMgm::extPath('css_styled_content').'pi1/class.tx_cssstyledcontent_pi1.php');
42
43
44
45 /**
46 * Plugin class - instantiated from TypoScript.
47 * Rendering some content elements from tt_content table.
48 *
49 * @author Kasper Skaarhoj <kasperYYYY@typo3.com>
50 * @package TYPO3
51 * @subpackage tx_cssstyledcontent
52 */
53 class tx_damttcontent_pi1 extends tx_cssstyledcontent_pi1 {
54
55
56 function addMetaToData ($meta) {
57 foreach ($meta as $key => $value) {
58 $this->pObj->cObj->data['txdam_' . $key] = $value;
59 }
60 }
61
62 function removeMetaFromData () {
63 foreach ($this->pObj->cObj->data as $key => $value) {
64 if (substr($key, 0, 6) == 'txdam_') {
65 unset($this->pObj->cObj->data[$key]);
66 }
67 }
68 }
69
70 /**
71 * returns an array containing width relations for $colCount columns.
72 *
73 * tries to use "colRelations" setting given by TS.
74 * uses "1:1" column relations by default.
75 *
76 * @param array $conf TS configuration for img
77 * @param int $colCount number of columns
78 * @return array
79 */
80 protected function getImgColumnRelations($conf, $colCount) {
81 $relations = array();
82 $equalRelations= array_fill(0, $colCount, 1);
83 $colRelationsTypoScript = trim($this->pObj->cObj->stdWrap($conf['colRelations'], $conf['colRelations.']));
84
85 if ($colRelationsTypoScript) {
86 // try to use column width relations given by TS
87 $relationParts = explode(':', $colRelationsTypoScript);
88 // enough columns defined?
89 if (count($relationParts) >= $colCount) {
90 $out = array();
91 for ($a = 0; $a < $colCount; $a++) {
92 $currentRelationValue = intval($relationParts[$a]);
93 if ($currentRelationValue >= 1) {
94 $out[$a] = $currentRelationValue;
95 } else {
96 t3lib_div::devLog('colRelations used with a value smaller than 1 therefore colRelations setting is ignored.', $this->extKey, 2);
97 unset($out);
98 break;
99 }
100 }
101 if (max($out) / min($out) <= 10) {
102 $relations = $out;
103 } else {
104 t3lib_div::devLog('The difference in size between the largest and smallest colRelation was not within a factor of ten therefore colRelations setting is ignored..', $this->extKey, 2);
105 }
106 }
107 }
108 return $relations ? $relations : $equalRelations;
109 }
110
111 /**
112 * Rendering the IMGTEXT content element, called from TypoScript (tt_content.textpic.20)
113 *
114 * @param string Content input. Not used, ignore.
115 * @param array TypoScript configuration. See TSRef "IMGTEXT". This function aims to be compatible.
116 * @return string HTML output.
117 * @access private
118 * @coauthor Ernesto Baschny <ernst@cron-it.de>
119 * @coauthor Patrick Broens <patrick@patrickbroens.nl>
120 */
121 function render_textpic($content, $conf) {
122 // Look for hook before running default code for function
123 if (method_exists($this, 'hookRequest') && $hookObj = $this->hookRequest('render_textpic')) {
124 return $hookObj->render_textpic($content,$conf);
125 }
126
127 $renderMethod = $this->pObj->cObj->stdWrap($conf['renderMethod'], $conf['renderMethod.']);
128
129 // Render using the default IMGTEXT code (table-based)
130 if (!$renderMethod || $renderMethod == 'table') {
131 return $this->pObj->cObj->IMGTEXT($conf);
132 }
133
134 // Specific configuration for the chosen rendering method
135 if (is_array($conf['rendering.'][$renderMethod . '.'])) {
136 $conf = $this->pObj->cObj->joinTSarrays($conf, $conf['rendering.'][$renderMethod . '.']);
137 }
138
139 // Image or Text with Image?
140 if (is_array($conf['text.'])) {
141 $content = $this->pObj->cObj->stdWrap($this->pObj->cObj->cObjGet($conf['text.'], 'text.'), $conf['text.']);
142 }
143
144 $imgList = trim($this->pObj->cObj->stdWrap($conf['imgList'], $conf['imgList.']));
145
146 if (!$imgList) {
147 // No images, that's easy
148 if (is_array($conf['stdWrap.'])) {
149 return $this->pObj->cObj->stdWrap($content, $conf['stdWrap.']);
150 }
151 return $content;
152 }
153
154 $imgs = t3lib_div::trimExplode(',', $imgList);
155 $imgStart = intval($this->pObj->cObj->stdWrap($conf['imgStart'], $conf['imgStart.']));
156 $imgCount = count($imgs) - $imgStart;
157 $imgMax = intval($this->pObj->cObj->stdWrap($conf['imgMax'], $conf['imgMax.']));
158 if ($imgMax) {
159 $imgCount = tx_dam::forceIntegerInRange($imgCount, 0, $imgMax); // reduce the number of images.
160 }
161
162 $imgPath = $this->pObj->cObj->stdWrap($conf['imgPath'], $conf['imgPath.']);
163
164 // Does we need to render a "global caption" (below the whole image block)?
165 $renderGlobalCaption = !$conf['captionEach'] && !$conf['captionSplit'] && !$conf['imageTextSplit'] && is_array($conf['caption.']);
166 if ($imgCount == 1) {
167 // If we just have one image, the caption relates to the image, so it is not "global"
168 $renderGlobalCaption = FALSE;
169 }
170
171 // Use the calculated information (amount of images, if global caption is wanted) to choose a different rendering method for the images-block
172 $GLOBALS['TSFE']->register['imageCount'] = $imgCount;
173 $GLOBALS['TSFE']->register['renderGlobalCaption'] = $renderGlobalCaption;
174 $fallbackRenderMethod = $this->pObj->cObj->cObjGetSingle($conf['fallbackRendering'], $conf['fallbackRendering.']);
175
176 // Set the accessibility mode which uses a different type of markup, used 4.7+
177 $accessibilityMode = FALSE;
178 if (strpos(strtolower($renderMethod), 'caption') || strpos(strtolower($fallbackRenderMethod), 'caption')) {
179 $accessibilityMode = TRUE;
180 }
181
182 // Global caption
183 $globalCaption = '';
184 if ($renderGlobalCaption) {
185 $globalCaption = $this->pObj->cObj->stdWrap($this->pObj->cObj->cObjGet($conf['caption.'], 'caption.'), $conf['caption.']);
186 }
187
188 // Positioning
189 $position = $this->pObj->cObj->stdWrap($conf['textPos'], $conf['textPos.']);
190
191 $imagePosition = $position&7; // 0,1,2 = center,right,left
192 $contentPosition = $position&24; // 0,8,16,24 (above,below,intext,intext-wrap)
193 $align = $this->pObj->cObj->align[$imagePosition];
194 $textMargin = intval($this->pObj->cObj->stdWrap($conf['textMargin'],$conf['textMargin.']));
195 if (!$conf['textMargin_outOfText'] && $contentPosition < 16) {
196 $textMargin = 0;
197 }
198
199 $colspacing = intval($this->pObj->cObj->stdWrap($conf['colSpace'], $conf['colSpace.']));
200 $rowspacing = intval($this->pObj->cObj->stdWrap($conf['rowSpace'], $conf['rowSpace.']));
201
202 $border = intval($this->pObj->cObj->stdWrap($conf['border'], $conf['border.'])) ? 1:0;
203 $borderColor = $this->pObj->cObj->stdWrap($conf['borderCol'], $conf['borderCol.']);
204 $borderThickness = intval($this->pObj->cObj->stdWrap($conf['borderThick'], $conf['borderThick.']));
205
206 $borderColor = $borderColor?$borderColor:'black';
207 $borderThickness = $borderThickness?$borderThickness:1;
208 $borderSpace = (($conf['borderSpace'] && $border) ? intval($conf['borderSpace']) : 0);
209
210 // Generate cols
211 $cols = intval($this->pObj->cObj->stdWrap($conf['cols'],$conf['cols.']));
212 $colCount = ($cols > 1) ? $cols : 1;
213 if ($colCount > $imgCount) {$colCount = $imgCount;}
214 $rowCount = ceil($imgCount / $colCount);
215
216 // Generate rows
217 $rows = intval($this->pObj->cObj->stdWrap($conf['rows'],$conf['rows.']));
218 if ($rows>1) {
219 $rowCount = $rows;
220 if ($rowCount > $imgCount) {$rowCount = $imgCount;}
221 $colCount = ($rowCount>1) ? ceil($imgCount / $rowCount) : $imgCount;
222 }
223
224 // Max Width
225 $maxW = intval($this->pObj->cObj->stdWrap($conf['maxW'], $conf['maxW.']));
226 $maxWInText = intval($this->pObj->cObj->stdWrap($conf['maxWInText'], $conf['maxWInText.']));
227 $fiftyPercentWidthInText = round($maxW / 100 * 50);
228
229 if ($contentPosition>=16) { // in Text
230 if (!$maxWInText) {
231 // If maxWInText is not set, it's calculated to the 50% of the max
232 $maxW = $fiftyPercentWidthInText;
233 } else {
234 $maxW = $maxWInText;
235 }
236 }
237
238 // max usuable width for images (without spacers and borders)
239 $netW = $maxW - $colspacing * ($colCount - 1) - $colCount * $border * ($borderThickness + $borderSpace) * 2;
240
241 // Specify the maximum width for each column
242 $columnWidths = $this->getImgColumnWidths($conf, $colCount, $netW);
243
244 $image_compression = intval($this->pObj->cObj->stdWrap($conf['image_compression'],$conf['image_compression.']));
245 $image_effects = intval($this->pObj->cObj->stdWrap($conf['image_effects'],$conf['image_effects.']));
246 $image_frames = intval($this->pObj->cObj->stdWrap($conf['image_frames.']['key'],$conf['image_frames.']['key.']));
247
248 // EqualHeight
249 $equalHeight = intval($this->pObj->cObj->stdWrap($conf['equalH'],$conf['equalH.']));
250 if ($equalHeight) {
251 // Initiate gifbuilder object in order to get dimensions AND calculate the imageWidth's
252 $gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
253 $gifCreator->init();
254 $relations_cols = Array();
255 $imgWidths = array(); // contains the individual width of all images after scaling to $equalHeight
256 for ($a=0; $a<$imgCount; $a++) {
257 $imgKey = $a+$imgStart;
258 $imgInfo = $gifCreator->getImageDimensions($imgPath.$imgs[$imgKey]);
259 $rel = $imgInfo[1] / $equalHeight; // relationship between the original height and the wished height
260 if ($rel) { // if relations is zero, then the addition of this value is omitted as the image is not expected to display because of some error.
261 $imgWidths[$a] = $imgInfo[0] / $rel;
262 $relations_cols[floor($a/$colCount)] += $imgWidths[$a]; // counts the total width of the row with the new height taken into consideration.
263 }
264 }
265 }
266
267 // Fetches pictures
268 $splitArr = array();
269 $splitArr['imgObjNum'] = $conf['imgObjNum'];
270 $splitArr = $GLOBALS['TSFE']->tmpl->splitConfArray($splitArr, $imgCount);
271
272 $imageRowsFinalWidths = Array(); // contains the width of every image row
273 $imgsTag = array(); // array index of $imgsTag will be the same as in $imgs, but $imgsTag only contains the images that are actually shown
274 $origImages = array();
275 $rowIdx = 0;
276 for ($a=0; $a<$imgCount; $a++) {
277 $imgKey = $a+$imgStart;
278 $totalImagePath = $imgPath.$imgs[$imgKey];
279
280 $GLOBALS['TSFE']->register['IMAGE_NUM'] = $imgKey; // register IMG_NUM is kept for backwards compatibility
281 $GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imgKey;
282 $GLOBALS['TSFE']->register['ORIG_FILENAME'] = $totalImagePath;
283
284 $this->pObj->cObj->data[$this->pObj->cObj->currentValKey] = $totalImagePath;
285
286 // fetch DAM data and provide it as field data prefixed with txdam_
287 $media = tx_dam::media_getForFile($totalImagePath, '*');
288 if ($media->isAvailable) {
289 $this->addMetaToData ($media->getMetaArray());
290 $imgsExtraData[$imgKey] = $media->getMetaArray();
291 } else {
292 $this->removeMetaFromData();
293 $imgsExtraData[$imgKey] = array();
294 }
295 unset($media);
296
297 $imgObjNum = intval($splitArr[$a]['imgObjNum']);
298 $imgConf = $conf[$imgObjNum.'.'];
299
300 if ($equalHeight) {
301
302 if ($a % $colCount == 0) {
303 // a new row startsS
304 $accumWidth = 0; // reset accumulated net width
305 $accumDesiredWidth = 0; // reset accumulated desired width
306 $rowTotalMaxW = $relations_cols[$rowIdx];
307 if ($rowTotalMaxW > $netW) {
308 $scale = $rowTotalMaxW / $netW;
309 } else {
310 $scale = 1;
311 }
312 $desiredHeight = $equalHeight / $scale;
313 $rowIdx++;
314 }
315
316 $availableWidth= $netW - $accumWidth; // this much width is available for the remaining images in this row (int)
317 $desiredWidth= $imgWidths[$a] / $scale; // theoretical width of resized image. (float)
318 $accumDesiredWidth += $desiredWidth; // add this width. $accumDesiredWidth becomes the desired horizontal position
319 // calculate width by comparing actual and desired horizontal position.
320 // this evenly distributes rounding errors across all images in this row.
321 $suggestedWidth = round($accumDesiredWidth - $accumWidth);
322 $finalImgWidth = (int) min($availableWidth, $suggestedWidth); // finalImgWidth may not exceed $availableWidth
323 $accumWidth += $finalImgWidth;
324 $imgConf['file.']['width'] = $finalImgWidth;
325 $imgConf['file.']['height'] = round($desiredHeight);
326
327 // other stuff will be calculated accordingly:
328 unset($imgConf['file.']['maxW']);
329 unset($imgConf['file.']['maxH']);
330 unset($imgConf['file.']['minW']);
331 unset($imgConf['file.']['minH']);
332 unset($imgConf['file.']['width.']);
333 unset($imgConf['file.']['maxW.']);
334 unset($imgConf['file.']['maxH.']);
335 unset($imgConf['file.']['minW.']);
336 unset($imgConf['file.']['minH.']);
337 } else {
338 $imgConf['file.']['maxW'] = $columnWidths[($a%$colCount)];
339 }
340
341 $titleInLink = $this->pObj->cObj->stdWrap($imgConf['titleInLink'], $imgConf['titleInLink.']);
342 $titleInLinkAndImg = $this->pObj->cObj->stdWrap($imgConf['titleInLinkAndImg'], $imgConf['titleInLinkAndImg.']);
343 $oldATagParms = $GLOBALS['TSFE']->ATagParams;
344 if ($titleInLink) {
345 // Title in A-tag instead of IMG-tag
346 $titleText = trim($this->pObj->cObj->stdWrap($imgConf['titleText'], $imgConf['titleText.']));
347 if ($titleText) {
348 // This will be used by the IMAGE call later:
349 $GLOBALS['TSFE']->ATagParams .= ' title="'. $titleText .'"';
350 }
351 }
352
353 if ($imgConf || $imgConf['file']) {
354 if ($this->pObj->cObj->image_effects[$image_effects]) {
355 $imgConf['file.']['params'] .= ' '.$this->pObj->cObj->image_effects[$image_effects];
356 }
357 if ($image_frames) {
358 if (is_array($conf['image_frames.'][$image_frames.'.'])) {
359 $imgConf['file.']['m.'] = $conf['image_frames.'][$image_frames.'.'];
360 }
361 }
362 if ($image_compression && $imgConf['file'] != 'GIFBUILDER') {
363 if ($image_compression == 1) {
364 $tempImport = $imgConf['file.']['import'];
365 $tempImport_dot = $imgConf['file.']['import.'];
366 unset($imgConf['file.']);
367 $imgConf['file.']['import'] = $tempImport;
368 $imgConf['file.']['import.'] = $tempImport_dot;
369 } elseif (isset($this->pObj->cObj->image_compression[$image_compression])) {
370 $imgConf['file.']['params'] .= ' '.$this->pObj->cObj->image_compression[$image_compression]['params'];
371 $imgConf['file.']['ext'] = $this->pObj->cObj->image_compression[$image_compression]['ext'];
372 unset($imgConf['file.']['ext.']);
373 }
374 }
375 if ($titleInLink && ! $titleInLinkAndImg) {
376 // Check if the image will be linked
377 $link = $this->pObj->cObj->imageLinkWrap('', $totalImagePath, $imgConf['imageLinkWrap.']);
378 if ($link) {
379 // Title in A-tag only (set above: ATagParams), not in IMG-tag
380 unset($imgConf['titleText']);
381 unset($imgConf['titleText.']);
382 $imgConf['emptyTitleHandling'] = 'removeAttr';
383 }
384 }
385 $imgsTag[$imgKey] = $this->pObj->cObj->IMAGE($imgConf);
386 } else {
387 $imgsTag[$imgKey] = $this->pObj->cObj->IMAGE(Array('file' => $totalImagePath)); // currentValKey !!!
388 }
389 // Restore our ATagParams
390 $GLOBALS['TSFE']->ATagParams = $oldATagParms;
391 // Store the original filepath
392 $origImages[$imgKey] = $GLOBALS['TSFE']->lastImageInfo;
393
394 if ($GLOBALS['TSFE']->lastImageInfo[0]==0) {
395 $imageRowsFinalWidths[floor($a/$colCount)] += $this->pObj->cObj->data['imagewidth'];
396 } else {
397 $imageRowsFinalWidths[floor($a/$colCount)] += $GLOBALS['TSFE']->lastImageInfo[0];
398 }
399
400 }
401 // How much space will the image-block occupy?
402 $imageBlockWidth = max($imageRowsFinalWidths)+ $colspacing*($colCount-1) + $colCount*$border*($borderSpace+$borderThickness)*2;
403 $GLOBALS['TSFE']->register['rowwidth'] = $imageBlockWidth;
404 $GLOBALS['TSFE']->register['rowWidthPlusTextMargin'] = $imageBlockWidth + $textMargin;
405
406 // noRows is in fact just one ROW, with the amount of columns specified, where the images are placed in.
407 // noCols is just one COLUMN, each images placed side by side on each row
408 $noRows = $this->pObj->cObj->stdWrap($conf['noRows'],$conf['noRows.']);
409 $noCols = $this->pObj->cObj->stdWrap($conf['noCols'],$conf['noCols.']);
410 if ($noRows) {$noCols=0;} // noRows overrides noCols. They cannot exist at the same time.
411
412 $rowCount_temp = 1;
413 $colCount_temp = $colCount;
414 if ($noRows) {
415 $rowCount_temp = $rowCount;
416 $rowCount = 1;
417 }
418 if ($noCols) {
419 $colCount = 1;
420 $columnWidths = array();
421 }
422
423 // Edit icons:
424 if (!is_array($conf['editIcons.'])) {
425 $conf['editIcons.'] = array();
426 }
427 $editIconsHTML = $conf['editIcons'] && $GLOBALS['TSFE']->beUserLogin ? $this->pObj->cObj->editIcons('',$conf['editIcons'],$conf['editIcons.']) : '';
428
429 // If noRows, we need multiple imagecolumn wraps
430 $imageWrapCols = 1;
431 if ($noRows) { $imageWrapCols = $colCount; }
432
433 // User wants to separate the rows, but only do that if we do have rows
434 $separateRows = $this->pObj->cObj->stdWrap($conf['separateRows'], $conf['separateRows.']);
435 if ($noRows) { $separateRows = 0; }
436 if ($rowCount == 1) { $separateRows = 0; }
437
438 if ($accessibilityMode) {
439 $imagesInColumns = round(($imgCount / ($rowCount * $colCount)), 0 , PHP_ROUND_HALF_UP);
440
441 // Apply optionSplit to the list of classes that we want to add to each column
442 $addClassesCol = $conf['addClassesCol'];
443 if (isset($conf['addClassesCol.'])) {
444 $addClassesCol = $this->pObj->cObj->stdWrap($addClassesCol, $conf['addClassesCol.']);
445 }
446 $addClassesColConf = $GLOBALS['TSFE']->tmpl->splitConfArray(array('addClassesCol' => $addClassesCol), $colCount);
447
448 // Apply optionSplit to the list of classes that we want to add to each image
449 $addClassesImage = $conf['addClassesImage'];
450 if (isset($conf['addClassesImage.'])) {
451 $addClassesImage = $this->pObj->cObj->stdWrap($addClassesImage, $conf['addClassesImage.']);
452 }
453 $addClassesImageConf = $GLOBALS['TSFE']->tmpl->splitConfArray(array('addClassesImage' => $addClassesImage), $imagesInColumns);
454
455 $rows = array();
456 $currentImage = 0;
457
458 // Set the class for the caption (split or global)
459 $classCaptionAlign = array(
460 'center' => 'csc-textpic-caption-c',
461 'right' => 'csc-textpic-caption-r',
462 'left' => 'csc-textpic-caption-l',
463 );
464
465 $captionAlign = $this->pObj->cObj->stdWrap($conf['captionAlign'], $conf['captionAlign.']);
466
467 // Iterate over the rows
468 for ($rowCounter = 1; $rowCounter <= $rowCount; $rowCounter++) {
469 $rowColumns = array();
470 // Iterate over the columns
471 for ($columnCounter = 1; $columnCounter <= $colCount; $columnCounter++) {
472 $columnImages = array();
473 // Iterate over the amount of images allowed in a column
474 for ($imagesCounter = 1; $imagesCounter <= $imagesInColumns; $imagesCounter++) {
475 $image = NULL;
476 $splitCaption = NULL;
477
478 // add DAM metadata to current object
479 $this->addMetaToData($imgsExtraData[$currentImage]);
480
481 $imageMarkers = $captionMarkers = array();
482 $single = '&nbsp;';
483
484 // Set the key of the current image
485 $imageKey = $currentImage + $imgStart;
486
487 // Register IMAGE_NUM_CURRENT for the caption
488 $GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imageKey;
489 $this->pObj->cObj->data[$this->pObj->cObj->currentValKey] = $origImages[$imageKey]['origFile'];
490
491 // Get the image if not an empty cell
492 if (isset($imgsTag[$imageKey])) {
493 $image = $this->pObj->cObj->stdWrap($imgsTag[$imageKey], $conf['imgTagStdWrap.']);
494
495 // Add the edit icons
496 if ($editIconsHTML) {
497 $image .= $this->pObj->cObj->stdWrap($editIconsHTML, $conf['editIconsStdWrap.']);
498 }
499
500 // Wrap the single image
501 $single = $this->pObj->cObj->stdWrap($image, $conf['singleStdWrap.']);
502
503 // Get the caption
504 if (!$renderGlobalCaption) {
505 $imageMarkers['caption'] = $this->pObj->cObj->stdWrap(
506 $this->pObj->cObj->cObjGet($conf['caption.'], 'caption.'), $conf['caption.']
507 );
508
509 if ($captionAlign) {
510 $captionMarkers['classes'] = ' ' . $classCaptionAlign[$captionAlign];
511 }
512
513 $imageMarkers['caption'] = $this->pObj->cObj->substituteMarkerArray(
514 $imageMarkers['caption'],
515 $captionMarkers,
516 '###|###',
517 1,
518 1
519 );
520 }
521
522 if ($addClassesImageConf[$imagesCounter - 1]['addClassesImage']) {
523 $imageMarkers['classes'] = ' ' . $addClassesImageConf[$imagesCounter - 1]['addClassesImage'];
524 }
525 }
526
527 $columnImages[] = $this->pObj->cObj->substituteMarkerArray(
528 $single,
529 $imageMarkers,
530 '###|###',
531 1,
532 1
533 );
534
535 $currentImage++;
536 }
537
538 $rowColumn = $this->pObj->cObj->stdWrap(
539 implode(LF, $columnImages),
540 $conf['columnStdWrap.']
541 );
542
543 // Start filling the markers for columnStdWrap
544 $columnMarkers = array();
545
546 if ($addClassesColConf[$columnCounter - 1]['addClassesCol']) {
547 $columnMarkers['classes'] = ' ' . $addClassesColConf[$columnCounter - 1]['addClassesCol'];
548 }
549
550 $rowColumns[] = $this->pObj->cObj->substituteMarkerArray(
551 $rowColumn,
552 $columnMarkers,
553 '###|###',
554 1,
555 1
556 );
557 }
558 if ($noRows) {
559 $rowConfiguration = $conf['noRowsStdWrap.'];
560 } elseif ($rowCounter == $rowCount) {
561 $rowConfiguration = $conf['lastRowStdWrap.'];
562 } else {
563 $rowConfiguration = $conf['rowStdWrap.'];
564 }
565
566 $row = $this->pObj->cObj->stdWrap(
567 implode(LF, $rowColumns),
568 $rowConfiguration
569 );
570
571 // Start filling the markers for columnStdWrap
572 $rowMarkers = array();
573
574 $rows[] = $this->pObj->cObj->substituteMarkerArray(
575 $row,
576 $rowMarkers,
577 '###|###',
578 1,
579 1
580 );
581 }
582
583 $images = $this->pObj->cObj->stdWrap(
584 implode(LF, $rows),
585 $conf['allStdWrap.']
586 );
587 // Start filling the markers for allStdWrap
588 $allMarkers = array();
589 $classes = array();
590
591 // Add the global caption to the allStdWrap marker array if set
592 if ($globalCaption) {
593 $allMarkers['caption'] = $globalCaption;
594 if ($captionAlign) {
595 $classes[] = $classCaptionAlign[$captionAlign];
596 }
597 }
598
599 // Add the border class if needed
600 if ($border){
601 $classes[] = $conf['borderClass'] ? $conf['borderClass'] : 'csc-textpic-border';
602 }
603
604 // Add the class for equal height if needed
605 if ($equalHeight) {
606 $classes[] = 'csc-textpic-equalheight';
607 }
608
609 $addClasses = $this->pObj->cObj->stdWrap($conf['addClasses'], $conf['addClasses.']);
610 if ($addClasses) {
611 $classes[] = $addClasses;
612 }
613
614 // Set the margin for image + text, no wrap always to avoid multiple stylesheets
615 $noWrapMargin = (integer) (($maxWInText ? $maxWInText : $fiftyPercentWidthInText) +
616 intval($this->pObj->cObj->stdWrap($conf['textMargin'],$conf['textMargin.']
617 )));
618
619 $this->addPageStyle(
620 '.csc-textpic-intext-right-nowrap .csc-textpic-text',
621 'margin-right: ' . $noWrapMargin . 'px;'
622 );
623
624 $this->addPageStyle(
625 '.csc-textpic-intext-left-nowrap .csc-textpic-text',
626 'margin-left: ' . $noWrapMargin . 'px;'
627 );
628
629 // Beside Text where the image block width is not equal to maxW
630 if ($contentPosition == 24 && $maxW != $imageBlockWidth) {
631 $noWrapMargin = $imageBlockWidth + $textMargin;
632
633 // Beside Text, Right
634 if ($imagePosition == 1) {
635 $this->addPageStyle(
636 '.csc-textpic-intext-right-nowrap-' . $noWrapMargin . ' .csc-textpic-text',
637 'margin-right: ' . $noWrapMargin . 'px;'
638 );
639
640 $classes[] = 'csc-textpic-intext-right-nowrap-' . $noWrapMargin;
641
642 // Beside Text, Left
643 } elseif ($imagePosition == 2) {
644 $this->addPageStyle(
645 '.csc-textpic-intext-left-nowrap-' . $noWrapMargin . ' .csc-textpic-text',
646 'margin-left: ' . $noWrapMargin . 'px;'
647 );
648
649 $classes[] = 'csc-textpic-intext-left-nowrap-' . $noWrapMargin;
650 }
651 }
652
653 if ($classes) {
654 $class = ' ' . implode(' ', $classes);
655 }
656
657 // Fill the markers for the allStdWrap
658 $images = $this->pObj->cObj->substituteMarkerArray(
659 $images,
660 $allMarkers,
661 '###|###',
662 1,
663 1
664 );
665 } else {
666 // Apply optionSplit to the list of classes that we want to add to each image
667 $addClassesImage = $conf['addClassesImage'];
668 if (isset($conf['addClassesImage.'])) {
669 $addClassesImage = $this->pObj->cObj->stdWrap($addClassesImage, $conf['addClassesImage.']);
670 }
671 $addClassesImageConf = $GLOBALS['TSFE']->tmpl->splitConfArray(array('addClassesImage' => $addClassesImage), $colCount);
672
673 // Render the images
674 $images = '';
675 for ($c = 0; $c < $imageWrapCols; $c++) {
676 $tmpColspacing = $colspacing;
677 if (($c == $imageWrapCols - 1 && $imagePosition == 2) || ($c == 0 && ($imagePosition == 1 || $imagePosition == 0))) {
678 // Do not add spacing after column if we are first column (left) or last column (center/right)
679 $tmpColspacing = 0;
680 }
681
682 $thisImages = '';
683 $allRows = '';
684 $maxImageSpace = 0;
685 for ($i = $c; $i < count($imgsTag); $i = $i + $imageWrapCols) {
686 $imgKey = $i + $imgStart;
687 $colPos = $i % $colCount;
688 if ($separateRows && $colPos == 0) {
689 $thisRow = '';
690 }
691
692 // add DAM metadata to current object
693 $this->addMetaToData($imgsExtraData[$i]);
694
695 // Render one image
696 if($origImages[$imgKey][0]==0) {
697 $imageSpace = $this->pObj->cObj->data['imagewidth'] + $border * ($borderSpace + $borderThickness) * 2;
698 } else {
699 $imageSpace = $origImages[$imgKey][0] + $border * ($borderSpace + $borderThickness) * 2;
700 }
701
702 $GLOBALS['TSFE']->register['IMAGE_NUM'] = $imgKey;
703 $GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imgKey;
704 $GLOBALS['TSFE']->register['ORIG_FILENAME'] = $origImages[$imgKey]['origFile'];
705 $GLOBALS['TSFE']->register['imagewidth'] = $origImages[$imgKey][0];
706 $GLOBALS['TSFE']->register['imagespace'] = $imageSpace;
707 $GLOBALS['TSFE']->register['imageheight'] = $origImages[$imgKey][1];
708 if ($imageSpace > $maxImageSpace) {
709 $maxImageSpace = $imageSpace;
710 }
711 $thisImage = '';
712 $thisImage .= $this->pObj->cObj->stdWrap($imgsTag[$imgKey], $conf['imgTagStdWrap.']);
713
714 if (!$renderGlobalCaption) {
715 $thisImage .= $this->pObj->cObj->stdWrap($this->pObj->cObj->cObjGet($conf['caption.'], 'caption.'), $conf['caption.']);
716 }
717 if ($editIconsHTML) {
718 $thisImage .= $this->pObj->cObj->stdWrap($editIconsHTML, $conf['editIconsStdWrap.']);
719 }
720 $thisImage = $this->pObj->cObj->stdWrap($thisImage, $conf['oneImageStdWrap.']);
721 $classes = '';
722 if ($addClassesImageConf[$colPos]['addClassesImage']) {
723 $classes = ' ' . $addClassesImageConf[$colPos]['addClassesImage'];
724 }
725 $thisImage = str_replace('###CLASSES###', $classes, $thisImage);
726
727 if ($separateRows) {
728 $thisRow .= $thisImage;
729 } else {
730 $allRows .= $thisImage;
731 }
732 $GLOBALS['TSFE']->register['columnwidth'] = $maxImageSpace + $tmpColspacing;
733
734
735 // Close this row at the end (colCount), or the last row at the final end
736 if ($separateRows && ($i + 1 == count($imgsTag))) {
737 // Close the very last row with either normal configuration or lastRow stdWrap
738 $allRows .= $this->pObj->cObj->stdWrap($thisRow, (is_array($conf['imageLastRowStdWrap.']) ? $conf['imageLastRowStdWrap.'] : $conf['imageRowStdWrap.']));
739 } elseif ($separateRows && $colPos == $colCount - 1) {
740 $allRows .= $this->pObj->cObj->stdWrap($thisRow, $conf['imageRowStdWrap.']);
741 }
742 }
743 if ($separateRows) {
744 $thisImages .= $allRows;
745 } else {
746 $thisImages .= $this->pObj->cObj->stdWrap($allRows, $conf['noRowsStdWrap.']);
747 }
748 if ($noRows) {
749 // Only needed to make columns, rather than rows:
750 $images .= $this->pObj->cObj->stdWrap($thisImages, $conf['imageColumnStdWrap.']);
751 } else {
752 $images .= $thisImages;
753 }
754 }
755
756 // Add the global caption, if not split
757 if ($globalCaption) {
758 $images .= $globalCaption;
759 }
760
761 // CSS-classes
762 $captionClass = '';
763 $classCaptionAlign = array(
764 'center' => 'csc-textpic-caption-c',
765 'right' => 'csc-textpic-caption-r',
766 'left' => 'csc-textpic-caption-l',
767 );
768 $captionAlign = $this->pObj->cObj->stdWrap($conf['captionAlign'], $conf['captionAlign.']);
769 if ($captionAlign) {
770 $captionClass = $classCaptionAlign[$captionAlign];
771 }
772 $borderClass = '';
773 if ($border) {
774 $borderClass = $conf['borderClass'] ? $conf['borderClass'] : 'csc-textpic-border';
775 }
776
777 // Multiple classes with all properties, to be styled in CSS
778 $class = '';
779 $class .= ($borderClass ? ' ' . $borderClass : '');
780 $class .= ($captionClass ? ' ' . $captionClass : '');
781 $class .= ($equalHeight ? ' csc-textpic-equalheight' : '');
782 $addClasses = $this->pObj->cObj->stdWrap($conf['addClasses'], $conf['addClasses.']);
783 $class .= ($addClasses ? ' ' . $addClasses : '');
784
785 // Do we need a width in our wrap around images?
786 $imgWrapWidth = '';
787 if ($position == 0 || $position == 8) {
788 // For 'center' we always need a width: without one, the margin:auto trick won't work
789 $imgWrapWidth = $imageBlockWidth;
790 }
791 if ($rowCount > 1) {
792 // For multiple rows we also need a width, so that the images will wrap
793 $imgWrapWidth = $imageBlockWidth;
794 }
795 if ($globalCaption) {
796 // If we have a global caption, we need the width so that the caption will wrap
797 $imgWrapWidth = $imageBlockWidth;
798 }
799
800 // Wrap around the whole image block
801 $GLOBALS['TSFE']->register['totalwidth'] = $imgWrapWidth;
802 if ($imgWrapWidth) {
803 $images = $this->pObj->cObj->stdWrap($images, $conf['imageStdWrap.']);
804 } else {
805 $images = $this->pObj->cObj->stdWrap($images, $conf['imageStdWrapNoWidth.']);
806 }
807 }
808
809 $output = $this->pObj->cObj->cObjGetSingle($conf['layout'], $conf['layout.']);
810 $output = str_replace('###TEXT###', $content, $output);
811 $output = str_replace('###IMAGES###', $images, $output);
812 $output = str_replace('###CLASSES###', $class, $output);
813
814 if ($conf['stdWrap.']) {
815 $output = $this->pObj->cObj->stdWrap($output, $conf['stdWrap.']);
816 }
817
818 $this->removeMetaFromData();
819
820 return $output;
821 }
822
823
824
825
826 /**
827 * Returns an object reference to the hook object if any
828 *
829 * @param string Name of the function you want to call / hook key
830 * @return object Hook object, if any. Otherwise null.
831 */
832 function &hookRequest($functionName) {
833 global $TYPO3_CONF_VARS;
834
835 // Hook: menuConfig_preProcessModMenu
836 if ($TYPO3_CONF_VARS['EXTCONF']['dam_ttcontent']['pi1_hooks'][$functionName]) {
837 $hookObj = &t3lib_div::getUserObj($TYPO3_CONF_VARS['EXTCONF']['dam_ttcontent']['pi1_hooks'][$functionName]);
838 if (method_exists ($hookObj, $functionName)) {
839 $hookObj->pObj = &$this;
840 return $hookObj;
841 }
842 }
843 }
844 }
845
846
847
848 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dam_ttcontent/pi_cssstyledcontent/class.tx_damttcontent_pi1.php']) {
849 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/dam_ttcontent/pi_cssstyledcontent/class.tx_damttcontent_pi1.php']);
850 }
851 ?>