Index: t3lib/class.t3lib_tsparser.php =================================================================== --- t3lib/class.t3lib_tsparser.php (revision 9230) +++ t3lib/class.t3lib_tsparser.php (working copy) @@ -581,7 +581,113 @@ } return $array; } + + /** + * Search for commented INCLUDE_TYPOSCRIPT statements + * and save the content between the BEGIN and the END line to the specified file + * + * @param string template content + * @param int Counter for detecting endless loops + * @return string template content with uncommented include statements + * @author Fabrizio Branca + */ + function extractIncludes($string, $cycle_counter=1) { + + if ($cycle_counter>100) { + t3lib_div::sysLog('It appears like TypoScript code is looping over itself. Check your templates for "<INCLUDE_TYPOSCRIPT: ..." tags','Core',2); + return $string; + } + + $fileContent = array(); + $restContent = array(); + $fileName = NULL; + $inIncludePart = false; + $lines = explode("\n", $string); + $skipNextLineIfEmpty = false; + foreach ($lines as $line) { + + // t3lib_TSparser::checkIncludeLines inserts an additional empty line, remove this again + if ($skipNextLineIfEmpty) { + if (trim($line) == '') { + continue; + } + $skipNextLineIfEmpty = false; + } + + if (!$inIncludePart) { // outside commented include statements + + // search for beginning commented include statements + $matches = array(); + if (preg_match('/### BEGIN/', $line, $matches)) { + + // found a commented include statement + $fileName = trim($matches[1]); + $inIncludePart = true; + + $expectedEndTag = '### END'; + // strip all whitespace characters to make comparision safer + $expectedEndTag = preg_replace('/\s/', '', $expectedEndTag); + } else { + // if this is not a beginning commented include statement this line goes into the rest content + $restContent[] = $line; + } + + } else { // inside commented include statements + + // search for the matching ending commented include statement + $strippedLine = preg_replace('/\s/', '', $line); + if (strpos($strippedLine, $expectedEndTag) !== false) { + + // found the matching ending include statement + $fileContentString = implode("\n", $fileContent); + + // recursive call to detected nested commented include statements + $fileContentString = self::extractIncludes($fileContentString, ++$cycle_counter); + + // write the content to the file + $realFileName = t3lib_div::getFileAbsFileName($fileName); + file_put_contents($realFileName, $fileContentString); + + // insert reference to the file in the rest content + $restContent[] = ""; + + // reset variables (preparing for the next commented include statement) + $fileContent = array(); + $fileName = NULL; + $inIncludePart = false; + // t3lib_TSparser::checkIncludeLines inserts an additional empty line, remove this again + $skipNextLineIfEmpty = true; + } else { + // if this is not a ending commented include statement this line goes into the file content + $fileContent[] = $line; + } + + } + + } + + // if we're still inside commented include statements copy the lines back to the rest content + if ($inIncludePart) { + $restContent = array_merge($restContent, $fileContent); + } + + $restContentString = implode("\n", $restContent); + return $restContentString; + } + /** + * Processes the string in each value of the input array with extractIncludes + * + * @param array Array with TypoScript in each value + * @return array Same array but where the values has been processed with extractIncludes + * @author Fabrizio Branca + */ + function extractIncludes_array($array) { + foreach ($array as $k => $v) { + $array[$k]=t3lib_TSparser::extractIncludes($array[$k]); + } + return $array; + } Index: typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php =================================================================== --- typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php (revision 9230) +++ typo3/sysext/t3editor/classes/class.tx_t3editor_hooks_tstemplateinfo.php (working copy) @@ -168,6 +168,12 @@ } } if (count($recData)) { + + // process template row before saving + require_once t3lib_extMgm::extPath('tstemplate_info').'class.tx_tstemplateinfo.php'; + $tstemplateinfo = t3lib_div::makeInstance('tx_tstemplateinfo'); /* @var $tstemplateinfo tx_tstemplateinfo */ + $recData['sys_template'][$saveId] = $tstemplateinfo->processTemplateRowBeforeSaving($recData['sys_template'][$saveId]); + // Create new tce-object $tce = t3lib_div::makeInstance('t3lib_TCEmain'); $tce->stripslashes_values = 0; Index: typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php =================================================================== --- typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php (revision 9230) +++ typo3/sysext/tstemplate_info/class.tx_tstemplateinfo.php (working copy) @@ -152,8 +152,37 @@ $tmpl->init(); $tplRow = $tmpl->ext_getFirstTemplate($pageId, $template_uid); // Get the row of the first VISIBLE template of the page. whereclause like the frontend. + $tplRow = $this->processTemplateRowAfterLoading($tplRow); return (is_array($tplRow) ? true : false); } + + /** + * Process template row after loading + * + * @param array $tplRow: template row + * @return array preprocessed template row + * @author Fabrizio Branca + */ + function processTemplateRowAfterLoading(array $tplRow) { + if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) { + $tplRow = t3lib_TSparser::checkIncludeLines_array($tplRow); + } + return $tplRow; + } + + /** + * Process template row before saving + * + * @param array $tplRow: template row + * @return array preprocessed template row + * @author Fabrizio Branca + */ + function processTemplateRowBeforeSaving(array $tplRow) { + if ($this->pObj->MOD_SETTINGS['includeTypoScriptFileContent']) { + $tplRow = t3lib_TSparser::extractIncludes_array($tplRow); + } + return $tplRow; + } /** * The main processing method if this class @@ -163,6 +192,8 @@ function main() { global $SOBE,$BE_USER,$LANG,$BACK_PATH,$TCA_DESCR,$TCA,$CLIENT,$TYPO3_CONF_VARS; global $tmpl,$tplRow,$theConstants; + + $this->pObj->MOD_MENU['includeTypoScriptFileContent'] = true; $edit = $this->pObj->edit; $e = $this->pObj->e; @@ -274,6 +305,9 @@ $recData['sys_template'][$saveId]['resources'] = $resList; } if (count($recData)) { + + $recData['sys_template'][$saveId] = $this->processTemplateRowBeforeSaving($recData['sys_template'][$saveId]); + // Create new tce-object $tce = t3lib_div::makeInstance('t3lib_TCEmain'); $tce->stripslashes_values=0; @@ -460,7 +494,20 @@ $theOutput.= $this->pObj->doc->section($GLOBALS['LANG']->getLL('setup'), ''); $theOutput.= $this->pObj->doc->sectionEnd().$outCode; } - + + // Display "Include TypoScript file content?" checkbox + if ($e['config'] || $e['constants']) { + $theOutput .= t3lib_BEfunc::getFuncCheck( + $this->pObj->id, + 'SET[includeTypoScriptFileContent]', + $this->pObj->MOD_SETTINGS['includeTypoScriptFileContent'], + 'index.php', + $e['config'] ? '&e[config]=1' : '&e[constants]=1', + 'id="checkIncludeTypoScriptFileContent"' + ); + $theOutput .= '
'; + } + // Processing: $outCode = ''; $outCode.= $this->tableRow( Index: typo3/sysext/tstemplate_info/locallang.xml =================================================================== --- typo3/sysext/tstemplate_info/locallang.xml (revision 9230) +++ typo3/sysext/tstemplate_info/locallang.xml (working copy) @@ -29,6 +29,7 @@ + \ No newline at end of file