PageRenderTime 57ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

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