PageRenderTime 64ms CodeModel.GetById 8ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/typo3/sysext/css_styled_content/pi1/class.tx_cssstyledcontent_pi1.php

https://bitbucket.org/linxpinx/mercurial
PHP | 932 lines | 589 code | 132 blank | 211 comment | 161 complexity | 0ed50992481d5b1c0a9ae75a4e688ed6 MD5 | raw file
  1<?php
  2/***************************************************************
  3*  Copyright notice
  4*
  5*  (c) 1999-2010 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 7905 2010-06-13 14:42:33Z ohader $
 31 *
 32 * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
 33 */
 34/**
 35 * [CLASS/FUNCTION INDEX of SCRIPT]
 36 *
 37 *
 38 *
 39 *   68: class tx_cssstyledcontent_pi1 extends tslib_pibase
 40 *
 41 *              SECTION: Rendering of Content Elements:
 42 *   96:     function render_bullets($content,$conf)
 43 *  141:     function render_table($content,$conf)
 44 *  283:     function render_uploads($content,$conf)
 45 *  395:     function render_textpic($content, $conf)
 46 *
 47 *              SECTION: Helper functions
 48 *  832:     function getTableAttributes($conf,$type)
 49 *  861:     function &hookRequest($functionName)
 50 *
 51 * TOTAL FUNCTIONS: 6
 52 * (This index is automatically created/updated by the extension "extdeveval")
 53 *
 54 */
 55/**
 56 * Plugin class - instantiated from TypoScript.
 57 * Rendering some content elements from tt_content table.
 58 *
 59 * @author	Kasper Skaarhoj <kasperYYYY@typo3.com>
 60 * @package TYPO3
 61 * @subpackage tx_cssstyledcontent
 62 */
 63class tx_cssstyledcontent_pi1 extends tslib_pibase {
 64
 65		// Default plugin variables:
 66	var $prefixId = 'tx_cssstyledcontent_pi1';		// Same as class name
 67	var $scriptRelPath = 'pi1/class.tx_cssstyledcontent_pi1.php';	// Path to this script relative to the extension dir.
 68	var $extKey = 'css_styled_content';		// The extension key.
 69	var $conf = array();
 70
 71
 72
 73
 74
 75
 76
 77	/***********************************
 78	 *
 79	 * Rendering of Content Elements:
 80	 *
 81	 ***********************************/
 82
 83	/**
 84	 * Rendering the "Bulletlist" type content element, called from TypoScript (tt_content.bullets.20)
 85	 *
 86	 * @param	string		Content input. Not used, ignore.
 87	 * @param	array		TypoScript configuration
 88	 * @return	string		HTML output.
 89	 * @access private
 90	 */
 91	function render_bullets($content,$conf)	{
 92
 93			// Look for hook before running default code for function
 94		if ($hookObj = $this->hookRequest('render_bullets')) {
 95			return $hookObj->render_bullets($content,$conf);
 96		} else {
 97
 98				// Get bodytext field content, returning blank if empty:
 99			$field = (isset($conf['field']) && trim($conf['field']) ? trim($conf['field']) : 'bodytext');
100			$content = trim($this->cObj->data[$field]);
101			if (!strcmp($content,''))	return '';
102
103				// Split into single lines:
104			$lines = t3lib_div::trimExplode(LF,$content);
105			foreach($lines as &$val)	{
106				$val = '<li>'.$this->cObj->stdWrap($val,$conf['innerStdWrap.']).'</li>';
107			}
108
109				// Set header type:
110			$type = intval($this->cObj->data['layout']);
111
112				// Compile list:
113			$out = '
114				<ul class="csc-bulletlist csc-bulletlist-'.$type.'">'.
115					implode('',$lines).'
116				</ul>';
117
118				// Calling stdWrap:
119			if ($conf['stdWrap.']) {
120				$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
121			}
122
123				// Return value
124			return $out;
125		}
126	}
127
128	/**
129	 * Rendering the "Table" type content element, called from TypoScript (tt_content.table.20)
130	 *
131	 * @param	string		Content input. Not used, ignore.
132	 * @param	array		TypoScript configuration
133	 * @return	string		HTML output.
134	 * @access private
135	 */
136	function render_table($content,$conf)	{
137
138			// Look for hook before running default code for function
139		if ($hookObj = $this->hookRequest('render_table')) {
140			return $hookObj->render_table($content,$conf);
141		} else {
142				// Init FlexForm configuration
143			$this->pi_initPIflexForm();
144
145				// Get bodytext field content
146			$field = (isset($conf['field']) && trim($conf['field']) ? trim($conf['field']) : 'bodytext');
147			$content = trim($this->cObj->data[$field]);
148			if (!strcmp($content,''))	return '';
149
150				// get flexform values
151			$caption = trim(htmlspecialchars($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_caption')));
152			$summary = trim(htmlspecialchars($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_summary')));
153			$useTfoot = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_tfoot'));
154			$headerPos = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_headerpos');
155			$noStyles = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_nostyles');
156			$tableClass = $this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'acctables_tableclass');
157
158			$delimiter = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'tableparsing_delimiter','s_parsing'));
159			if ($delimiter)	{
160				$delimiter = chr(intval($delimiter));
161			} else {
162				$delimiter = '|';
163			}
164			$quotedInput = trim($this->pi_getFFvalue($this->cObj->data['pi_flexform'], 'tableparsing_quote','s_parsing'));
165			if ($quotedInput)	{
166				$quotedInput = chr(intval($quotedInput));
167			} else {
168				$quotedInput = '';
169			}
170
171				// generate id prefix for accessible header
172			$headerScope = ($headerPos=='top'?'col':'row');
173			$headerIdPrefix = $headerScope.$this->cObj->data['uid'].'-';
174
175				// Split into single lines (will become table-rows):
176			$rows = t3lib_div::trimExplode(LF,$content);
177			reset($rows);
178
179				// Find number of columns to render:
180			$cols = t3lib_div::intInRange($this->cObj->data['cols']?$this->cObj->data['cols']:count(explode($delimiter,current($rows))),0,100);
181
182				// Traverse rows (rendering the table here)
183			$rCount = count($rows);
184			foreach($rows as $k => $v)	{
185				$cells = explode($delimiter,$v);
186				$newCells=array();
187				for($a=0;$a<$cols;$a++)	{
188						// remove quotes if needed
189					if ($quotedInput && substr($cells[$a],0,1) == $quotedInput && substr($cells[$a],-1,1) == $quotedInput)	{
190						$cells[$a] = substr($cells[$a],1,-1);
191					}
192
193					if (!strcmp(trim($cells[$a]),''))	$cells[$a]='&nbsp;';
194					$cellAttribs = ($noStyles?'':($a>0 && ($cols-1)==$a) ? ' class="td-last td-'.$a.'"' : ' class="td-'.$a.'"');
195					if (($headerPos == 'top' && !$k) || ($headerPos == 'left' && !$a))	{
196						$scope = ' scope="'.$headerScope.'"';
197						$scope .= ' id="'.$headerIdPrefix.(($headerScope=='col')?$a:$k).'"';
198
199						$newCells[$a] = '
200							<th'.$cellAttribs.$scope.'>'.$this->cObj->stdWrap($cells[$a],$conf['innerStdWrap.']).'</th>';
201					} else {
202						if (empty($headerPos))	{
203							$accessibleHeader = '';
204						} else {
205							$accessibleHeader = ' headers="'.$headerIdPrefix.(($headerScope=='col')?$a:$k).'"';
206						}
207						$newCells[$a] = '
208							<td'.$cellAttribs.$accessibleHeader.'>'.$this->cObj->stdWrap($cells[$a],$conf['innerStdWrap.']).'</td>';
209					}
210				}
211				if (!$noStyles)	{
212					$oddEven = $k%2 ? 'tr-odd' : 'tr-even';
213					$rowAttribs =  ($k>0 && ($rCount-1)==$k) ? ' class="'.$oddEven.' tr-last"' : ' class="'.$oddEven.' tr-'.$k.'"';
214				}
215				$rows[$k]='
216					<tr'.$rowAttribs.'>'.implode('',$newCells).'
217					</tr>';
218			}
219
220			$addTbody = 0;
221			$tableContents = '';
222			if ($caption)	{
223				$tableContents .= '
224					<caption>'.$caption.'</caption>';
225			}
226			if ($headerPos == 'top' && $rows[0])	{
227				$tableContents .= '<thead>'. $rows[0] .'
228					</thead>';
229				unset($rows[0]);
230				$addTbody = 1;
231			}
232			if ($useTfoot)	{
233				$tableContents .= '
234					<tfoot>'.$rows[$rCount-1].'</tfoot>';
235				unset($rows[$rCount-1]);
236				$addTbody = 1;
237			}
238			$tmpTable = implode('',$rows);
239			if ($addTbody)	{
240				$tmpTable = '<tbody>'.$tmpTable.'</tbody>';
241			}
242			$tableContents .= $tmpTable;
243
244				// Set header type:
245			$type = intval($this->cObj->data['layout']);
246
247				// Table tag params.
248			$tableTagParams = $this->getTableAttributes($conf,$type);
249			if (!$noStyles)	{
250				$tableTagParams['class'] = 'contenttable contenttable-'.$type.($tableClass?' '.$tableClass:'');
251			} elseif ($tableClass) {
252				$tableTagParams['class'] = $tableClass;
253			}
254
255
256				// Compile table output:
257			$out = '
258				<table '.t3lib_div::implodeAttributes($tableTagParams).($summary?' summary="'.$summary.'"':'').'>'.	// Omitted xhtmlSafe argument TRUE - none of the values will be needed to be converted anyways, no need to spend processing time on that.
259				$tableContents.'
260				</table>';
261
262				// Calling stdWrap:
263			if ($conf['stdWrap.']) {
264				$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
265			}
266
267				// Return value
268			return $out;
269		}
270	}
271
272	/**
273	 * Rendering the "Filelinks" type content element, called from TypoScript (tt_content.uploads.20)
274	 *
275	 * @param	string		Content input. Not used, ignore.
276	 * @param	array		TypoScript configuration
277	 * @return	string		HTML output.
278	 * @access private
279	 */
280	function render_uploads($content,$conf)	{
281
282			// Look for hook before running default code for function
283		if ($hookObj = $this->hookRequest('render_uploads')) {
284			return $hookObj->render_uploads($content,$conf);
285		} else {
286
287			$out = '';
288
289				// Set layout type:
290			$type = intval($this->cObj->data['layout']);
291
292				// see if the file path variable is set, this takes precedence
293			$filePathConf = $this->cObj->stdWrap($conf['filePath'], $conf['filePath.']);
294			if ($filePathConf) {
295				$fileList = $this->cObj->filelist($filePathConf);
296				list($path) = explode('|', $filePathConf);
297			} else {
298					// Get the list of files from the field
299				$field = (trim($conf['field']) ? trim($conf['field']) : 'media');
300				$fileList = $this->cObj->data[$field];
301				t3lib_div::loadTCA('tt_content');
302				$path = 'uploads/media/';
303				if (is_array($GLOBALS['TCA']['tt_content']['columns'][$field]) && !empty($GLOBALS['TCA']['tt_content']['columns'][$field]['config']['uploadfolder'])) {
304					// in TCA-Array folders are saved without trailing slash, so $path.$fileName won't work
305				    $path = $GLOBALS['TCA']['tt_content']['columns'][$field]['config']['uploadfolder'] .'/';
306				}
307			}
308			$path = trim($path);
309
310				// Explode into an array:
311			$fileArray = t3lib_div::trimExplode(',',$fileList,1);
312
313				// If there were files to list...:
314			if (count($fileArray))	{
315
316					// Get the descriptions for the files (if any):
317				$descriptions = t3lib_div::trimExplode(LF,$this->cObj->data['imagecaption']);
318
319					// Adding hardcoded TS to linkProc configuration:
320				$conf['linkProc.']['path.']['current'] = 1;
321				$conf['linkProc.']['icon'] = 1;	// Always render icon - is inserted by PHP if needed.
322				$conf['linkProc.']['icon.']['wrap'] = ' | //**//';	// Temporary, internal split-token!
323				$conf['linkProc.']['icon_link'] = 1;	// ALways link the icon
324				$conf['linkProc.']['icon_image_ext_list'] = ($type==2 || $type==3) ? $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'] : '';	// If the layout is type 2 or 3 we will render an image based icon if possible.
325				if ($conf['labelStdWrap.']) {
326					$conf['linkProc.']['labelStdWrap.'] = $conf['labelStdWrap.'];
327				}
328
329					// Traverse the files found:
330				$filesData = array();
331				foreach($fileArray as $key => $fileName)	{
332					$absPath = t3lib_div::getFileAbsFileName($path.$fileName);
333					if (@is_file($absPath))	{
334						$fI = pathinfo($fileName);
335						$filesData[$key] = array();
336
337						$filesData[$key]['filename'] = $fileName;
338						$filesData[$key]['path'] = $path;
339						$filesData[$key]['filesize'] = filesize($absPath);
340						$filesData[$key]['fileextension'] = strtolower($fI['extension']);
341						$filesData[$key]['description'] = trim($descriptions[$key]);
342
343						$this->cObj->setCurrentVal($path);
344						$GLOBALS['TSFE']->register['ICON_REL_PATH'] = $path.$fileName;
345						$GLOBALS['TSFE']->register['filename'] = $filesData[$key]['filename'];
346						$GLOBALS['TSFE']->register['path'] = $filesData[$key]['path'];
347						$GLOBALS['TSFE']->register['fileSize'] = $filesData[$key]['filesize'];
348						$GLOBALS['TSFE']->register['fileExtension'] = $filesData[$key]['fileextension'];
349						$GLOBALS['TSFE']->register['description'] = $filesData[$key]['description'];
350						$filesData[$key]['linkedFilenameParts'] = explode('//**//',$this->cObj->filelink($fileName, $conf['linkProc.']));
351					}
352				}
353
354					// optionSplit applied to conf to allow differnt settings per file
355				$splitConf = $GLOBALS['TSFE']->tmpl->splitConfArray($conf, count($filesData));
356
357					// Now, lets render the list!
358				$outputEntries = array();
359				foreach($filesData as $key => $fileData)	{
360					$GLOBALS['TSFE']->register['linkedIcon'] = $fileData['linkedFilenameParts'][0];
361					$GLOBALS['TSFE']->register['linkedLabel'] = $fileData['linkedFilenameParts'][1];
362					$GLOBALS['TSFE']->register['filename'] = $fileData['filename'];
363					$GLOBALS['TSFE']->register['path'] = $fileData['path'];
364					$GLOBALS['TSFE']->register['description'] = $fileData['description'];
365					$GLOBALS['TSFE']->register['fileSize'] = $fileData['filesize'];
366					$GLOBALS['TSFE']->register['fileExtension'] = $fileData['fileextension'];
367					$outputEntries[] = $this->cObj->cObjGetSingle($splitConf[$key]['itemRendering'], $splitConf[$key]['itemRendering.']);
368				}
369
370				if (isset($conf['outerWrap']))	{
371						// Wrap around the whole content
372					$outerWrap = $conf['outerWrap'];
373				} else	{
374						// Table tag params
375					$tableTagParams = $this->getTableAttributes($conf,$type);
376					$tableTagParams['class'] = 'csc-uploads csc-uploads-'.$type;
377					$outerWrap = '<table ' . t3lib_div::implodeAttributes($tableTagParams) . '>|</table>';
378				}
379
380					// Compile it all into table tags:
381				$out = $this->cObj->wrap(implode('', $outputEntries), $outerWrap);
382			}
383
384				// Calling stdWrap:
385			if ($conf['stdWrap.']) {
386				$out = $this->cObj->stdWrap($out, $conf['stdWrap.']);
387			}
388
389				// Return value
390			return $out;
391		}
392	}
393
394	/**
395	 * Rendering the IMGTEXT content element, called from TypoScript (tt_content.textpic.20)
396	 *
397	 * @param	string		Content input. Not used, ignore.
398	 * @param	array		TypoScript configuration. See TSRef "IMGTEXT". This function aims to be compatible.
399	 * @return	string		HTML output.
400	 * @access private
401	 * @coauthor	Ernesto Baschny <ernst@cron-it.de>
402	 */
403	 function render_textpic($content, $conf)	{
404			// Look for hook before running default code for function
405		if (method_exists($this, 'hookRequest') && $hookObj = $this->hookRequest('render_textpic')) {
406			return $hookObj->render_textpic($content,$conf);
407		}
408
409		$renderMethod = $this->cObj->stdWrap($conf['renderMethod'], $conf['renderMethod.']);
410
411			// Render using the default IMGTEXT code (table-based)
412		if (!$renderMethod || $renderMethod == 'table')	{
413			return $this->cObj->IMGTEXT($conf);
414		}
415
416			// Specific configuration for the chosen rendering method
417		if (is_array($conf['rendering.'][$renderMethod . '.']))	{
418			$conf = $this->cObj->joinTSarrays($conf, $conf['rendering.'][$renderMethod . '.']);
419		}
420
421			// Image or Text with Image?
422		if (is_array($conf['text.']))	{
423			$content = $this->cObj->stdWrap($this->cObj->cObjGet($conf['text.'], 'text.'), $conf['text.']);
424		}
425
426		$imgList = trim($this->cObj->stdWrap($conf['imgList'], $conf['imgList.']));
427
428		if (!$imgList)	{
429				// No images, that's easy
430			if (is_array($conf['stdWrap.']))	{
431				return $this->cObj->stdWrap($content, $conf['stdWrap.']);
432			}
433			return $content;
434		}
435
436		$imgs = t3lib_div::trimExplode(',', $imgList);
437		$imgStart = intval($this->cObj->stdWrap($conf['imgStart'], $conf['imgStart.']));
438		$imgCount = count($imgs) - $imgStart;
439		$imgMax = intval($this->cObj->stdWrap($conf['imgMax'], $conf['imgMax.']));
440		if ($imgMax)	{
441			$imgCount = t3lib_div::intInRange($imgCount, 0, $imgMax);	// reduce the number of images.
442		}
443
444		$imgPath = $this->cObj->stdWrap($conf['imgPath'], $conf['imgPath.']);
445
446			// Does we need to render a "global caption" (below the whole image block)?
447		$renderGlobalCaption = !$conf['captionSplit'] && !$conf['imageTextSplit'] && is_array($conf['caption.']);
448		if ($imgCount == 1) {
449				// If we just have one image, the caption relates to the image, so it is not "global"
450			$renderGlobalCaption = false;
451		}
452
453			// Use the calculated information (amount of images, if global caption is wanted) to choose a different rendering method for the images-block
454		$GLOBALS['TSFE']->register['imageCount'] = $imgCount;
455		$GLOBALS['TSFE']->register['renderGlobalCaption'] = $renderGlobalCaption;
456		$fallbackRenderMethod = $this->cObj->cObjGetSingle($conf['fallbackRendering'], $conf['fallbackRendering.']);
457		if ($fallbackRenderMethod && is_array($conf['rendering.'][$fallbackRenderMethod . '.']))	{
458			$conf = $this->cObj->joinTSarrays($conf, $conf['rendering.'][$fallbackRenderMethod . '.']);
459		}
460
461			// Global caption
462		$globalCaption = '';
463		if ($renderGlobalCaption)	{
464			$globalCaption = $this->cObj->stdWrap($this->cObj->cObjGet($conf['caption.'], 'caption.'), $conf['caption.']);
465		}
466
467			// Positioning
468		$position = $this->cObj->stdWrap($conf['textPos'], $conf['textPos.']);
469
470		$imagePosition = $position&7;	// 0,1,2 = center,right,left
471		$contentPosition = $position&24;	// 0,8,16,24 (above,below,intext,intext-wrap)
472		$align = $this->cObj->align[$imagePosition];
473		$textMargin = intval($this->cObj->stdWrap($conf['textMargin'],$conf['textMargin.']));
474		if (!$conf['textMargin_outOfText'] && $contentPosition < 16)	{
475			$textMargin = 0;
476		}
477
478		$colspacing = intval($this->cObj->stdWrap($conf['colSpace'], $conf['colSpace.']));
479		$rowspacing = intval($this->cObj->stdWrap($conf['rowSpace'], $conf['rowSpace.']));
480
481		$border = intval($this->cObj->stdWrap($conf['border'], $conf['border.'])) ? 1:0;
482		$borderColor = $this->cObj->stdWrap($conf['borderCol'], $conf['borderCol.']);
483		$borderThickness = intval($this->cObj->stdWrap($conf['borderThick'], $conf['borderThick.']));
484
485		$borderColor = $borderColor?$borderColor:'black';
486		$borderThickness = $borderThickness?$borderThickness:1;
487		$borderSpace = (($conf['borderSpace']&&$border) ? intval($conf['borderSpace']) : 0);
488
489			// Generate cols
490		$cols = intval($this->cObj->stdWrap($conf['cols'],$conf['cols.']));
491		$colCount = ($cols > 1) ? $cols : 1;
492		if ($colCount > $imgCount)	{$colCount = $imgCount;}
493		$rowCount = ceil($imgCount / $colCount);
494
495			// Generate rows
496		$rows = intval($this->cObj->stdWrap($conf['rows'],$conf['rows.']));
497		if ($rows>1)	{
498			$rowCount = $rows;
499			if ($rowCount > $imgCount)	{$rowCount = $imgCount;}
500			$colCount = ($rowCount>1) ? ceil($imgCount / $rowCount) : $imgCount;
501		}
502
503			// Max Width
504		$maxW = intval($this->cObj->stdWrap($conf['maxW'], $conf['maxW.']));
505
506		if ($contentPosition>=16)	{	// in Text
507			$maxWInText = intval($this->cObj->stdWrap($conf['maxWInText'],$conf['maxWInText.']));
508			if (!$maxWInText)	{
509					// If maxWInText is not set, it's calculated to the 50% of the max
510				$maxW = round($maxW/100*50);
511			} else {
512				$maxW = $maxWInText;
513			}
514		}
515
516			// All columns have the same width:
517		$defaultColumnWidth = ceil(($maxW-$colspacing*($colCount-1)-$colCount*$border*($borderThickness+$borderSpace)*2)/$colCount);
518
519			// Specify the maximum width for each column
520		$columnWidths = array();
521		$colRelations = trim($this->cObj->stdWrap($conf['colRelations'],$conf['colRelations.']));
522		if (!$colRelations)	{
523				// Default 1:1-proportion, all columns same width
524			for ($a=0;$a<$colCount;$a++)	{
525				$columnWidths[$a] = $defaultColumnWidth;
526			}
527		} else {
528				// We need another proportion
529			$rel_parts = explode(':',$colRelations);
530			$rel_total = 0;
531			for ($a=0;$a<$colCount;$a++)	{
532				$rel_parts[$a] = intval($rel_parts[$a]);
533				$rel_total+= $rel_parts[$a];
534			}
535			if ($rel_total)	{
536				for ($a=0;$a<$colCount;$a++)	{
537					$columnWidths[$a] = round(($defaultColumnWidth*$colCount)/$rel_total*$rel_parts[$a]);
538				}
539				if (min($columnWidths)<=0 || max($rel_parts)/min($rel_parts)>10)	{
540					// The difference in size between the largest and smalles must be within a factor of ten.
541					for ($a=0;$a<$colCount;$a++)	{
542						$columnWidths[$a] = $defaultColumnWidth;
543					}
544				}
545			}
546		}
547		$image_compression = intval($this->cObj->stdWrap($conf['image_compression'],$conf['image_compression.']));
548		$image_effects = intval($this->cObj->stdWrap($conf['image_effects'],$conf['image_effects.']));
549		$image_frames = intval($this->cObj->stdWrap($conf['image_frames.']['key'],$conf['image_frames.']['key.']));
550
551			// EqualHeight
552		$equalHeight = intval($this->cObj->stdWrap($conf['equalH'],$conf['equalH.']));
553		if ($equalHeight)	{
554				// Initiate gifbuilder object in order to get dimensions AND calculate the imageWidth's
555			$gifCreator = t3lib_div::makeInstance('tslib_gifbuilder');
556			$gifCreator->init();
557			$relations_cols = Array();
558			for ($a=0; $a<$imgCount; $a++)	{
559				$imgKey = $a+$imgStart;
560				$imgInfo = $gifCreator->getImageDimensions($imgPath.$imgs[$imgKey]);
561				$rel = $imgInfo[1] / $equalHeight;	// relationship between the original height and the wished height
562				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.
563					$relations_cols[floor($a/$colCount)] += $imgInfo[0]/$rel;	// counts the total width of the row with the new height taken into consideration.
564				}
565			}
566		}
567
568			// Fetches pictures
569		$splitArr = array();
570		$splitArr['imgObjNum'] = $conf['imgObjNum'];
571		$splitArr = $GLOBALS['TSFE']->tmpl->splitConfArray($splitArr, $imgCount);
572
573		$imageRowsFinalWidths = Array();	// contains the width of every image row
574		$imgsTag = array();		// array index of $imgsTag will be the same as in $imgs, but $imgsTag only contains the images that are actually shown
575		$origImages = array();
576		for ($a=0; $a<$imgCount; $a++)	{
577			$imgKey = $a+$imgStart;
578			$totalImagePath = $imgPath.$imgs[$imgKey];
579
580			$GLOBALS['TSFE']->register['IMAGE_NUM'] = $imgKey;	// register IMG_NUM is kept for backwards compatibility
581			$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imgKey;
582			$GLOBALS['TSFE']->register['ORIG_FILENAME'] = $totalImagePath;
583
584			$this->cObj->data[$this->cObj->currentValKey] = $totalImagePath;
585			$imgObjNum = intval($splitArr[$a]['imgObjNum']);
586			$imgConf = $conf[$imgObjNum.'.'];
587
588			if ($equalHeight)	{
589				$scale = 1;
590				$totalMaxW = $defaultColumnWidth*$colCount;
591				$rowTotalMaxW = $relations_cols[floor($a/$colCount)];
592				if ($rowTotalMaxW > $totalMaxW)	{
593					$scale = $rowTotalMaxW / $totalMaxW;
594				}
595
596					// transfer info to the imageObject. Please note, that
597				$imgConf['file.']['height'] = round($equalHeight/$scale);
598
599					// other stuff will be calculated accordingly:
600				unset($imgConf['file.']['width']);
601				unset($imgConf['file.']['maxW']);
602				unset($imgConf['file.']['maxH']);
603				unset($imgConf['file.']['minW']);
604				unset($imgConf['file.']['minH']);
605				unset($imgConf['file.']['width.']);
606				unset($imgConf['file.']['maxW.']);
607				unset($imgConf['file.']['maxH.']);
608				unset($imgConf['file.']['minW.']);
609				unset($imgConf['file.']['minH.']);
610			} else {
611				$imgConf['file.']['maxW'] = $columnWidths[($a%$colCount)];
612			}
613
614			$titleInLink = $this->cObj->stdWrap($imgConf['titleInLink'], $imgConf['titleInLink.']);
615			$titleInLinkAndImg = $this->cObj->stdWrap($imgConf['titleInLinkAndImg'], $imgConf['titleInLinkAndImg.']);
616			$oldATagParms = $GLOBALS['TSFE']->ATagParams;
617			if ($titleInLink)	{
618					// Title in A-tag instead of IMG-tag
619				$titleText = trim($this->cObj->stdWrap($imgConf['titleText'], $imgConf['titleText.']));
620				if ($titleText)	{
621						// This will be used by the IMAGE call later:
622					$GLOBALS['TSFE']->ATagParams .= ' title="'. $titleText .'"';
623				}
624			}
625
626			if ($imgConf || $imgConf['file'])	{
627				if ($this->cObj->image_effects[$image_effects])	{
628					$imgConf['file.']['params'] .= ' '.$this->cObj->image_effects[$image_effects];
629				}
630				if ($image_frames)	{
631					if (is_array($conf['image_frames.'][$image_frames.'.']))	{
632						$imgConf['file.']['m.'] = $conf['image_frames.'][$image_frames.'.'];
633					}
634				}
635				if ($image_compression && $imgConf['file'] != 'GIFBUILDER')	{
636					if ($image_compression == 1)	{
637						$tempImport = $imgConf['file.']['import'];
638						$tempImport_dot = $imgConf['file.']['import.'];
639						unset($imgConf['file.']);
640						$imgConf['file.']['import'] = $tempImport;
641						$imgConf['file.']['import.'] = $tempImport_dot;
642					} elseif (isset($this->cObj->image_compression[$image_compression])) {
643						$imgConf['file.']['params'] .= ' '.$this->cObj->image_compression[$image_compression]['params'];
644						$imgConf['file.']['ext'] = $this->cObj->image_compression[$image_compression]['ext'];
645						unset($imgConf['file.']['ext.']);
646					}
647				}
648				if ($titleInLink && ! $titleInLinkAndImg)	{
649						// Check if the image will be linked
650					$link = $this->cObj->imageLinkWrap('', $totalImagePath, $imgConf['imageLinkWrap.']);
651					if ($link)	{
652							// Title in A-tag only (set above: ATagParams), not in IMG-tag
653						unset($imgConf['titleText']);
654						unset($imgConf['titleText.']);
655						$imgConf['emptyTitleHandling'] = 'removeAttr';
656					}
657				}
658				$imgsTag[$imgKey] = $this->cObj->IMAGE($imgConf);
659			} else {
660				$imgsTag[$imgKey] = $this->cObj->IMAGE(Array('file' => $totalImagePath)); 	// currentValKey !!!
661			}
662				// Restore our ATagParams
663			$GLOBALS['TSFE']->ATagParams = $oldATagParms;
664				// Store the original filepath
665			$origImages[$imgKey] = $GLOBALS['TSFE']->lastImageInfo;
666
667			if ($GLOBALS['TSFE']->lastImageInfo[0]==0) {
668				$imageRowsFinalWidths[floor($a/$colCount)] += $this->cObj->data['imagewidth'];
669			} else {
670				$imageRowsFinalWidths[floor($a/$colCount)] += $GLOBALS['TSFE']->lastImageInfo[0];
671 			}
672
673		}
674			// How much space will the image-block occupy?
675		$imageBlockWidth = max($imageRowsFinalWidths)+ $colspacing*($colCount-1) + $colCount*$border*($borderSpace+$borderThickness)*2;
676		$GLOBALS['TSFE']->register['rowwidth'] = $imageBlockWidth;
677		$GLOBALS['TSFE']->register['rowWidthPlusTextMargin'] = $imageBlockWidth + $textMargin;
678
679			// noRows is in fact just one ROW, with the amount of columns specified, where the images are placed in.
680			// noCols is just one COLUMN, each images placed side by side on each row
681		$noRows = $this->cObj->stdWrap($conf['noRows'],$conf['noRows.']);
682		$noCols = $this->cObj->stdWrap($conf['noCols'],$conf['noCols.']);
683		if ($noRows) {$noCols=0;}	// noRows overrides noCols. They cannot exist at the same time.
684
685		$rowCount_temp = 1;
686		$colCount_temp = $colCount;
687		if ($noRows)	{
688			$rowCount_temp = $rowCount;
689			$rowCount = 1;
690		}
691		if ($noCols)	{
692			$colCount = 1;
693			$columnWidths = array();
694		}
695
696			// Edit icons:
697		$editIconsHTML = $conf['editIcons']&&$GLOBALS['TSFE']->beUserLogin ? $this->cObj->editIcons('',$conf['editIcons'],$conf['editIcons.']) : '';
698
699			// If noRows, we need multiple imagecolumn wraps
700		$imageWrapCols = 1;
701		if ($noRows)	{ $imageWrapCols = $colCount; }
702
703			// User wants to separate the rows, but only do that if we do have rows
704		$separateRows = $this->cObj->stdWrap($conf['separateRows'], $conf['separateRows.']);
705		if ($noRows)	{ $separateRows = 0; }
706		if ($rowCount == 1)	{ $separateRows = 0; }
707
708			// Apply optionSplit to the list of classes that we want to add to each image
709		$addClassesImage = $conf['addClassesImage'];
710		if ($conf['addClassesImage.'])	{
711			$addClassesImage = $this->cObj->stdWrap($addClassesImage, $conf['addClassesImage.']);
712		}
713		$addClassesImageConf = $GLOBALS['TSFE']->tmpl->splitConfArray(array('addClassesImage' => $addClassesImage), $colCount);
714
715			// Render the images
716		$images = '';
717		for ($c = 0; $c < $imageWrapCols; $c++)	{
718			$tmpColspacing = $colspacing;
719			if (($c==$imageWrapCols-1 && $imagePosition==2) || ($c==0 && ($imagePosition==1||$imagePosition==0))) {
720					// Do not add spacing after column if we are first column (left) or last column (center/right)
721				$tmpColspacing = 0;
722			}
723
724			$thisImages = '';
725			$allRows = '';
726			$maxImageSpace = 0;
727			for ($i = $c; $i<count($imgsTag); $i=$i+$imageWrapCols)	{
728				$imgKey = $i+$imgStart;
729				$colPos = $i%$colCount;
730				if ($separateRows && $colPos == 0) {
731					$thisRow = '';
732				}
733
734					// Render one image
735				if($origImages[$imgKey][0]==0) {
736					$imageSpace=$this->cObj->data['imagewidth'] + $border*($borderSpace+$borderThickness)*2;
737				} else {
738					$imageSpace = $origImages[$imgKey][0] + $border*($borderSpace+$borderThickness)*2;
739				}
740
741				$GLOBALS['TSFE']->register['IMAGE_NUM'] = $imgKey;
742				$GLOBALS['TSFE']->register['IMAGE_NUM_CURRENT'] = $imgKey;
743				$GLOBALS['TSFE']->register['ORIG_FILENAME'] = $origImages[$imgKey]['origFile'];
744				$GLOBALS['TSFE']->register['imagewidth'] = $origImages[$imgKey][0];
745				$GLOBALS['TSFE']->register['imagespace'] = $imageSpace;
746				$GLOBALS['TSFE']->register['imageheight'] = $origImages[$imgKey][1];
747				if ($imageSpace > $maxImageSpace)	{
748					$maxImageSpace = $imageSpace;
749				}
750				$thisImage = '';
751				$thisImage .= $this->cObj->stdWrap($imgsTag[$imgKey], $conf['imgTagStdWrap.']);
752
753				if (!$renderGlobalCaption)	{
754					$thisImage .= $this->cObj->stdWrap($this->cObj->cObjGet($conf['caption.'], 'caption.'), $conf['caption.']);
755				}
756				if ($editIconsHTML)	{
757					$thisImage .= $this->cObj->stdWrap($editIconsHTML, $conf['editIconsStdWrap.']);
758				}
759				$thisImage = $this->cObj->stdWrap($thisImage, $conf['oneImageStdWrap.']);
760				$classes = '';
761				if ($addClassesImageConf[$colPos]['addClassesImage'])	{
762					$classes = ' ' . $addClassesImageConf[$colPos]['addClassesImage'];
763				}
764				$thisImage = str_replace('###CLASSES###', $classes, $thisImage);
765
766				if ($separateRows)	{
767					$thisRow .= $thisImage;
768				} else {
769					$allRows .= $thisImage;
770				}
771				$GLOBALS['TSFE']->register['columnwidth'] = $maxImageSpace + $tmpColspacing;
772
773
774					// Close this row at the end (colCount), or the last row at the final end
775				if ($separateRows && ($i+1 == count($imgsTag)))	{
776						// Close the very last row with either normal configuration or lastRow stdWrap
777					$allRows .= $this->cObj->stdWrap($thisRow, (is_array($conf['imageLastRowStdWrap.']) ? $conf['imageLastRowStdWrap.'] : $conf['imageRowStdWrap.']));
778				} elseif ($separateRows && $colPos == $colCount-1)	{
779					$allRows .= $this->cObj->stdWrap($thisRow, $conf['imageRowStdWrap.']);
780				}
781			}
782			if ($separateRows)	{
783				$thisImages .= $allRows;
784			} else {
785				$thisImages .= $this->cObj->stdWrap($allRows, $conf['noRowsStdWrap.']);
786			}
787			if ($noRows)	{
788					// Only needed to make columns, rather than rows:
789				$images .= $this->cObj->stdWrap($thisImages, $conf['imageColumnStdWrap.']);
790			} else {
791				$images .= $thisImages;
792			}
793		}
794
795			// Add the global caption, if not split
796		if ($globalCaption)	{
797			$images .= $globalCaption;
798		}
799
800			// CSS-classes
801		$captionClass = '';
802		$classCaptionAlign = array(
803			'center' => 'csc-textpic-caption-c',
804			'right' => 'csc-textpic-caption-r',
805			'left' => 'csc-textpic-caption-l',
806		);
807		$captionAlign = $this->cObj->stdWrap($conf['captionAlign'], $conf['captionAlign.']);
808		if ($captionAlign)	{
809			$captionClass = $classCaptionAlign[$captionAlign];
810		}
811		$borderClass = '';
812		if ($border)	{
813			$borderClass = $conf['borderClass'] ? $conf['borderClass'] : 'csc-textpic-border';
814		}
815
816			// Multiple classes with all properties, to be styled in CSS
817		$class = '';
818		$class .= ($borderClass? ' '.$borderClass:'');
819		$class .= ($captionClass? ' '.$captionClass:'');
820		$class .= ($equalHeight? ' csc-textpic-equalheight':'');
821		$addClasses = $this->cObj->stdWrap($conf['addClasses'], $conf['addClasses.']);
822		$class .= ($addClasses ? ' '.$addClasses:'');
823
824			// Do we need a width in our wrap around images?
825		$imgWrapWidth = '';
826		if ($position == 0 || $position == 8)	{
827				// For 'center' we always need a width: without one, the margin:auto trick won't work
828			$imgWrapWidth = $imageBlockWidth;
829		}
830		if ($rowCount > 1)	{
831				// For multiple rows we also need a width, so that the images will wrap
832			$imgWrapWidth = $imageBlockWidth;
833		}
834		if ($caption)	{
835				// If we have a global caption, we need the width so that the caption will wrap
836			$imgWrapWidth = $imageBlockWidth;
837		}
838
839			// Wrap around the whole image block
840		$GLOBALS['TSFE']->register['totalwidth'] = $imgWrapWidth;
841		if ($imgWrapWidth)	{
842			$images = $this->cObj->stdWrap($images, $conf['imageStdWrap.']);
843		} else {
844			$images = $this->cObj->stdWrap($images, $conf['imageStdWrapNoWidth.']);
845		}
846
847		$output = $this->cObj->cObjGetSingle($conf['layout'], $conf['layout.']);
848		$output = str_replace('###TEXT###', $content, $output);
849		$output = str_replace('###IMAGES###', $images, $output);
850		$output = str_replace('###CLASSES###', $class, $output);
851
852		if ($conf['stdWrap.'])	{
853			$output = $this->cObj->stdWrap($output, $conf['stdWrap.']);
854		}
855
856		return $output;
857	}
858
859
860
861
862
863
864
865
866
867
868
869
870	/************************************
871	 *
872	 * Helper functions
873	 *
874	 ************************************/
875
876	/**
877	 * Returns table attributes for uploads / tables.
878	 *
879	 * @param	array		TypoScript configuration array
880	 * @param	integer		The "layout" type
881	 * @return	array		Array with attributes inside.
882	 */
883	function getTableAttributes($conf,$type)	{
884
885			// Initializing:
886		$tableTagParams_conf = $conf['tableParams_'.$type.'.'];
887
888		$conf['color.'][200] = '';
889		$conf['color.'][240] = 'black';
890		$conf['color.'][241] = 'white';
891		$conf['color.'][242] = '#333333';
892		$conf['color.'][243] = 'gray';
893		$conf['color.'][244] = 'silver';
894
895			// Create table attributes array:
896		$tableTagParams = array();
897		$tableTagParams['border'] =  $this->cObj->data['table_border'] ? intval($this->cObj->data['table_border']) : $tableTagParams_conf['border'];
898		$tableTagParams['cellspacing'] =  $this->cObj->data['table_cellspacing'] ? intval($this->cObj->data['table_cellspacing']) : $tableTagParams_conf['cellspacing'];
899		$tableTagParams['cellpadding'] =  $this->cObj->data['table_cellpadding'] ? intval($this->cObj->data['table_cellpadding']) : $tableTagParams_conf['cellpadding'];
900		$tableTagParams['bgcolor'] =  isset($conf['color.'][$this->cObj->data['table_bgColor']]) ? $conf['color.'][$this->cObj->data['table_bgColor']] : $conf['color.']['default'];
901
902			// Return result:
903		return $tableTagParams;
904	}
905
906	/**
907	 * Returns an object reference to the hook object if any
908	 *
909	 * @param	string		Name of the function you want to call / hook key
910	 * @return	object		Hook object, if any. Otherwise null.
911	 */
912	function hookRequest($functionName) {
913		global $TYPO3_CONF_VARS;
914
915			// Hook: menuConfig_preProcessModMenu
916		if ($TYPO3_CONF_VARS['EXTCONF']['css_styled_content']['pi1_hooks'][$functionName]) {
917			$hookObj = t3lib_div::getUserObj($TYPO3_CONF_VARS['EXTCONF']['css_styled_content']['pi1_hooks'][$functionName]);
918			if (method_exists ($hookObj, $functionName)) {
919				$hookObj->pObj = $this;
920				return $hookObj;
921			}
922		}
923	}
924}
925
926
927
928if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/css_styled_content/pi1/class.tx_cssstyledcontent_pi1.php'])	{
929	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['ext/css_styled_content/pi1/class.tx_cssstyledcontent_pi1.php']);
930}
931
932?>